当前位置: 首页 > news >正文

ffplay 嵌入

没成功:

方法 1:自己编译支持 -xid 的 ffmpeg(最彻底)

这个是开发者常用的方案,一劳永逸:

这个是开发者常用的方案,一劳永逸:sudo apt install build-essential yasm pkg-config libx11-dev libsdl2-dev libxext-dev libxv-dev
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
./configure --enable-gpl --enable-sdl2 --enable-libx11 --enable-x11grab --enable-opengl --enable-libx264
make -j$(nproc)
sudo make install
#!/usr/bin/env bash
set -e
WORKDIR="$HOME/ffmpeg_build_x11"
mkdir -p "$WORKDIR"
cd "$WORKDIR"# 1) 安装基础依赖(Debian/Ubuntu / 麒麟 通用)
sudo apt update
sudo apt install -y \autoconf automake build-essential cmake git libtool pkg-config nasm yasm \libx11-dev libxext-dev libxv-dev libxi-dev libxinerama-dev libxrandr-dev \libsdl2-dev libgl1-mesa-dev libpulse-dev libavcodec-dev libavformat-dev \libswscale-dev libv4l-dev libdrm-dev libx264-dev libx265-dev libfreetype6-dev \libwebp-dev libvpx-dev libopus-dev libvorbis-dev libmp3lame-dev libass-dev \libfdk-aac-dev libnuma-dev# 可选:安装一些编码库的源码(略——如果你需要更多 codec,可单独编译)
# 2) 获取 ffmpeg 源码(最新版 stable 分支)
if [ ! -d ffmpeg ]; thengit clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
elsecd ffmpeggit pullcd ..
ficd ffmpeg# 为了保险,清理
make distclean || true# 3) 配置(启用 SDL2、X11、x11grab、opengl 等)
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/lib/pkgconfig"
export PKG_CONFIG_PATH./configure \--prefix=/usr/local \--enable-gpl \--enable-nonfree \--enable-libx264 \--enable-libx265 \--enable-libvpx \--enable-libopus \--enable-libvorbis \--enable-libmp3lame \--enable-libfreetype \--enable-libwebp \--enable-libass \--enable-sdl2 \--enable-opengl \--enable-libdrm \--enable-x11grab \--enable-libx11 \--enable-shared \--disable-debug \--disable-static# 4) 编译与安装
make -j"$(nproc)"
sudo make install
sudo ldconfig# 5) 验证
echo "验证 ffplay 是否支持 -xid ..."
if ffplay -h 2>&1 | grep -q xid; thenecho "OK: ffplay 支持 -xid"
elseecho "警告: ffplay 未显示 -xid(可能编译环境还有缺失依赖)"
fiecho "完成。ffmpeg/ffplay 已安装到 /usr/local/bin"

sudo apt install xdotool x11-utils

屏幕会闪一下。

import subprocess
import sys
import time
import re
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QWindowclass FFplayEmbedHack(QWidget):def __init__(self, video_path):super().__init__()self.video_path = video_pathself.proc = Noneself.setWindowTitle("FFplay 伪嵌入版(麒麟系统 X11)")self.resize(800, 450)# 视频容器区域self.video_widget = QWidget(self)self.video_widget.setStyleSheet("background-color: black;")layout = QVBoxLayout(self)layout.addWidget(self.video_widget)self.btn = QPushButton("播放视频")layout.addWidget(self.btn)self.setLayout(layout)self.btn.clicked.connect(self.play_video)def play_video(self):if self.proc:print("视频已在播放。")return# 唯一标题,用于识别窗口self.unique_title = f"FFPLAY_{int(time.time())}"# 启动 ffplaycmd = ["ffplay","-window_title", self.unique_title,"-noborder","-loglevel", "quiet","-nostats","-autoexit",self.video_path]print("执行命令:", " ".join(cmd))self.proc = subprocess.Popen(cmd)# 延迟执行嵌入(等待 ffplay 窗口出现)QTimer.singleShot(800, self.try_embed_ffplay)def try_embed_ffplay(self):# 获取 ffplay 窗口 IDtry:out = subprocess.check_output(["xwininfo", "-name", self.unique_title], text=True)m = re.search(r"Window id: (0x[0-9a-f]+)", out)if not m:print("未找到 ffplay 窗口,稍后重试...")QTimer.singleShot(500, self.try_embed_ffplay)returnwid = m.group(1)except subprocess.CalledProcessError:print("ffplay 窗口未出现,重试中...")QTimer.singleShot(500, self.try_embed_ffplay)returnprint(f"🎬 找到 ffplay 窗口 ID: {wid}")# 获取 PyQt 子窗口 IDpyqt_wid = hex(int(self.video_widget.winId()))print(f"🎯 PyQt 容器窗口 ID: {pyqt_wid}")# 执行重父化命令subprocess.call(["xdotool", "windowreparent", wid, pyqt_wid])subprocess.call(["xdotool", "windowmove", wid, "0", "0"])subprocess.call(["xdotool", "windowsize", wid,str(self.video_widget.width()),str(self.video_widget.height())])print("✅ ffplay 已嵌入 PyQt 区域")# 定时同步大小QTimer.singleShot(500, lambda: self.adjust_ffplay_window(wid))def adjust_ffplay_window(self, wid):"""保持 ffplay 窗口与 PyQt 容器同步大小"""if self.proc and self.proc.poll() is None:subprocess.call(["xdotool", "windowsize", wid,str(self.video_widget.width()),str(self.video_widget.height())])QTimer.singleShot(500, lambda: self.adjust_ffplay_window(wid))def closeEvent(self, event):if self.proc:self.proc.terminate()event.accept()if __name__ == "__main__":app = QApplication(sys.argv)player = FFplayEmbedHack("/home/ykll/guozhan/download/prod-api/profile/2025/11/04/20ecd2f9e6704712bceefc77833c1f1b.mp4")player.show()sys.exit(app.exec_())

http://www.dtcms.com/a/572929.html

相关文章:

  • TDengine 产品组件 taosX
  • 链表相关的算法题(2)
  • 10月谷歌新政 | 涉及真金游戏、约会社交、个人贷款、医疗健康等类别App
  • python实现语音转文本STT
  • 十大免费建站app做网站公司不给源码
  • 07.docker介绍与常用命令
  • 【Docker下部署高可用】StarRocks 存算一体架构高可用部署要点
  • 小型工厂怎么找外贸客户?
  • 【Android】正式打包发布
  • 寻找做网站的合作伙伴北京北京网址建设
  • PyTorch2 Python深度学习 - 模型保存与加载
  • 南京html5网站建设今天发生的重大新闻5条
  • 台州网站排名优化公司中国石油第一建设公司官网
  • JS原型和原型链
  • Rust 赋能图片批量处理:从 ImageKit 实现到行业前沿优化实践
  • ceph osd down排查
  • Android 14 系统启动流程深度解析:内置SD卡挂载流程
  • 【Qt】大数据量表格刷新优化--只刷新可见区域
  • 基于 React 的倒计时组件实现:暴露方法供父组件状态管理
  • 2.每日机器学习——张量(Tensors)
  • wordpress换php7出错内蒙古seo公司
  • 设计模式——桥接模式(bridge)
  • 阳光家园广州网站个人网站如何做即时支付
  • Arbess零基础学习 - 使用Arbess+GitLab实现.Net 项目构建/主机部署
  • 【数据结构】PriorityQueue优先队列:基于堆(heap)实现
  • PCB设计如何防止别人抄板?
  • macOS自定义安装PlatformIO Core
  • VSCode中Copilot的询问、编辑、代理有啥区别?
  • 二重积分器(Double Integrator)
  • APP与小程序分账系统是什么?资金管理新思路,合规高效分账