美文网首页AndroidMultimediaAndroid 学习
Android 仿今日头条的视频播放控件(几行代码快速实现)

Android 仿今日头条的视频播放控件(几行代码快速实现)

作者: Angelicas | 来源:发表于2016-12-04 20:12 被阅读17457次

    前段时间由于项目需要用到类似于今日头条的视频播放器,实现在线播放,边缓存边播放,当然也可以播放本地文件,如下图:

    这里写图片描述
    这里我推荐大家使用的是jiecaovideoplayer开源库,这个库的播放引擎是ijkplayer,它调用ffmpeg, 原项目GitHub地址:https://github.com/lipangit/JieCaoVideoPlayer
    一、项目引入:
    1、添加类库
    compile 'fm.jiecao:jiecaovideoplayer:4.8.3'
    compile 'com.github.bumptech.glide:glide:3.7.0'
    

    2、添加布局

     <fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard
            android:id="@+id/player_list_video"
            android:layout_width="match_parent"
            android:layout_height="220dp" />
    

    3、下面就是我所说的通过设置视频地址、缩略图地址、标题等几行代码快速实现视频的播放啦

     JCVideoPlayerStandard player = (JCVideoPlayerStandard) findViewById(R.id.player_list_video);
            boolean setUp = player.setUp("http://gslb.miaopai.com/stream/ed5HCfnhovu3tyIQAiv60Q__.mp4", JCVideoPlayer.SCREEN_LAYOUT_LIST, "");
            if (setUp) {
                Glide.with(MainActivity.this).load("http://a4.att.hudong.com/05/71/01300000057455120185716259013.jpg").into(player.thumbImageView);
            }
    

    4、在Activity中

    @Override
        public void onBackPressed() {
            if (JCVideoPlayer.backPress()) {
                return;
            }
            super.onBackPressed();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            JCVideoPlayer.releaseAllVideos();
        }
    

    5、还有一点不要忘记哦,要添加权限滴:

    <!--联网权限-->
        <uses-permission android:name="android.permission.INTERNET" />
    

    下面我们来看看我们运行效果:


    这里写图片描述

    二、如何使用jiecaovideoplayer播放本地视频
    注意:jiecaovideoplayer支持file:///开头的文件播放,但是不支持assets或者raw目录下的视频,assets下的视频要先复制到本地路径才能播放,至于怎么监听播放完全呢,要继承JCvideoPlayerStandard 复写onAutoCOmplete函数

    三、模拟用户点击开始按钮,直接进入全屏

     //直接进入全屏
            player.startFullscreen(this, JCVideoPlayerStandard.class, videoUrl, "");
            //模拟用户点击开始按钮,NORMAL状态下点击开始播放视频,播放中点击暂停视频
            player.startButton.performClick();
    

    我把代码都贴出来吧:

    package la.trytry.jiecaovideoplayer;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    
    import com.bumptech.glide.Glide;
    
    import fm.jiecao.jcvideoplayer_lib.JCVideoPlayer;
    import fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard;
    
    public class MainActivity extends AppCompatActivity {
        private String videoUrl = "http://gslb.miaopai.com/stream/ed5HCfnhovu3tyIQAiv60Q__.mp4";
        private JCVideoPlayerStandard player;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            player = (JCVideoPlayerStandard) findViewById(R.id.player_list_video);
            boolean setUp = player.setUp(videoUrl, JCVideoPlayer.SCREEN_LAYOUT_LIST, "");
            if (setUp) {
                Glide.with(MainActivity.this).load("http://a4.att.hudong.com/05/71/01300000057455120185716259013.jpg").into(player.thumbImageView);
            }
    
            //直接进入全屏
            player.startFullscreen(this, JCVideoPlayerStandard.class, videoUrl, "");
            //模拟用户点击开始按钮,NORMAL状态下点击开始播放视频,播放中点击暂停视频
            player.startButton.performClick();
        }
    
        @Override
        public void onBackPressed() {
            if (JCVideoPlayer.backPress()) {
                return;
            }
            super.onBackPressed();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            JCVideoPlayer.releaseAllVideos();
        }
    
    }
    

    四、下面回到我们的主题上,实现仿今日头条的视频播放
    1、VideoActivity.java

    package la.trytry.jiecaovideoplayer;
    
    import android.graphics.Rect;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.AbsListView;
    import android.widget.ListView;
    
    import java.util.ArrayList;
    
    import fm.jiecao.jcvideoplayer_lib.JCVideoPlayer;
    import fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard;
    
    public class VideoActivity extends AppCompatActivity {
        private String videoUrl = "http://gslb.miaopai.com/stream/ed5HCfnhovu3tyIQAiv60Q__.mp4";
        private ListView listView;
        private ArrayList<String> datas;
        private JCVideoPlayerStandard currPlayer;
        private VideoAdapter adapter;
        private AbsListView.OnScrollListener onScrollListener;
        private int firstVisible;//当前第一个可见的item
        private int visibleCount;//当前可见的item个数
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_video);
            listView = (ListView) findViewById(R.id.listview);
            initDatas();
            initListener();
        }
    
        private void initDatas() {
            datas = new ArrayList<String>();
            for (int i = 0; i < 20; i++) {
                datas.add(videoUrl);
            }
            adapter = new VideoAdapter(VideoActivity.this, datas, R.layout.item_video);
            listView.setAdapter(adapter);
        }
    
        /**
         * 滑动监听
         */
        private void initListener() {
            onScrollListener = new AbsListView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
    
                    switch (scrollState) {
                        case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                            break;
    
                        case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                            //滑动停止自动播放视频
                            autoPlayVideo(view);
                            break;
    
                        case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                            break;
                    }
                }
    
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    if (firstVisible == firstVisibleItem) {
                        return;
                    }
    
                    firstVisible = firstVisibleItem;
                    visibleCount = visibleItemCount;
                }
            };
    
            listView.setOnScrollListener(onScrollListener);
        }
    
        /**
         * 滑动停止自动播放视频
         */
        private void autoPlayVideo(AbsListView view) {
    
            for (int i = 0; i < visibleCount; i++) {
                if (view != null && view.getChildAt(i) != null && view.getChildAt(i).findViewById(R.id.player_list_video) != null) {
                    currPlayer = (JCVideoPlayerStandard) view.getChildAt(i).findViewById(R.id.player_list_video);
                    Rect rect = new Rect();
                    //获取当前view 的 位置
                    currPlayer.getLocalVisibleRect(rect);
                    int videoheight = currPlayer.getHeight();
                    if (rect.top == 0 && rect.bottom == videoheight) {
                        if (currPlayer.currentState == JCVideoPlayer.CURRENT_STATE_NORMAL
                                || currPlayer.currentState == JCVideoPlayer.CURRENT_STATE_ERROR) {
                            currPlayer.startButton.performClick();
                        }
                        return;
                    }
                }
            }
            //释放其他视频资源
            JCVideoPlayer.releaseAllVideos();
        }
    
        @Override
        public void onBackPressed() {
            if (JCVideoPlayer.backPress()) {
                return;
            }
            super.onBackPressed();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            JCVideoPlayer.releaseAllVideos();
        }
    }
    

    在我们滑动的时候,jiecaovideoplayer会自动停止正在播放的视频,这里面我还添加了一个功能,就是监听当滑动停止的时候自动播放下一个视频
    2、VideoAdapter.java

    package la.trytry.jiecaovideoplayer;
    
    import android.content.Context;
    
    import com.bumptech.glide.Glide;
    import com.zhy.adapter.abslistview.CommonAdapter;
    import com.zhy.adapter.abslistview.ViewHolder;
    
    import java.util.List;
    
    import fm.jiecao.jcvideoplayer_lib.JCVideoPlayer;
    import fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard;
    
    /**
     * @author: lijuan
     * @description: 适配器
     * @date: 2016-12-04
     * @time: 17:04
     */
    public class VideoAdapter extends CommonAdapter<String> {
        private Context mContext;
    
        public VideoAdapter(Context context, List<String> datas, int layoutId) {
            super(context, layoutId, datas);
            this.mContext = context;
        }
    
        @Override
        protected void convert(ViewHolder viewHolder, String url, int position) {
            JCVideoPlayerStandard player = viewHolder.getView(R.id.player_list_video);
            if (player != null) {
                player.release();
            }
            boolean setUp = player.setUp(url, JCVideoPlayer.SCREEN_LAYOUT_LIST, "");
            if (setUp) {
                Glide.with(mContext).load("http://a4.att.hudong.com/05/71/01300000057455120185716259013.jpg").into(player.thumbImageView);
            }
        }
    }
    

    这里的适配器,我继承了鸿洋大神写的万能的Adapter,所以我们还需添加这个库的引用

    compile 'com.zhy:base-adapter:3.0.3'
    

    3、item_video.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    
        <fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard
            android:id="@+id/player_list_video"
            android:layout_width="match_parent"
            android:layout_height="190dp" />
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="8dp"
            android:paddingTop="8dp">
    
            <ImageView
                android:id="@+id/img_video_icon"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_marginLeft="12dp"
                android:src="@mipmap/icon_default_head" />
    
            <TextView
                android:id="@+id/tv_video_userName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="12dp"
                android:layout_toRightOf="@id/img_video_icon"
                android:text="空城旧梦" />
    
            <TextView
                android:id="@+id/tv_video_comment"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="12dp"
                android:drawablePadding="4dp"
                android:drawableLeft="@mipmap/icon_comment"
                android:text="21"
                android:textSize="12sp" />
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginRight="12dp"
                android:layout_toLeftOf="@id/tv_video_comment"
                android:text="3万次播放" />
        </RelativeLayout>
    </LinearLayout>
    

    4、activity_video.xml

    <?xml version="1.0" encoding="utf-8"?>
    <ListView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" />
    

    下面我们看看最终的效果

    这里写图片描述
    好了,本篇文章已经全部写完了,存在总结不到位的地方还望指导,感谢_

    相关文章

      网友评论

      • 03f3ff6ae3cf:怎么监听视频播放的进度啊
      • 要爱就爱到底:楼主,我想监听视频已经开始播放的事件,应该怎么弄
      • b27b68b09ae6:谢谢博主,集成了下很好用,博主还有没有进阶的博客提供参考吗?
      • 谜之龙:在不,我们老板想做成西瓜视频的重力感应的模式怎么办?
      • 谜之龙:我想知道如何触发全屏的按钮
      • 尼古拉斯xq:能指定位置播放视频吗?
      • eb67a9527cd6:这个缓存,指的是放在哪里的缓存?比如断网了,还支持播放吗?或者下次再进来应用,还支持无网络播放吗?
      • 步调Consistent:请问一下能播放非mp4的视频吗???/?
      • b7ef7e7905e2:楼主您好,很好的播放控件,便捷性和可移植性都很好,请问在全屏播放的时候可以横屏吗,谢谢
        6e717a7450e9:点击全屏按钮之后,不不横屏播放,怎么弄
      • 29cf09857d6c:您好,怎么监听停止和播放啊
      • 都很好的难道你:compile 'com.github.bumptech.glide:glide:3.7.0怎么下载不来了啊
      • 507b472e4c40:楼主你好我那个缩略图设置报错啊?
      • 6e717a7450e9:楼主,我想监听视频已经开始播放的事件,应该怎么弄
        要爱就爱到底:你的解决了吗
      • 搬运工大钞:我想问你下 您用的这个jiecao 怎么获取总播放时长 并让他不能快进呀?
      • 鲨鱼麻辣岁月:12-08 18:11:32.475 32573-32619/com.example.yzq.csdn_bottomnav E/IJKMEDIA: http://gslb.miaopai.com/stream/ed5HCfnhovu3tyIQAiv60Q__.mp4: Immediate exit requested
        怎么出现这种错误
        d656b77485bd:我也是这样,你解决了吗
      • Mr李先生_:请问这个怎么混淆?我打了签名包之后就播放失败,闪退。还有个问题是怎么监听到视频要开始播放了?因为现在有个需求,每次播放前都要检验是否在WiFi环境下,如果不是在WiFi环境下的话每次都要给用户一个温馨提示。但是我现在监听不到视频是否开始播放,如果看到的话希望博主能回复下,谢谢!:blush:
      • 谜之龙:您好,可以加个QQ问一下吗?我这里放大播放视频时,用手机自带的返回键就退出App是什么情况
        励綕tu漒:你要在物理返回键监听那里进行拦截
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
        //点击物理返回键时 判断视频是否全屏播放 是的话销毁全屏
        if (JZVideoPlayer.backPress()) {
        return true;
        }
        }
        return super.onKeyDown(keyCode, event);
        }
      • 谜之龙:楼主给个QQ,帮一下忙
      • 谜之龙:楼主,我的视频一直报dalvikvm: Could not find class 'android.graphics.drawable.RippleDrawable', referenced from method android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
        09-19 18:07:41.216 24181-24529/com.example.aa.videoapp E/IJKMEDIA: https://app.tongyejianghubang.com/UploadImages/201709/19/201709191731133120ru7RU2.mp4: Protocol not found
        09-19 18:07:41.226 24181-24296/com.example.aa.videoapp E/tv.danmaku.ijk.media.player.IjkMediaPlayer: Error (-10000,0)
        09-19 18:07:41.266 24181-24181/com.example.aa.videoapp E/JieCaoVideoPlayer: onError -10000 - 0 [1124619048]
        09-19 18:09:40.704 24181-24181/com.example.aa.videoapp E/Parcel: Reading a NULL string not supported here.
        濺m:你的视频的地址是https开头需要protocol 你需要将视频地址的https改成http
      • 6ebfdf81f63b:终于可以正常播放了
        fd07bd1b8a68:没事了,看漏了
        fd07bd1b8a68:VideoAdapter 继承的那个,继承不了
      • 6ebfdf81f63b:楼主 我的播发不了视频 其他都行了
      • 被代码耽误的演员:楼主麻烦看一下我的报错,这个怎么解决?你们都没遇到过吗?
        急啊!
        java.lang.UnsatisfiedLinkError: dlopen failed: /data/app/com.example.ken.testmedioplay-1/lib/x86/libijkffmpeg.so: has text relocations
        fd07bd1b8a68:@被代码耽误的演员 6666666666666666666给你一串6
        被代码耽误的演员:@左耳666 不要用模拟器就没事
        6fa12fdde261:咱俩的一样 请问,您解决了吗
      • 悠叶:你好,请问下列表上有多个视频,当在这界面上点击播放一个视频后,我又点击在同一个界面上的另外一个视频,JieCaoVideoPlayer这个控件会自动把前面第一个视频给停止掉的吗?还是要我们自己弄。
        6e717a7450e9:自动把前面第一个视频给停止掉
      • 文艺范码农:能播放 网络视频吗
        Angelicas:@文艺范码农 可以啊
      • b9025d0c5abf:打包后出现问题:UnstatisfiedLinkError ,请问有遇到过吗? 该怎么解决?先谢过了!
        e6bd3f605065:-dontwarn fm.jiecao.**
        -keep class fm.jiecao.** {*;}

        -dontwarn tv.danmaku.**
        -keep class tv.danmaku.** {*;}
        Mr李先生_:我打包后也播放失败,闪退。是因为混淆的问题。不知道这个有什么混淆规则
      • 本王不退位尔等平身:操作视频的Activity类继承的是Activity,然后一直报错 java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v7.app.ActionBar android.support.v7.app.AppCompatActivity.getSupportActionBar()' on a null object reference
        怎么解决啊?
        9866127d5f34:http://blog.csdn.net/First_CooMan/article/details/69367519

        因为这个需要父类继承AppCompatActivity 而不能是Activity,报错是因为Activity中没有actionbar。如果项目暂时不能继承AppCompatActivity,上面地址会给出解决方案
      • 61de52728bec:------------------------------------------报错了--------不能在FragmentActivity 切换播放视频 闪退

        05-09 16:49:58.496 17511-17511/fm.jiecao.jiecaovideoplayer E/AndroidRuntime: in writeCrashedAppName, pkgName :fm.jiecao.jiecaovideoplayer
        05-09 16:49:58.496 17511-17511/fm.jiecao.jiecaovideoplayer D/AndroidRuntime: file written successfully with content: fm.jiecao.jiecaovideoplayer StringBuffer : ;fm.jiecao.jiecaovideoplayer
        05-09 16:49:58.496 17511-17511/? E/AndroidRuntime: FATAL EXCEPTION: main
        Process: fm.jiecao.jiecaovideoplayer, PID: 17511
        java.lang.NullPointerException
        at fm.jiecao.jcvideoplayer_lib.JCVideoPlayer.showSupportActionBar(JCVideoPlayer.java:878)
        at fm.jiecao.jcvideoplayer_lib.JCVideoPlayer.clearFullscreenLayout(JCVideoPlayer.java:446)
        at fm.jiecao.jcvideoplayer_lib.JCVideoPlayer.onCompletion(JCVideoPlayer.java:482)
        at fm.jiecao.jcvideoplayer_lib.JCVideoPlayerManager.completeAll(JCVideoPlayerManager.java:42)
        at fm.jiecao.jcvideoplayer_lib.JCVideoPlayer.prepareMediaPlayer(JCVideoPlayer.java:199)
        at
        枫叶豆腐汤:@莱州影帝小马 正解,需要继承AppCompatActivity才可以的
        9866127d5f34:@本王不退位尔等平身
        http://blog.csdn.net/First_CooMan/article/details/69367519

        因为这个需要父类继承AppCompatActivity 而不能是Activity,报错是因为Activity中没有actionbar。如果项目暂时不能继承AppCompatActivity,上面地址会给出解决方案
        本王不退位尔等平身:我们俩报错一样,你解决了没
      • 61de52728bec:请问 你修改后的代码 下载地址在哪里 谢谢
      • 程序亦非猿580230:全屏时候为啥不是横屏的 啊?
        6e717a7450e9:添加之后,同样也是不能横屏呀
        fd07bd1b8a68:@刘凯_ce2c 明白
        17b3b95d2dc0:<activity android:name=".你的Activity"
        android:configChanges="orientation|screenSize|keyboardHidden"
        android:screenOrientation="portrait"></activity>
        明白了吗?
      • c04b077feebc:@Override
        public void onBackPressed() {
        if (JCVideoPlayer.backPress()) {
        return;
        }
        super.onBackPressed();
        }
        JCVideoPlayer.backPress() 有这个方法吗?报错耶
        励綕tu漒: 你要在物理返回键监听那里进行拦截
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
        //点击物理返回键时 判断视频是否全屏播放 是的话销毁全屏
        if (JZVideoPlayer.backPress()) {
        return true;
        }
        }
        return super.onKeyDown(keyCode, event);
        }
      • 焦27:正需要的, 先收藏了,晚上回去看下,

      本文标题:Android 仿今日头条的视频播放控件(几行代码快速实现)

      本文链接:https://www.haomeiwen.com/subject/nanhmttx.html