ExoPlayer是google开源的应用级媒体播放器项目,该开源项目包含ExoPlayer库和演示demo,github地址:https://github.com/google/ExoPlayer。java
ExoPlayer库的核心是ExoPlayer接口。ExoPlayer公开了传统的高水平媒体播放器的功能,例如媒体缓冲,播放,暂停和快进功能。ExoPlayer没有直接实现媒体文件的加载和渲染,而是把这些工做委托给了在建立播放器或者播放器准备好播放的时候注入的组件。全部ExoPlayer实现的通用组件是:android
MediaSource
:媒体资源,用于定义要播放的媒体,加载媒体,以及从哪里加载媒体。简单的说,MediaSource
就是表明咱们要播放的媒体文件,能够是本地资源,能够是网络资源。MediaSource
在播放开始的时候,经过ExoPlayer.prepare
方法注入。Renderer
:渲染器,用于渲染媒体文件。当建立播放器的时候,Renderers
被注入。TrackSelector
:轨道选择器,用于选择MediaSource
提供的轨道(tracks),供每一个可用的渲染器使用。LoadControl
:用于控制MediaSource
什么时候缓冲更多的媒体资源以及缓冲多少媒体资源。LoadControl
在建立播放器的时候被注入。implementation 'com.google.android.exoplayer:exoplayer:2.X.X'
此种方式依赖了整个ExoPlayer库。咱们也能够只依赖本身真正须要的库。例若是你要播放普通的媒体资源,你能够只依赖Core,UI
这两个个库。git
implementation 'com.google.android.exoplayer:exoplayer-core:2.X.X' implementation 'com.google.android.exoplayer:exoplayer-ui:2.X.X'
整个ExoPlayer库包括5个子库,依赖了整个ExoPlayer库和依赖5个子库是等效的。github
exoplayer-core
:核心功能 (必要)exoplayer-dash
:支持DASH内容exoplayer-hls
:支持HLS内容exoplayer-smoothstreaming
:支持SmoothStreaming内容exoplayer-ui
:用于ExoPlayer的UI组件和相关的资源。<com.google.android.exoplayer2.ui.PlayerView android:id="@+id/exo_play_view" android:layout_width="match_parent" android:layout_height="match_parent" />
private PlayerView mPlayerView; @Override protected void onCreate(Bundle savedInstanceState) { [...] mPlayerView = findViewById(R.id.exo_play_view); }
// 获得默认合适的带宽 BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); // 建立跟踪的工厂 TrackSelection.Factory factory = new AdaptiveTrackSelection.Factory(bandwidthMeter); // 建立跟踪器 DefaultTrackSelector trackSelection = new DefaultTrackSelector(factory); // 建立播放器 SimpleExoPlayer exoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelection); // 第二种方式 传入了默认的渲染工厂(DefaultRenderersFactory),默认的轨道选择器(DefaultTrackSelector)和默认的加载控制器(DefaultLoadControl),而后把返回的播放器实例 //SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance( // new DefaultRenderersFactory(context), // new DefaultTrackSelector(), // new DefaultLoadControl());
// 生成数据媒体实例,经过该实例加载媒体数据 DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(context, "exoplayerdemo")); // 建立资源 Uri uri = Uri.parse(url); MediaSource mediaSources = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri); // 将播放器附加到view mPlayerView.setPlayer(exoPlayer); // 准备播放 exoPlayer.prepare(mediaSource); // 准备好了以后自动播放,若是已经准备好了,调用该方法实现暂停、开始功能 exoPlayer.setPlayWhenReady(true);
if (null != exoPlayer) { exoPlayer.stop(); exoPlayer.release(); exoPlayer = null; }
ExoPlayer库提供了ConcatenatingMediaSource和DynamicConcatenatingMediaSource能够用来无缝的合并播放多个媒体资源。网络
使用ConcatenatingMediaSource
下面的方法构建了组合的媒体文件。app
/** * list是资源地址集合,能够是音频、视频等 */ private MediaSource getMediaSource(ArrayList<String> list) { DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(context, "exoplayerdemo")); // 将URL组装成资源类 MediaSource[] mediaSources = new MediaSource[list.size()]; for (int i = 0; i < list.size(); i++) { Uri uri = Uri.parse(list.get(i)); mediaSources[i] = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri); } MediaSource mediaSource = mediaSources.length == 1 ? mediaSources[0] : new ConcatenatingMediaSource(mediaSources); return mediaSource; }
ExoPlayer库提供了LoopingMediaSource实现循环播放。ide
// 单个资源循环播放 可指定loopCount循环次数 MediaSource source = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri); MediaSource mediaSource = new LoopingMediaSource(source, loopCount); // 多个资源循环播放 MediaSource source = new ConcatenatingMediaSource(mediaSources); MediaSource mediaSource = new LoopingMediaSource(source, loopCount);
// 添加事件监听 exoPlayer.addListener(listener); // 移除事件监听 exoPlayer.removeListener(listener); private Player.DefaultEventListener listener = new Player.DefaultEventListener() { @Override public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { // 视频播放状态 L.d("playbackState = " + playbackState + " playWhenReady = " + playWhenReady); switch (playbackState){ case Player.STATE_IDLE: // 空闲 break; case Player.STATE_BUFFERING: // 缓冲中 break; case Player.STATE_READY: // 准备好 break; case Player.STATE_ENDED: // 结束 break; default: break; } } @Override public void onPlayerError(ExoPlaybackException error) { // 报错 switch (error.type){ case ExoPlaybackException.TYPE_SOURCE: // 加载资源时出错 break; case ExoPlaybackException.TYPE_RENDERER: // 渲染时出错 break; case ExoPlaybackException.TYPE_UNEXPECTED: // 意外的错误 break; } } };
若是不设置的话,ExoPlayer 默认使用的播放控制界面是PlayerControlView
若是彻底不想使用这个控制界面,能够在布局文件里面修改oop
<com.google.android.exoplayer2.ui.PlayerView [...] app:use_controller="false"/>
这样控制界面就不显示了。布局
自定义PlayerControlView的行为ui
<com.google.android.exoplayer2.ui.PlayerView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="match_parent" app:show_timeout="10000" app:fastforward_increment="30000" app:rewind_increment="30000"/>
上面的例子中,快进和快退都改为了30秒。控制界面自动消失时间是10秒。
自定义PlayerControlView界面的外观
你能够自定义控制界面,而后在布局文件里更改属性 controller_layout_id。
<com.google.android.exoplayer2.ui.PlayerView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="match_parent" app:controller_layout_id="@layout/custom_playback_control"/>
PlayerControlView经过id来识别它使用的全部UI元素。当你自定义布局文件的时候,必须保持标准元素的id,例如@id/exo_play 或 @id/exo_pause,以便让PlayerControlView有机会找到它们。
默认的PlayerControlView的控制界面是R.layout.exo_playback_control_view.xml
。你也能够直接从ExoPlayer库中复制到app的res目录下面,而后作相应的更改便可。
基本的播放差很少已经完成了。ExoPlayer还有不少高级功能,例如
一、资源剪切 ClippingMediaSource 二、倍速播放 三、字幕 四、播放流媒体 等等等等
尚未研究,有兴趣的小伙伴能够去看看。