# gstreamer_python_learn **Repository Path**: pivotfuture/gstreamer_python_learn ## Basic Information - **Project Name**: gstreamer_python_learn - **Description**: No description available - **Primary Language**: Python - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-12 - **Last Updated**: 2025-11-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # GStreamer Python 示例 这个项目包含三个GStreamer Python示例,演示如何使用Python和GStreamer播放本地视频文件、RTSP流以及保存RTSP流到本地文件。 ## 项目结构 ``` gstreamer_python_learn/ ├── play_local_video_file/ # Demo1 播放本地视频文件 │ └── play_local_video.py ├── play_rtsp_stream/ # Demo2 播放RTSP流 │ └── play_rtsp_stream.py ├── save_rtsp_stream/ # Demo3 保存RTSP流到本地文件 │ └── save_rtsp_stream.py ├── data/ # 视频文件目录 │ └── 1.mp4 # 示例视频文件 ├── requirements.txt # Python依赖 └── README.md # 说明文档 ``` ## 环境要求 **⚠️ 重要提示:不要使用PowerShell运行这些脚本,请使用命令提示符(cmd)** ### 1. 安装GStreamer #### Windows 1. 从 [GStreamer官网](https://gstreamer.freedesktop.org/download/) 下载Windows安装包 2. 安装时选择"Complete"安装选项 3. 确保将GStreamer的bin目录添加到系统PATH中 ### 2. 安装Python依赖 ```bash pip install -r requirements.txt ``` ## 使用方法 ### Demo1 播放本地视频文件/play_local_video_file #### 方法1:在项目根目录运行(推荐) ```bash # 在项目根目录下运行 python play_local_video_file/play_local_video.py data/1.mp4 ``` #### 方法2:进入脚本目录运行 ```bash # 先进入脚本目录 cd play_local_video_file # 然后运行脚本(注意路径要指向data目录) python play_local_video.py ../data/1.mp4 ``` **完整示例:** ```bash # 示例1:播放data目录中的1.mp4 python play_local_video_file/play_local_video.py data/1.mp4 # 示例2:播放其他位置的视频文件 python play_local_video_file/play_local_video.py /path/to/your/video.mp4 # 示例3:进入脚本目录后运行 cd play_local_video_file python play_local_video.py ../data/1.mp4 ``` **支持格式:** - MP4, AVI, MKV, MOV, WMV - 几乎所有GStreamer支持的视频格式 ### Demo2 播放RTSP流/play_rtsp_stream #### 方法1:在项目根目录运行(推荐) ```bash # 在项目根目录下运行 python play_rtsp_stream/play_rtsp_stream.py rtsp://192.168.2.199/1 ``` #### 方法2:进入脚本目录运行 ```bash # 先进入脚本目录 cd play_rtsp_stream # 然后运行脚本 python play_rtsp_stream.py rtsp://192.168.2.199/1 ``` **完整示例:** ```bash # 示例1:播放指定IP的RTSP流(默认端口) python play_rtsp_stream/play_rtsp_stream.py rtsp://192.168.2.199/1 # 示例2:播放自定义端口的RTSP流 python play_rtsp_stream/play_rtsp_stream.py rtsp://192.168.2.199:554/stream ``` **测试RTSP流地址:** - `rtsp://192.168.2.199/1` - 本地局域网RTSP流(默认端口554) - `rtsp://192.168.2.199:554/1` - 指定端口554 ### Demo3 保存RTSP流到本地文件/save_rtsp_stream #### 方法1:在项目根目录运行(推荐) ```bash # 在项目根目录下运行 python save_rtsp_stream/save_rtsp_stream.py rtsp://192.168.2.199/1 ``` #### 方法2:进入脚本目录运行 ```bash # 先进入脚本目录 cd save_rtsp_stream # 然后运行脚本 python save_rtsp_stream.py rtsp://192.168.2.199/1 ``` **完整示例:** ```bash # 示例1:保存RTSP流到默认文件 output.mp4 python save_rtsp_stream/save_rtsp_stream.py rtsp://192.168.2.199/1 # 示例2:保存RTSP流到指定文件 python save_rtsp_stream/save_rtsp_stream.py rtsp://192.168.2.199/1 my_video.mp4 # 示例3:保存自定义端口的RTSP流 python save_rtsp_stream/save_rtsp_stream.py rtsp://192.168.2.199:554/stream output.mp4 ``` **功能说明:** - 直接保存H.264编码流,不需要解码,文件小且速度快 - 自动封装为MP4格式,可直接播放 - 支持自定义输出文件名 - 按 `Ctrl+C` 停止保存 **注意事项:** - 如果RTSP流没有时间戳(PTS),可能会遇到 "Buffer has no PTS" 错误 - 建议使用稳定的RTSP流源(如EasyDarwin、FFmpeg推流等) - 保存的文件大小取决于RTSP流的码率和保存时长 ## 功能特性 ### 本地视频播放器 - 支持多种视频格式 - 自动解码和渲染 - 错误处理和状态监控 - 键盘中断支持(Ctrl+C) ### RTSP流播放器 - 实时网络流播放(支持rtspsrc) - 低延迟配置(latency=0 + sync=false)适合实时流 - 使用TCP协议(protocols=tcp)确保稳定性 - H.264解码流程(rtph264depay -> h264parse -> decodebin) - 跨平台兼容(使用decodebin自动选择最佳解码器) - 网络错误处理和流状态监控 - 键盘中断支持(Ctrl+C) ### RTSP流保存器 - 直接保存H.264编码流,无需解码,文件小且速度快 - 自动封装为MP4格式(使用mp4mux) - 支持自定义输出文件名 - 使用TCP协议(protocols=tcp)确保稳定性 - H.264处理流程(rtph264depay -> h264parse -> mp4mux) - 网络错误处理和流状态监控 - 键盘中断支持(Ctrl+C) ## 控制说明 - **停止播放:** 按 `Ctrl+C` - **查看状态:** 程序会显示管道状态变化 - **错误处理:** 自动显示错误和警告信息 ## 故障排除 ### 常见问题 1. **"No module named 'gi'"** - 安装PyGObject:`pip install PyGObject` 2. **"GStreamer not found"** - 确保GStreamer已正确安装 - 检查PATH环境变量 3. **"无法播放视频"** - 检查文件路径是否正确 - 确认视频格式受支持 - 查看错误信息 4. **"RTSP连接失败"** - 检查网络连接 - 验证RTSP地址是否正确 - 确认流服务器可访问 5. **"Buffer has no PTS"(保存RTSP流时)** - 这是时间戳问题,通常是因为RTSP流没有提供时间戳 - 确保RTSP流源正确配置时间戳(如使用FFmpeg推流时) - 如果使用EasyDarwin等流媒体服务器,确保服务器正确传递时间戳 - 某些RTSP服务器可能不提供时间戳,建议使用稳定的流源 6. **"保存的MP4文件无法播放"** - 确保管道正确使用mp4mux封装(不要使用decodebin) - 检查输出文件是否完整(确保没有中途中断) - 验证RTSP流是否为H.264编码(其他编码格式需要调整管道) ### 调试模式 如果需要更详细的调试信息,可以设置环境变量: ```bash # Windows set GST_DEBUG=3 python play_local_video.py video.mp4 # Linux/macOS GST_DEBUG=3 python play_local_video.py video.mp4 ``` ## 技术说明 ### GStreamer 核心组件关系 #### gi、Gst、GLib 组件架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ Python应用程序 │ ├─────────────────────────────────────────────────────────────┤ │ gi (GObject Introspection) │ │ ├─ 提供Python到C/C++的绑定 │ │ ├─ 自动类型转换 │ │ └─ 版本管理 │ ├─────────────────────────────────────────────────────────────┤ │ Gst (GStreamer Core) │ │ ├─ 管道管理 (Pipeline) │ │ ├─ 元素系统 (Elements) │ │ ├─ 消息总线 (Message Bus) │ │ └─ 状态管理 (State Management) │ ├─────────────────────────────────────────────────────────────┤ │ GLib (GObject Library) │ │ ├─ 主循环 (Main Loop) │ │ ├─ 事件处理 (Event Handling) │ │ ├─ 定时器 (Timers) │ │ └─ 线程支持 (Threading) │ ├─────────────────────────────────────────────────────────────┤ │ C/C++ GStreamer库 (底层实现) │ └─────────────────────────────────────────────────────────────┘ ``` #### 组件详细说明 | 组件 | 作用 | 关键功能 | 依赖关系 | |------|------|----------|----------| | **gi** | Python绑定系统 | 版本管理、类型转换、跨语言支持 | 独立组件 | | **Gst** | 音视频处理核心 | 管道管理、元素系统、消息处理 | 依赖GLib | | **GLib** | 底层系统服务 | 主循环、事件处理、线程管理 | 独立基础库 | **重要说明:** - ✅ **GLib是独立的**:可以单独使用,不是GStreamer的一部分 - ✅ **GStreamer依赖GLib**:需要GLib提供基础服务 - ✅ **GLib更底层**:提供系统抽象 - ✅ **GStreamer更专业**:专注于音视频处理 ### GStreamer Bus 和 Pipeline 关系 #### Bus 的作用 - Bus就是软件上的消息总线对象 - `bus.add_signal_watch()` 启用消息总线监听 - 建立管道后台线程与主线程的通信桥梁 - 确保消息回调函数能够被正确触发 #### Bus 与 Pipeline 的关系 - **一对一绑定**:每个pipeline有且仅有一个bus - **生命周期一致**:pipeline创建时bus创建,pipeline销毁时bus销毁 - **不能共享**:不同pipeline的bus不能混用 - **消息隔离**:每个bus只接收自己pipeline的消息 #### 代码示例 ```python # 获取pipeline专属的bus bus = self.pipeline.get_bus() # 启用信号监听(必需步骤) bus.add_signal_watch() # 连接消息处理函数 bus.connect("message", self.on_message) ``` #### 多Pipeline场景 ```python # 每个pipeline都需要自己的bus pipeline1 = Gst.parse_launch("filesrc ! decodebin ! autovideosink") pipeline2 = Gst.parse_launch("rtspsrc ! decodebin ! autovideosink") bus1 = pipeline1.get_bus() # pipeline1的专属bus bus2 = pipeline2.get_bus() # pipeline2的专属bus ``` ## 扩展功能 这些示例可以进一步扩展: 1. **添加音频支持** 2. **实现播放控制(暂停、快进等)** 3. **添加GUI界面** 4. **支持更多流协议(HTTP、UDP等)** 5. **支持更多编码格式(H.265、VP8等)** 6. **录制功能** ## 许可证 本项目仅用于学习和演示目的。