为了账号安全,请及时绑定邮箱和手机立即绑定

「播放器」Android视频开发介绍

2018.08.01 20:15 1920浏览

移动端流媒体随着各种视频app的火爆,以及移动流量的升级逐渐占据人们大量宝贵的时间。但是从开发小白的角度来看,这一直是个很有难度的开发领域,真正深度接触视频业务的app也不多,恰好有了浅度的需求,往往又会花费大量的时间了解、踩坑。「播放器」系列文章的目的,就是想完成一个「还可以的」实践,读完文章也能达到实践的程度。基于ijkplayer
这篇文章更多的是总体的介绍,会随着理解加深不断更新。

0 播放器基本原理

首先简单了解一下播放器的基本原理和结构。
原理图

主要包含以下几个步骤:

  • 数据接收(数据获取、解协议)
  • 解封装(demux)
  • 解码
  • 音视频同步(图中没有)
  • 输出

解封装:将多个轨道的数据分解出来,比如一个mp4格式的文件解封装后输出H.264编码的视频流、aac编码的音频流
解码:将视频/音频压缩编码数据,解码成为非压缩的视频/音频原始数据

结合上面的结构来看,客户端的视频开发主要包含了:视频源、播放器、业务场景几个部分,下面逐个进行分析。

1 视频源

视频源决定了传输协议、封装格式、编码类型,影响着播放器内核的选择、支持格式的拓展,以及加解密。一般来说播放器开发时视频源都是已经确定了的,我目前使用的视频源主要是HLS(m3u8 + ts),部分使用MP4封装,H.264 AAC编码,ijkplayer和ExoPlayer都支持良好。

  • 传输协议:hls,crypto加密
  • 封装格式:ts切片
  • 编码类型:H.264 AAC

M3U8视频源的加解密

视频源的加解密环节也相当重要,项目中m3u8文件和hxk key都进行了加密,需要通过接口获取并解密,标准的hls协议并不支持,其中m3u8文件经过解密后可直接使用,但hxk文件是在播放器内部实现hls协议时处理的,如果不修改native代码的话,就需要自定义hxk文件获取的过程。加解密的过程会单独开文章分析。

视频源也可以叫DataSource、MediaSource,包含了众多的分类,如果想要详细了解可以参考exoplayer的实现。

2 播放器

播放器要完成获取视频流、解码、输出到屏幕,最后还要提供丰富的功能,这一系列的操作主要由MediaPlayer、SurfaceView、Controller和相关功能模块组成,下面逐一介绍。

  • MediaPlayer:负责音视频流的获取、解码、输出、状态控制。
  • SurfaceView:负责解码后视频帧的显示(大小、比例、方向等)。如SurfaceView、TextureView、GLSurfaceView,项目中主要使用TextureView
  • Controller:播放器相关的功能控制。进度条、手势操作、播放速度、画面显示比例、屏幕锁等
  • 其他功能:如音频焦点、屏幕常亮、后台播放、旋转、状态栏控制等

MediaPlayer

对于MediaPlayer来说,以下能力非常关键:

  • 网络能力:支持各种预期的协议,如完整的支持hls各种特性,有良好的网络能力,如各种拉流的控制、容错
  • 解码能力:能够支持预期的格式(点播时,视频格式通常都是确定的几种),不能(不适合)硬解时提供软解
  • 兼容性:在各种设备上的解码能力和解码策略
  • 功能特性:播放速度(变速不变调)、精准seek、max-fps、缓冲区大小(基于FFmpeg)
  • 信息反馈:返回准确丰富的状态信息、错误信息

MediaPlayer的能力是播放器的基础,这个环节ijkplayer等都已经实现(网络功能直接集成在内部),我们主要是理解相关api的效果和如何使用。除此之外,通过接口,我们还可以使用不同的mp,不过不同的mp功能特性差别很大,实际项目中还是要使用综合考虑最优秀的。
media player

Surface

接下来是视频的显示,常用的主要是SurfaceView、TextureView两种,如果要添加特效、滤镜之类的则需要用到opengl。
对于视频的显示来说,以下能力非常关键:

  • 切换前后台的流畅度(在有些设备上Surface会被销毁重建)
  • 对软硬解的兼容(比如软解+TextureView,重复使用TextureView会出现被锁住的情况)
  • 旋转、缩放、平移
    综合来看大家最终都选择了TextureView,同样的也可以使用接口来使用不同的surface
    surface

SurfaceView和TextureView的比较已经有了很丰富的资料,这里简单介绍下在视频播放中主要的差别:

  • SurfaceView的实现是在屏幕上“挖洞”,在Android N以下版本界面移动时会有很严重的黑边
  • SurfaceView播放效率略高于TextureView
  • TextureView可以使用view的各种方法,比如说matrix

到这里VideoView就诞生了,mediaplayer + surface组合成了VideoView核心部分,和音频播放不同,mediaplayer 和 surface之间既独立又充满联系,他们之间的配合和影响后面单独开文章分析。

Controller

复习一下,Controller负责播放器相关的功能控制,如进度条、手势操作、播放速度、画面显示比例、屏幕锁、切换清晰度等。也就是这个画面。
Controller-shot

针对视频播放,系统提供了MediaController类给我们使用,但是自定义性差,还非常丑。。。不过却提供了很好的与VideoView一起协作的示例,完全可以copy一份,然后根据需求修改。针对横屏和竖屏一般会有两套Controller,所以这里我们也使用接口,既满足和VideoView的交互,又可以随时替换不同的实现。
Controller

Controller已经是我们需要开发的核心部分了,比如手势控制、沉浸式下显示popup window等,可以单开一篇来介绍,这里就不细说,也可以在demo中查看效果和具体实现。

丰富的功能

只使用VideoView进行播放的场景估计只有广告了^_^,所以除了基础的控制功能之外,我们还要提供丰富的功能来提升使用体验,比如音频焦点、屏幕常亮、后台播放、旋转、悬浮窗、网络状态切换、状态栏控制,这一部分大多数需要与播放器的状态关联,同时较少或者几乎没有涉及到业务逻辑,也是开发的核心部分。与上面一样,很多细节都可以单开一篇来介绍,后续会逐渐完善。

至此可以看到播放器的部分和业务的交集很小,很容易整理成lib,将与UI无关的部分抽象出来,与UI、业务依赖多的部分也可以提供默认的实现以供参考。

3 业务场景

上面的内容好像将播放器几乎都涵盖了,但实际上缺少了非常重要的一个环节,业务场景。我非常认同这个的观点,我们要做懂技术,也懂行业、懂业务的人。
业务

所以呢,这个部分我们会简单讨论一下当前热门的视频应用和他们实现的效果,然后我们进行仿写。
业务范围:

  • 单视频点播:参考APP:bilibili、爱奇艺,特点:弹幕、播放详情页面、后台播放、播放详情页面、播放列表
  • 离线播放
  • feed流:参考APP:bilibili weibo 网易云音乐
  • 短视频
  • 小窗播放:参考APP:youtube,特点:小窗口view、画中画
  • 直播:参考APP:bilibili,特点:直播、悬浮窗

此外还有一个特别重要部分:视频编辑(还包括直播推流、特效等),因为暂时没有接触,这部分不会涉及。

敬请期待~

及时更新的版本可以在我的blog看到.

点击查看更多内容

本文原创发布于慕课网 ,转载请注明出处,谢谢合作

2人点赞

若觉得本文不错,就分享一下吧!

评论

相关文章推荐

正在加载中
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消