视屏播放_使用原生MediaPlayer+TextureView实现全屏、小窗口、视频列表、m3u8监控播放

来源:互联网 发布:网络司法拍卖流程 编辑:程序博客网 时间:2024/05/21 10:52

Android 视屏播放器————MediaPlayer+TextureView实现全屏、小窗口、视频列表播放

标签(空格分隔): 视屏播放器


一、效果图

这里写图片描述

这里写图片描述

这里写图片描述

二、集成步骤

  • 按文件目录复制进自己项目【文件下载】
  • AndroidManifest.xml文件,添加权限:
<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  • app-gradle依赖:
    minSdkVersion 21必须是>21的
compileSdkVersion 24    buildToolsVersion "24.0.1"    defaultConfig {        applicationId "com.daqsoft.textvideoview"        minSdkVersion 21        targetSdkVersion 24        versionCode 1        versionName "1.0"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    }//ijk(我们要做切换播放器功能)//# required, enough for most devices.compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.0'compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.0'//# Other ABIs: optionalcompile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.0'compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.0'compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.0'compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.0'//# ExoPlayer as IMediaPlayer: optional, experimentalcompile 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.0'//图片加载compile 'com.github.bumptech.glide:glide:3.7.0'

三、使用参见完整项目

项目地址

四、原理剖析

Android视屏播放可直接使用VideoView(继承自SurfaceView来实现的)

1、SurfaceView 与TextureView对比

区别 SurfaceView TextureView 原理 现有的view的位置上创建一个新的Window,内容的显示和渲染都在新的Window中这使得SurfaceView的绘制和刷新可以在单独的线程中进行,从而提高效率。但是呢,由于SurfaceView的内容没有显示在View中而是显示在新建的Window中, 使得SurfaceView的显示不受View的属性控制,不能进行平移,缩放等变换,也不能放在其它RecyclerView或ScrollView中,一些View中的特性也无法使用。 是API 14引入的 ,与SurfaceView相比,它不会创建新的窗口来显示内容。它是将内容流直接投放到View中,并且可以和其它普通View一样进行移动,旋转,缩放,动画等变化。TextureView必须在硬件加速的窗口中使用 col 2 is centered $12 zebra stripes are neat $1

TextureView被创建后不能直接使用,必须要在它被它添加到ViewGroup后,待SurfaceTexture准备就绪才能起作用(看TextureView的源码,TextureView是在绘制的时候创建的内部SurfaceTexture)。通常需要给TextureView设置监听器SurfaceTextuListener:

mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {    @Override    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {        // SurfaceTexture准备就绪    }    @Override    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {        // SurfaceTexture缓冲大小变化    }    @Override    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {        // SurfaceTexture即将被销毁        return false;    }    @Override    public void onSurfaceTextureUpdated(SurfaceTexture surface) {        // SurfaceTexture通过updateImage更新    }});

SurfaceTexture的准备就绪、大小变化、销毁、更新等状态变化时都会回调相对应的方法。当TextureView内部创建好SurfaceTexture后,在监听器的onSurfaceTextureAvailable方法中,用SurfaceTexture来关联MediaPlayer,作为播放视频的图像数据来源。

SurfaceTexture作为数据通道,把从数据源(MediaPlayer)中获取到的图像帧数据转为GL外部纹理,交给TextureVeiw作为View heirachy中的一个硬件加速层来显示,从而实现视频播放功能。

2、MediaPlayer介绍

MediaPlayer是Android原生的多媒体播放器,可以用它来实现本地或者在线音视频的播放,同时它支持https和rtsp。
MediaPlayer定义了各种状态,可以理解为是它的生命周期。
这里写图片描述

这个状态图描述了MediaPlayer的各种状态,以及主要方法调用后的状态变化。

MediaPlayer的相关方法及监听接口:

方法 介绍 状态 setDataSource 设置数据源 Initialized prepare 准备播放,同步 Preparing —> Prepared prepareAsync 准备播放,异步 Preparing —> Prepared start 开始或恢复播放 Started pause 暂停 Paused stop 停止 Stopped seekTo 到指定时间点位置 PrePared/Started reset 重置播放器 Idle setAudioStreamType 设置音频流类型 – setDisplay 设置播放视频的Surface – setVolume 设置声音 – getBufferPercentage 获取缓冲半分比 – getCurrentPosition 获取当前播放位置 – getDuration 获取播放文件总时间 – 内部回调接口 介绍 状态 OnPreparedListener 准备监听 Preparing ——>Prepared OnVideoSizeChangedListener 视频尺寸变化监听 – OnInfoListener 指示信息和警告信息监听 – OnCompletionListener 播放完成监听 PlaybackCompleted OnErrorListener 播放错误监听 Error OnBufferingUpdateListener 缓冲更新监听 –

MediaPlayer在直接new出来之后就进入了Idle状态,此时可以调用多个重载的setDataSource()方法从idle状态进入Initialized状态(如果调用setDataSource()方法的时候,MediaPlayer对象不是出于Idle状态,会抛异常,可以调用reset()方法回到Idle状态)。

调用prepared()方法和preparedAsync()方法进入Prepared状态,prepared()方法直接进入Parpared状态,preparedAsync()方法会先进入PreParing状态,播放引擎准备完毕后会通过OnPreparedListener.onPrepared()回调方法通知Prepared状态。

在Prepared状态下就可以调用start()方法进行播放了,此时进入started()状态,如果播放的是网络资源,Started状态下也会自动调用客户端注册的OnBufferingUpdateListener.OnBufferingUpdate()回调方法,对流播放缓冲的状态进行追踪。

pause()方法和start()方法是对应的,调用pause()方法会进入Paused状态,调用start()方法重新进入Started状态,继续播放。

stop()方法会使MdiaPlayer从Started、Paused、Prepared、PlaybackCompleted等状态进入到Stoped状态,播放停止。

当资源播放完毕时,如果调用了setLooping(boolean)方法,会自动进入Started状态重新播放,如果没有调用则会自动调用客户端播放器注册的OnCompletionListener.OnCompletion()方法,此时MediaPlayer进入PlaybackCompleted状态,在此状态里可以调用start()方法重新进入Started状态。

3、封装考虑

MediaPlayer的方法和接口比较多,不同的状态调用各个方法后状态变化情况也比较复杂。播放相关的逻辑只与MediaPlayer的播放状态和调用方法相关,而界面展示和UI操作很多时候都需要根据自己项目来定制。参考原生的VideoView,为了解耦和方便定制,把MediaPlayer的播放逻辑和UI界面展示及操作相关的逻辑分离。我是把MediaPlayer直接封装到NiceVideoPlayer中,各种UI状态和操作反馈都封装到NiceVideoPlayerController里面。如果需要根据不同的项目需求来修改播放器的功能,就只重写NiceVideoPlayerController就可以了。

4、NiceVideoPlayer

感谢:
xiaoyanger
github地址

阅读全文
0 0
原创粉丝点击