安卓音视频播放器

简介: 安卓音视频播放器 随着短视频的发展,短视频的需求越来越复杂,比如添加滤镜、特效、字幕、贴纸等越来越多的功能都将添加到短视频编辑的功能里面。 为了能够实时预览我们想要的效果,我们一般都需要自研播放器。

安卓音视频播放器

随着短视频的发展,短视频的需求越来越复杂,比如添加滤镜、特效、字幕、贴纸等越来越多的功能都将添加到短视频编辑的功能里面。
为了能够实时预览我们想要的效果,我们一般都需要自研播放器。
有些资料/项目虽然讲解了音视频,但也只是单纯地将数据解码然后进行播放,并没有做音视频同步以及丢帧处理等操作,并不能算一个真正的播放器,只是把媒体播放出来而已。
有些资料/项目虽然做了音视频同步等处理,但在定位(seek)等处理上毛病比较多,比如快速定位出现杂音、渲染的视频画面出现雪花、块状等问题。
下面这个例子是Android环境下基于FFmpeg播放器开发的比较好的例子。
https://github.com/CainKernel/CainPlayer 

初始化流程
1 利用avformat_alloc_context()方法创建解复用上下文并设置解复用中断回调
2 利用 avformat_open_input()方法打开url,url可以是本地文件,也可以使网络媒体流
3 在成功打开文件之后,我们需要利用avformat_find_stream_info()方法查找媒体流信息
4 如果开始播放的位置不是AV_NOPTS_VALUE,即从文件开头开始的话,需要先利用avformat_seek_file方法定位到播放的起始位置
5 查找音频流、视频流索引,然后根据是否禁用音频流、视频流判断的设置,分别准备解码器对象
6 当我们准备好解码器之后,通过媒体播放器回调播放器已经准备。
7 判断音频解码器是否存在,通过openAudioDevice方法打开音频输出设备
8 判断视频解码器是否存在,打开视频同步输出设备
其中,第7、第8步骤,我们需要根据实际情况,重新设定同步类型。同步有三种类型,同步到音频时钟、同步到视频时钟、同步到外部时钟。默认是同步到音频时钟,如果音频解码器不存在,则根据需求同步到视频时钟还是外部时钟。

解复用流程
经过前面的初始化之后,我们就可以进入读数据包流程。读数据包流程如下:
1 判断是否退出播放器
2 判断暂停状态是否发生改变,设置解复用是否暂停还是播放 —— av_read_pause 和 av_read_play
3 处理定位状态。利用avformat_seek_file()方法定位到实际的位置,如果定位成功,我们需要清空音频解码器、视频解码器中待解码队列的数据。处理完前面的逻辑,我们需要更新外部时钟,并且更新视频同步刷新的时钟
4 根据是否设置attachmentRequest标志,从视频流取出attached_pic的数据包
5 判断解码器待解码队列的数据包如果大于某个数量,则等待解码器消耗
6 读数据包
7 判断数据包是否读取成功。如果没成功,则判断读取的结果是否AVERROR_EOF,即结尾标志。如果到了结尾,则入队一个空的数据包。如果读取出错,则直接退出读数据包流程。如果都不是,则判断解码器中的待解码数据包、待输出帧是否存在数据,如果都不存在数据,则判断是否跳转至起始位置还是判断是否自动退出,或者是继续下一轮读数据包流程。
8 根据取得的数据包判断是否在播放范围内的数据包。如果在播放范围内,则根据数据包的媒体流索引判断是否入队数据包舍弃。

准备解码器
准备解码器的流程一般如下:
1 创建解码上下文
2 从解复用上下文中复制参数到解码上下文
3 根据解码上下文的id查找解码器,如果在播放器指定了实际的解码器名称,则需要根据指定的解码器名称查找解码器
4 给解码上下文设置一些解码参数,比如lowres、refcounted_frames等解码参数
5 打开解码器
6 如果成功打开解码器,则根据类型创建解码器类,AudioDecoder或者是VideoDecoder。
7 如果不成功,则需要释放解码上下文

OpenSLES 音频输出
Android 环境下音频播放通常有两种方式—— AudioTrack 和 OpenSLES。AudioTrack 本身是Java实现,如果要使用的话,需要通过JNI Call的方式调用,实现起来也比较简单,这里就不做介绍了,有兴趣的可以自行实现。本项目采用OpenSLES 播放音频。
我们继承前面的AudioDevice基类,封装OpenSLES 音频输出设备。
OpenSLES 在open方法时初始化,并根据传进来的数据计算出需要的SL采样率、channel layout 等数据。并且在调用start方法时,启用一个音频输出处理线程。由于slBufferQueueItf设定了缓冲区大小,这里是设置了4个缓冲区,因此,线程不断从回调中取得PCM数据时,需要首先取得缓冲区填充的数量,如果队列中的4个缓冲区都填满了数据,则等待消耗,再从回调中取得PCM数据入队SL中进行播放。

MediaSync 媒体同步器
MediaSync 媒体同步器包含了音频时钟、视频时钟以及外部时钟,分别对应三种同步类型。同时媒体同步器另外开启了一条同步视频的线程。在线程中不断刷新并记录剩余时间,根据剩余时间来判断是否更新视频画面。

视频转码输出
视频输出的逻辑就是根据视频帧(AVFrame)的格式,判断是否需要进行转码,然后通知VideoDevice请求渲染画面。
VideoDevice 是一个视频设备的基类,主要包括结束方法(terminate)、初始化文理(onInitTexture)、更新YUV/ARGB数据(onUpdateYUV/onUpdateARGB),请求渲染画面(onRequestRender)几个方法组成,基类啥也不做处理。
这里我们采用OpenGLES来渲染视频。因此我们创建GLESDevice类,继承VideoDevice基类。
我们在代码里面根据传递进来的格式创建不同的Renderer进行渲染视频画面。视频帧的数据存放在Texture 结构体中,并传递给Renderer对象进行处理。Renderer又分成BGRARenderer 和 YUV420PRenderer对象。
GLESDevice由于使用了ANativeWindow来构建EGLSurface,对应Java层的Surface,此时会有surfaceCreated、surfaceChanged、surfaceDestroyed三个方法来改变状态的。
为了方便使用,我们打算将视频输出设备对象,从外面传进来 ,这样我们就可以根据不同的OS环境进行更换输出设备了,比如你想接入iOS设备的时候,播放器的逻辑基本不需要更改,只需要将音频输出设备、视频输出设备进行更换即可。
--------------------- 
作者:carlshen8 
来源:CSDN 
原文:https://blog.csdn.net/carlshen/article/details/87474532 
版权声明:本文为博主原创文章,转载请附上博文链接!
相关文章
|
开发工具 Android开发 开发者
Android如何回调编码后的音视频数据
有开发者提到,在RTMP推送端的基础上,希望能回调编码后的音视频数据,便于开发者对接第三方系统,如GB28181.
|
编解码 监控 网络协议
Android平台音视频推送选RTMP还是GB28181?
早在2015年,我们发布了RTMP直播推送模块,那时候音视频直播这块场景需求,还不像现在这么普遍,我们做这块的初衷,主要是为了实现移动单兵应急指挥系统的低延迟音视频数据传输。好多开发者可能会疑惑,走RTMP怎么可能低延迟?网上看到的RTMP推拉流延迟,总归要2-3秒起,如果是自己实现框架,RTMP推拉流逻辑自己实现的话,延迟确实可以控制在毫秒级,这个已无需赘述。
|
Web App开发 数据采集 物联网
Android平台基于RTMP或RTSP的一对一音视频互动技术方案探讨
随着智能门禁等物联网产品的普及,越来越多的开发者对音视频互动体验提出了更高的要求。目前市面上大多一对一互动都是基于WebRTC,优点不再赘述,我们这里先说说可能需要面临的问题:WebRTC的服务器部署非常复杂,可以私有部署,但是非常复杂。传输基于UDP,很难保证传输质量,由于UDP是不可靠的传输协议,在复杂的公网网络环境下,各种突发流量、偶尔的传输错误、网络抖动、超时等等都会引起丢包异常,都会在一定程度上影响音视频通信的质量,难以应对复杂的互联网环境,如跨区跨运营商、低带宽、高丢包等场景,行话说的好:从demo到实用,中间还差1万个WebRTC。
143 0
|
监控 前端开发 网络协议
Android前端音视频数据接入GB28181平台意义
在我们研发Android平台GB28181前端音视频接入模块之前,业内听到最多的是,如何用Android或者Windows端,在没有国标IPC设备的前提下,模拟GB28181的信令和媒体流交互流程,实现GB28181整体方案的测试?
131 0
|
1月前
|
Web App开发 网络协议 Android开发
Android平台一对一音视频通话方案大比拼:WebRTC VS RTMP VS RTSP,谁才是王者?
【9月更文挑战第4天】本文详细对比了在Android平台上实现一对一音视频通话时常用的WebRTC、RTMP及RTSP三种技术方案。从技术原理、性能表现与开发难度等方面进行了深入分析,并提供了示例代码。WebRTC适合追求低延迟和高质量的场景,但开发成本较高;RTMP和RTSP则在简化开发流程的同时仍能保持较好的传输效果,适用于不同需求的应用场景。
62 1
|
5月前
|
监控 Unix 应用服务中间件
Android-音视频学习系列-(八)基于-Nginx-搭建(rtmp、http)直播服务器
Android-音视频学习系列-(八)基于-Nginx-搭建(rtmp、http)直播服务器
|
5月前
|
Java Android开发 设计模式
flutter音视频开发,Android开发需要学什么
flutter音视频开发,Android开发需要学什么
|
Web App开发 开发工具 Android开发
Android平台不需要单独部署流媒体服务如何实现内网环境下一对一音视频互动
我们在做内网环境的一对一音视频互动的时候,遇到这样的技术诉求:如智能硬件场景下(比如操控智能硬件),纯内网环境,如何不要单独部署RTMP或类似流媒体服务,实现一对一音视频互动。
|
编解码 Android开发 数据安全/隐私保护
Android平台GB28181设备接入端对接编码前后音视频源类型浅析
今天主要对Android平台GB28181设备接入模块支持的接入数据类型,做个简单的汇总: 1. 编码前数据(目前支持的有YV12/NV21/NV12/I420/RGB24/RGBA32/RGB565等数据类型),其中,Android平台前后摄像头数据,或者屏幕数据,或者Unity拿到的数据,均属编码前数据; 2. 编码后数据(如无人机等264/HEVC数据,或者本地解析的MP4音视频数据); 3. 拉取RTSP或RTMP流并接入至GB28181平台(比如其他IPC的RTSP流,可通过Android平台GB28181接入到国标平台)。
|
编解码 Java 开发工具
[技术分享]Android平台实时音视频录像模块设计之道
录像有什么难的?无非就是数据过来,编码保存mp4而已,这可能是好多开发者在做录像模块的时候的思考输出。是的,确实不难,但是做好,或者和其他模块有非常好的逻辑配合,确实不容易。
下一篇
无影云桌面