EasyPlayer现在支持多视频源快速切换了,我们介绍一下是如何实现的.

这个需求通常应用在一个客户端需要查看多个视频源的情况,比如多个监控场景轮播.

由于EasyPlayer的播放端已经放在Fragment了,这使得SDK层可以对好多应用层的代码做以封装,这样尽可能给开发者带来方便.比如,两个视频源切换的时候,只需要创建两个PlayFragment,然后对这两个Fragment进行显示切换,如代码所示:

public void onSwitchPlayer(View view) {
PlayFragment f = (PlayFragment) getSupportFragmentManager().findFragmentByTag("first");
PlayFragment s = (PlayFragment) getSupportFragmentManager().findFragmentByTag("second"); if (!s.isHidden()){
getSupportFragmentManager().beginTransaction().show(f).commit();
getSupportFragmentManager().beginTransaction().hide(s).commit();
mRenderFragment = f;
}else{
getSupportFragmentManager().beginTransaction().show(s).commit();
getSupportFragmentManager().beginTransaction().hide(f).commit();
mRenderFragment = s;
}
}

是不是很简单?只需要对两个Fragment的显示状态进行toggle,就可以实现播放的toggle.

有的同学可能想问,这样实际上只是切换了当前显示的View,实际上视频还是会在后台播放吧?的确是这样的,为了最快地进行视频切换,不至于在切换过程中导致视频延迟\黑屏\卡顿,我们保留了后台一个视频没有释放.

这样可能有些同学觉得不好,我们也觉得不好.所以别急,接着往下看,看看PlayFragment内部又在这个过程中发生了什么:

    @Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden){
// stop
// stopRending();
if (mStreamRender != null) {
mStreamRender.pause();
}
}else{
if (mStreamRender != null) {
mStreamRender.resume();
}
}
}

可以看到,在一个Fragment被hidden时,播放状态实际上会暂停.而当他又显示时,播放会继续.

又有同学可能由疑问,EasyPlayer播放RTSP时,基本上是直播需求,那直播的情况下,暂停\继续又应该如何实现呢?我们是这样做的:

暂停:

    public void pause(){
mQueue.clear();
if (mClient != null) {
mClient.pause();
}
mQueue.clear();
}

继续:

    public void resume(){
if (mClient != null) {
mClient.resume();
}
}

暂停时,首先将缓冲队列情调,然后调用Client的暂停;继续时,调用Client的继续.那Client内部又是如何实现的?

暂停:

public void pause() {
if (Looper.myLooper() != Looper.getMainLooper()){
throw new IllegalThreadStateException("please call pause in Main thread!");
}
synchronized (_channelPause) {
_channelPause.add(_channel);
}
paused = 1;
Log.i(TAG,"pause:=" + 1);
h.postDelayed(closeTask, 10000);
}

继续:

public void resume() {
if (Looper.myLooper() != Looper.getMainLooper()){
throw new IllegalThreadStateException("call resume in Main thread!");
}
synchronized (_channelPause) {
_channelPause.remove(_channel);
}
h.removeCallbacks(closeTask);
if (paused == 2){
Log.i(TAG,"resume:=" + 0);
openStream();
}
Log.i(TAG,"resume:=" + 0);
paused = 0;
}

可见暂停时,在EasyRTSPClient内部,我们设置了一个暂停标志位,当这个标志位为ture时,我们收到的媒体数据并不回调给上层,而是直接丢弃.这样是不是白白浪费了流量?别急,我们post了一个task,这个task在10秒之后,会关闭流的传输.

而继续播放时,我们会将标志位设置为false,同时将task取消掉,这样,如果在10秒内快速进行暂停和恢复,实际上流并没有断开,这样切换时,用户体验是最好的.而当长时间没有恢复的时候,也会在暂停10秒后把链接关闭,不至于消耗额外的流量.

综上,实现了快速的切换.请看效果:

关于EasyPlayer流媒体播放器

An elegant, simple, fast android RTSP/RTMP/HLS/HTTP Player.EasyPlayer support RTSP(RTP over TCP/UDP)version & Pro version,cover all kinds of streaming media!EasyPlayer是一款精炼、高效、稳定的流媒体播放器,分为RTSP版、RTMP版和Pro版三个版本,支持各种各样的流媒体音视频协议和文件的播放,在安防、互联网、教育、录播、IPTV等多个领域大放异彩,广泛应用!

EasyPlayer:https://github.com/EasyDSS/EasyPlayer

点击链接加入群【EasyPlayer】:544917793

获取更多信息

邮件:support@easydarwin.org

EasyDarwin开源流媒体服务器:www.EasyDarwin.org

EasyDSS商用流媒体解决方案:www.EasyDSS.com

EasyNVR无插件直播方案:www.EasyNVR.com

Copyright © EasyDarwin Team 2012-2017

EasyPlayer RTSP Android安卓播放器实现视频源快速切换的更多相关文章

  1. EasyPlayer RTSP Android安卓播放器修复播放画面卡在第一帧bug

    本文转自EasyDarwin团队成员John的博客:http://blog.csdn.net/jyt0551/article/details/75717097 最近发现某些手机在运行EasyPlaye ...

  2. RTSP Windows专用播放器EasyPlayer : 稳定、兼容、高效、超低延时

    EasyPlayer RTSP Windows专用播放器 EasyPlayer RTSP Windows 播放器是由EasyDarwin团队开发和维护的一个完善的RTSP流媒体播放器项目,视频编码支持 ...

  3. EasyPlayer_Android RTSP安卓播放器直播画面卡在第一帧问题修复

    最近发现某些Android安卓手机在运行EasyPlayer播放视频时,会停留在第一帧画面,虽然有码率预示着接收端没有问题,但是画面却卡着不动. 一般来讲,这个现象有三种原因导致: 没有接收到视频帧; ...

  4. 使用Vitamio打造自己的Android万能播放器(5)——在线播放(播放优酷视频)

    前言 为了保证每周一篇的进度,又由于Vitamio新版本没有发布, 决定推迟本地播放的一些功能(截图.视频时间.尺寸等),跳过直接写在线播放部分的章节.从Vitamio的介绍可以看得出,其支持http ...

  5. 使用Vitamio打造自己的Android万能播放器(7)——在线播放(下载视频)

    前言 本章将实现非常实用的功能——下载在线视频.涉及到多线程.线程更新UI等技术,还需思考产品的设计,如何将新加的功能更好的融入到现有的产品中,并不是简单的加一个界面就行了,欢迎大家交流产品设计和技术 ...

  6. 使用Vitamio打造自己的Android万能播放器(1)——准备

    前言 虽然Android已经内置了VideoView组件和MediaPlayer类来支持开发视频播放器,但支持格式.性能等各方面都十分有限,这里与大家一起利用免费的Vitamio来打造属于自己的And ...

  7. 使用Vitamio打造自己的Android万能播放器(6)——在线播放(播放列表)

    前言 新版本的VPlayer由设计转入开发阶段,预计开发周期为一个月,这也意味着新版本的Vitamio将随之发布,开发者们可以和本系列文章一样,先开发其他功能.本章内容为"在线视频播放列表& ...

  8. 使用Vitamio打造自己的Android万能播放器(4)——本地播放(快捷搜索、数据存储)

    前言 关键字:Vitamio.VPlayer.Android播放器.Android影音.Android开源播放器 本章节把Android万能播放器本地播放的主要功能(缓存播放列表和A-Z快速查询功能) ...

  9. 使用Vitamio打造自己的Android万能播放器(3)——本地播放(主界面、播放列表)

    前言 打造一款完整可用的Android播放器有许多功能和细节需要完成,也涉及到各种丰富的知识和内容,本章将结合Fragment.ViewPager来搭建播放器的主界面,并实现本地播放基本功能.系列文章 ...

随机推荐

  1. Java IO 学习(二)select/poll/epoll

    如上文所说,select/poll/epoll本质上都是同步阻塞的,但是由于实现了IO多路复用,在处理聊天室这种需要处理大量长连接但是每个连接上数据事件较少的场景时,相比最原始的为每个连接新开一个线程 ...

  2. JMeter常见四种变量简介

    在JMeter自动化测试脚本编写过程中,经常需要对测试脚本进行一些参数设置.例如,设置测试计划的全局变量(方便切换不同的测试环境).样本线程(HTTP请求等)的参数传递等. 通常,JMeter中常用的 ...

  3. NULL的学问

    在数据库中存在一种特殊的值:NULL(空值).一个字段如果没有被赋值,那么它的值就是NULL,NULL并不代表没有值而是表示值未知.员工信息表中存储着身份证号.姓名.年龄等信息,其中某条记录中年龄字段 ...

  4. luogu P1579 哥德巴赫猜想(升级版)

    题目描述 一个等差数列是一个能表示成a, a+b, a+2b,..., a+nb (n=0,1,2,3,...)的数列. 在这个问题中a是一个非负的整数,b是正整数.写一个程序来找出在双平方数集合(双 ...

  5. 各语言最原始数据库访问组件封装DBHelper

    源码:https://github.com/easonjim/DBHelper bug提交:https://github.com/easonjim/DBHelper/issues 每个语言放在不同的分 ...

  6. C#中结构体与类的区别

    一.结构体和类非常相似 1,定义和使用非常相似,例子如下:public struct Student{    string Name;    int Age;}public class Questio ...

  7. Displaying Tabbed and Stacked Canvas Using Show_View In Oracle Forms

    Displays the indicated canvas at the coordinates specified by the canvas's X Position and Y Position ...

  8. iOS -- iOS11新特性,如何适配iOS11

    前言 这几天抽空把WWDC的Session看了一些,总结了一些iOS11新的特性,可能对我们的App有影响,需要我们进行适配.本文作为一个总结. 本文内容包括:集成了搜索的大标题栏.横向选项卡栏.Ma ...

  9. const的限定

    const对象一旦创建后,其值就不可以改变,所以const对象必须初始化.与非const的类型比较,主要区别在于const类型对象执行但是不改变其操作内容. 在默认状态下,const只在文件内有效.在 ...

  10. HDU2830

    一开始把题目意思理解错啦,做那好久没做出来.本题是一个dp问题:题目说列可以无限次对换,设矩阵为M[i][j],要找到面积大的矩形其实就是处理连续1的个数问题,用d[i][j](i表示行,j表示列)表 ...