在嵌入式板子上搭建和自定义live555服务器---编译问题和方法整理

本文主要是介绍在嵌入式板子上搭建和自定义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交互流程

RTSP Server RTSP Client OPTION 请求有哪些方法可用 OPTION 回应服务器所有可用方法 DESCRIBE 请求目标媒体的描述信息以初始化 DESCRIBE 回应媒体的描述信息,主要是sdp SETUP 设置会话的属性,以及传输模式,建立RTP&RTCP会话 SETUP 建立会话,返回会话标识符,以及会话相关信息 PLAY 请求播放 PLAY 回应该请求的信息 发送流媒体数据 loop [开始传输实际的视频数据] TEARDOWN 请求关闭会话 TEARDOWN 回应该请求 RTSP Server RTSP Client

此段参考出处


官方的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服务器的实践过程,查阅了很多文章,在这之中索引一部分个人觉得比较好的的文章,大家一起进步!

这篇关于在嵌入式板子上搭建和自定义live555服务器---编译问题和方法整理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1144478

相关文章

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

解决RocketMQ的幂等性问题

《解决RocketMQ的幂等性问题》重复消费因调用链路长、消息发送超时或消费者故障导致,通过生产者消息查询、Redis缓存及消费者唯一主键可以确保幂等性,避免重复处理,本文主要介绍了解决RocketM... 目录造成重复消费的原因解决方法生产者端消费者端代码实现造成重复消费的原因当系统的调用链路比较长的时

Python极速搭建局域网文件共享服务器完整指南

《Python极速搭建局域网文件共享服务器完整指南》在办公室或家庭局域网中快速共享文件时,许多人会选择第三方工具或云存储服务,但这些方案往往存在隐私泄露风险或需要复杂配置,下面我们就来看看如何使用Py... 目录一、android基础版:HTTP文件共享的魔法命令1. 一行代码启动HTTP服务器2. 关键参

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

kkFileView启动报错:报错2003端口占用的问题及解决

《kkFileView启动报错:报错2003端口占用的问题及解决》kkFileView启动报错因office组件2003端口未关闭,解决:查杀占用端口的进程,终止Java进程,使用shutdown.s... 目录原因解决总结kkFileViewjavascript启动报错启动office组件失败,请检查of

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束