ZLMediaKit是什么

ZLMediaKit一个基于C++11的高性能运营级流媒体服务框架,支持多种协议,支持协议互转,打通了视频监控协议栈与直播协议栈, 支持集群、按需转协议、按需推拉流、先播后推、断连续推等功能,支持多轨道模式(一个流中多个视频/音频)。

它的Gitee地址:https://gitee.com/xia-chu/ZLMediaKit

编译

拉取ZLMediaKit。

git clone git@gitee.com:xia-chu/ZLMediaKit.git

安装依赖库

  • 安装FFmpeg:用于处理多媒体数据,Ubuntu下执行sudo apt-get install ffmpeg

构建项目

在ZLMediaKit目录下创建build目录并进入,执行cmake..,然后执行make -j4进行编译。

cd ZLMediaKit
mkdir build
cd build
cmake ..
make -j4

问题处理

问题1: srtp 未找到, WebRTC 相关功能打开失败

cmake时遇到下面的错误

错误1:

-- srt 功能已开启
CMake Warning at webrtc/CMakeLists.txt:28 (message):
srtp 未找到, WebRTC 相关功能打开失败

解决方法:安装 SRTP 库

sudo apt-get install libsrtp2-dev

问题2:依赖库问题

-- Configuring done (2.7s)
CMake Error at 3rdpart/CMakeLists.txt:32 (add_library):
No SOURCES given to target: jsoncpp CMake Error at 3rdpart/CMakeLists.txt:55 (add_library):
No SOURCES given to target: mov CMake Error at 3rdpart/CMakeLists.txt:68 (add_library):
No SOURCES given to target: flv CMake Error at 3rdpart/CMakeLists.txt:91 (add_library):
No SOURCES given to target: mpeg CMake Error at 3rdpart/CMakeLists.txt:201 (add_library):
No SOURCES given to target: zltoolkit

ZLMediaKit 项目里有一些依赖库是通过 Git 子模块来管理的。你需要保证所有子模块都已正确初始化并且更新。在项目根目录下执行以下命令:

git submodule update --init --recursive

安装

如果需要安装到系统中,执行sudo make install

配置和运行

  • 修改配置文件:配置文件位于conf目录下,可按需修改。如修改config.ini中的apiDebug等参数。
  • 启动ZLMediaKit:在ZLMediaKit/release/linux/Debug目录下,可执行./MediaServer -h查看启动参数,
./MediaServer -h
2025-03-03 21:15:10.198 I [MediaServer] [5747-MediaServer] Factory.cpp:35 registerPlugin | Load codec: H264
2025-03-03 21:15:10.219 I [MediaServer] [5747-MediaServer] Factory.cpp:35 registerPlugin | Load codec: H265
2025-03-03 21:15:10.223 I [MediaServer] [5747-MediaServer] Factory.cpp:35 registerPlugin | Load codec: JPEG
2025-03-03 21:15:10.228 I [MediaServer] [5747-MediaServer] Factory.cpp:35 registerPlugin | Load codec: mpeg4-generic
2025-03-03 21:15:10.228 I [MediaServer] [5747-MediaServer] Factory.cpp:35 registerPlugin | Load codec: opus
2025-03-03 21:15:10.228 I [MediaServer] [5747-MediaServer] Factory.cpp:35 registerPlugin | Load codec: PCMA
2025-03-03 21:15:10.228 I [MediaServer] [5747-MediaServer] Factory.cpp:35 registerPlugin | Load codec: PCMU
2025-03-03 21:15:10.228 I [MediaServer] [5747-MediaServer] Factory.cpp:35 registerPlugin | Load codec: L16
2025-03-03 21:15:10.236 I [MediaServer] [5747-MediaServer] Factory.cpp:35 registerPlugin | Load codec: MP3
-h --help 无参 默认:null 选填 打印此信息
-d --daemon 无参 默认:null 选填 是否以Daemon方式启动
-l --level 有参 默认:1 选填 日志等级,LTrace~LError(0~4)
-m --max_day 有参 默认:7 选填 日志最多保 存天数
-c --config 有参 默认:/mnt/d/ubunt/xmr/program/cpp/ZLMediaKit/release/linux/Debug/config.ini 选填 配置文件路 径
-s --ssl 有参 默认:/mnt/d/ubunt/xmr/program/cpp/ZLMediaKit/release/linux/Debug/default.pem 选填 ssl证书文件或文件夹,支持p12/pem类型
-t --threads 有参 默认:16 选填 启动事件触 发线程数
--affinity 有参 默认:1 选填 是否启动cpu亲和性设置
-v --version 无参 默认:null 选填 显示版本号
--log-slice 有参 默认:100 选填 最大保存日 志切片个数
--log-size 有参 默认:256 选填 单个日志切 片最大容量,单位MB
--log-dir 有参 默认:/mnt/d/ubunt/xmr/program/cpp/ZLMediaKit/release/linux/Debug/log/ 选填 日志保存文 件夹路径 2025-03-03 21:15:10.441 I [MediaServer] [5747-MediaServer] logger.cpp:91 ~Logger |

./MediaServer -d &以守护进程模式启动。

sudo ./MediaServer -d &

问题处理

问题1: 无权限监听554端口

启动./MediaServer -d时显示无权限监听554端口

2025-03-03 21:41:18.193 W [MediaServer] [5879-MediaServer] sockutil.cpp:433 bind_sock6 | Bind socket failed: permission denied
2025-03-03 21:41:18.227 E [MediaServer] [5879-MediaServer] main.cpp:448 start_main | Start server failed: Listen on :: 554 failed: permission denied
2025-03-03 21:41:19.241 W [MediaServer] [5876-MediaServer] System.cpp:153 operator() | 收到主动退出信号,关闭父进程与子进程
2025-03-03 21:41:19.249 I [MediaServer] [5876-MediaServer] logger.cpp:91 ~Logger |

使用sudo执行。

问题2: 80端口已经被使用

2025-03-03 21:41:28.908 W [MediaServer] [5906-MediaServer] sockutil.cpp:433 bind_sock6 | Bind socket failed: address already in use
2025-03-03 21:41:28.967 E [MediaServer] [5906-MediaServer] main.cpp:448 start_main | Start server failed: Listen on :: 80 failed: address already in use
2025-03-03 21:41:29.973 W [MediaServer] [5903-MediaServer] System.cpp:153 operator() | 收到主动退出信号,关闭父进程与子进程
2025-03-03 21:41:29.985 I [MediaServer] [5903-MediaServer] logger.cpp:91 ~Logger |
  • 处理

    80端口被占用,是因为MediaServer处理http时,使用80端口,我采用不处理http的解决方式。

    打开MediaServer的connf.ini(和MediaServer在同一个目录下), 关闭http功能。

    将http下的port由80修改为-1
[http]
port=-1

重新启动MediaServer,查看是否启动成功(554是否监听)

sudo ./MediaServer -d &
netstat -ant | grep 554
tcp6 0 0 :::554 :::* LISTEN

推流测试

RTSP推流

准备

准备视频文件

找一段mp4视频,放到特定目录下,例如:/path/to/test.mp4, 稍后使用ffmpeg将视频推送的ZLMediaKit

安装VLC

安装VL用来拉取ZLMediaKit转发的数据流

推流

执行下面的推流命令,将test.mp4推送到 rtsp://127.0.0.1/live/test

ffmpeg -re -i "/path/to/test.mp4" -vcodec h264 -acodec aac -f rtsp -rtsp_transport tcp rtsp://127.0.0.1/live/test
  • -re:以本地帧率读取输入文件,模拟实时流。
  • -i "/path/to/test.mp4":指定输入的视频文件路径。
  • -vcodec h264:设置视频编码格式为 H.264。
  • -acodec aac:设置音频编码格式为 AAC。
  • -f rtsp:指定输出格式为 RTSP。
  • -rtsp_transport tcp:使用 TCP 作为 RTSP 传输协议。
  • rtsp://127.0.0.1/live/test:推流的目标地址,127.0.0.1 是 ZLMediaKit 服务器的 IP 地址,live 是应用名,test 是流名称。
  • 建议添加 -stream_loop -1参数,实现循环推流,否则,如果test.mp4比较小,很快会推流结束
ffmpeg -stream_loop -1 -re -i "/path/to/test.mp4" -vcodec h264 -acodec aac -f rtsp -rtsp_transport tcp rtsp://127.0.0.1/live/test

拉流验证

使用 VLC 等播放器进行拉流验证。在 VLC 中选择“媒体” -> “打开网络串流”,输入推流地址 rtsp://127.0.0.1/live/test 即可观看视频。

问题:拉流失败

如果是在windows下,使用wsl+ubuntu,在ubunut环境下启动MediaServer和推流, 则不能使用rtsp://127.0.0.1/live/test地址进行拉流。

在 WSL(Windows Subsystem for Linux)的 Ubuntu 中启动 MediaServer 并通过 FFmpeg 推 RTSP 流到 rtsp://127.0.0.1/live/test ,在 Windows 下使用 VLC 播放时,需要注意 WSL 和 Windows 之间的网络通信情况。

  • 获取 WSL 的 IP 地址

    在 WSL 的 Ubuntu 终端中,使用以下命令获取 WSL 的 IP 地址:
ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'

该命令会输出 WSL 的 IP 地址,例如 172.28.224.1。

  • 在 VLC 中设置 RTSP 路径

    在 Windows 下打开 VLC 播放器,选择 “媒体” -> “打开网络串流”,在输入框中输入 RTSP 路径,格式为:

    plaintext

    rtsp://<WSL的IP地址>/live/test

例如,如果 WSL 的 IP 地址是 172.28.224.1,则输入 rtsp://172.28.224.1/live/test,然后点击 “播放” 按钮。

ZLMediaKit 在 RTSP 推流测试中的作用

接收推流数据

ZLMediaKit 作为 RTSP 服务器,监听指定的端口(默认 554),等待客户端(如 FFmpeg)发起的 RTSP 推流请求。当接收到请求后,它会与客户端建立 RTSP 会话,并接收客户端发送的音视频流数据

协议处理

  • RTSP 协议解析:ZLMediaKit 会对 RTSP 协议进行解析,处理客户端发送的各种 RTSP 请求,如 OPTIONS、DESCRIBE、SETUP、PLAY 等,确保会话的正常建立和数据的正确传输。
  • RTP/RTCP 处理:RTSP 通常与 RTP(Real-time Transport Protocol)和 RTCP(Real-time Transport Control Protocol)一起使用。ZLMediaKit 会处理 RTP 数据包,将其还原为音视频流,并通过 RTCP 协议进行流的控制和反馈。

流管理

  • 流注册:当接收到新的推流时,ZLMediaKit 会将该流进行注册,记录流的相关信息,如流名称、应用名、编码格式等。
  • 流分发:ZLMediaKit 可以将接收到的流分发给多个拉流客户端。当有拉流请求时,它会根据流的注册信息,将相应的流数据发送给拉流客户端。

存储和转发

  • 存储:ZLMediaKit 支持将接收到的流数据进行存储,如保存为本地文件或写入数据库,方便后续的回放和分析。
  • 转发:可以将接收到的流转发到其他服务器,实现流的多级分发和跨网络传输。

流的流转过程

推流阶段

  1. 客户端发起请求:FFmpeg 作为推流客户端,向 ZLMediaKit 服务器发送 RTSP OPTIONS 请求,询问服务器支持的 RTSP 方法。
  2. 服务器响应:ZLMediaKit 服务器收到 OPTIONS 请求后,返回支持的 RTSP 方法列表。
  3. 客户端发送 DESCRIBE 请求:FFmpeg 发送 DESCRIBE 请求,获取服务器上的媒体描述信息(SDP,Session Description Protocol)。
  4. 服务器返回 SDP:ZLMediaKit 服务器返回 SDP 信息,包含音视频流的编码格式、传输地址等信息。
  5. 客户端发送 SETUP 请求:FFmpeg 根据 SDP 信息,发送 SETUP 请求,设置传输通道和参数。
  6. 服务器响应 SETUP:ZLMediaKit 服务器响应 SETUP 请求,确认传输通道和参数。
  7. 客户端发送 PLAY 请求:FFmpeg 发送 PLAY 请求,开始推流。
  8. 数据传输:FFmpeg 将音视频数据封装成 RTP 数据包,通过 TCP 或 UDP 发送给 ZLMediaKit 服务器。

拉流阶段

  1. 拉流客户端发起请求:VLC 等拉流客户端向 ZLMediaKit 服务器发送 RTSP OPTIONS 请求。
  2. 服务器响应:ZLMediaKit 服务器返回支持的 RTSP 方法列表。
  3. 拉流客户端发送 DESCRIBE 请求:获取媒体描述信息。
  4. 服务器返回 SDP:ZLMediaKit 服务器返回 SDP 信息。
  5. 拉流客户端发送 SETUP 请求:设置传输通道和参数。
  6. 服务器响应 SETUP:确认传输通道和参数。
  7. 拉流客户端发送 PLAY 请求:开始拉流。
  8. 数据传输:ZLMediaKit 服务器将接收到的音视频流数据封装成 RTP 数据包,发送给拉流客户端。

ZLMediaKit: 快速入门的更多相关文章

  1. Web Api 入门实战 (快速入门+工具使用+不依赖IIS)

    平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html 屁话我也就不多说了,什么简介的也省了,直接简单概括+demo ...

  2. SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)

     SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/si ...

  3. 前端开发小白必学技能—非关系数据库又像关系数据库的MongoDB快速入门命令(2)

    今天给大家道个歉,没有及时更新MongoDB快速入门的下篇,最近有点小忙,在此向博友们致歉.下面我将简单地说一下mongdb的一些基本命令以及我们日常开发过程中的一些问题.mongodb可以为我们提供 ...

  4. 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  5. 【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  6. Mybatis框架 的快速入门

    MyBatis 简介 什么是 MyBatis? MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及结果 ...

  7. grunt快速入门

    快速入门 Grunt和 Grunt 插件是通过 npm 安装并管理的,npm是 Node.js 的包管理器. Grunt 0.4.x 必须配合Node.js >= 0.8.0版本使用.:奇数版本 ...

  8. 【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  9. 【第四篇】ASP.NET MVC快速入门之完整示例(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  10. Vue.js 快速入门

    什么是Vue.js vue是法语中视图的意思,Vue.js是一个轻巧.高性能.可组件化的MVVM库,同时拥有非常容易上手的API.作者是尤雨溪,写下这篇文章时vue.js版本为1.0.7 准备 我推荐 ...

随机推荐

  1. 如何在Linux上使用pbcopy和pbpaste命令

    由于 Linux 和 Mac OS X 是基于 *Nix 的系统,因此许多命令可以在两个平台上运行.但是,某些命令可能在两个平台上都没有,比如 pbcopy 和 pbpast.这些命令仅在 Mac O ...

  2. 9.4classtest rewrite(仓库管理系统)

    第一部分,设计界面以及类的定义. import java.util.Scanner; public class viovo { static int number = 5;//五个商品信息 stati ...

  3. error C2065: “CV_DATA_AS_ROW”: 未声明的标识符

    ce_dect\main_face.cpp(117): error C2065: "CV_DATA_AS_ROW": 未声明的标识符将 "CV_PCA_DATA_AS_R ...

  4. 跟着源码学IM(八):万字长文,手把手教你用Netty打造IM聊天

    本文作者芋艿,原题"使用 Netty 实现 IM 聊天贼简单",本底价有修订和改动. 一.本文引言 上篇<跟着源码学IM(七):手把手教你用WebSocket打造Web端IM ...

  5. Centos-基础配置

    切换下载源到阿里云 备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 下载新的 Cent ...

  6. 今天记录一下css布局的flex布局的一个小妙招之gap

    在平常前端开发中,常见的开发布局flex布局,常见的布局有这个样子,这个是可以用css进行修改,但是今天分享一个简单的方法 这种布局的话,如果是偶数的话可以用flex的 justify-content ...

  7. 监听sessionStorage中值的变化

    应用场景:将登录接口所返回的用户信息存入sessionStorage,在其他地方需要使用到用户信息,但不知道什么时候接口请求完,此时可以监听sessionStorage中值的变化. 应用:Event自 ...

  8. (七).NET6.0部署RabbitMQ

    1.下载erlang语言包OTP.官网地址: https://www.erlang.org/downloads 2.Rabbitmq官网下载地址: https://www.rabbitmq.com/d ...

  9. CentOS扩容boot分区并升级内核

    本文作者CVE-柠檬i:https://www.cnblogs.com/CVE-Lemon 前言 由于安装k8s需要升级内核,但我自己的的boot分区只有200M大小,无法安装新内核,所以干脆把swa ...

  10. GD32F4xx FLASH存储

    一.GD32F4xx的内存 GD32F4xx的内存结构由:主存储器.系统信息存储器.一次性编程区域和选项字节等 4 部分组成. 主存储器:用来存放代码和数据常数(如 const 类型的数据).分为 2 ...