前言
上篇文章讲了如何在gsyVideoPlayer中集成腾讯播放器。那么为什么要集成?gsyVideo是个很棒的播放器了,但是在播放H265高码率m3u8视频时,更改进度就会发生卡帧现象,10秒或10分钟都有可能。这是因为m3u8是一个个切片视频,同时这也是ijk的不能兼容问题。更深入点是ijk使用的ffmepg的问题,那么更改ffmepg就解决了。
本人当然不想改这个,这相当于开发了一个新的播放器,那自然就去找个新播放器。在试过腾讯播放器后发现其对H265高码率m3u8优化的不错,就是自己想要的,那赶紧装上准没错的。
公司实际项目中,还有其他mp4或flv的短视频需要播放并需要各种小窗播放情况的切换,腾讯播放器就GG了(出现只有声音没有视频的情况)。
那么就同时使用两种播放器。
初始化
IjkPlayerManagerSss继承IjkPlayerManager,当需要QQPlayerManager时,利用Java反射使用。
PlayerFactory.setPlayManager(IjkPlayerManagerSss.class);
IjkPlayerManagerSss.java
package com.shopshops.cn.player;
import android.content.Context;
import android.os.Message;
import android.text.TextUtils;
import com.shuyu.gsyvideoplayer.GSYVideoManager;
import com.shuyu.gsyvideoplayer.cache.ICacheManager;
import com.shuyu.gsyvideoplayer.model.VideoOptionModel;
import com.shuyu.gsyvideoplayer.player.IjkPlayerManager;
import java.util.List;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
/**
* Created by 磁磁帅 on 2020/2/25.
* 功能:
*/
public class IjkPlayerManagerSss extends IjkPlayerManager {
@Override
public void initVideoPlayer(Context context, Message msg, List<VideoOptionModel> optionModelList, ICacheManager cacheManager) {
GSYVideoManager videoManager = GSYVideoManager.instance();
String playTag = videoManager.getPlayTag();
if (TextUtils.isEmpty(playTag) || !playTag.startsWith("m3u8Speed")) {
super.initVideoPlayer(context, msg, optionModelList, cacheManager);
} else {
//利用反射-狸猫换太子
QQPlayerManager qqPlayerManager = MyVideoManager.getInstance().changePlayer();
qqPlayerManager.initVideoPlayer(context, msg, optionModelList, cacheManager);
}
}
}
MyVideoManager 实现反射替换,GSYVideoBaseManager会存一个PlayerManager对象,只要用反射替换GSYVideoBaseManager中的对象就能实现。GSYVideoManager继承GSYVideoBaseManager,获取GSYVideoManager实例就能完成这些操作。
MyVideoManager .java
package com.shopshops.cn.player;
import com.shopshops.cn.BuildConfig;
import com.shuyu.gsyvideoplayer.GSYVideoManager;
import com.shuyu.gsyvideoplayer.player.IPlayerManager;
import java.lang.reflect.Field;
/**
* Created by 磁磁帅 on 2020/3/18.
* 功能:
*/
public class MyVideoManager {
public static MyVideoManager getInstance() {
if (myVideoManager == null) {
synchronized (MyVideoManager.class) {
if (myVideoManager == null) myVideoManager = new MyVideoManager();
}
}
return myVideoManager;
}
private static MyVideoManager myVideoManager;
private MyVideoManager() {
}
/**
* 更改播放器
*/
public QQPlayerManager changePlayer() {
QQPlayerManager qqPlayerManager = new QQPlayerManager();
GSYVideoManager videoManager = GSYVideoManager.instance();
Class<? extends GSYVideoManager> aClass = videoManager.getClass();
try {
Class<?> superclass = aClass.getSuperclass();
Field playerManagerField = superclass.getDeclaredField("playerManager");
if (playerManagerField.getType() == IPlayerManager.class) {
playerManagerField.setAccessible(true);
playerManagerField.set(videoManager, qqPlayerManager);
}
} catch (Exception e) {
if (BuildConfig.DEBUG) e.printStackTrace();
}
return qqPlayerManager;
}
}
从IjkPlayerManagerSss代码中看到,getPlayTag()的开头部分是m3u8Speed才会执行反射。所以给视频播放器添加标记一个标记就行。
if (url.toLowerCase().contains(".m3u8")) {//增加一个标记
UUID uuid = UUID.randomUUID();
//videoPlayer是一个VideoView
videoPlayer.setPlayTag("m3u8Speed" + uuid.toString());
}
最后
在项目中,短视频点播播放及直播均使用ijk播放,当有视频是m3u8时就使用腾讯播放器。完全满足需要,就是体积又大了点。
注意,播放H265编码的m3u8视频,腾讯播放器必须打开硬解码。