各位大哥,小菜现在遇到问题了:
用live555保存的文件不可以用vlc播放,在网上查找到了很多的这种问题,就是没有一个完整的答案。
通过查找,说在每个包的前面加上00 00 00 01 但是我在liveMedia/H264VideoFileSink.cpp的 void afterGettingFrame1函数中发现了unsigned char start_code[4] = {0x00, 0x00, 0x00, 0x01}; addData(start_code, 4, presentationTime);这两句,我的理解是在包里面live555自己已经加上了,有的说在保存文件的时候把sps和pps通过Base64解码写到文件中,这种说法也都不一样,有些人说只在文件的开头写上就行,有的说在每个I帧前面加上,有的说只写sps,有的说全都写。
虽然说的方法是很多,但是只有这样冷统的说法,对于初学者来说,根本就不会理解的,比如,sps和pps是怎么得到的?解答的人说在SDP中,SDP从RTSP流中提取,还要通过Base64进行解码,如果你是初学者,你会吗?我不会。在解出sps和pps后怎么和addData的写文件结合?牛X的人会说,自己看,代码写的很清楚。live555不是个小的东西把,它的结构很大,类继承的也很深,不是一朝一夕就可以看会的,也许真的很简单,初学者也会钻牛角尖,不是吗?
希望有经验的人可以指点一下小菜,谢谢!我的问题有这么几个:
1、我知道调用MediaSubsession类中的fmtp_spropparametersets方法可以得到SDP中的sps和pps,但是在什么地方得到才是最好的?就是说在什么地方得到sps和pps与文件结合最方便。
2、在什么地方调用Base64去对sps和pps解码?
3、是在文件的开头些sps和pps还是在每一个I帧前面写?如果在每个I帧前面写怎样判断是I帧?
4、在代码的什么地方保存文件好?还是在addData中?
5、在什么地方sps和pps与文件结合?
6、或者有什么更好的方法呢?
谢谢各位大哥的讲解,当问题解决后我会总结出一个详细的方案更大家一起学习,谢谢!(该贴会继续加分)
------解决方案--------------------------------------------------------
是在文件的开头些sps和pps还是在每一个I帧前面写?如果在每个I帧前面写怎样判断是I帧?
sps是序列头 是在一段视频前的, pps是图像头 对于每帧的。
具体在哪写 我也不知道。
------解决方案--------------------------------------------------------
光加0001还不够, sps和pps在服务器返回的SDP description里 用base64编码,格式是“sprop-parameter-sets=Z0JADJWwUH7AQCA=,aM4NyA==”,只要basedecode出来放在第一帧之前 一起送入解码器就可以了。
请LZ认真研究示例程序playCommon.cpp。
------解决方案--------------------------------------------------------
在脱去rtp标签后,那部分数据你直接写入文件,那么这个数据应该就是你服务器发的原始流媒体文件数据。
记住要找对位置,不要将RTCP的数据写入文件。rtp 的。
------解决方案--------------------------------------------------------
udp:乱序,丢包,速度较快。
tcp:反之。
live555默认是rtp over UDP,符合实时性要求,所以你要下载再播放,的确叫做录播。而不是live 直播。这样就需要你在内存中进行缓存,将RTP包进行排序,并且有丢包发生的话,还需要处理容错。
不过,根据rfc标准,可以考虑rtp over TCP。这样就没问题了。
------解决方案--------------------------------------------------------
没有看回复,注意Live555在写入pps和sps时分别都加入了00 00 00 01,就成了00 00 00 01 pps 00 00 00 01 psp 00 00 00 01图像数据。live555是这样的格式,所以VLC不能播放
应该的格式是00 00 00 01 pps psp 图像数据,这样vlc就能够播放,你可以这样修改下.
------解决方案--------------------------------------------------------
从sdp description提取出sprop-parameter-sets之后的内容然后再做base64解码。 已经足够具体了,难道还要“手把手教你流媒体开发”? 多看文档,多GOOGLE吧。
a=fmtp:96 packetization-mode=1;profile-level-id=4366376;sprop-parameter-sets=Z0KgKOcoDwBE/LgIgAAHCAABX5AwAAANWfgAAas/EXvxgAAAas/AAA1Z+IvfjQ==,aN48gA==
a=control:track1
------解决方案--------------------------------------------------------
你可以用抓包工具,看DESCRIBE返回的sdp description字段有没有lius1984说的sprop-parameter-sets信息,如果有就按照lius1984方法,
我们的设备sps和pps信息是发RTP时发过来的,你的应该不是
------解决方案--------------------------------------------------------
NALU中不是可以判断该单元是什么类型吗?如果是sps,pps,你就开始保存