在嵌入式板子上搭建和自定义live555服务器---编译问题和方法整理
live555 官方网站
点我直达,live555是一个简单的专注于实现RTSP服务器的开源库。它自带解析H264 H265 mp3等源的API,有一个简单的推流文件参考RTSP服务器例程testH264VideoStreamer
也有官方实现的LIVE555 Media Server
。无论是命令行使用还是用API实现定制需求是很方便的。
图龙宝刀点击下载
文章目录
- live555 官方网站
- 编译过程 && 问题:
- 板上执行
- live555 简单分析
- 一次标准的RTSP交互流程
- 官方的H264例程分析
- 如何实现一个自己的RTSP流(.h264)
- 后记
编译过程 && 问题:
解压
tar -gzvf live.2024.04.19.tar.gz
编译是执行genMakefiles you_choice
,生成MakeFile,然后再走流程,官方提供了一个默认的交叉编译config.armlinux
,我们复制一份,自行复制成config.myarmlinux
后,进行修改:
CROSS_COMPILE?= /home/qd06/ak39AV100-v109/tools/gcc-build/arm-anycloud-linux-uclibcgnueabi/bin/arm-linux-
COMPILE_OPTS = $(INCLUDES) -I. -O2 -DSOCKLEN_T=socklen_t -DNO_SSTREAM=1 -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -DNO_OPENSSL=1 -DLOCALE_NOT_USED
C = c
C_COMPILER = $(CROSS_COMPILE)gcc
C_FLAGS = $(COMPILE_OPTS)
CPP = cpp
CPLUSPLUS_COMPILER = $(CROSS_COMPILE)g++
CPLUSPLUS_FLAGS = $(COMPILE_OPTS) -Wall -DBSD=1 -Wno-deprecated -std=c++11 -std=gnu++11
OBJ = o
LINK = $(CROSS_COMPILE)g++ -o
LINK_OPTS =
CONSOLE_LINK_OPTS = $(LINK_OPTS)
LIBRARY_LINK = $(CROSS_COMPILE)ar cr
LIBRARY_LINK_OPTS = $(LINK_OPTS)
LIB_SUFFIX = a
# 我这个设备是嵌入式局域网,不需要openssl
#LIBS_FOR_CONSOLE_APPLICATION = -lssl -lcrypto
LIBS_FOR_GUI_APPLICATION =
EXE =
# 指定make install 后的输出目录
PREFIX = /home/qd06/live555/output
$COMPILE_OPTS
的部分选项:
NO_OPENSSL=1
不需要openssl, 如果需要ssl,可以在这个链接获取
LOCALE_NOT_USED
点这,在live555下载与交叉编译章节处
$CPLUSPLUS_FLAGS
部分选项:
-Wno-deprecated
官方文档要求的 If you’re using “gcc” version 3.0 or greater: You may also wish to add the -Wno-deprecated flag to CPLUSPLUS_FLAGS.
-std=c++11 -std=gnu++11
我这个版本的live555使用了11语法,要加上这个支持.
执行生成Makefile:
./genMakefiles myarmlinux
执行make
make -j4
我这里遇到的问题就是
简单查阅了一下,原来是 std::atomic_flag没有这个test方法,于是根据这个修改方法为test_and_set()
即可。
- 有的朋友可能遇到奇奇怪怪的编译顺序问题,类似live555 undefined reference to `HashTable::create(int)'这样,找不到实现的方法了,根据这个博主的方法可以妥善解决。
一般到这里也解决了,如果在引入项目后编译时报错找不到实现,可以根据这篇文章修改索引库的顺序为libliveMedia.a libBasicUsageEnvironment.a libgroupsock.a libUsageEnvironment.a
,即可。保证libliveMedia.a
是首位即可。
板上执行
live555默认是静态库编译的,编译完成后可以直接去bin文件夹里获取可执行文件,这里我们使用官方自带的很完善的RTSP服务器live555MediaServer
: 文档直达
./live555MediaServer
输出以下内容就算成功:
live555 简单分析
一次标准的RTSP交互流程
此段参考出处
官方的H264例程分析
官方有一个简单的H264示例程序,里面实现了点播各种音视频文件的简单服务器testH264VideoStreamer
,根据这个示例程序可以简单地了解live555的部分API使用。
可以看到大概流程是这样:
- 新建一个空的RTSP 服务(这一步可以继承,定制自己的RTSP服务),设置了默认端口
- 创建源服务媒体会话
ServerMediaSession
,设置会话名字及描述,客户端通过会话名字发起请求。 - 给这个会话添加一个实际执行的运行会话
ServerMediaSubsession
,这个会话就是负责具体解码推流工作的(如果要定制流服务,就从这里继承和修改)。 音频和视频是分开的两个会话。 - 将这个源服务媒体会话添加到RTSP服务里去。
这里附上一篇源码分析这个博主讲了服务器主进程和消息循环,个人觉得讲的还可以。
这是整个live555源码的文件功能分类,在官方文档的Description也有讲解。
上图出处文章有简单介绍RTSP和RTP、TCP、UDP的层级关系。还通过修改源码实现了实时直播,适合刚入手时阅读。
如何实现一个自己的RTSP流(.h264)
live555的RTSP部分已经很完善,要实现自己的推流小项目,可以以testOnDemandRTSPServer
为服务端基础,以testRTSPClient
为客户端基础,自定义源的读取和写入以实现传输h264视频。
- 发送端 (
testOnDemandRTSPServer
为服务端基础) :
目的是让live555能读到自己的流,参考官方实现的H264VideoFileServerMediaSubsession::createNewStreamSource
返回的FramedSource
基类,看定义应该是负责控制流读取用的,需要实现的重要函数是doGetNextFrame
。
这里是实际流读取数据帧的地方,可以参考官方用的ByteStreamFileSource
来实现读取流(这个是基于FIFO or unix socket的文件读取,如果是其他的源读取方法可以看liveMedia
目录。设备buffer流也可以参考DeviceSource
)。
fFrameSize
是要写入的数据长度,把你的数据拷贝给fTo
指针即可。
流控制操作则是H264VideoFileServerMediaSubsession
,它继承于OnDemandServerMediaSubsession
如果想进一步自定义服务端,推荐阅读这篇博客,比较详细的live555整体结构学习。值得花时间细读
- 接收端 (
testRTSPClient
为客户端基础):
根据上面大佬的文章(文章是15年写的,2024年版的live555可能有点不一样,但逻辑是不变的),可以看到,最终是在DummySink::afterGettingFrame
里的fReceiveBuffer
指针获取到每一帧数据,这里可以丢去解码或者用FIFO之类的保存文件。这有个保存文件的例子
如果修改完后,不知道怎么编译。那就在live555源码的编译日志里看testOnDemandRTSPServer.cpp的编译语句是咋样的,参考它去写Makefile就行。
后记
live555只是个流媒体服务器,视频流可以是文件也可以是摄像头。一般用摄像头做输入比较多。之前有接触过ffmpeg的使用,要读取摄像头也许还能通过ffmpeg获取,再推送到局域网内搭建的RTSP服务器(GStreamer 或live555),这样来实现网络摄像头的功能。
- 参考这篇文章,介绍在ffmpeg里怎么把流保存成MP4文件,和推送到RTSP服务器,先记录下来。
- 如果大家有更好的方案或者文章讲解,欢迎在评论区留言! 大家一起学习
以上是个人在搭建RTSP服务器的实践过程,查阅了很多文章,在这之中索引一部分个人觉得比较好的的文章,大家一起进步!