热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

音视频之模拟今日头条列表视频

想着练习下学习下 ijkplayer ,但不知道做个啥,就想着做个今日头条类似的视频播放列表,当item滑出了可视区域就自动播放下一个视频,因为播放器需要opengl渲染,所以就需要glsurfaceview,最开始的思路就是每个item都有一个surfaceview然后新建一个IjkMediaPlayer.使用后发现还没加入播放等动作就已经卡顿的不得了。如下图:
音视频之模拟今日头条列表视频
条状图就是手机开启了gpu呈现模式分析(在绿色横线以下就是每帧<=16ms)大于就是有些卡顿了,对于滚动界面来说就有必要优化了。

后来改换思路整个列表只使用一个MyVideoView(glsurfaceview+ijkplayer的整合)
然后通过addview到指定的item中,然后跟随滑动,就普通的addview,removeview这两个操作就已经要60ms左右,这对于一个滑动列表肯定也是不行的,不过相对之前已经有所进步了。

最后想干脆我也不addview进去了,直接新建一个MyVideoView,滑动的时候跟随着滑动,不addview也不用removeview,就简单的跟随滑动,发现要完全滑出了界面,就自动播放下一个item视频。

滑动效果如下:感觉已经能满足需求了(视频的播放暂停,进度条没加入进去,这个不会影响滑动卡顿问题,添加简单所以就没继续写了。)
音视频之模拟今日头条列表视频
gif效果图:
音视频之模拟今日头条列表视频

现在简单看看代码:
MyVideoView(是GlSurfaceView 和ijkPlayer的封装):

public void play(final String path) {
    new Thread() {
        @Override
        public void run() {
            super.run();
            synchronized (MyVideoView.class) {
                try {
                    playRelease();
                    player = new IjkMediaPlayer();
                    player.setDisplay(surfaceView.getHolder());
                    player.setAudioStreamType(AudioManager.STREAM_MUSIC);
                    player.setDataSource(path);
                    player.prepareAsync();
                    player.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(IMediaPlayer iMediaPlayer) {
                            if (lis != null) lis.startSuccess();
                            iMediaPlayer.start();
                            Log.e("xhc", " start ...");
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
    }.start();
}

将Ijkplayer的释放,新建,都是在子线程中处理的,为的就是不阻塞主线程。

下面来看看recycleview的滑动事件的监听把:

 if(currentPosition >= 0 && currentPosition  linearLayoutManager.findLastVisibleItemPosition() && autoPlay){
            lastPosition = currentPosition;
            currentPosition = linearLayoutManager.findLastVisibleItemPosition();
            playVideo(currentPosition , listVB.get(currentPosition));
        }
        else if((currentPosition  linearLayoutManager.findLastVisibleItemPosition()) && !autoPlay){
            //没有自动播放,如果超出了可视区域直接停止播放器
            new Thread(){
                @Override
                public void run() {
                    super.run();
                    mv.playRelease();
                }
            }.start();
            return ;
        }
        contain.setTranslationY(linearLayoutManager.findViewByPosition(currentPosition).getY());
    }
}

基本逻辑就是
1.当前播放的视频的position是比当前可视界面的第一个item的position还小,那么就播放下一个
2.如果当前视频的item的position比可视界面的最后一个还大,就播放上条视频。

VideoBean vb = new VideoBean();
vb.setVideoPath("sdcard/FFmpeg/video_src/v1080.mp4");

VideoBean vb2 = new VideoBean();
vb2.setVideoPath("sdcard/FFmpeg/video_src/test.mp4");

VideoBean vb3 = new VideoBean();
vb3.setVideoPath("sdcard/FFmpeg/video_src/time.mp4");

VideoBean vb4 = new VideoBean();
vb4.setVideoPath("sdcard/FFmpeg/video_src/input.mp4");

VideoBean vb5 = new VideoBean();
vb5.setVideoPath("rtmp://58.200.131.2:1935/livetv/hunantv");

VideoBean vb6 = new VideoBean();
vb6.setVideoPath("rtmp://media3.sinovision.net:1935/live/livestream");

测试视频有本地一些mp4和一些rmtp网络流,因为rtmp的网络给予tcp并且自己也要握手,所以加载时间更久点。

视频的测试文件在项目中可看到

这里可以找到测试文件

源码地址


推荐阅读
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 深入理解CSS中的margin属性及其应用场景
    本文主要介绍了CSS中的margin属性及其应用场景,包括垂直外边距合并、padding的使用时机、行内替换元素与费替换元素的区别、margin的基线、盒子的物理大小、显示大小、逻辑大小等知识点。通过深入理解这些概念,读者可以更好地掌握margin的用法和原理。同时,文中提供了一些相关的文档和规范供读者参考。 ... [详细]
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • 1简介本文结合数字信号处理课程和Matlab程序设计课程的相关知识,给出了基于Matlab的音乐播放器的总体设计方案,介绍了播放器主要模块的功能,设计与实现方法.我们将该设 ... [详细]
  • SmartRefreshLayout自定义头部刷新和底部加载
    1.添加依赖implementation‘com.scwang.smartrefresh:SmartRefreshLayout:1.0.3’implementation‘com.s ... [详细]
  • vb.net不用多线程如何同时运行两个过程?不用多线程?即使用多线程,也不会是“同时”执行,题主只要略懂一些计算机编译原理就能明白了。不用多线程更不可能让两个过程同步执行了。不过可 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • PHP组合工具以及开发所需的工具
    本文介绍了PHP开发中常用的组合工具和开发所需的工具。对于数据分析软件,包括Excel、hihidata、SPSS、SAS、MARLAB、Eview以及各种BI与报表工具等。同时还介绍了PHP开发所需的PHP MySQL Apache集成环境,包括推荐的AppServ等版本。 ... [详细]
  • VBA操作Excel之设置单元格属性
    VBA操作Excel简介一、VBA读写Excel文件二、VBA设置单元格属性三、VBA弹出输入和输出窗口参考文档一、VBA读写Excel文件VBA简介及打开Excel文件方法见VB ... [详细]
author-avatar
猫猫爱妞_462
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有