Windows 下用 Python + GStreamer 推 RTSP 流并注入 SEI,以及pyinstaller打包

代码仓库:https://github.com/zhyx1996/GStreamer-SEI

网上 Windows + Python + GStreamer + 打包 的攻略比较少,踩了好多坑,简单记录一下。

1. 环境安装

有两种方式。

方式一:直接 pip 安装

需要 Python > 3.8:

pip install gstreamer-bundle

安装后可以直接:

import gi

方式二:使用官方 MSVC 安装程序

下载地址:https://gstreamer.freedesktop.org/download/

安装时选择:

  • runtime
  • devel
  • 勾选自动设置环境变量 GSTREAMER_1_0_ROOT_MSVC_X86_64

然后安装 Python 绑定:

pip install pygobject pycairo

这种方式在 Python >= 3.8 的环境下,好像还需要手动用os.add_dll_directory,把 %GSTREAMER_1_0_ROOT_MSVC_X86_64%(GStreamer安装目录) 的 bin 目录加进去,才能正确找到 DLL。

原因可能是 Python 3.8 开始,DLL 搜索规则变了,不会像以前那样直接到系统 PATH 里找 DLL。

2. 插入 SEI

或许可以直接用 GstCodecParsers 来创建 SEI,但是我导入时缺了 typelib,于是干脆自己一字节一字节写了。

需要注意创建 NAL 的时候要做防竞争处理(详见代码)。

也就是在:

00 00 {00, 01, 02, 03}

之间插入一个 03,变成:

00 00 03 {00, 01, 02, 03}

如果不加,可能会触发 start code 误匹配,最后导致传进去的 payload 和接收到的 payload 不一致。

3. PyInstaller 打包

一开始用 MSVC 安装包安装的环境,直接:

pyinstaller --onefile demo.py

好像也能运行,但需要其他电脑上也装好 GStreamer,并且似乎还会报一些奇怪的错误来着?

后来卸载了安装包,改成在虚拟环境里用 pip 安装:

pip install gstreamer-bundle pyinstaller pyinstaller-hooks-contrib

然后在 import gi 之前加:

import gstreamer_libs
gstreamer_libs.setup_python_environment()

再在 PyInstaller 的 spec 文件里,把用到的 gi 模块加入 hiddenimports,并且用 collect_all 收集相关的 GStreamer 包,就可以脱离本机环境单独运行了。

大致包括:

hiddenimports = [
    "gi",
    "gi.repository.Gst",
    "gi.repository.GstApp",
    "gi.repository.GLib",
    "gi.repository.GObject",
    "gi.repository.Gio",
]

以及:

from PyInstaller.utils.hooks import collect_all

for package in [
    "gstreamer_libs",
    "gstreamer_plugins",
    "gstreamer_plugins_libs",
    "gstreamer_plugins_restricted",
    "gstreamer_plugins_gpl",
    "gstreamer_plugins_gpl_restricted",
    "gstreamer_python",
    "gstreamer_ext_runtime",
]:
    package_datas, package_binaries, package_hiddenimports = collect_all(package)

不过这样打包默认会把 NVIDIA 相关的 DLL 也打进去。在没有 GPU 的电脑上可能会报错,可能还需要进一步裁剪插件或做其他处理,这块我就没有继续测试了。

posted @ 2026-06-30 16:21  扶摇接海  阅读(2)  评论(0)    收藏  举报