x264直播(6) - aac封装到flv
x264里面已经有flv视频, 加入音频需要修改比较多东西
- flv详细格式文档可以从官网下载 http://www.adobe.com/content/dam/acom/en/devnet/flv/video_file_format_spec_v10.pdf
- 检查生成文件的格式可以用工具 010 Editor, 这个软件比较强大, 一般文件都可以直接分析成结构体查看, 方便检查生成的文件是否正常
- 按照文档修改flv头, 修改metadata, 添加一个aac头, 后续按时添加音频数据
- tag_flv 的timestamp 储存注意是24+8方式
- faac输出的格式有两种, 封装必须对应
Config->outputFormat = ADTS_STREAM; // 直接播放器可以播放
Config->outputFormat = RAW_STREAM; // 打包到flv只能用原始流 - 加入声音生成的文件速度不对, 前面没声音, AudioSpecificConfig 设置不对, 这个很麻烦, 文档都很难找到, 可以参考lsmash函数 mp4a_put_AudioSpecificConfig
- 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];
}
- 部分播放器播放速度飞快, 部分正常, faac编码后放入flv, 不能多个块写入一个tag, 就是用这个方式导致这个问题
必须一个aac的frame写入一个tag, 一个视频frame可能有多个音频frame, 这样就正常了 - 每个frame, 无论是avc还是aac都需要填写准确的timestamp
最终打包的flv正常, 在手机端可以flv.js直接看电脑运行的直播了