写点什么

Android 进阶:十一、视频播放器初体验,给大家安排上

用户头像
Android架构
关注
发布于: 2021 年 11 月 05 日

这是一个用于承载显示‘数据流’的 View,它不会创建新的窗口来显示内容。它是将内容流直接投放到 View 中,并且可以和其它普通 View 一样进行移动,旋转,缩放,动画等变化。TextureView 初始化方式如下,并且我们这个播放器 View 要实现其监听方法:


class SmallVideoPlayer extends FrameLayout implements TextureView.SurfaceTextureListener


private void initTextureView() {if (mTextureView == null) {mTextureView = new TextureView(mContext);


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


mTextureView.setSurfaceTextureListener(this);}}


然后我们把这个 TextureView 添加到我们的视频播放器的 view 上,并且设置跟视频播放器 View 一样大小:


private void addTextureView() {removeView(mTextureView);LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT,Gravity.CENTER);addView(mTextureView, 0, params);}


###三、初始化播放器内核一个公司想要实现机的播放器内核需要一定的成本,所以大部分公司都选择使用第三方的内核,比如 bilibili 开源的 ijkplayer。ijkplayer 是一个基于 FFmpeg 的轻量级 Android/iOS 视频播放器。FFmpeg 的是全球领先的多媒体框架,能够解码,编码,转码,复用,解复用,流,过滤器和播放大部分的视频格式。它提供了录制、转换以及流化音视频的完整解决方案。这里我们也用它。


在项目 module 的 gradle 里面添加依赖:


implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.3'implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.3'implementation 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.3'implementation 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.3'


编译成功之后我们就可以在代码里面用它了,这个也很简单一般不会出什么问题。ijplayer 里面提供了一个 IMediaPlayer,我们初始化它即可:


private void initMediaPlayer() {if (mMediaPlayer == null) {mMediaPlayer = new IjkMediaPlayer();mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);}}


准备工作都做好了,我们要在什么时候开始播放呢?当然是 TextureView 准备好之后就可以播放了,TextuerView 的 draw 方法中会调用 TextureLayer layer = getTextureLayer();方法,而 getTextureLayer()这个方法中当 surface 创建成功之后会执行我们实现的接口方法:


if (mListener != null && createNewSurface) {mListener.onSurfaceTextureAvailable(mSurface, getWidth(), getHeight());}


从上面代码可以看出当我们设置了 mListener,并且创建 surface 成功之后会为我们回调 onSurfaceTextureAvailable 方法,并传递给我们一个 mSurface 及其宽高。那我们在这个方法里播放视频就可以了:


@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {if (mSurfaceTexture == null) {mSurfaceTexture = surface;openMediaPlayer();} else {mTextureView.setSurfaceTexture(mSurfaceTexture);}}


我们自己创建一个 SurfaceTexture 对象存储 TextureView 给我传递的 SurfaceTexture 对象,然后开启视频播放。如果你自己实现了 SurfaceTexture,你也可以用你自己的。


private void openMediaPlayer() {// 屏幕常亮 setKeepScreenOn(true);// 设置 dataSourcetry {mMediaPlayer.setDataSource(mContext.getApplicationContext(), Uri.parse(mUrl));if (mSurface == null) {mSurface = new Surface(mSurfaceTexture);}mMediaPlayer.setSurface(mSurface);mMediaPlayer.prepareAsync();} catch (IOException e) {e.printStackTrace();}}


使用 ijplayer 播放视频很简单,只要为其设置数据源即可。但是为了能让视频显示出来,也就是能在 view 上播放出来,我们需要使用 Surface。创建对象 private Surface mSurface;,传入刚才存储的 SurfaceTexture 对象:mSurface = new Surface(mSurfaceTexture);,然后把这个 surface 对象传递给播放器即可,最后使用播放器开始播放,注意这个方法是同步的。完成以上步骤,简单的视频播放器就可以完成了。代码:我们把代码进行整理如下:播放器


public class SmallVideoPlayer extends FrameLayout implements TextureView.SurfaceTextureListener {private TextureView mTextureView;private SurfaceTexture mSurfaceTexture;private Surface mSurface;private AudioManager mAudioManager;private IMediaPlayer mMediaPlayer;private Context mContext;private String mUrl;


public SmallVideoPlayer(@NonNull Context context) {this(context, null);}


public SmallVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs) {this(context, attrs, -1);}


public SmallVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.mContext = context;}


public void setUp(String url) {mUrl = url;


}


public void start() {initAudioManager();initMediaPlayer();initTextureView();addTextureView();}


private void initAudioManager() {if (mAudioManager == null) {mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {mAudioManager.requestAudioFocus(new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).build());} else {mAudioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);}}}


private void initMediaPlayer() {if (mMediaPlayer == null) {mMediaPlayer = new IjkMediaPlayer();mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android进阶:十一、视频播放器初体验,给大家安排上