live555移植到hi3516做rtsp服务器

live555移植到hi3516做rtsp服务器,第1张

live555库本身实现了做rtsp服务器,客户端可以通过rtsp客户端访问服务器上的文件并播放,支持的文件格式如下:

本次任务实现了把live555移植到嵌入式海思芯片hi3516上做rtsp服务器,除了支持客户端播放服务器上上面格式文件外,另添加了实时播放hi3516摄像头图像与音频的功能。

live555源码目录如下:

四个基本的库分别是:BasicUsageEnvironment, groupsock, liveMedia和UsageEnvironment。

编译后即生成这4个库文件:

这里我只简单说下liveMedia库的功能,其他三个库是live555运行的基础库,太(mei)简(yan)单(jiu),就不说了。

liveMedia库包含了音视频相关的所有功能,包含音视频文件的解析,RTP传输封装等,我们可以看到这个目录下有对h264、AAC等文件解析的支持:

交叉编译过程:略

这里我主要是修改mediaServer文件夹下的示例程序,添加实时预览摄像头图像与mic声音功能。

hi3516芯片,视频编码格式为h264,音频编码格式为AAC。

1.添加音频AAC支持

添加类 ADTSAudioLiveSource ,继承自FramedSource

在该类的doGetNextFrame函数里实现获取hi3516音频数据做为rtsp服务器音频源。

注意点:

1.1 adts默认是带7字节或者9字节的头,传给rtsp的时候是要去掉头的,实际上RTSP通过rtp传输AAC帧的时候是不带adts头的,而是带4个字节的mpeg4-generic头。

1.2 从FramedSource继承而来的变量

每次doGetNextFrame帧时,从FIFO里取一个完整的AAC帧,把帧拷贝到fTo buf里面,然后比较帧大小与fMaxSize来赋值几个关键的变量:

注意,不管帧长是否大于fMaxSize,每次都需要把完整的帧拷贝到fTo指针,live555内部会根据fNumTruncatedBytes等变量自行处理分包。

1.3 doGetNextFrame函数最后不管有没有取到帧,都需要执行FramedSource::afterGetting

1.4 采样率,通道数,configstr等的计算

这几个变量在mediaSubbsession建立RTPsink时要用到,它直接影响了SDP里对于AAC音频描述字段的产生

添加类 AACAudioLiveServerMediaSubsession ,继承自ADTSAudioFileServerMediaSubsession

createNewStreamSource函数创建上面的ADTSAudioLiveSource做为音频输入源,参数estBitrate为预估的码率,海思AAC编码码率设置为24kbps,所以estBitrate设置为24.

createNewRTPSink有必要继承,因为需要根据音频源的采样率、通道数等创建RTPSink.

2.添加h264支持

添加 H264FramedLiveSource ,继承自FramedSource

unsigned maxFrameSize()函数必须继承,里面设置帧最大可能的大小,我设置为100000,如果不继承就是默认的,会出现画面马赛克

doGetNextFrame函数里面和AAC取帧的处理差不多,我加多了一个步骤,就是第一次取帧的时候会调用接口去产生一个关键帧,并且等待这个关键帧到来才处理,这样连接后出图会比较快。

添加类 H264VideoLiveServerMediaSubsession ,继承自H264VideoFileServerMediaSubsession

这个类就是实现createNewStreamSource时创建H264FramedLiveSource

3.修改DynamicRTSPServer

修改类DynamicRTSPServer,在lookupServerMediaSession函数里动点手脚,默认在这个函数里面会根据文件名去寻找服务器下相应的文件做为直播源,我这里比较如果是我特定的live源名字则直接返回,相应的live源创建rtsp服务器的时候就添加好

4.初始化rtsp server

初始化rtsp服务器,添加一个ServerMediaSession,该mediaSession添加一个AACAudioLiveServerMediaSubsession和一个H264VideoLiveServerMediaSubsession,然后把该mediaSession添加给rtsp服务器。

客户端访问 rtsp://x.x.x.x/ch0.live 时就可以看到实时的摄像头图像与声音啦!

rtsp流在主流浏览器并不支持直接播放。比如大华的视频流:rtsp://admin:123456@

192.168.10.129/cam/realmonitor?channel=1&subtype=0,用vlc可以直接播放。但在浏览器会报ERR_UNKNOWN_URL_SCHEME。那如何在浏览器中播放呢。

以下列出几种方案。

1、安装插件(chrome最新版基本都不支持)

类如:kurento,vlc插件(谷歌浏览器版本41以下),vgx插件(不支持高版本,chrome72.0版本可用)等。

2、安装软件(中间件,基本都付费)

类如:Appemit(调用vlc插件播放rtsp),可以免安装的,目前只能windows,免费版会有提示。

猿大师中间件(底层调用VLC的ActiveX控件,实现在主流浏览器网页中内嵌播放多路RTSP的实时视频流),中间件收费的。

PluginOK(牛插)中间件。底层调用ActiveX控件VlcOcx.dll。(商业用途需付费使用)

3、服务器拉流转发及协议转换

示意图如下所示:

推流--------------服务器转发--------------拉流

方法一览:

a,vlc软件串流到http协议 ,网页显示几个视频需启动几个vlc,只适合应急场景。

b,html5 + websocket_rtsp_proxy 实现视频流直播 ,基于MSE(Media Source Extensions,W3C),扩展H5的功能。

步骤:服务器安装streamedian服务器,客户端通过video标签播放。

原型图:

价格:

c.基于nginx的rsmp转发

基于nginx实现rtmp转化,用flash实现播放。由于flash目前大多浏览器默认禁用,不推荐此方式。

步骤:安装ffmpeg工具,安装nginx。

另外nginx-rtmp-module也支持HLS协议,可以搭建基于hls的直播服务器。

d.rtsp转hls播放,通过ffmpeg转码

步骤:安装ffmpeg工具,ffmpeg转码。

形如:

ffmpeg -i "rtsp://admin:123456@192.168.10.129/cam/realmonitor?channel=1&subtype=0" -c copy -f hls -hls_time 2.0 -hls_list_size 0 -hls_wrap 15 "D:/hls/test.m3u8"

缺点是直播流延时很大,对实时要求比较高的不满足要求。

案例:基于EasyDarwin拾建转码服务器。参考地址:https://blog.csdn.net/jyt0551/article/details/84189498

通过存储的m3u8去读取。

e.websocket代理推送,FFMPEG转码

此方法与a,b类似。但更实用。

以下提供两种方案:

(1)Gin+WebSocket+FFMPEG实现rtsp转码,参考:https://juejin.cn/post/6844904024072798216

通过FFMPEG把rstp转成http,ginrtsp作为转发服务器,但需要自己写相应接口,需要了解go语言。

(2)node + ffmpeg + websocket + flv.js,参考:https://juejin.cn/post/6908641550046068744

步骤:在node服务中建立websocket;通过fluent-ffmpeg转码,将RTSP 流转为flv格式;通过flv.js连接websocket,并对获取的flv格式视频数据进行渲染播放。

import WebSocket from 'ws'import webSocketStream from 'websocket-stream/stream'import ffmpeg from 'fluent-ffmpeg'// 建立WebSocket服务const wss = new WebSocket.Server({ port: 8888, perMessageDeflate: false })// 监听连接wss.on('connection', handleConnection)// 连接时触发事件function handleConnection (ws, req) {  // 获取前端请求的流地址(前端websocket连接时后面带上流地址)  const url = req.url.slice(1)  // 传入连接的ws客户端 实例化一个流  const stream = webSocketStream(ws, { binary: true })  // 通过ffmpeg命令 对实时流进行格式转换 输出flv格式  const ffmpegCommand = ffmpeg(url)    .addInputOption('-analyzeduration', '100000', '-max_delay', '1000000')    .on('start', function () { console.log('Stream started.') })    .on('codecData', function () { console.log('Stream codecData.') })    .on('error', function (err) {      console.log('An error occured: ', err.message)      stream.end()    })    .on('end', function () {      console.log('Stream end!')      stream.end()    })    .outputFormat('flv').videoCodec('copy').noAudio()  stream.on('close', function () {    ffmpegCommand.kill('SIGKILL')  })  try {    // 执行命令 传输到实例流中返回给客户端    ffmpegCommand.pipe(stream)  } catch (error) {    console.log(error)  }}

优点全部基于js。前端即可搞定。

参考:https://www.zhihu.com/question/29973696

实时流协议RTSP(RealTimeStreamingProtocol)是由RealNetworks和Netscape共同提出的,该

协议定义了一对多应用程序如何有效地通过IP网络传送多媒体数据。RTSP在体系结构上位于RTP

和RTCP之上,它使用TCP或RTP完成数据传输。HTTP与RTSP相比,HTTP传送HTML,而RTP传送的

是多媒体数据。HTTP请求由客户机发出,服务器作出响应;使用RTSP时,客户机和服务器都可

以发出请求,即RTSP可以是双向的。

6.3 RTSP协议

实时流协议(RTSP)是应用级协议,控制实时数据的发送。RTSP提供了一个可扩展框架,使

实时数据,如音频与视频,的受控、点播成为可能。数据源包括现场数据与存储在剪辑中数据

。该协议目的在于控制多个数据发送连接,为选择发送通道,如UDP、组播UDP与TCP,提供途径

,并为选择基于RTP上发送机制提供方法。

6.3.1 简介

6.3.1.1 目的

实时流协议(RTSP)建立并控制一个或几个时间同步的连续流媒体。尽管连续媒体流与控制

流交*是可能的,通常它本身并不发送连续流。换言之,RTSP充当多媒体服务器的网络远程控

制。RTSP连接没有绑定到传输层连接,如TCP。在RTSP连接期间,RTSP用户可打开或关闭多个对

服务器的可*传输连接以发出RTSP 请求。此外,可使用无连接传输协议,如UDP。RTSP流控制

的流可能用到RTP,但RTSP操作并不依赖用于携带连续媒体的传输机制。实时流协议在语法和操

作上与HTTP/1.1类似,因此HTTP的扩展机制大都可加入RTSP。协议支持的操作如下:

从媒体服务器上检索媒体:

用户可通过HTTP或其它方法提交一个演示描述。如演示是组播,演示式就包含用于连续媒体

的的组播地址和端口。如演示仅通过单播发送给用户,用户为了安全应提供目的地址。

媒体服务器邀请进入会议:

媒体服务器可被邀请参加正进行的会议,或回放媒体,或记录其中一部分,或全部。这种模

式在分布式教育应用上很有用,会议中几方可轮流按远程控制按钮。

将媒体加到现成讲座中:

如服务器告诉用户可获得附加媒体内容,对现场讲座显得尤其有用。如HTTP/1.1中类似,RTSP

请求可由代理、通道与缓存处理。

6.3.1.2 协议特点

RTSP 特性如下:

可扩展性:

新方法和参数很容易加入RTSP。

易解析:

RTSP可由标准 HTTP或MIME解吸器解析。

安全:

RTSP使用网页安全机制。

独立于传输:

RTSP可使用不可*数据报协议(UDP)、可*数据报协议(RDP),如要实现应用级可*,可

使用可*流协议。

多服务器支持:

每个流可放在不同服务器上,用户端自动同不同服务器建立几个并发控制连接,媒体同步在

传输层执行。

记录设备控制:

协议可控制记录和回放设备。

流控与会议开始分离:

仅要求会议初始化协议提供,或可用来创建唯一会议标识号。特殊情况下, SIP或H.323

可用来邀请服务器入会。

适合专业应用:

通过SMPTE 时标,RTSP支持帧级精度,允许远程数字编辑

演示描述中立:

协议没强加特殊演示或元文件,可传送所用格式类型;然而,演示描述至少必须包含一个RTSP

URI。

代理与防火墙友好:

协议可由应用和传输层防火墙处理。防火墙需要理解SETUP方法,为UDP媒体流打开一个"缺

口"。

HTTP友好:

此处,RTSP明智的采用HTTP观念,使现在结构都可重用。结构包括Internet 内容选择平台

(PICS)。由于在大多数情况下控制连续媒体需要服务器状态, RTSP不仅仅向HTTP 添加方法

。 适当的服务器控制:

如用户启动一个流,他必须也可以停止一个流。

传输协调;

实际处理连续媒体流前,用户 可协调传输方法。

性能协调:

如基本特征无效,必须有一些清理机制让用户决定那种方法没生效。这允许用户提出适合的

用户界面。

6.3.1.3扩展RTSP

由于不是所有媒体服务器有着相同的功能,媒体服务器有必要支持不同请求集。RTSP 可以

如下三种方式扩展,这里以改变大小排序:

以新参数扩展。如用户需要拒绝通知,而方法扩展不支持,相应标记就加入要求的段中。

加入新方法。如信息接收者不理解请求,返回501错误代码(还未实现),发送者不应再次

尝试这种方法。用户可使用OPTIONS方法查询服务器支持的方法。服务器使用公共响应头列出支

持的方法。

定义新版本协议,允许改变所有部分。(除了协议版本号位置)

6.3.1.4操作模式

每个演示和媒体流可用RTSP URL识别。演示组成的整个演示与媒体属性由演示描述文件定义

。使用HTTP或其它途径用户可获得这个文件,它没有必要保存在媒体服务器上。

为了说明,假设演示描述描述了多个演示,其中每个演示维持了一个公共时间轴。为简化说

明,且不失一般性,假定演示描述的确包含这样一个演示。演示可包含多个媒体流。除媒体参

数外,网络目标地址和端口也需要决定。下面区分几种操作模式:

单播:

以用户选择的端口号将媒体发送到RTSP请求源。

组播,服务器选择地址:

媒体服务器选择组播地址和端口,这是现场直播或准点播常用的方式。

组播,用户选择地址:

如服务器加入正在进行的组播会议,组播地址、端口和密匙由会议描述给出。

6.3.1.5 RTSP状态

RTSP控制通过单独协议发送的流,与控制通道无关。例如,RTSP控制可通过TCP连接,而数

据流通过UDP。因此,即使媒体服务器没有收到请求,数据也会继续发送。在连接生命期,单个

媒体流可通过不同TCP连接顺序发出请求来控制。所以,服务器需要维持能联系流与RTSP请求的

连接状态。RTSP中很多方法与状态无关,但下列方法在定义服务器流资源的分配与应用上起着

重要的作用:

SETUP:

让服务器给流分配资源,启动RTSP连接。

PLAY与RECORD:

启动SETUP 分配流的数据传输。

PAUSE:

临时停止流,而不释放服务器资源。

TEARDOWN:

释放流的资源,RTSP连接停止。

标识状态的RTSP方法使用连接头段识别RTSP连接,为响应SETUP请求,服务器连

接产生连接标识。

6.3.1.6 与其他协议关系

RTSP在功能上与HTTP有重叠,与HTTP相互作用体现在与流内容的初始接触是通过网页的。目

前的协议规范目的在于允许在网页服务器与实现RTSP媒体服务器之间存在不同传递点。例如,

演示描述可通过HTTP和RTSP检索,这降低了浏览器的往返传递,也允许独立RTSP 服务器与用户

不全依*HTTP。

但是,RTSP与HTTP 的本质差别在于数据发送以不同协议进行。HTTP是不对称协议,用户发

出请求,服务器作出响应。RTSP中,媒体用户和服务器都可发出请求,且其请求都是无状态的

;在请求确认后很长时间内,仍可设置参数,控制媒体流。重用HTTP功能至少在两个方面有好

处,即安全和代理。要求非常接近,在缓存、代理和授权上采用HTTP功能是有价值的。

当大多数实时媒体使用RTP作为传输协议时,RTSP没有绑定到RTP。RTSP假设存在演示描述格

式可表示包含几个媒体流的演示的静态与临时属性。

6.3.2 协议参数

6.3.3 RTSP 信息

RTSP是基于文本的协议,采用ISO 10646 字符集,使用UTF-8编码方案。行以CRLF中断,但

接收者本身可将CR和LF解释成行终止符。基于文本的协议使以自描述方式增加可选参数更容易

。由于参数的数量和命令的频率出现较低,处理效率没引起注意。如仔细研究,文本协议很容

易以脚本语言(如:Tcl、Visual Basic与Perl)实现研究原型。

10646字符集避免敏感字符集切换,但对应用来说不可见。RTCP也采用这种编码方案。带有

重要意义位的ISO 8859-1字符表示如100001x 10xxxxxx.。RTSP信息可通过任何低层传输协议

携带。

请求包括方法、方法作用于其上的对象和进一步描述方法的参数。方法也可设计为在服务器

端只需要少量或不需要状态维护。当信息体包含在信息中,信息体长度有如下因素决定:

不管实体头段是否出现在信息中,不包括信息体的的响应信息总以头段后第一和空行结束。

如出现内容长度头段,其值以字节计,表示信息体长度。如未出现头段,其值为零。

服务器关闭连接。

注意:RTSP目前并不支持HTTP/1.1"块"传输编码,需要有内容长度头。假如返回适度演示描

述长度,即使动态产生,使块传输编码没有必要,服务器也应该能决定其长度。如有实体,即

使必须有内容长度,且长度没显式给出,规则可确保行为合理。

从用户到服务器端的请求信息在第一行内包括源采用的方法、源标识和所用协议版本。RTSP

定义了附加状态代码,而没有定义任何HTTP代码。

6.3.4 实体

如不受请求方法或响应状态编码限制,请求和响应信息可传输实体,实体由实体头文件和试

题体组成,有些响应仅包括实体头。在此,根据谁发送实体、谁接收实体,发送者和接收者可

分别指用户和服务器。

实体头定义实体体可选元信息,如没有实体体,指请求标识的资源。扩展头机制允许定义附

加实体头段,而不用改变协议,但这些段不能假定接收者能识别。不可识别头段应被接收者忽

略,而让代理转发。

6.3.5 连接

RTSP请求可以几种不同方式传送:

1、持久传输连接,用于多个请求/响应传输。

2、每个请求/响应传输一个连接。

3、无连接模式。

传输连接类型由RTSP URI来定义。对 "rtsp" 方案,需要持续连接;而"rtspu"方案,调用

RTSP 请求发送,而不用建立连接。

不象HTTP,RTSP允许媒体服务器给媒体用户发送请求。然而,这仅在持久连接时才支持,否

则媒体服务器没有可*途径到达用户,这也是请求通过防火墙从媒体服务器传到用户的唯一途

径。

6.3.6 方法定义

方法记号表示资源上执行的方法,它区分大小写。新方法可在将来定义,但不能以$开头。

某些防火墙设计与其他环境可能要求服务器插入RTSP方法和流数据。由于插入将使客户端和

服务器操作复杂,并强加附加开销,除非有必要,应避免这样做。插入二进制数据仅在RTSP通

过TCP传输时才可使用。流数据(如RTP包)用一个ASCII美圆符号封装,后跟一个一字节通道标

识,其后是封装二进制数据的长度,两字节整数。


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/399441.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-20
下一篇2023-05-20

发表评论

登录后才能评论

评论列表(0条)

    保存