flv支持的音频包含pcm_mulaw和
pcm_alaw
但使用ffmpeg打包输出的文件使用解码器打开发现无法真确得到音频的格式信息,分析源码发现除了AAC、H264、MPEG4之外,其余的格式信息未被写入到流中,修改flvenc.c,找到flv_write_header函数,在函数最后写格式信息部分修改如下:
for (i = 0; i < s->nb_streams; i++) {
AVCodecContext *enc = s->streams[i]->codec;
if (enc->codec_id == AV_CODEC_ID_AAC
|| enc->codec_id == AV_CODEC_ID_H264
|| enc->codec_id == AV_CODEC_ID_MPEG4
|| enc->codec_id == AV_CODEC_ID_PCM_MULAW
|| enc->codec_id == AV_CODEC_ID_PCM_ALAW
) {
int64_t pos;
avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ?
FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
avio_wb24(pb, 0); // size patched later
avio_wb24(pb, 0); // ts
avio_w8(pb, 0); // ts ext
avio_wb24(pb, 0); // streamid
pos = avio_tell(pb);
if (enc->codec_id == AV_CODEC_ID_AAC
|| enc->codec_id == AV_CODEC_ID_PCM_MULAW
|| enc->codec_id == AV_CODEC_ID_PCM_ALAW) {
avio_w8(pb, get_audio_flags(s, enc));
avio_w8(pb, 0); // AAC sequence header
avio_write(pb, enc->extradata, enc->extradata_size);
} else {
avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags
avio_w8(pb, 0); // AVC sequence header
avio_wb24(pb, 0); // composition time
ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size);
}
data_size = avio_tell(pb) - pos;
avio_seek(pb, -data_size - 10, SEEK_CUR);
avio_wb24(pb, data_size);
avio_skip(pb, data_size + 10 - 3);
avio_wb32(pb, data_size + 11); // previous tag size
}
}
红色部分为添加的内容
添加此部分内容后,输出的文件解码器可以得到音频信息,但读不出音频数据,跟踪后发现音频数据没有被写入,猜测与在转换时dts被重置有关,查了下有AV_NOPTS_VALUE这个变量,强制将stream的cur_dts和pkt的dts置为此常量,声音就有了