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 的电脑上可能会报错,可能还需要进一步裁剪插件或做其他处理,这块我就没有继续测试了。

浙公网安备 33010602011771号