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修改相关推荐

  1. EasyPlayer:安卓播放器Android MediaMuxer录像(支持G711音频)支持MP4、音视频同步

    Android平台的MediaMuxer是个非常好的录像库,它能将H.264视频+AAC音频存储成.mp4格式的文件,而且稳定性.同步效果都非常好.MediaMuxer在安卓版的EasyPlayer和 ...

  2. 利用ffmpeg 把.mp4转换为.flv

    1. 下载安装 ffmpeg Download FFmpeg windows下载编译之后的exe文件,放到path环境变量中. Linux 下 tar xvf xxx.tar.bz2 ./config ...

  3. 软编码Flv 到Mp4 容器(十三) fmp4 生成ftyp和moov所必要的 flv数据

    https://github.com/332065255/flv2fmp4 代码库 软编码Flv 到Mp4 容器(一) 软编码Flv 到Mp4 容器(二) flv tag拆解 软编码Flv 到Mp4 ...

  4. Android直播开发之旅(17):使用FFmpeg提取MP4中的H264和AAC

    最近在开发中遇到了一个问题,即无法提取到MP4中H264流的关键帧进行处理,且保存到本地的AAC音频也无法正常播放.经过调试分析发现,这是由于解封装MP4得到的H264和AAC是ES流,它们缺失解码时 ...

  5. 解决ffmpeg生成mp4文件不能正常预览的问题

    框架的使用极大的提高了开发效率,让我们能够有更多的精力去关注系统的整体架构和业务需求,而不需要过多的关注一些具体的实现细节,但任何事情都有两面性,如果某个细节出了问题,由于对具体的实现不了解,那么会给 ...

  6. Java使用FFmpeg实现mp4转m3u8

    Java使用FFmpeg实现mp4转m3u8 前言 FFmpeg M3U8 一.需求及思路分析 二.安装FFmpeg 1.windows下安装FFmpeg 2.linux下安装FFmpeg Ubunt ...

  7. FFmpeg给mp4视频加上旋转90度的代码

    1.准备h264视频流.(这之前可能是yuv转成的视频流.) 2.准备aac音频流. 3.开始muxer成mp4. 一.如果初始视频是ios或者安卓手机拍摄的竖拍视频,那么这个视频是有90,180,2 ...

  8. 使用FFmpeg合并MP4视频

    使用FFmpeg合并MP4视频 1. 使用mpeg拼接 2. ==使用ts拼接== 使用FFmpeg合并MP4视频 windows/linux下均可用 1. 使用mpeg拼接 速度慢,文件大 将 mp ...

  9. python之 ffmpeg给mp4视频添加字幕

    目录 ffmpeg给mp4视频加字幕 执行结果: ffmpeg给mp4视频加字幕 前期输入准备: mp4视频 外挂字幕:是一个单独的外部字幕文件,格式类型一般有srt.vtt.ass等等.播放视频时, ...

最新文章

  1. 6.java设计模式
  2. Springmvc的helloworld实例
  3. 中石油计算机组成原理a在线考试,计算机组成原理试题A.doc
  4. pdfLaTeX和XeLaTeX
  5. [luoguP2463] [SDOI2008]Sandy的卡片(后缀数组 + st表)
  6. php动态写入vue,Vue.js中使用动态组件的方法
  7. vue 中使用rem布局
  8. [转载] Java异常处理习题
  9. struts2中struts:iterator标签的使用
  10. 【Unity优化】怎样实现Unity编辑器中的协程
  11. 服务器配置文件设计,IM配置服务器概要的设计文件.doc
  12. jenkins - publish over ssh 学习+踩坑记
  13. 开源项目推荐:基于Qt开发的远程桌面监控和文件传输软件Aspia
  14. 计算机桌面底边出现库如何去掉,桌面图标有蓝底怎么去掉? 去掉桌面图标阴影技巧...
  15. PHP支付宝转账到支付宝账号
  16. locale 国际化配置(springboot)
  17. SOFABoot框架(蚂蚁金服)
  18. 学生写给老师的一封邮件
  19. 第三章:电子商务平台选择
  20. python计算召回率_Pytorch 计算误判率,计算准确率,计算召回率的例子

热门文章

  1. 【学习笔记】SQL数据库
  2. GPU-CUDA-图形渲染分析
  3. 计算机老师 杂事多,有人说,老师忙,都忙在了教学之外的杂事上。你怎么看?...
  4. NightWatchJS
  5. 几款开源的ETL工具及ELT初探
  6. R语言中的fitted() 和 predict()
  7. MySQL - 用户管理
  8. 22061周市场回顾
  9. 需要达到什么水平才能找到一份计算机实习?
  10. 2022年零基础自学网络安全/Web安全,看这一篇就够了