基于exoPlayer 自定義播放器 Jplayer支持功能:
- 1 ExoUserPlayer 基本播放
- 2 GestureVideoPlayer 增加手勢(shì) 亮度粗悯,音量,快進(jìn),等手勢(shì)
- 3 ManualPlayer 默認(rèn)手動(dòng)播放荆几,增加默認(rèn)圖
- 5 增加廣告視頻預(yù)覽切換
- 6 增加視頻清晰度切換
- 7 增加緩存視頻功能
- 8 支持自定義各種數(shù)據(jù)源加載 Okttp,Rtmp, 緩存,Cronet等協(xié)議,
- 9 支持列表播放視頻
- 10 支持多種文件類型,MP4,M4A唉锌,WebM,Matroska竿奏,Ogg袄简,WAV,MP3泛啸,MPEG-TS绿语,MPEG-PS,F(xiàn)LV候址,ADTS (AAC)吕粹,F(xiàn)lac,M3U8 等
- 11 支持網(wǎng)絡(luò)類型 提示是否播放
預(yù)覽 顯示有點(diǎn)卡宗雇,幀數(shù)低昂芜,實(shí)際很流暢
一.引用類庫(kù)
repositories {
jcenter()
maven { url "https://jitpack.io" }
}
dependencies {
compile 'com.ycjiang:VideoPlayModule:1.5.4'
}
二.控件屬性
1.控件屬性引用
<chuangyuan.ycj.videolibrary.widget.VideoPlayerView
android:id="@+id/exo_play_context_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
app:resize_mode="fit"
app:show_timeout="3000"
app:controller_layout_id="@layout/simple_exo_playback_control_view"
app:player_layout_id="@layout/simple_exo_view"
app:surface_type="texture_view"
app:use_artwork="true"
app:paddingEnd="0dp"
app:paddingStart="0dp"
app:fastforward_increment="0"
app:rewind_increment="0"
app:user_watermark="@mipmap/watermark_big"
app:player_list="true"
app:use_controller="true" />
2.屬性說(shuō)明
- player_layout_id 播放器布局, //必選
player_layout_id 目前支持指定布局simple_exo_playback_control_view 后續(xù)版本赔蒲,開(kāi)放自定義使用這自定義
- controller_layout_id 控制器布局` //必選
controller_layout_id 支持自定義布局
- surface_type 視頻渲染類型 //texture_view 和surface_view //枚舉類型。默認(rèn)surface_view
列表播放只能選擇texture_view 不能選擇surface_view良漱,詳情頁(yè)面播放推薦surface_view
- use_controller 是否用戶控制控制器 布爾類型
- resize_mode 視頻縮放渲染顯示方式一共4種 //可選 美劇類型
1.fit //正常模式 2.fixed_width //保持的是視頻寬度舞虱,拉伸視頻高度 3.fixed_height //保持的是視頻高度,拉伸視頻寬度 4.fill //全屏模式母市,拉伸視頻寬高
- default_artwork 占位圖 //可選
占位圖 注意在控制布局后下面
- show_timeout 控制布局隱藏時(shí)間 默認(rèn)值為3秒 //可選
- paddingEnd矾兜,paddingStart 設(shè)置邊距 默認(rèn)值為0 //可選
- fastforward_increment 設(shè)置快進(jìn)增量,以毫秒為單位。 //可選
- rewind_increment 設(shè)置快退增量,以毫秒為單位患久。 //可選
- user_watermark 水印圖片 默認(rèn)在右上角 //可選
- player_list 是否指定列表播放 //可選 默認(rèn) false true 列表播放
3.修改網(wǎng)絡(luò)對(duì)話框提示文字內(nèi)容
app.strings.xml <string name="exo_play_reminder">您當(dāng)前網(wǎng)絡(luò)不是wifi椅寺,是否繼續(xù)觀看視頻</string> <string name="exo_play_wifi_hint_no">提示</string>
4.在功能清單聲明 AndroidManifest.xml
在activity節(jié)點(diǎn) 加上“android:configChanges="orientation|keyboardHidden|screenSize"”
如下實(shí)例:
<activity android:name="chuangyuan.ycj.yjplay.MainListActivity" android:configChanges="orientation|keyboardHidden|screenSize" android:screenOrientation="portrait">
3.JAVA 代碼
1 播放控制類
1.ExoUserPlayer 基本播放父類浑槽,實(shí)現(xiàn)基本播放,設(shè)置setPlayUri();會(huì)自動(dòng)加載播放
2.GestureVideoPlayer 具有手勢(shì)操作播放(調(diào)節(jié)亮度和視頻進(jìn)度,和音量)會(huì)自動(dòng)加載播放
2.ManualPlayer 點(diǎn)擊開(kāi)始按鈕播放,具有手勢(shì)功能返帕,和列表播放
2 播放
//實(shí)例化播放控制類 ManualPlayer exoPlayerManager = new ManualPlayer(this,R.id.exo_play_context_id); //自定義你的數(shù)據(jù)源桐玻,后面詳細(xì)介紹如何自定義數(shù)據(jù)源類 // ManualPlayer exoPlayerManager = new ManualPlayer(this,R.id.exo_play_context_id,new DataSource(this)); //加載m3u8 exoPlayerManager.setPlayUri("http://dlhls.cdn.zhanqi.tv/zqlive/35180_KUDhx.m3u8"); //加載ts.文件 exoPlayerManager.setPlayUri("http://185.73.239.15:25461/live/1/1/924.ts"); //播放本地視頻 // exoPlayerManager.setPlayUri("/storage/emulated/0/DCIM/Camera/VID_20170717_011150.mp4"); //下面開(kāi)啟多線路播放 // exoPlayerManager.setShowVideoSwitch(true); //開(kāi)啟切換按鈕,默認(rèn)關(guān)閉 //String [] test={"http://120.25.246.21/vrMobile/travelVideo/zhejiang_xuanchuanpian.mp4","http://120.25.246.21/vrMobile/travelVideo/zhejiang_xuanchuanpian.mp4","http://120.25.246.21/vrMobile/travelVideo/zhejiang_xuanchuanpian.mp4"}; // String[] name={"超清","高清","標(biāo)清"}; //exoPlayerManager.setPlaySwitchUri(test,name); //添加水印圖片 // exoPlayerManager.setExoPlayWatermarkImg();
1.實(shí)例化播放控制類
ManualPlayer exoPlayerManager = new ManualPlayer(this,R.id.exo_play_context_id); ManualPlayer exoPlayerManager = new ManualPlayer(this,videoPlayerView);
2.自定義你的數(shù)據(jù)源荆萤,后面詳細(xì)介紹如何自定義數(shù)據(jù)源類
ManualPlayer exoPlayerManager = new ManualPlayer(this,R.id.exo_play_context_id,new DataSource(this)); ManualPlayer exoPlayerManager = new ManualPlayer(this,videoPlayerView,new DataSource(this));
3.設(shè)置視頻標(biāo)題
exoPlayerManager.setTitle("視頻標(biāo)題");
4.添加水印圖片
exoPlayerManager.setExoPlayWatermarkImg(R.mipmap.watermark_big);
5.設(shè)置開(kāi)始播放進(jìn)度
exoPlayerManager.setPosition(1000)
6.設(shè)置視頻路徑
exoPlayerManager.setPlayUri("http://dlhls.cdn.zhanqi.tv/zqlive/35180_KUDhx.m3u8"); exoPlayerManager.setPlayUri(Uri.parse("http://dlhls.cdn.zhanqi.tv/zqlive/35180_KUDhx.m3u8")); exoPlayerManager.setPlayUri(Environment.getExternalStorageDirectory().getAbsolutePath()+"/test.h264"); //本地視頻
7.設(shè)置多線路播放
//開(kāi)啟多線路設(shè)置镊靴,默認(rèn)關(guān)閉 exoPlayerManager.setShowVideoSwitch(true); //支持List列表 String [] test={"http://120.25.246.21/vrMobile/travelVideo/zhejiang_xuanchuanpian.mp4", "http://120.25.246.21/vrMobile/travelVideo/zhejiang_xuanchuanpian.mp4", http://120.25.246.21/vrMobile/travelVideo/zhejiang_xuanchuanpian.mp4"}; String[] name={"超清","高清","標(biāo)清"}; exoPlayerManager.setPlaySwitchUri(test,name);
8.設(shè)置監(jiān)聽(tīng)回調(diào)VideoInfoListener
exoPlayerManager.setVideoInfoListener(new VideoInfoListener() { @Override public void onPlayStart() { //開(kāi)始播放 } @Override public void onLoadingChanged() { //加載變化 } @Override public void onPlayerError(ExoPlaybackException e) { //加載錯(cuò)誤 } @Override public void onPlayEnd() { //播放結(jié)束 }
@Override public void onRepeatModeChanged(int repeatMode) { //模式變化 } });
9.覆寫Activity和Fragment周期方法
Override public void onResume() { super.onResume(); Log.d(TAG, "onResume"); exoPlayerManager.onResume(); } @Override public void onPause() { super.onPause(); Log.d(TAG, "onPause"); exoPlayerManager.onPause(); } @Override protected void onDestroy() { exoPlayerManager.onDestroy(); super.onDestroy(); } @Override public void onConfigurationChanged(Configuration newConfig) { exoPlayerManager.onConfigurationChanged(newConfig);//橫豎屏切換 super.onConfigurationChanged(newConfig); } @Override public void onBackPressed() {//使用播放返回鍵監(jiān)聽(tīng) if ( exoPlayerManager.onBackPressed()){ finish(); } }
三.列表
1.列表播放,只能使用ManualPlayer,在你的VideoHolder
- 1在列表控件使用屬性 ”app:controller_layout_id="@layout/simple_exo_playback_list_view"“ //提供默列表控制布局
- 2.player_list="true" 設(shè)置為true 開(kāi)啟列表模式
- 3.demo:
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoViewHolder> { private Context mContext; private List<String> mVideoList; public VideoAdapter(Context context, List<String> videoList) { mContext = context; mVideoList = videoList; } @Override public int getItemCount() { return mVideoList.size(); } @Override public VideoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(mContext).inflate(R.layout.item_video1, parent, false); return new VideoViewHolder(itemView); } @Override public void onBindViewHolder(VideoViewHolder holder, int position) { String video = mVideoList.get(position); holder.bindData(video); } public class VideoViewHolder extends RecyclerView.ViewHolder { ManualPlayer userPlayer; VideoPlayerView playerView; public VideoViewHolder(View itemView) { super(itemView); //初始化控件 playerView = (VideoPlayerView) itemView.findViewById(R.id.item_exo_player_view); userPlayer = new ManualPlayer((Activity) mContext, playerView); } /** *綁定數(shù)據(jù)源 ***/ public void bindData(String videoBean) { userPlayer.setTitle("" + getAdapterPosition()); userPlayer.setPlayUri(videoBean); Glide.with(mContext) .load("http://i3.letvimg.com/lc08_yunzhuanma/201707/29/20/49/3280a525bef381311b374579f360e80a_v2_MTMxODYyNjMw/thumb/2_960_540.jpg") .into(playerView.getPreviewImage()); } }
2.列表播放周期方法 列表在Activity或者Fragment 實(shí)現(xiàn)相應(yīng)周期方法
protected void onPause() { super.onPause(); VideoPlayerManager.getInstance().onPause(); } @Override protected void onResume() { super.onResume(); VideoPlayerManager.getInstance().onResume(); } @Override protected void onDestroy() { super.onDestroy(); VideoPlayerManager.getInstance().onDestroy(); } @Override public void onBackPressed() { //返回監(jiān)聽(tīng)類 if (VideoPlayerManager.getInstance().onBackPressed()){ finish(); } }
四.數(shù)據(jù)源工廠類
1.默認(rèn)數(shù)據(jù)源
緩存 : CacheDataSinkFactory,CacheDataSourceFactory http : DefaultDataSourceFactory,DefaultHttpDataSourceFactory Priority : PriorityDataSourceFactory
2 自定義數(shù)據(jù)源引用
compile 'com.google.android.exoplayer:extension-okhttp:r2.5.1' compile 'com.google.android.exoplayer:extension-rtmp:r2.5.1'
3.自定義數(shù)據(jù)源工廠類:
- 實(shí)現(xiàn)接口 DataSourceListener 然后在getDataSourceFactory方法里 自定義 數(shù)據(jù)源
- 在你使用播放控件時(shí)中實(shí)例化類
exoPlayerManager = new GestureVideoPlayer(this,videoPlayerView,new DataSource(this)); exoPlayerManager = new GestureVideoPlayer(this,(R.id.exo_play_context_id,new DataSource(this));
- demo代碼:
public class DataSource implements DataSourceListener { public static final String TAG = "DataSource"; private Context context; public DataSource (Context context){ this.context=context; } @Override public com.google.android.exoplayer2.upstream.DataSource.Factory getDataSourceFactory() { OkHttpClient okHttpClient = new OkHttpClient(); OkHttpDataSourceFactory OkHttpDataSourceFactory= new OkHttpDataSourceFactory(okHttpClient, Util.getUserAgent(context, context.getApplicationContext().getPackageName()),new DefaultBandwidthMeter() ); //使用OkHttpClient 數(shù)據(jù)源工廠 //return OkHttpDataSourceFactory; ; //默認(rèn)數(shù)據(jù)源工廠 // return new JDefaultDataSourceFactory(context); // Rtmp數(shù)據(jù)源工廠 對(duì) Rtmp 協(xié)議支持 // return new RtmpDataSourceFactory(); //緩存使用和組合使用 LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(1000000000); SimpleCache simpleCache = new SimpleCache(new File(context.getCacheDir(), "media"), evictor); //緩存數(shù)據(jù)源使用链韭,內(nèi)部使用DefaultDataSourceFactory數(shù)據(jù)源工廠類 // return new CacheDataSinkFactory(simpleCache,10000); // 配合okHttp數(shù)據(jù)源工廠類 return new CacheDataSourceFactory(simpleCache, OkHttpDataSourceFactory); //使用配合默認(rèn)數(shù)據(jù)源紅工廠類 // return new CacheDataSourceFactory(simpleCache, new JDefaultDataSourceFactory(context)); //使用提供緩存數(shù)據(jù)源工廠類 // return new CacheDataSourceFactory(context,1000,1000); }
}
五.自定義控制布局
- 1.使用自定義控制布局 app:controller_layout_id="@layout/simple_exo_playback_control_view" 詳細(xì)看 demo
app:controller_layout_id 指向您的布局名稱
- 2.注意自定義控制布局事項(xiàng) 不能改變控件類型偏竟,可以改變控件的樣式,位置敞峭,屬性等