版权声明
本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/11378133.html
前言
MediaExtractor字面意思是多媒体提取器,它在Android的音视频开发里主要负责提取视频或者音频中的信息和数据流(例如将视频文件,剥离出音频与视频).本章博客将讲解一些入门简单的东西.如何分别音频和视频轨道和获取视频里的一些信息.我将在其他章节里讲解其他MediaExtractor使用方法.
获取轨道
在一个多媒体视频里,可以包含多个数据流(一般是视频与音频各一个,但是音频可以多个).我们需要先获取需要的数据轨道编号,才能后续的各种操作.所以使用MediaExtractor的第一步就是获取轨道.如下代码展示了获取轨道的方法.
列举所有轨道编码格式的Demo方法
private void trackDemo(){ mFile = new File(getExternalCacheDir(),"demo.mp4"); if (!mFile.exists()){ Log.e(TAG, "mp4文件不存在"); return; } MediaExtractor extractor = new MediaExtractor();//实例一个MediaExtractor try { extractor.setDataSource(mFile.getAbsolutePath());//设置添加MP4文件路径 } catch (IOException e) { e.printStackTrace(); } int count = extractor.getTrackCount();//获取轨道数量 Log.e(TAG, "轨道数量 = "+count); for (int i = 0; i < count; i++){ MediaFormat mediaFormat = extractor.getTrackFormat(0); Log.e(TAG, i+"编号通道格式 = "+mediaFormat.getString(MediaFormat.KEY_MIME)); } }
上面的代码已经注释的很清楚了.注意! 实际项目里建议将这些操作放到线程中.
结果:
2019-08-19 17:08:21.197 18775-18775/demo.yt.com.demo E/测试Demo: 轨道数量 = 2
2019-08-19 17:08:21.198 18775-18775/demo.yt.com.demo E/测试Demo: 0编号通道格式 = video/avc
2019-08-19 17:08:21.198 18775-18775/demo.yt.com.demo E/测试Demo: 1编号通道格式 = audio/mp4a-latm
从结果可以看到,这个demo.mp4视频文件有2个轨道数量,一个是视频流的轨道,一个是音频流的轨道.
通过编码格式字符串对比获取指定轨道的方法
private Integer getTrackIndex(String targetTrack) { MediaExtractor extractor = new MediaExtractor();//实例一个MediaExtractor try { extractor.setDataSource(mFile.getAbsolutePath());//设置添加MP4文件路径 } catch (IOException e) { e.printStackTrace(); } Integer trackIndex = null; int count = extractor.getTrackCount();//获取轨道数量 for (int i = 0; i < count; i++) { MediaFormat mediaFormat = extractor.getTrackFormat(i); String currentTrack = mediaFormat.getString(MediaFormat.KEY_MIME); if (currentTrack.startsWith(targetTrack)) { trackIndex = i; break; } } return trackIndex; }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_media_extractor); mFile = new File(getExternalCacheDir(), "demo.mp4"); int index = getTrackIndex("video/"); Log.e(TAG, "onCreate: index = " + index); }
提取视频数据信息
从MediaFormat里获取数据信息
在上面的获取轨道的代码里我们,可以看到使用MediaFormat可以获取当前轨道的编码格式.除了获取编码格式我们还能获取到很多其他信息.这里我们将会一一列出,但是视频里的一些数据是肯定可以获取到的,而一些其他数据是需要看视频是否携带这些这些数据,如果未携带操作获取这些数据会抛出空指针错误.
基本可以获取到的信息
1.获取MIME信息,上面也有已经演示过了
MediaFormat mediaFormat = extractor.getTrackFormat(0);//获取多媒体格式,因为是demo已经确定自己的视频文件没问题,所以直接获取0位轨道 String mimeFormat = mediaFormat.getString(MediaFormat.KEY_MIME);//获取MIME格式内容 Log.e(TAG, "mediaExtractor: 获取MIME格式内容="+mimeFormat);
2.获取语言格式(大多数情况是获取到空的字符串,但是至少不会报null)
MediaFormat mediaFormat = extractor.getTrackFormat(0); String language = mediaFormat.getString(MediaFormat.KEY_LANGUAGE);//获取语言格式内容 Log.e(TAG, "mediaExtractor: 获取语言格式内容="+language);
3.视频的高度与宽度
MediaFormat mediaFormat = extractor.getTrackFormat(0); int width = mediaFormat.getInteger(MediaFormat.KEY_WIDTH);//获取高度 int height = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);//获取高度
4.播放总时长
long durationTime = mediaFormat.getLong(MediaFormat.KEY_DURATION);//总时间
5.获取MediaFormat描述的数据缓冲区的最大字节数的键
int maxByteCount = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);//获取视频缓存输出的最大大小
不确定可以获取到的信息
1.获取采样率
int sampleRate = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);//获取采样率
2.获取比特率
int bitRate = mediaFormat.getInteger(MediaFormat.KEY_BIT_RATE);//获取比特
3.获取声道数量
int channelCount = mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);//获取声道数量
4.获取最大高度与最大宽度
int maxWidth = mediaFormat.getInteger(MediaFormat.KEY_MAX_WIDTH);//最大宽度 int maxHeight = mediaFormat.getInteger(MediaFormat.KEY_MAX_HEIGHT);//最大高度
5.获取颜色格式
int colorFormat = mediaFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);//颜色格式
6.获取帧率
int frameRate = mediaFormat.getInteger(MediaFormat.KEY_FRAME_RATE);//帧率
7.获取图块的高度与宽度
int tileWidth = mediaFormat.getInteger(MediaFormat.KEY_TILE_WIDTH);//图块分辨率 int tileHeight = mediaFormat.getInteger(MediaFormat.KEY_TILE_HEIGHT);//图块分辨率
8.获取网格行
int gridRows = mediaFormat.getInteger(MediaFormat.KEY_GRID_ROWS);//网格行
9.获取网格列
int gridColumns = mediaFormat.getInteger(MediaFormat.KEY_GRID_COLUMNS);//网格列
10.PCM-编码 模拟信号编码
int pcmEncoding = mediaFormat.getInteger(MediaFormat.KEY_PCM_ENCODING);//PCM-编码 模拟信号编码
11.捕获率
float captureRate = mediaFormat.getFloat(MediaFormat.KEY_CAPTURE_RATE);//捕获率
12.是否是AAS
int isAdts = mediaFormat.getInteger(MediaFormat.KEY_IS_ADTS);
API列表
- setDataSource(String path):即可以设置本地文件又可以设置网络文件
- getTrackCount():得到源文件通道数
- getTrackFormat(int index):获取指定(index)的通道格式
- getSampleTime():返回当前的时间戳
- readSampleData(ByteBuffer byteBuf, int offset):把指定通道中的数据按偏移量读取到ByteBuffer中;
- advance():读取下一帧数据
- release(): 读取结束后释放资源
本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/11378133.html