x264直播(6) - aac封装到flv

x264里面已经有flv视频, 加入音频需要修改比较多东西

  1. flv详细格式文档可以从官网下载 http://www.adobe.com/content/dam/acom/en/devnet/flv/video_file_format_spec_v10.pdf
  2. 检查生成文件的格式可以用工具 010 Editor, 这个软件比较强大, 一般文件都可以直接分析成结构体查看, 方便检查生成的文件是否正常
  3. 按照文档修改flv头, 修改metadata, 添加一个aac头, 后续按时添加音频数据
  4. tag_flv 的timestamp 储存注意是24+8方式
  5. faac输出的格式有两种, 封装必须对应
    Config->outputFormat = ADTS_STREAM; // 直接播放器可以播放
    Config->outputFormat = RAW_STREAM; // 打包到flv只能用原始流
  6. 加入声音生成的文件速度不对, 前面没声音, AudioSpecificConfig 设置不对, 这个很麻烦, 文档都很难找到, 可以参考lsmash函数 mp4a_put_AudioSpecificConfig
  7. AudioSpecificConfig生成的代码如下

sbr_mode = MP4A_AAC_SBR_NOT_SPECIFIED;
// sbr_mode = MP4A_AAC_SBR_NONE;

uuVal = 0;
uuVal	= uuVal << 5;		uuVal |= cfg.audioObjectType;
uuVal	= uuVal << 4;		uuVal |= cfg.samplingFrequencyIndex;
uuVal	= uuVal << 4;		uuVal |= cfg.channelConfiguration;
uuVal	= uuVal << 1;		uuVal |= cfg.frameLengthFlag;
uuVal	= uuVal << 1;		uuVal |= cfg.dependsOnCoreCoder;
uuVal	= uuVal << 1;		uuVal |= cfg.extensionFlag;

if(sbr_mode == MP4A_AAC_SBR_BACKWARD_COMPATIBLE || sbr_mode == MP4A_AAC_SBR_NONE)
{
	uuVal	= uuVal << 11;		uuVal |= cfg.sbr_SyncType;
	uuVal	= uuVal << 5;		uuVal |= cfg.sbr_extensionbjectType;
	uuVal	= uuVal << 1;		uuVal |= cfg.sbr_PresentFlag;
	uuVal	= uuVal << 7;		uuVal |= cfg._align;

	asc_size = 5;
	data->Data[0] = ((byte *)&uuVal)[4];
	data->Data[1] = ((byte *)&uuVal)[3];
	data->Data[2] = ((byte *)&uuVal)[2];
	data->Data[3] = ((byte *)&uuVal)[1];
	data->Data[4] = ((byte *)&uuVal)[0];
}
else
{
	asc_size = 2;
	data->Data[0] = ((byte *)&uuVal)[1];
	data->Data[1] = ((byte *)&uuVal)[0];
}
  1. 部分播放器播放速度飞快, 部分正常, faac编码后放入flv, 不能多个块写入一个tag, 就是用这个方式导致这个问题
    必须一个aac的frame写入一个tag, 一个视频frame可能有多个音频frame, 这样就正常了
  2. 每个frame, 无论是avc还是aac都需要填写准确的timestamp

最终打包的flv正常, 在手机端可以flv.js直接看电脑运行的直播了

posted @ 2020-11-06 12:10  Yofoo  阅读(1825)  评论(0编辑  收藏  举报