02 MediaExtractor 的基本使用 对音视频媒体文件解码时,我们首先需要分离出媒体文件的音视频轨道,MediaExtractor 就是干这个的,它可以告诉你媒体中轨道(Track)数量,并根据索引读取指定轨道数据 创建一个媒体分离器 MediaExtractor extractor = new MediaExtractor(); 为媒体分离器装载媒体文件路径 // 指定文件路径 String videoPath extractor.getTrackCount(); // mime type 指示需要分离的轨道类型 String extractMimeType = "video/"; // 记录轨道索引id,MediaExtractor API 概述 1. createDecoderByType(String mimeType) 根据 mime type 创建一个解码器(mimeType 可通过 MediaExtractor 的 MediaFormat 示例 // step 1:创建一个媒体分离器 MediaExtractor extractor = new MediaExtractor(); // step 2:为媒体分离器装载媒体文件路径 //
工具准备: 视频的分离合成我主要用到了MediaExtractor和MediaMuxer两个类: MediaExtractor是用于提取多路的、通常编码的视频资源的,通过它我们可以选择音频或者视频轨, 开始搞: 1.提取音视频: 我们将视频一的路径通过setDataSource方法设置给MediaExtractor对象,然后通过方法getTrackCount获取到该视频的轨道数,接着循环轨道数,此时我们可以通过 MediaExtractor对象的getTrackFormat方法获取到MediaFormat,然后找到我们想要的音频轨,还记得MediaMuxer类是用来合成的吧,那么我们将找到的音频轨通过addTrack 2.合成: 那么到这里,视频一的音频和视频二的视频图像都已经设置给MediaMuxer对象了,我们就可以合成啦,还记得我们在找音频和视频的时候记录下的新旧轨道吧,现在通过MediaExtractor对象的 frameVideoExtractor = new MediaExtractor(); int frameExtractorTrackIndex = -1; //视频轨
获得音视频的配置器MediaFormat private static MediaFormat getFormat(String path,boolean isVideo) { try { MediaExtractor mediaExtractor = new MediaExtractor(); mediaExtractor.setDataSource(path); int trackCount = mediaExtractor.getTrackCount(); for (int i = 0; i < trackCount; i++) { MediaFormat trackFormat = mediaExtractor.getTrackFormat(i); if (trackFormat.getString(MediaFormat.KEY_MIME "video/" :"audio/")) { return mediaExtractor.getTrackFormat(i); } } }
end-of-stream标记到达输出端; 可以调用stop方法结束执行状态,编解码器将回到未初始化状态(Uninitialized) 当不再使用编解码器时,必须调用release方法释放相关资源 MediaExtractor 这里我们引入MediaExtractor,它可以分离mp4,flv生成视频h264/mpeg和音频mp3或aac(无adts头) MediaExtractor的用法很简单,参考官方文档的举例即可 ? MediaCodec解码音视频 解码视频创建视频解码器 val trackFormat = mediaExtractor.getTrackFormat(videoTrackIndex) val type surfaceView.holder.surface videoCodec.configure(trackFormat, surface, null, 0) 启动解码器 videoCodec.start() 从MediaExtractor : continue // clear old data inputBuffer.clear() // read data to input buffer val sampleSize = mediaExtractor.readSampleData
为了讲解的方便,我们引入了 MediaExtractor 类。它用于打开MP4等媒体文件,并从中抽取出音视频数据。 打开媒体文件 MediaExtractor,音视频数据分离器。 MediaExtractor的作用就是根据容器协议打开容器,并读取其中的音频或视频数据。 在容器文件(MP4)中,音频数据与视频数据是以轨道(�track)的概念存放的。 我们使用MediaExtractor类打开媒体文件,它的使用非常简单,步骤如下: 1. 创建一个MediaExtractor对象。 2. 将媒体文件设置给MediaExtractor对象。 3. MediaExtractor extractor = null; try { extractor = new MediaExtractor(); extractor.setDataSource 通过 MediaExtractor 对象从视频轨道中取出H264数据存到InputBuffer中。 3. 将InputBuffer放到InputBuffer队列中。
在介绍AAC编解码之前,首先要先学习几个新知识MediaExtractor和ADTS格式 仓库源码FFmpegSample,对应版本代码v1.6 MediaExtractor 前面在介绍视频编码的时候使用到了 下面要介绍另外一个类MediaExtractor:负责将指定类型的媒体文件从文件中找到轨道,可以用来分离容器中的视频track和音频track。将得到的原始数据解析成解码器需要的数据。 ? 分离轨道信息 getTrackCount()获取轨道数量 MediaFormat format = mediaExtractor.getTrackFormat(i);获取对应轨道的信息。 = new MediaExtractor();//此类可分离视频文件的音轨和视频轨道 mediaExtractor.setDataSource(srcPath);//媒体文件的位置 = null) { mediaExtractor.release(); mediaExtractor = null; }
通过MediaExtractor::Create(dataSource)来实现。 Create方法通过两步来生成对应的 MediaExtractor(MediaExtractor.cpp): 通过dataSource->sniff来探測数据类型 生成对应的Extractor MediaSource &source是一个MediaExtractor。 由DataSource生成MediaExtractor。 通过sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);来实现。
KFDemuxerConfig mConfig = null; ///< 解封装配置 private KFDemuxerListener mListener = null; ///< 回调 private MediaExtractor mAudioMediaExtractor = null; ///< 音频解封装器 private MediaFormat mAudioMediaFormat = null; ///< 音频格式描述 private MediaExtractor if (bufferInfo.size > 0) { bufferInfo.flags = mAudioMediaExtractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC if (mAudioMediaExtractor == null) { mAudioMediaExtractor = new MediaExtractor(); if (mVideoMediaExtractor == null) { mVideoMediaExtractor = new MediaExtractor();
随着Android 4.4及以上版本的逐渐普及,Android 4.1引入的MediaExtractor类,以及Android 4.3引入的MediaMuxer类,终于可以开始正式地“发光发热”了。 MediaMuxer类主要用于将音频和视频数据进行混合生成多媒体文件(如:mp4文件),而MediaExtractor则刚好相反,主要用于多媒体文件的音视频数据的分离。 本文将介绍如何利用Android SDK提供的MediaExtractor和MediaMuxer类来完成mp4文件的提取和生成,指出开发过程中会遇到的坑,并给出简单的Demo示例代码。 MediaExtractor 该类主要用于音视频混合数据的分离,接口比较简单,首先要通过setDataSource(String path)函数设置数据源,数据源可以是本地文件地址,也可以使用HTTP协议的网络码流地址 在本示例中,可以直接使用MediaExtractor.getTrackFormat()解析得到的MediaFormat对象,如果你希望自己来创建这个MediaFormat对象的话,可以使用该类的如下静态方法创建
/获得音视频的配置器MediaFormat private static MediaFormat getFormat(String path,boolean isVideo) { try { MediaExtractor mediaExtractor = new MediaExtractor(); mediaExtractor.setDataSource(path); int trackCount = mediaExtractor.getTrackCount (); for (int i = 0; i < trackCount; i++) { MediaFormat trackFormat = mediaExtractor.getTrackFormat( "video/" :"audio/")) { return mediaExtractor.getTrackFormat(i); } } } catch (IOException e) { e.printStackTrace
这里我们分析三种可行的技术方案:方案1:解析视频文件推送Android终端的话,先利用MediaExtractor,把mp4文件的音视频数据分离,然后调用我们publisher模块,实现编码后的数据对接到 mFile.exists()){ Log.e(TAG, "mp4文件不存在"); return; } MediaExtractor mediaExtractor = new MediaExtractor(); try { mediaExtractor.setDataSource(mFile.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } int count = mediaExtractor.getTrackCount();//获取轨道数量 Log.e (TAG, "轨道数量 = "+count); for (int i = 0; i < count; i++) { MediaFormat trackFormat = mediaExtractor.getTrackFormat
MediaCodec 介绍 MediaCodec 是 Android 提供的用于对音视频进行编解码的类,它通过访问底层的 codec 来实现编解码的功能,是 Android media 基础框架的一部分,通常和 MediaExtractor 配置 AMediaCodec 对象,只解码视频流: m_MediaExtractor = AMediaExtractor_new(); media_status_t err = AMediaExtractor_setDataSourceFd(m_MediaExtractor, fd,static_cast<off64_t>(outStart),static_cast<off64 err=%d", err); break; } int numTracks = AMediaExtractor_getTrackCount(m_MediaExtractor AMediaExtractor_selectTrack(m_MediaExtractor, i); m_MediaCodec = AMediaCodec_createDecoderByType
MediaExtractor extractor = null; MediaFormat mediaFormat = null; MediaCodec decoder = null; extractor static private MediaExtractor initMediaExtractor(File path) throws IOException { MediaExtractor extractor = null; extractor = new MediaExtractor(); extractor.setDataSource(path.toString ()); return extractor; } static private MediaFormat initMediaFormat(String path, MediaExtractor } return decoder; } 初始化完成后我们可以利用这三个对象进行关键帧获取: private static Bitmap getBitmapBySec(MediaExtractor
获取一个视频的关键帧序列,基于 Android 平台 API 实现: MediaExtractor extractor = new MediaExtractor(); extractor.setDataSource = -1) { long sampleTime = extractor.getSampleTime(); if ((extractor.getSampleFlags() & MediaExtractor.SAMPLE_FLAG_SYNC sampleTime / 1000); } // 此处表示 extractor seek 的间隔为 1000 微妙 extractor.seekTo(sampleTime + 1000, MediaExtractor.SEEK_TO_NEXT_SYNC
喂入数据到解码器 * * @return true 喂入成功 * @since v3.0.1 */ private boolean feedInputBuffer(MediaExtractor * 启动解码器 */ public void doDecoder(Surface surface){ // step 1:创建一个媒体分离器 MediaExtractor extractor = new MediaExtractor(); // step 2:为媒体分离器装载媒体文件路径 // 指定文件路径 try { String extractMimeType = mDecodeMimeType; MediaFormat trackFormat = null; // 记录轨道索引id,MediaExtractor
本次以MediaExtractor为例,先利用MediaExtractor,把mp4文件的音视频数据分离,然后调用我们publisher模块,实现编码后的数据对接到RTMP服务器、轻量级RTSP服务或GB28181 mFile.exists()){Log.e(TAG, "mp4文件不存在");return;}MediaExtractor mediaExtractor = new MediaExtractor();try {mediaExtractor.setDataSource(mFile.getAbsolutePath());} catch (IOException e) {e.printStackTrace(); }int count = mediaExtractor.getTrackCount();//获取轨道数量Log.e(TAG, "轨道数量 = "+count);for (int i = 0; i < count ; i++){MediaFormat trackFormat = mediaExtractor.getTrackFormat(i);String mineType = trackFormat.getString
图2:mediacodec解码流程 MediaExtractor 负责从视频文件中解析每一帧的原始数据; Mediacodec 负责对音视频数据进行解码,并渲染指定的surface上; 代码示例: // 初始化extractor MediaExtractor extractor = new MediaExtractor(); extractor.setDataSource(...); ...
MediaExtractor是Android平台的多媒体提取器,能够根据视频轨道或者音频轨道去提取对应的数据。 在进行视频编辑时,可以利用MediaExtractor来提取指定的音频信息,封装到目标音视频文件中。 //根据指定文件路径创建MediaExtractor val mediaExtractor = MediaExtractor(...) //为MediaExtractor选择好对应的媒体轨道 mediaExtractor.selectTrack(...) mediaExtractor.readSampleData(inputBuffer, 0) //进入下一帧 mediaExtractor.advance() //MediaExtractor读取到的音频数据可以使用
这时候作为一个做责任的社会主义青少年,我发现了这个MP3RadioStreamPlayer,看简介:An MP3 online Stream player that uses MediaExtractor 其中MediaExtractor,我们需要支持网络数据,这个类可以负责中间的过程,即将从DataSource得到的原始数据解析成解码器需要的es数据,并通过MediaSource的接口输出。 下面直接看代码吧,都有注释(真的不是懒得讲╮(╯_╰)╭): 流程就是定义好buffer,初始化MediaExtractor来获取数据,MediaCodec对数据进行解码,初始化AudioTrack播放数据 ByteBuffer[] codecInputBuffers; ByteBuffer[] codecOutputBuffers; // 这里配置一个路径文件 extractor = new MediaExtractor
它是Android底层多媒体支持基础架构的一部分(通常与MediaExtractor, MediaSync, MediaMuxer, MediaCrypto, MediaDrm, Image, Surface private c b; public b(c cVar) { this.b = cVar; } private void a(MediaExtractor mediaExtractor, int i, MediaCodec mediaCodec) throws Exception { } public void a() i2 + 1; return i2; } /* access modifiers changed from: private */ public int a(MediaExtractor mediaExtractor) { return 0; } /* access modifiers changed from: private */ public