- 前言
- 流程
- android的截屏
- h264封装
- 注意事项
- 验证封装结果
- spspps的单独处理
- 横竖屏切换
- 播放器需要改吗
- 总结
前言
这不是指导性的文章。
只是列出了几个注意点。
你必须把每个位代表什么意思都弄明白。
流程
1,android的截屏,这里我们需要的数据是h264
2,将h264使用java封装成flv格式的文件
android的截屏
必须是android5.0及以上的系统,否则会很麻烦(因为太麻烦我放弃)。
github上有很多。
h264封装
网上有很多
具体可以看参考1,参考2。
写的很不错。
注意事项
验证封装结果
将h264单独保存出来,然后使用ffmpeg命令生成flv文件。对比自己封装的与ffmpeg封装的。除了时间戳之外(这个没办法做到一样,至少我是这么认为的),其他最好都一样。
对比工具:
Beyond Compare;上文参考中的工具。
下面的几条都是对这一条的补充。
sps,pps的单独处理
这个两个数据跟其他h264数据一起传出来的。也就是说它是编码器生成的。
if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0)
封装flv的时候,sps和pps必须放到正确的位置中。
//这里有点奇怪,我通过ffmpeg将h264转为flv,发现一个问题sps和pps传输了两次
//第一次是在video的第一个tag里,标准的组合格式
//第二次实在video的第二个tag里,也是标准的,不过结构是pps、sps+I帧data,这三个组成了一个tag
//后面再遇到I帧的tag,就没再加pps和sps了,很奇怪的说。
//我怀疑这是ffmpeg自定义的方式,也就是AVcodec
//还有就是SEI这里没有考虑
这里有个demo,可以看到第一个tag的构造方法。
横竖屏切换
android设备旋转的时候。编码器和VirtualDisplay,需要析构掉然后重新生成。
这样的话会产生一个作用:重新产生sps和pps。然后封装的时候注意一下,放在下一个key帧数据前面。
播放器需要改吗?
不需要。
使用ffmpeg进行解码的时候,如果解码器是自定义的,那么AVCodecContext::extradata需要单独设置,里面保存的是sps和pps混合的那些内容。
需要注意的是
AVFormatContext->pb->buf_ptr = s->pb->buffer + 13;
//13的意思是:9(flv文件头部)+4(保存tag大小所占的字节)
也就是偏移要放到正确的位置。不然解码会报警告。
总结
发现flv支持旋转屏,从而推断出分辨率也可以改,从这里可以看出flv是趋势是有原因的。