1 简介

本文以 mp4 文件为例,讲解去音频操作。mp4 是一种视频封装的容器,里面包含音频(audio)和视频(video)数据,对应的数据编码格式分别为 aac 和 h264。在去音频过程中,主要使用到 MediaFormat、MediaExtractor、MediaMuxer,其作用如下:

  • MediaFormat:用于存储视频轨或音频轨的信息(MIME、时长、帧率、比特率、关键帧间隔、视频宽高等);
  • MediaExtractor:媒体分离器,用于分离音频和视频数据,并且能够遍历帧数据;
  • MediaMuxer:媒体复合器,用于合成音频和视频数据。

        (1)MediaFormat

//初始化
MediaFormat mediaFormat = new MediaFormat()
MediaFormat mediaFormat = mediaExtractor.getTrackFormat(i)//获取MIME
String mime = mediaFormat.getString(MediaFormat.KEY_MIME)//获取总时长(单位:微秒us)
long durationTime = mediaFormat.getLong(MediaFormat.KEY_DURATION)//获取帧率
int frameRate = mediaFormat.getInteger(MediaFormat.KEY_FRAME_RATE)//获取比特率
int bitRate = mediaFormat.getInteger(MediaFormat.KEY_BIT_RATE)//获取视频宽度(像素:px)
int width = mediaFormat.getInteger(MediaFormat.KEY_WIDTH)//获取视频高度(像素:px)
int height = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT)//获取关键帧间隔(单位:秒)
int iFrameInterval = mediaFormat.getInteger(MediaFormat.KEY_I_FRAME_INTERVAL)

用户也可以调用 mediaFormat.setX()方法注入属性。

        (2)MediaExtractor

//初始化
MediaExtractor mediaExtractor = new MediaExtractor()//设置资源
setDataSource(String input_path)
mediaExtractor.setDataSource("/sdcard/Pictures/WeiXin/a.mp4")//获取轨道数
mediaExtractor.getTrackCount()//获取 mediaFormat
MediaFormat mediaFormat = mediaExtractor.getTrackFormat(index) //index为轨道编号//选择轨道
mediaExtractor.selectTrack(index) //index为轨道编号//读取1帧数据到buffer
int input_size = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE) //获取最大输入缓存大小
ByteBuffer buffer = ByteBuffer.allocate(input_size)
int sampleSize = mediaExtractor.readSampleData(buffer, offset) //offset一般取0//读取下一帧数据
mediaExtractor.advance()//定位到timeUs附近的关键帧
mediaExtractor.seekTo(timeUs, mode) //mode一般取 MediaExtractor.SEEK_TO_CLOSEST_SYNC//释放资源
mediaExtractor.release()

        (3)MediaMuxer

//初始化
MediaMuxer(String output_path, int format)
MediaMuxer mediaMuxer = new MediaMuxer("/sdcard/a.mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)//添加轨道
int videoTrackIndex = mediaMuxer.addTrack(mediaFormat)//开始合成文件
mediaMuxer.start()//写入数据
writeSampleData(int trackIndex, ByteBuffer byteBuf, MediaCodec.BufferInfo bufferInfo)//释放资源
mediaMuxer.stop()
mediaMuxer.release()

2 案例

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void get_video() throws IOException {String input_path = "/sdcard/Pictures/WeiXin/a.mp4"; //源视频素材String output_path = "/sdcard/a.mp4"; //去音频后的素材MediaExtractor mediaExtractor = new MediaExtractor();mediaExtractor.setDataSource(input_path);MediaMuxer mediaMuxer = new MediaMuxer(output_path, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);int input_size =0;int videoTrackIndex = -1;int count = mediaExtractor.getTrackCount(); //获取轨道数for (int i = 0; i < count; i++) {MediaFormat format = mediaExtractor.getTrackFormat(i);String mime = format.getString(MediaFormat.KEY_MIME);if (mime.startsWith("video/")) { // mp4为“video/avc”input_size = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);mediaExtractor.selectTrack(i);videoTrackIndex = mediaMuxer.addTrack(format);break;}}mediaMuxer.start();int sampleSize = 0;MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();ByteBuffer buffer = ByteBuffer.allocate(input_size); //也可以设置为:500*1024while ((sampleSize = mediaExtractor.readSampleData(buffer, 0)) > 0) {info.offset = 0;info.size = sampleSize;info.flags = mediaExtractor.getSampleFlags();info.presentationTimeUs = mediaExtractor.getSampleTime();mediaMuxer.writeSampleData(videoTrackIndex, buffer, info); //写入数据mediaExtractor.advance(); //下一帧}mediaExtractor.release();mediaMuxer.stop();mediaMuxer.release();
}

3 拓展

可以通过修改 BufferInfo 的 presentationTimeUs 属性,实现倍速导出视频,如下:

float speed = 3.0f; //播放速度
info.presentationTimeUs = (long)(mediaExtractor.getSampleTime()/speed);
mediaMuxer.writeSampleData(videoTrackIndex, buffer, info); //写入数据

特别注意:不要试图通过修改 BufferInfo 的 flags 属性改变帧标签(I帧、P帧、B帧),若想修改帧标签,需要使用 Mediacodec 重新解码和编码。

【Android】使用MediaExtractor、MediaMuxer去掉视频文件中的音频数据相关推荐

  1. 使用ffmpeg从视频文件中提取音频文件、视频抽帧和切割视频

    目录 ffmpeg下载 使用ffmpeg从视频文件中提取音频文件 批量提取文件夹下多个视频文件的音频 使用ffmpeg从视频文件中提取视频帧 使用ffmpeg将按固定时长将视频切割成多个小片段 将分割 ...

  2. FFmpeg进阶: 转码输出视频文件中的音频

    很多时候为了方便收听视频文件中的音频信息,我们会将视频文件中的音频流转码输出成音频文件,方便在对应的平台上进行播放.这里就介绍一下如何通过FFmpeg将视频文件中的音频流转码成特定编码格式的音频文件. ...

  3. [SimplePlayer] 4. 从视频文件中提取音频

    提取音频,具体点来说就是提取音频帧.提取方法与从视频文件中提取图像的方法基本一样,这里仅列出其中的不同点: 1. 由于目的提取音频,因此在demux的时候需要指定的是提取audio stream Au ...

  4. ffmpeg批量去掉mp4视频文件中的音频,仅保留视频

    1.新建一个txt文件,并复制如下代码进入,然后保存. @echo off & titlecd /d %~dp0for %%a in (*.mp4) do (ffmpeg -i "% ...

  5. 如何将视频文件中的音频提取出来?

    今天要讲的就是将视频中的音频提取出来,小编找到一款快速提取视频音频的软件,接下来就看看小编是如何操作的吧! 方法步骤: 1.这款软件很容易就能找到,在百度搜索"迅捷音频转换器"即可 ...

  6. ffmpeg_拼接并提取flv视频文件中的音频生成mp3文件

    使用ffmpeg拼接多个 flv 视频并提取拼接好的 flv 文件的音频生成 mp3 文件 下一篇博文:ffmpeg_分割一个mp4文件到多个小的mp4文件 起因 下载了一个视频,网站上虽然是一整个, ...

  7. Python从视频文件中提取音频

    利用python库moviepy或者ffmpeg处理 # 这是一个示例 Python 脚本. from moviepy.editor import * import tkinter as tk fro ...

  8. ffmpeg批量提取mp4视频文件中的音频

    1.新建一个txt文件,并复制如下代码进入,然后保存. @echo off & titlecd /d %~dp0for %%a in (*.mp4) do (ffmpeg -i "% ...

  9. 使用Python,提取视频文件中的音频

    ■前言 一些好的视频,我们只需要其中的声音就够了. (抖音上的一首,五十音图的儿歌) ■Step1 安装Python Python 语言 Hello world_sun0322的博客-CSDN博客 ■ ...

最新文章

  1. PEOPEO中国区总经理于景:当我谈交互设计时我谈些什么
  2. linux动态分配全局置换,深入理解计算机系统 第九章 虚拟存储器
  3. 仿照支付宝账单界面--listview分组显示 用来做!发!财树充值交易明细
  4. 数据库DBA(3年以内需求)
  5. linux 普通io实现pwm,用普通IO口做PWM输出 - 51单片机 - 电子工程世界-论坛 - 手机版...
  6. 《天天数学》连载35:二月四日
  7. python怎么创建类的例题_Python_面向对象练习题
  8. 域 禁用计算机,域成员 在 Windows 10 (禁用计算机帐户) - Windows security | Microsoft Docs...
  9. Win10电脑如何定时关机
  10. 【数据结构】KMP算法分析与理解(图文分析)
  11. poj1062 昂贵的聘礼
  12. cs1.6正版僵尸服务器ip,cs1.6僵尸服务器
  13. 海康威视-海康门禁设备对接SDK-已完成完整封装调用
  14. 【HDU2019多校】E - Snowy Smile (最大字段和)
  15. mysql rank_MySQL实现rank排名(一)自定义变量@rank
  16. uC/OS II移植
  17. [KDD 2022]ROLAND Graph Learning Framework for Dynamic Graphs
  18. 软件测试工程师笔试题
  19. Oracle数据库Timestamp数据差值计算Sql语句
  20. 牛客网笔试系统ACM模式下的程序输入格式总结

热门文章

  1. 华为鸿蒙OS摄像头,首款华为鸿蒙OS摄像头开售:分布式看家新神器 无需SD卡
  2. 使用FFMPEG库封装264视频和acc音频数据到MP4文件中
  3. 图解三代测序(SMRT Sequencing)
  4. 轻量级的肝脏与肝肿瘤 2.5D 分割网络阅读笔记
  5. Java多线程的使用方法,Thread,Runnable
  6. 穷人跨越阶层有多难?
  7. 我是小小志愿者——国际志愿者日线上宣传活动
  8. web程序发布后发送传真失败记要
  9. 方向比努力重要,能力比知识重要,健康比成绩重要,生活比文凭重要,情商比智商重要
  10. world标题是大写数字,题注要阿拉伯数字,交叉引用不会出错