Android 音视频深入 三 MP4解码播放视频 (附源码下载)
本篇项目地址,求star
https://github.com/979451341/Audio-and-video-learning-materials/tree/master/%E5%AA%92%E4%BD%93%E8%A7%A3%E7%A0%81MediaCodec%2CMediaExtractor
这次要用到新的东西SurfaceView、MediaCodec、MediaExtractor、MediaFormat
1.文字说明
SurfaceView:一个View,用来显示视频的,使用的时候代码都比较简单就不多说了
MediaCodec:访问底层媒体编码,能够完成媒体编码和解码
编码是将源对象内容按照一种标准转换为一种标准格式内容。
解码是和编码对应的,它使用和编码相同的标准将编码内容还原为最初的对象内容。
MediaExtractor:负责将指定类型的媒体文件从文件中找到轨道,并填充到MediaCodec的缓冲区中
MediaFormat:封装描述媒体数据格式的信息,无论是音频还是视频。媒体数据的格式被指定为字符串/值对。所有格式通用的键,所有未标记为可选的键都是必需的:
名称 值类型 描述
KEY_MIME 串 格式的类型。
KEY_MAX_INPUT_SIZE 整数 可选,输入数据缓冲区的最大大小
KEY_BIT_RATE 整数 仅编码器,所需比特率(以比特/秒为单位)
2.视频播放顺序
(1)开启两个线程分别处理MP4的音频和视频
我先说一下视频的处理
使用MediaExtractor提取资源,选择频道
MediaExtractor videoExtractor = new MediaExtractor();MediaCodec videoCodec = null;try {videoExtractor.setDataSource(filePath);} catch (IOException e) {e.printStackTrace();}int videoTrackIndex;//获取视频所在轨道videoTrackIndex = getMediaTrackIndex(videoExtractor, "video/");
videoExtractor.selectTrack(videoTrackIndex);
设置解码配置,并给MediaCodec配置,而且将SurfaceView于MediaCodec相关联,设置为在这个SurfaceView上显示
MediaFormat mediaFormat = videoExtractor.getTrackFormat(videoTrackIndex);int width = mediaFormat.getInteger(MediaFormat.KEY_WIDTH);int height = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);float time = mediaFormat.getLong(MediaFormat.KEY_DURATION) / 1000000;callBack.videoAspect(width, height, time);videoExtractor.selectTrack(videoTrackIndex);try {videoCodec = MediaCodec.createDecoderByType(mediaFormat.getString(MediaFormat.KEY_MIME));videoCodec.configure(mediaFormat, surface, null, 0);} catch (IOException e) {e.printStackTrace();}
循环从MediaExtractor取数据放入MediaCodec,同时MediaCodec返回数据,表示视频播放状态,然后对应转台做不同的处理,
while (!Thread.interrupted()) {if (!isPlaying) {continue;}//将资源传递到解码器if (!isVideoEOS) {isVideoEOS = putBufferToCoder(videoExtractor, videoCodec, inputBuffers);}int outputBufferIndex = videoCodec.dequeueOutputBuffer(videoBufferInfo, TIMEOUT_US);switch (outputBufferIndex) {case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:Log.v(TAG, "format changed");break;case MediaCodec.INFO_TRY_AGAIN_LATER:Log.v(TAG, "超时");break;case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED://outputBuffers = videoCodec.getOutputBuffers();Log.v(TAG, "output buffers changed");break;default://直接渲染到Surface时使用不到outputBuffer//ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];//延时操作//如果缓冲区里的可展示时间>当前视频播放的进度,就休眠一下sleepRender(videoBufferInfo, startMs);//渲染videoCodec.releaseOutputBuffer(outputBufferIndex, true);break;}if ((videoBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {Log.v(TAG, "buffer stream end");break;}}//end while
然后是音频,很相似
MediaExtractor获取资源,选择频道,得到MediaFormat,获取一些参数来配置AudioTrack,然后就不说了,上一篇博客说了如何播放音频,
MediaExtractor audioExtractor = new MediaExtractor();try {audioExtractor.setDataSource(filePath);} catch (IOException e) {e.printStackTrace();}MediaFormat mediaFormat = audioExtractor.getTrackFormat(i);String mime = mediaFormat.getString(MediaFormat.KEY_MIME);if (mime.startsWith("audio/")) {audioExtractor.selectTrack(i);int audioChannels = mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);int audioSampleRate = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);int minBufferSize = AudioTrack.getMinBufferSize(audioSampleRate,(audioChannels == 1 ? AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO),AudioFormat.ENCODING_PCM_16BIT);int maxInputSize = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,audioSampleRate,(audioChannels == 1 ? AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO),AudioFormat.ENCODING_PCM_16BIT,audioInputBufferSize,AudioTrack.MODE_STREAM);
其实这做的不太好,因为音频和视频没有做协调,之前可能不同步
完整代码下载地址在文章头部
参考文章:
http://blog.csdn.net/qq_36467463/article/details/77990089
https://www.cnblogs.com/jiy-for-you/p/7282033.html
https://www.jianshu.com/p/6df2ab17651a
Android 音视频深入 三 MP4解码播放视频 (附源码下载)相关推荐
- android画板需求分析,Android编程实现画板功能的方法总结【附源码下载】
本文实例讲述了Android编程实现画板功能的方法.分享给大家供大家参考,具体如下: Android实现画板主要有2种方式,一种是用自定义View实现,另一种是通过Canvas类实现.当然自定义Vie ...
- leaflet-webpack 入门开发系列三地图分屏对比(附源码下载)
前言 leaflet-webpack 入门开发系列环境知识点了解: node 安装包下载 webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载地址 ...
- android flv 编码器,Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载)...
Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载) 项目地址 https://github.com/979451341/RtmpSave 这个项目主要代码 ...
- 酷毙了!三种风格的全屏幻灯片效果【附源码下载】
今天,我们想向您展示如何创建平铺背景图像的幻灯片效果.其灵感来自于国外的一个工作室网站(围观),这个网站充满了各种有趣和创意效果,一定记得去看看. 这个幻灯片效果是由四个区域的独立移动构成,通过画面分 ...
- 短视频去水印多功能工具箱微信小程序源码下载支持多种流量主
没错这是一款以去水印为主的一款多功能微信小程序源码 该小程序源码除了拥有去水印功能以外还拥有N款其它实用的功能 比如喝酒神器,短网址生成,历史上的今天等等如下: 短视频去水印(自带接口,速度非常快) ...
- android+仿iphone,Android编程实现仿iphone抖动效果的方法(附源码)
Android编程实现仿iphone抖动效果的方法(附源码) 时间:2021-05-20 本文实例讲述了Android编程实现仿iphone抖动效果的方法.分享给大家供大家参考,具体如下: 布局文件: ...
- Android 百度地图-实现POI的搜索(搜索周边)附源码
首先贴出主要代码 Activity package cn.yhsh.maptest;import java.util.ArrayList; import utils.PoiOverlay; impor ...
- Android 统一打包框架(附源码下载)
唠叨: 把手给我,我带你去吃云浮吃石磨肠粉.云吞面,木瓜渣. 那里的肠粉和广州的不一样,皮很薄很滑,肉馅没广州的那么花里胡哨,只有肉碎和香葱.但吃起来就很香滑,再配上它的甜辣酱.那味道好极了. 云吞面 ...
- Android 利用广播实现黑名单【指定号码】的短信的拦截 附源码下载链接
Android 利用广播实现指定号码的短信的拦截 根据最近的学习内容,今天实现了利用广播进行指定号码的拦截 步骤: ①.写一个数据库的帮助类,实现对数据库的创建,总共创建两个数据库psms(受保护的短 ...
最新文章
- Hackthebox--------irked
- 不忘初心,砥砺前行——写在数据院成立四周年之际
- 关于从 coding 拉项目的操作
- python那么慢为什么还有人用-为什么Python比C++慢很多?
- can a select block a truncate (ZT)
- Java 8 - 数值流Numberic Stream
- 互联网1分钟 |1205
- onvif_discover虚拟摄像头
- java 执行顺序混乱_java类执行顺序问题
- JAVA中的反射机制和模块化
- 远程桌面复制文件到本地磁盘
- 渐进式Web应用(PWA)入门教程(下)
- 在c语言中保留35位小数,C语言程序设计复习题(供学有余力学生练习)(35页)-原创力文档...
- 封装,继承,多态的理解
- win7自定义html为桌面,Win7系统如何自定义个性桌面?
- Python解决数字棒球游戏
- NS3 Tutorial 中文版:第二章 资源
- VSCode添加背景图片
- 一个好用的源代码阅读工具——Understand
- 【成本收集器】目标成本与实际成本差异分析