基于exoPlayer 拓展自定义播放器

基于exoPlayer 自定义播放器 Jplayer支持功能:

  • 1 ExoUserPlayer 基本播放
  • 2 GestureVideoPlayer 增加手势 亮度,音量,快进,等手势
  • 3 ManualPlayer 默认手动播放,增加默认图
  • 5 增加广告视频预览切换
  • 6 增加视频清晰度切换
  • 7 增加缓存视频功能
  • 8 支持自定义各种数据源加载 Okttp,Rtmp, 缓存,Cronet等协议,
  • 9 支持列表播放视频
  • 10 支持多种文件类型,MP4,M4A,WebM,Matroska,Ogg,WAV,MP3,MPEG-TS,MPEG-PS,FLV,ADTS (AAC),Flac,M3U8 等
  • 11 支持网络类型 提示是否播放

预览 显示有点卡,帧数低,实际很流畅

sss.gif

一.引用类库

 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.属性说明

  1. player_layout_id 播放器布局, //必选
player_layout_id 目前支持指定布局simple_exo_playback_control_view 后续版本,开放自定义使用这自定义
  1. controller_layout_id 控制器布局` //必选
controller_layout_id  支持自定义布局
  1. surface_type 视频渲染类型 //texture_view 和surface_view //枚举类型。默认surface_view
    列表播放只能选择texture_view 不能选择surface_view,详情页面播放推荐surface_view 
  1. use_controller 是否用户控制控制器 布尔类型
  2. resize_mode 视频缩放渲染显示方式一共4种 //可选 美剧类型
    1.fit          //正常模式
    2.fixed_width  //保持的是视频宽度,拉伸视频高度
    3.fixed_height //保持的是视频高度,拉伸视频宽度
    4.fill          //全屏模式,拉伸视频宽高
  1. default_artwork 占位图 //可选
 占位图 注意在控制布局后下面
  1. show_timeout 控制布局隐藏时间 默认值为3秒 //可选
  2. paddingEnd,paddingStart 设置边距 默认值为0 //可选
  3. fastforward_increment 设置快进增量,以毫秒为单位。 //可选
  4. rewind_increment 设置快退增量,以毫秒为单位。 //可选
  5. user_watermark 水印图片 默认在右上角 //可选
  6. player_list 是否指定列表播放 //可选 默认 false true 列表播放

3.修改网络对话框提示文字内容

 app.strings.xml
 <string name="exo_play_reminder">您当前网络不是wifi,是否继续观看视频</string>
 <string name="exo_play_wifi_hint_no">提示</string>

4.在功能清单声明 AndroidManifest.xml

在activity节点 加上“android:configChanges="orientation|keyboardHidden|screenSize"”
如下实例:

      <activity android:name="chuangyuan.ycj.yjplay.MainListActivity"
       android:configChanges="orientation|keyboardHidden|screenSize"
       android:screenOrientation="portrait">

3.JAVA 代码

1 播放控制类

1.ExoUserPlayer 基本播放父类,实现基本播放,设置setPlayUri();会自动加载播放
2.GestureVideoPlayer 具有手势操作播放(调节亮度和视频进度,和音量)会自动加载播放
2.ManualPlayer 点击开始按钮播放,具有手势功能,和列表播放

2 播放

//实例化播放控制类
 ManualPlayer exoPlayerManager = new ManualPlayer(this,R.id.exo_play_context_id);
//自定义你的数据源,后面详细介绍如何自定义数据源类
 // 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");
 //下面开启多线路播放
 //  exoPlayerManager.setShowVideoSwitch(true); //开启切换按钮,默认关闭
 //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={"超清","高清","标清"};
 //exoPlayerManager.setPlaySwitchUri(test,name);
 //添加水印图片
 // exoPlayerManager.setExoPlayWatermarkImg();

1.实例化播放控制类

  ManualPlayer exoPlayerManager = new ManualPlayer(this,R.id.exo_play_context_id);
  ManualPlayer exoPlayerManager = new ManualPlayer(this,videoPlayerView);

2.自定义你的数据源,后面详细介绍如何自定义数据源类

 ManualPlayer exoPlayerManager = new ManualPlayer(this,R.id.exo_play_context_id,new DataSource(this));
 ManualPlayer exoPlayerManager = new ManualPlayer(this,videoPlayerView,new DataSource(this));

3.设置视频标题

  exoPlayerManager.setTitle("视频标题");

4.添加水印图片

 exoPlayerManager.setExoPlayWatermarkImg(R.mipmap.watermark_big);     

5.设置开始播放进度

 exoPlayerManager.setPosition(1000)

6.设置视频路径

 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.设置多线路播放

  //开启多线路设置,默认关闭 
  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={"超清","高清","标清"};
   exoPlayerManager.setPlaySwitchUri(test,name);

8.设置监听回调VideoInfoListener

 exoPlayerManager.setVideoInfoListener(new VideoInfoListener() {
               @Override
               public void onPlayStart() {
                     //开始播放
               }
   
               @Override
               public void onLoadingChanged() {
                         //加载变化
               }
   
               @Override
               public void onPlayerError(ExoPlaybackException e) {
                         //加载错误
              }
   
               @Override
               public void onPlayEnd() {
                      //播放结束
               }
               @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() {//使用播放返回键监听
        
                   if (   exoPlayerManager.onBackPressed()){
                       finish();
                   }
        }

三.列表

1.列表播放,只能使用ManualPlayer,在你的VideoHolder

  • 1在列表控件使用属性 ”app:controller_layout_id="@layout/simple_exo_playback_list_view"“ //提供默列表控制布局
  • 2.player_list="true" 设置为true 开启列表模式
  • 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);
          }
 
         /**
         *绑定数据源
         ***/
          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 实现相应周期方法

               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() {
                   //返回监听类
                   if (VideoPlayerManager.getInstance().onBackPressed()){
                       finish();
                   }
               } 

四.数据源工厂类

1.默认数据源

    缓存 : CacheDataSinkFactory,CacheDataSourceFactory
    http : DefaultDataSourceFactory,DefaultHttpDataSourceFactory
    Priority : PriorityDataSourceFactory      

2 自定义数据源引用

compile 'com.google.android.exoplayer:extension-okhttp:r2.5.1'
compile 'com.google.android.exoplayer:extension-rtmp:r2.5.1'

3.自定义数据源工厂类:

  • 实现接口 DataSourceListener 然后在getDataSourceFactory方法里 自定义 数据源
  • 在你使用播放控件时中实例化类
   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 数据源工厂
            //return  OkHttpDataSourceFactory; ;
            //默认数据源工厂
            // return new JDefaultDataSourceFactory(context);
            // Rtmp数据源工厂 对 Rtmp 协议支持
            // return  new RtmpDataSourceFactory();
           //缓存使用和组合使用
            LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(1000000000);
           SimpleCache   simpleCache = new SimpleCache(new File(context.getCacheDir(), "media"), evictor);
           //缓存数据源使用,内部使用DefaultDataSourceFactory数据源工厂类
           // return  new CacheDataSinkFactory(simpleCache,10000);
           // 配合okHttp数据源工厂类
           return  new CacheDataSourceFactory(simpleCache, OkHttpDataSourceFactory);
           //使用配合默认数据源红工厂类
           // return  new CacheDataSourceFactory(simpleCache, new JDefaultDataSourceFactory(context));
           //使用提供缓存数据源工厂类
           // return new CacheDataSourceFactory(context,1000,1000);
          }

}

五.自定义控制布局

  • 1.使用自定义控制布局 app:controller_layout_id="@layout/simple_exo_playback_control_view" 详细看 demo
app:controller_layout_id  指向您的布局名称 
20170905164501.png
  • 2.注意自定义控制布局事项 不能改变控件类型,可以改变控件的样式,位置,属性等

项目地址-戳我

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • 本人初学Android,最近做了一个实现安卓简单音乐播放功能的播放器,收获不少,于是便记录下来自己的思路与知识总结...
    落日柳风阅读 19,065评论 2 41
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,350评论 0 17
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,560评论 18 399
  • 一、鸡汤 appwidget是android中小组件,我们经常说的widget其实是指的那些button、text...
    欢乐斗佛阅读 2,228评论 1 8