ffmpeg当前版本mp4容器 支持G711修改
1,编译脚本设置编译参数
#支持PCM和G711编解码 --enable-encoder=pcm_alaw --enable-decoder=pcm_alaw
#–enable-demuxer=mov 支持mov,mp4,m4a,3gp,3g2,mj2解复用 configure_flags="–enable-cross-compile --disable-debug
–disable-programs --disable-doc --enable-pic --enable-encoder=pcm_alaw --enable-decoder=pcm_alaw --enable-demuxer=mov"
2,修改 ffmpeg libavformat 的代码
ffmpeg当前版本mp4容器不支持G711。因此做了源代码修改。详见libavformat/movenc.c
1051行(mov_write_audio_tag函数内部)
1585行(mov_find_codec_tag函数内部)
static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb,
MOVMuxContext *mov, MOVTrack *track) {
int64_t pos = avio_tell(pb);
int version = 0;
uint32_t tag = track->tag;if (track->mode == MODE_MOV) {if (track->timescale > UINT16_MAX || !track->par->channels) {if (mov_get_lpcm_flags(track->par->codec_id))tag = AV_RL32("lpcm");version = 2;} else if (track->audio_vbr || mov_pcm_le_gt16(track->par->codec_id) ||mov_pcm_be_gt16(track->par->codec_id) ||track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||track->par->codec_id == AV_CODEC_ID_QDM2) {version = 1;} }avio_wb32(pb, 0); /* size */ if (mov->encryption_scheme != MOV_ENC_NONE) {ffio_wfourcc(pb, "enca"); } else {avio_wl32(pb, tag); // store it byteswapped } avio_wb32(pb, 0); /* Reserved */ avio_wb16(pb, 0); /* Reserved */ avio_wb16(pb, 1); /* Data-reference index, XXX == 1 *//* SoundDescription */ avio_wb16(pb, version); /* Version */ avio_wb16(pb, 0); /* Revision level */ avio_wb32(pb, 0); /* Reserved */if (version == 2) {avio_wb16(pb, 3);avio_wb16(pb, 16);avio_wb16(pb, 0xfffe);avio_wb16(pb, 0);avio_wb32(pb, 0x00010000);avio_wb32(pb, 72);avio_wb64(pb, av_double2int(track->par->sample_rate));avio_wb32(pb, track->par->channels);avio_wb32(pb, 0x7F000000);avio_wb32(pb, av_get_bits_per_sample(track->par->codec_id));avio_wb32(pb, mov_get_lpcm_flags(track->par->codec_id));avio_wb32(pb, track->sample_size);avio_wb32(pb, get_samples_per_packet(track)); } else { #if 1 // zzbif (track->mode == MODE_MOV) {avio_wb16(pb, track->par->channels);if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||track->par->codec_id == AV_CODEC_ID_PCM_S8)avio_wb16(pb, 8); /* bits per sample */else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)avio_wb16(pb, track->par->bits_per_coded_sample);elseavio_wb16(pb, 16);avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */} else { /* reserved for mp4/3gp */avio_wb16(pb, track->par->channels > 0 ?track->par->channels : 1);track->par->bits_per_coded_sample = av_get_bits_per_sample(track->par->codec_id);avio_wb16(pb, track->par->bits_per_coded_sample > 0 ?track->par->bits_per_coded_sample : 16);avio_wb16(pb, 0);}avio_wb16(pb, 0); /* packet size (= 0) */avio_wb16(pb, track->par->sample_rate <= UINT16_MAX ?track->par->sample_rate : 0);avio_wb16(pb, 0); /* Reserved */
#else
if (track->mode == MODE_MOV) {
avio_wb16(pb, track->par->channels);
if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||
track->par->codec_id == AV_CODEC_ID_PCM_S8)
avio_wb16(pb, 8); /* bits per sample /
else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)
avio_wb16(pb, track->par->bits_per_coded_sample);
else
avio_wb16(pb, 16);
avio_wb16(pb, track->audio_vbr ? -2 : 0); / compression ID /
} else { / reserved for mp4/3gp */
if (track->par->codec_id == AV_CODEC_ID_FLAC ||
track->par->codec_id == AV_CODEC_ID_OPUS) {
avio_wb16(pb, track->par->channels);
} else {
avio_wb16(pb, 2);
}
if (track->par->codec_id == AV_CODEC_ID_FLAC) {
avio_wb16(pb, track->par->bits_per_raw_sample);
} else {
avio_wb16(pb, 16);
}
avio_wb16(pb, 0);
}avio_wb16(pb, 0); /* packet size (= 0) */if (track->par->codec_id == AV_CODEC_ID_OPUS)avio_wb16(pb, 48000);elseavio_wb16(pb, track->par->sample_rate <= UINT16_MAX ?track->par->sample_rate : 0);avio_wb16(pb, 0); /* Reserved */
#endif
// if (track->mode == MODE_MOV) {// avio_wb16(pb, track->par->channels);// if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||// track->par->codec_id == AV_CODEC_ID_PCM_S8)// avio_wb16(pb, 8); /* bits per sample */// else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)// avio_wb16(pb, track->par->bits_per_coded_sample);// else// avio_wb16(pb, 16);// avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */// } else { /* reserved for mp4/3gp */// if (track->par->codec_id == AV_CODEC_ID_FLAC ||// track->par->codec_id == AV_CODEC_ID_OPUS) {// avio_wb16(pb, track->par->channels);// } else {// avio_wb16(pb, 2);// }// if (track->par->codec_id == AV_CODEC_ID_FLAC) {// avio_wb16(pb, track->par->bits_per_raw_sample);// } else {// avio_wb16(pb, 16);// }// avio_wb16(pb, 0);// }// avio_wb16(pb, 0); /* packet size (= 0) */// if (track->par->codec_id == AV_CODEC_ID_OPUS)// avio_wb16(pb, 48000);// else// avio_wb16(pb, track->par->sample_rate <= UINT16_MAX ?// track->par->sample_rate : 0);// avio_wb16(pb, 0); /* Reserved */ }if (version == 1) { /* SoundDescription V1 extended info */if (mov_pcm_le_gt16(track->par->codec_id) ||mov_pcm_be_gt16(track->par->codec_id))avio_wb32(pb, 1); /* must be 1 for uncompressed formats */elseavio_wb32(pb, track->par->frame_size); /* Samples per packet */avio_wb32(pb, track->sample_size / track->par->channels); /* Bytes per packet */avio_wb32(pb, track->sample_size); /* Bytes per frame */avio_wb32(pb, 2); /* Bytes per sample */ }if (track->mode == MODE_MOV &&(track->par->codec_id == AV_CODEC_ID_AAC ||track->par->codec_id == AV_CODEC_ID_AC3 ||track->par->codec_id == AV_CODEC_ID_EAC3 ||track->par->codec_id == AV_CODEC_ID_AMR_NB ||track->par->codec_id == AV_CODEC_ID_ALAC ||track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||track->par->codec_id == AV_CODEC_ID_QDM2 ||(mov_pcm_le_gt16(track->par->codec_id) && version==1) ||(mov_pcm_be_gt16(track->par->codec_id) && version==1)))mov_write_wave_tag(s, pb, track); else if (track->tag == MKTAG('m','p','4','a'))mov_write_esds_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_AMR_NB)mov_write_amr_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_AC3)mov_write_ac3_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_EAC3)mov_write_eac3_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_ALAC)mov_write_extradata_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_WMAPRO)mov_write_wfex_tag(s, pb, track); else if (track->par->codec_id == AV_CODEC_ID_FLAC)mov_write_dfla_tag(pb, track); else if (track->par->codec_id == AV_CODEC_ID_OPUS)mov_write_dops_tag(pb, track); else if (track->vos_len > 0)mov_write_glbl_tag(pb, track);if (track->mode == MODE_MOV && track->par->codec_type == AVMEDIA_TYPE_AUDIO)mov_write_chan_tag(s, pb, track);if (mov->encryption_scheme != MOV_ENC_NONE) {ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid); }return update_size(pb, pos); }
static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track) {
int tag;#if 1 // zzb if (track->mode == MODE_MP4 || track->mode == MODE_PSP) tag = track->par->codec_tag; else if (track->mode == MODE_ISM) { tag = track->par->codec_tag; } else if (track->mode == MODE_IPOD) {if (!av_match_ext(s->url, "m4a") &&!av_match_ext(s->url, "m4v") &&!av_match_ext(s->url, "m4b"))av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v ""Quicktime/Ipod might not play the file\n");tag = track->par->codec_tag; } else if (track->mode & MODE_3GP) tag = track->par->codec_tag; else if (track->mode == MODE_F4V)tag = track->par->codec_tag; if (tag == 0){tag = mov_get_codec_tag(s, track); }
#else
if (track->mode == MODE_MP4 || track->mode == MODE_PSP)
tag = track->par->codec_tag;
else if (track->mode == MODE_ISM)
tag = track->par->codec_tag;
else if (track->mode == MODE_IPOD) {
if (!av_match_ext(s->url, “m4a”) &&
!av_match_ext(s->url, “m4v”) &&
!av_match_ext(s->url, “m4b”))
av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
“Quicktime/Ipod might not play the file\n”);
tag = track->par->codec_tag;
} else if (track->mode & MODE_3GP)
tag = track->par->codec_tag;
else if (track->mode == MODE_F4V)
tag = track->par->codec_tag;
else
tag = mov_get_codec_tag(s, track);
#endif// if (is_cover_image(track->st)) // return ff_codec_get_tag(codec_cover_image_tags, track->par->codec_id);// if (track->mode == MODE_MP4 || track->mode == MODE_PSP) // tag = track->par->codec_tag; // else if (track->mode == MODE_ISM) // tag = track->par->codec_tag; // else if (track->mode == MODE_IPOD) { // if (!av_match_ext(s->url, "m4a") && // !av_match_ext(s->url, "m4v") && // !av_match_ext(s->url, "m4b")) // av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v " // "Quicktime/Ipod might not play the file\n"); // tag = track->par->codec_tag; // } else if (track->mode & MODE_3GP) // tag = track->par->codec_tag; // else if (track->mode == MODE_F4V) // tag = track->par->codec_tag; // else // tag = mov_get_codec_tag(s, track);return tag; }
ffmpeg当前版本mp4容器 支持G711修改相关推荐
- EasyPlayer:安卓播放器Android MediaMuxer录像(支持G711音频)支持MP4、音视频同步
Android平台的MediaMuxer是个非常好的录像库,它能将H.264视频+AAC音频存储成.mp4格式的文件,而且稳定性.同步效果都非常好.MediaMuxer在安卓版的EasyPlayer和 ...
- 利用ffmpeg 把.mp4转换为.flv
1. 下载安装 ffmpeg Download FFmpeg windows下载编译之后的exe文件,放到path环境变量中. Linux 下 tar xvf xxx.tar.bz2 ./config ...
- 软编码Flv 到Mp4 容器(十三) fmp4 生成ftyp和moov所必要的 flv数据
https://github.com/332065255/flv2fmp4 代码库 软编码Flv 到Mp4 容器(一) 软编码Flv 到Mp4 容器(二) flv tag拆解 软编码Flv 到Mp4 ...
- Android直播开发之旅(17):使用FFmpeg提取MP4中的H264和AAC
最近在开发中遇到了一个问题,即无法提取到MP4中H264流的关键帧进行处理,且保存到本地的AAC音频也无法正常播放.经过调试分析发现,这是由于解封装MP4得到的H264和AAC是ES流,它们缺失解码时 ...
- 解决ffmpeg生成mp4文件不能正常预览的问题
框架的使用极大的提高了开发效率,让我们能够有更多的精力去关注系统的整体架构和业务需求,而不需要过多的关注一些具体的实现细节,但任何事情都有两面性,如果某个细节出了问题,由于对具体的实现不了解,那么会给 ...
- Java使用FFmpeg实现mp4转m3u8
Java使用FFmpeg实现mp4转m3u8 前言 FFmpeg M3U8 一.需求及思路分析 二.安装FFmpeg 1.windows下安装FFmpeg 2.linux下安装FFmpeg Ubunt ...
- FFmpeg给mp4视频加上旋转90度的代码
1.准备h264视频流.(这之前可能是yuv转成的视频流.) 2.准备aac音频流. 3.开始muxer成mp4. 一.如果初始视频是ios或者安卓手机拍摄的竖拍视频,那么这个视频是有90,180,2 ...
- 使用FFmpeg合并MP4视频
使用FFmpeg合并MP4视频 1. 使用mpeg拼接 2. ==使用ts拼接== 使用FFmpeg合并MP4视频 windows/linux下均可用 1. 使用mpeg拼接 速度慢,文件大 将 mp ...
- python之 ffmpeg给mp4视频添加字幕
目录 ffmpeg给mp4视频加字幕 执行结果: ffmpeg给mp4视频加字幕 前期输入准备: mp4视频 外挂字幕:是一个单独的外部字幕文件,格式类型一般有srt.vtt.ass等等.播放视频时, ...
最新文章
- 6.java设计模式
- Springmvc的helloworld实例
- 中石油计算机组成原理a在线考试,计算机组成原理试题A.doc
- pdfLaTeX和XeLaTeX
- [luoguP2463] [SDOI2008]Sandy的卡片(后缀数组 + st表)
- php动态写入vue,Vue.js中使用动态组件的方法
- vue 中使用rem布局
- [转载] Java异常处理习题
- struts2中struts:iterator标签的使用
- 【Unity优化】怎样实现Unity编辑器中的协程
- 服务器配置文件设计,IM配置服务器概要的设计文件.doc
- jenkins - publish over ssh 学习+踩坑记
- 开源项目推荐:基于Qt开发的远程桌面监控和文件传输软件Aspia
- 计算机桌面底边出现库如何去掉,桌面图标有蓝底怎么去掉? 去掉桌面图标阴影技巧...
- PHP支付宝转账到支付宝账号
- locale 国际化配置(springboot)
- SOFABoot框架(蚂蚁金服)
- 学生写给老师的一封邮件
- 第三章:电子商务平台选择
- python计算召回率_Pytorch 计算误判率,计算准确率,计算召回率的例子