main
于俊 11 months ago
parent a2478ed429
commit f36a9c7d5b
  1. 2
      app/src/main/java/com/github/tvbox/osc/base/App.java
  2. 50
      app/src/main/java/com/github/tvbox/osc/player/ExoPlayer.java
  3. 20
      app/src/main/java/com/github/tvbox/osc/player/IjkMediaPlayer.java
  4. 10
      app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java
  5. 16
      app/src/main/java/com/github/tvbox/osc/ui/activity/PlayActivity.java
  6. 23
      app/src/main/java/com/github/tvbox/osc/ui/fragment/PlayFragment.java
  7. 2
      gradle.properties
  8. 7
      player/src/main/java/xyz/doikki/videoplayer/exo/ExoMediaPlayer.java
  9. 10
      player/src/main/java/xyz/doikki/videoplayer/exo/ExoMediaSourceHelper.java

@ -92,7 +92,7 @@ public class App extends MultiDexApplication {
public static P2PClass getp2p() {
try {
if (p == null) {
p = new P2PClass(instance.getExternalCacheDir().getAbsolutePath());
p = new P2PClass(FileUtils.getExternalCachePath());
}
return p;
} catch (Exception e) {

@ -5,7 +5,6 @@ import android.util.Pair;
import com.github.tvbox.osc.util.LOG;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
@ -15,9 +14,7 @@ import xyz.doikki.videoplayer.exo.ExoMediaPlayer;
import com.google.android.exoplayer2.C;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ExoPlayer extends ExoMediaPlayer {
@ -28,11 +25,12 @@ public class ExoPlayer extends ExoMediaPlayer {
// 3. 获取所有轨道信息
public TrackInfo getTrackInfo() {
TrackInfo data = new TrackInfo();
MappingTrackSelector.MappedTrackInfo mappedInfo = getMappingTrackSelector().getCurrentMappedTrackInfo();
MappingTrackSelector.MappedTrackInfo mappedInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedInfo == null) return data;
DefaultTrackSelector.Parameters params = ((DefaultTrackSelector) getMappingTrackSelector()).getParameters();
DefaultTrackSelector.Parameters params = trackSelector.getParameters();
for (int rendererIndex = 0; rendererIndex < mappedInfo.getRendererCount(); rendererIndex++) {
int type = mappedInfo.getRendererType(rendererIndex);
if(type!=C.TRACK_TYPE_AUDIO && type!=C.TRACK_TYPE_TEXT)continue;
TrackGroupArray groups = mappedInfo.getTrackGroups(rendererIndex);
DefaultTrackSelector.SelectionOverride override = params.getSelectionOverride(rendererIndex, groups);
boolean hasSelected = false;
@ -63,7 +61,7 @@ public class ExoPlayer extends ExoMediaPlayer {
bean.selected = selected;
if (type == C.TRACK_TYPE_AUDIO) {
data.addAudio(bean);
} else if (type == C.TRACK_TYPE_TEXT) {
} else {
data.addSubtitle(bean);
}
}
@ -72,13 +70,10 @@ public class ExoPlayer extends ExoMediaPlayer {
return data;
}
protected MappingTrackSelector getMappingTrackSelector() {
if (mTrackSelector instanceof MappingTrackSelector) {
return (MappingTrackSelector) mTrackSelector;
}
throw new IllegalStateException("trackSelector 必须是 MappingTrackSelector 类型");
}
/** 缓存:key=播放地址,value=已选的 {groupIndex, trackIndex} */
private static final Map<String, Pair<Integer, Integer>> mTrackOverrideCache = new HashMap<>();
/**
* 设置当前播放的音轨
* @param groupIndex 音轨组的索引
@ -86,7 +81,6 @@ public class ExoPlayer extends ExoMediaPlayer {
*/
public void setTrack(int groupIndex, int trackIndex) {
try {
DefaultTrackSelector trackSelector = (DefaultTrackSelector) getMappingTrackSelector();
MappingTrackSelector.MappedTrackInfo mappedInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedInfo == null) {
LOG.i("echo-setTrack: MappedTrackInfo is null");
@ -107,11 +101,41 @@ public class ExoPlayer extends ExoMediaPlayer {
builder.clearSelectionOverrides(audioRendererIndex);
builder.setSelectionOverride(audioRendererIndex, audioGroups, newOverride);
trackSelector.setParameters(builder.build());
// 缓存到 map:下次同一路径播放时使用
if (currentPlayPath != null) {
mTrackOverrideCache.put(currentPlayPath, Pair.create(groupIndex, trackIndex));
}
} catch (Exception e) {
LOG.i("echo-setTrack error: " + e.getMessage());
}
}
//加载上一次选中的音轨
public void loadDefaultTrack() {
Pair<Integer, Integer> pair = mTrackOverrideCache.get(currentPlayPath);
if (pair == null) return;
MappingTrackSelector.MappedTrackInfo mappedInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedInfo == null) return;
int audioRendererIndex = findAudioRendererIndex(mappedInfo);
if (audioRendererIndex == C.INDEX_UNSET) return;
TrackGroupArray audioGroups = mappedInfo.getTrackGroups(audioRendererIndex);
int groupIndex = pair.first;
int trackIndex = pair.second;
if (!isTrackIndexValid(audioGroups, groupIndex, trackIndex)) return;
DefaultTrackSelector.SelectionOverride override = new DefaultTrackSelector.SelectionOverride(groupIndex, trackIndex);
DefaultTrackSelector.ParametersBuilder builder = trackSelector.buildUponParameters();
builder.clearSelectionOverrides(audioRendererIndex);
builder.setSelectionOverride(audioRendererIndex, audioGroups, override);
trackSelector.setParameters(builder.build());
}
/**
* 查找音频渲染器索引
*/

@ -15,6 +15,7 @@ import com.orhanobut.hawk.Hawk;
import java.io.File;
import java.net.URI;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@ -26,6 +27,7 @@ import xyz.doikki.videoplayer.ijk.IjkPlayer;
public class IjkMediaPlayer extends IjkPlayer {
private IJKCode codec = null;
protected String currentPlayPath;
public IjkMediaPlayer(Context context, IJKCode codec) {
super(context);
@ -127,6 +129,7 @@ public class IjkMediaPlayer extends IjkPlayer {
}
setDataSourceHeader(headers);
mMediaPlayer.setOption(tv.danmaku.ijk.media.player.IjkMediaPlayer.OPT_CATEGORY_FORMAT, "protocol_whitelist", "ijkio,ffio,async,cache,crypto,file,dash,http,https,ijkhttphook,ijkinject,ijklivehook,ijklongurl,ijksegment,ijktcphook,pipe,rtp,tcp,tls,udp,ijkurlhook,data");
currentPlayPath = path;
super.setDataSource(path, null);
}
@ -219,10 +222,16 @@ public class IjkMediaPlayer extends IjkPlayer {
.replace(" ", "");
}
/** 缓存:key=播放地址,value=已选的 {trackIndex} */
private static final Map<String, Integer> mTrackIndexCache = new HashMap<>();
public void setTrack(int trackIndex) {
int audioSelected = mMediaPlayer.getSelectedTrack(ITrackInfo.MEDIA_TRACK_TYPE_AUDIO);
int subtitleSelected = mMediaPlayer.getSelectedTrack(ITrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT);
if (trackIndex!=audioSelected && trackIndex!=subtitleSelected){
// 缓存到 map:下次同一路径播放时使用
if (currentPlayPath != null) {
mTrackIndexCache.put(currentPlayPath, trackIndex);
}
mMediaPlayer.selectTrack(trackIndex);
}
}
@ -231,4 +240,15 @@ public class IjkMediaPlayer extends IjkPlayer {
mMediaPlayer.setOnTimedTextListener(listener);
}
public void loadDefaultTrack(TrackInfo trackInfo) {
Integer trackIndex = mTrackIndexCache.get(currentPlayPath);
if (trackIndex == null) {
if(trackInfo!=null && trackInfo.getAudio().size()>1){
int firsIndex=trackInfo.getAudio().get(0).index;
setTrack(firsIndex);
}
return;
};
setTrack(trackIndex);
}
}

@ -24,6 +24,7 @@ import androidx.recyclerview.widget.DiffUtil;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.github.tvbox.osc.R;
import com.github.tvbox.osc.api.ApiConfig;
import com.github.tvbox.osc.base.App;
import com.github.tvbox.osc.bean.IJKCode;
import com.github.tvbox.osc.bean.ParseBean;
import com.github.tvbox.osc.bean.SourceBean;
@ -41,6 +42,8 @@ import com.github.tvbox.osc.util.PlayerHelper;
import com.github.tvbox.osc.util.ScreenUtils;
import com.github.tvbox.osc.util.SubtitleHelper;
import com.github.tvbox.osc.util.VideoParseRuler;
import com.github.tvbox.osc.util.thunder.Jianpian;
import com.github.tvbox.osc.util.thunder.Thunder;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.AbsCallback;
import com.lzy.okgo.model.HttpHeaders;
@ -1414,4 +1417,11 @@ public class VodController extends BaseController {
}
}
}
public void stopOther()
{
Thunder.stop(false);//停止磁力下载
Jianpian.finish();//停止p2p下载
App.getInstance().setDashData(null);
}
}

@ -586,11 +586,8 @@ public class PlayActivity extends BaseActivity {
if (trackInfo != null && trackInfo.getSubtitle().size() > 0) {
mController.mSubtitleView.hasInternal = true;
}
//默认选中第一个音轨 一般第一个音轨是国语
if (trackInfo != null && trackInfo.getAudio().size() > 1) {
int firsIndex=trackInfo.getAudio().get(0).index;
((IjkMediaPlayer)(mVideoView.getMediaPlayer())).setTrack(firsIndex);
}
//默认选中第一个音轨 一般第一个音轨是国语 && 加载上一次选中的
((IjkMediaPlayer)mVideoView.getMediaPlayer()).loadDefaultTrack(trackInfo);
((IjkMediaPlayer)(mVideoView.getMediaPlayer())).setOnTimedTextListener(new IMediaPlayer.OnTimedTextListener() {
@Override
public void onTimedText(IMediaPlayer mp, IjkTimedText text) {
@ -603,6 +600,10 @@ public class PlayActivity extends BaseActivity {
}
});
}
if(mVideoView.getMediaPlayer() instanceof ExoPlayer){
//加载上一次选中的
((ExoPlayer) mVideoView.getMediaPlayer()).loadDefaultTrack();
}
mController.mSubtitleView.bindToMediaPlayer(mVideoView.getMediaPlayer());
mController.mSubtitleView.setPlaySubtitleCacheKey(subtitleCacheKey);
String subtitlePathCache = (String)CacheManager.getCache(MD5.string2MD5(subtitleCacheKey));
@ -837,9 +838,7 @@ public class PlayActivity extends BaseActivity {
}
stopLoadWebView(true);
stopParse();
Thunder.stop(false);//停止磁力下载
Jianpian.finish();//停止p2p下载
App.getInstance().setDashData(null);
mController.stopOther();
}
private VodInfo mVodInfo;
@ -953,6 +952,7 @@ public class PlayActivity extends BaseActivity {
stopParse();
initParseLoadFound();
mController.stopOther();
if(mVideoView!=null) mVideoView.release();
subtitleCacheKey = mVodInfo.sourceKey + "-" + mVodInfo.id + "-" + mVodInfo.playFlag + "-" + mVodInfo.playIndex+ "-" + vs.name + "-subt";
progressKey = mVodInfo.sourceKey + mVodInfo.id + mVodInfo.playFlag + mVodInfo.playIndex + vs.name;

@ -599,17 +599,15 @@ public class PlayFragment extends BaseLazyFragment {
private void initSubtitleView() {
TrackInfo trackInfo = null;
if (mVideoView.getMediaPlayer() instanceof IjkMediaPlayer) {
trackInfo = ((IjkMediaPlayer)(mVideoView.getMediaPlayer())).getTrackInfo();
AbstractPlayer mediaPlayer = mVideoView.getMediaPlayer();
if (mediaPlayer instanceof IjkMediaPlayer) {
trackInfo = ((IjkMediaPlayer)mediaPlayer).getTrackInfo();
if (trackInfo != null && trackInfo.getSubtitle().size() > 0) {
mController.mSubtitleView.hasInternal = true;
}
//默认选中第一个音轨 一般第一个音轨是国语
if (trackInfo != null && trackInfo.getAudio().size() > 1) {
int firsIndex=trackInfo.getAudio().get(0).index;
((IjkMediaPlayer)(mVideoView.getMediaPlayer())).setTrack(firsIndex);
}
((IjkMediaPlayer)(mVideoView.getMediaPlayer())).setOnTimedTextListener(new IMediaPlayer.OnTimedTextListener() {
//默认选中第一个音轨 一般第一个音轨是国语 && 加载上一次选中的
((IjkMediaPlayer)mediaPlayer).loadDefaultTrack(trackInfo);
((IjkMediaPlayer)mediaPlayer).setOnTimedTextListener(new IMediaPlayer.OnTimedTextListener() {
@Override
public void onTimedText(IMediaPlayer mp, IjkTimedText text) {
if(text==null)return;
@ -621,6 +619,10 @@ public class PlayFragment extends BaseLazyFragment {
}
});
}
if(mediaPlayer instanceof ExoPlayer){
//加载上一次选中的
((ExoPlayer) mediaPlayer).loadDefaultTrack();
}
mController.mSubtitleView.bindToMediaPlayer(mVideoView.getMediaPlayer());
mController.mSubtitleView.setPlaySubtitleCacheKey(subtitleCacheKey);
String subtitlePathCache = (String)CacheManager.getCache(MD5.string2MD5(subtitleCacheKey));
@ -873,9 +875,7 @@ public class PlayFragment extends BaseLazyFragment {
}
stopLoadWebView(true);
stopParse();
Thunder.stop(true);//停止磁力下载
Jianpian.finish();//停止p2p下载
App.getInstance().setDashData(null);
mController.stopOther();
}
private VodInfo mVodInfo;
@ -997,6 +997,7 @@ public class PlayFragment extends BaseLazyFragment {
stopParse();
initParseLoadFound();
mController.stopOther();
if(mVideoView!=null) mVideoView.release();
subtitleCacheKey = mVodInfo.sourceKey + "-" + mVodInfo.id + "-" + mVodInfo.playFlag + "-" + mVodInfo.playIndex+ "-" + vs.name + "-subt";
progressKey = mVodInfo.sourceKey + mVodInfo.id + mVodInfo.playFlag + mVodInfo.playIndex + vs.name;

@ -18,4 +18,4 @@ android.useAndroidX=true
android.enableJetifier=true
IsDebug=true
#build on off
#org.gradle.jvmargs=-Xmx2048m --add-opens java.base/java.io=ALL-UNNAMED
org.gradle.jvmargs=-Xmx2048m --add-opens java.base/java.io=ALL-UNNAMED

@ -53,6 +53,10 @@ public class ExoMediaPlayer extends AbstractPlayer implements Player.Listener {
private RenderersFactory mRenderersFactory;
protected TrackSelector mTrackSelector;
protected DefaultTrackSelector trackSelector;
protected String currentPlayPath;
public ExoMediaPlayer(Context context) {
mAppContext = context.getApplicationContext();
mMediaSourceHelper = ExoMediaSourceHelper.getInstance(context);
@ -76,7 +80,7 @@ public class ExoMediaPlayer extends AbstractPlayer implements Player.Listener {
if (VideoViewManager.getConfig().mIsEnableLog && mTrackSelector instanceof MappingTrackSelector) {
mInternalPlayer.addAnalyticsListener(new EventLogger((MappingTrackSelector) mTrackSelector, "ExoPlayer"));
}
if(trackSelector == null)trackSelector=(DefaultTrackSelector)mTrackSelector;
mInternalPlayer.addListener(this);
}
@ -95,6 +99,7 @@ public class ExoMediaPlayer extends AbstractPlayer implements Player.Listener {
@Override
public void setDataSource(String path, Map<String, String> headers) {
Log.i("Tvbox-runtime","echo-setDataSource:"+path);
currentPlayPath = path;
mMediaSource = mMediaSourceHelper.getMediaSource(path, headers);
}

@ -124,11 +124,19 @@ public final class ExoMediaSourceHelper {
private Cache newCache() {
return new SimpleCache(
new File(mAppContext.getExternalCacheDir(), "exo-video-cache"),//缓存目录
new File(externalCacheDir(), "exo-video-cache"),//缓存目录
new LeastRecentlyUsedCacheEvictor(512 * 1024 * 1024),//缓存大小,默认512M,使用LRU算法实现
new ExoDatabaseProvider(mAppContext));
}
private File externalCacheDir()
{
File externalCacheDir = mAppContext.getExternalCacheDir();
if (externalCacheDir == null){
externalCacheDir = mAppContext.getCacheDir();
}
return externalCacheDir;
}
/**
* Returns a new DataSource factory.
*

Loading…
Cancel
Save