red5 + rtmp篇2

3 篇文章 0 订阅
6.1 调研,测试视频服务器:
     live555, easy darwin, red5,crtmpserver,因为不但需要视频直播,还需要录制视频流,需要现成的,以及red5是有apache在维护,持续更新,所以选择red5

6.2 视频推送android客户端
6.2.1 了解rtmp协议后,发现server需要录制视频流,客户端需要以“record”模式推送,了解完之后决定修改librtmp,然后交叉编译往red5推送,red5可以保存视频

6.2.2 编写客户端代码,使用mediacodec进行h264编码,测试机使用的是三星s3,遇到的坑是手机支持的preview size,以及preview的数据格式,还有mediacodec支持的数据格式,设置“parameters.setPreviewFormat(ImageFormat.NV21);”得到的原始数据并不是yuv,而是yvu,所以会出现红,蓝色调相反。。。
把得到的h264流保存到文件可以使用vlc播放

6.2.3 把视频推送到red5,不能播放
6.2.3.1 直接把h264编码出来的流push到red5,red5不接受
6.2.3.1.1 不能直接往red5扔h264,还需要进行打包:根据rtmp协议,i帧和其他帧的包头不一样,而且,i帧还要先发送sps,pps
6.2.3.1.2 了解,分析h264码流编码方式
6.2.3.1.2 mediacodec出来的数据可能包含多帧,还需要split
6.2.3.2 timestamp没有设置对,无论是i帧,还是非i帧,发送之后都需要累加,1000/fps就是time gap
6.2.3.3 不能发送太快,否则red5不认。。。 其实,也就是按照1000/fps slepp一下~~
以上可以应该可以一边推送,一边看,但是花屏严重,而且卡得严重

6.2.3.4 花屏,以及卡:
     因为是在onPreviewFrame里Sleep,而onPreviewFrame是阻塞的,刚开始还误以为是非阻塞的(当时就奇怪。。。),问题就在这里,在这里sleep,不丢帧才怪,丢帧得花屏,而且,一sleep,再阻塞,不卡才怪
6.2.3.4.1 onPreviewFrame里有个坑:
     不能设置preview的帧率,最起码我设置了是没用,google之,说是个动态帧率。。。。。。。然后,然后统计,测量结果是30fps左右,跟得到的参数差不多
6.2.3.4.2 mediacode使用的一个主义事项
     bitrate很重要,没注意这个,对320x240用90k,花得一塌糊涂,然后用的500,好多了,虽然还是花,但是能用(还没找到原因)。。。
6.2.3.4.5 解决方法
1) 使用两个队列:一个yuv队列,一个h264码流队列,onPreviewFrame得到yuv数据立马往yuvqueue push,这样不会阻塞onPreviewFrame
2) 使用2个线程:EncodeThread和RtmpSendThread
     EncodeThread从yuvqueue pull yuv数据,编码,然后push到h264queue
     RtmpSendThread每隔1000/fps往red5推送数据,这样时间基本可以控制,以及保证!!!!
效果:
     流畅,但是有点点花屏,至今不晓得为啥,猜测是考虑效率,牺牲了质量,还需要对mediaccodec进行研究,或者其他硬编码方法进行研究!!!!

6.2.3.5 移植到定制机
1) 定制机一运行就出错,说找不到rtmp库。。。log,google,原来这货只认64bit的armebi-v8库,没有深入,编了个v8的库,ok
2)mediaccodec支持的格式问题,这货又只支持“COLOR_FormatYUV420Planar”,而s3支持“COLOR_FormatYUV420SemiPlanar”好吧,又的转换420p,而这货呢,出来的貌似是yuv420sp,s3出来的是yvu420sp,有什么区别,自己google吧。。。
好吧,流程算是通了~~~~ 就是那点花屏让人不爽
哎,哪只不爽,不爽只是妥协:本来以为丢包丢数据导致的花屏,在server端抓包,在android保存最终发送的数据,一帧一个byte对照,丝毫没有,这时想死的心都有!!!!!!!!!!!!!!!!!!!
只能认了,转到ffmpeg下
6.2.3 播放客户端
6.2.3.1 最后选的是vitamio库,感觉就这个靠谱点。。。把它弄到自己项目,立马报错,莫名其妙奥的错误。。。。客户端同学把它设置为lib,然后引用,可以用。。。。!!!! 高明!!!!!
6.2.3.2 播放界面很小,修改如下:
     在“MediaPlayerDemo_Video”类onVideoSizeChanged函数中修改“mVideoWidth = width”为“mVideoWidth = width * 2”,高度一样x2

6.4 使用ffmpeg
6.4.1 交叉编译ffmpeg+x264,默认的ffmpeg是没有h264编码器的。。。有h264解码器;要使用h264编码器,需要添加x264,至于怎么遍过的,我自己都搞忘了。。。
6.4.2 对ffmpeg编码出来的数据进行分析
     ffmpeg出来的数据和mediacodec出来的数据不一样,自己分析吧,推荐给工具:H264VideoESViewer.exe,用来看h264码流不错
6.4.3 流程:
      基本上和使用mediacodec一样,只是量:添加ffmpeg的编码,封装ffmpeg函数,交叉编译,以及封装针对ffmpeg发送的librtmp函数
6.4.4 效果
1) 一开始,也是绝望,也花。。。后来发现本地保存的也花,这还好。。。。说明应该只是参数问题,google之,修改如下:
          context->gop_size = 250; // emit one intra frame every ten frames
     添加这2行:
          context->qmin = 10;
          context->qmax = 51;
哇塞,保存的本地文件清晰!!!!!开心啊!!!!
6.4.5 问题:
     使用ffmpeg的一个明显问题就是:编码时间特高,需要800-900ms,算下来10fps的效率;把6.4.4的参数注释,有点点提高,不够也会有花屏,带来的提高抵不上效果的损失
     这是现在要做的事情!!!!!!!!!!!

代码整理好上传到github,再更新。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值