From 1593fb8949a575a6261c67e1a7ed570822f8d013 Mon Sep 17 00:00:00 2001 From: okjackcaptain <378702538@qq.com> Date: Fri, 23 Sep 2022 19:48:30 +0800 Subject: [PATCH] =?UTF-8?q?-=20ijk=E6=94=AF=E6=8C=81=E5=86=85=E7=BD=AE?= =?UTF-8?q?=E5=AD=97=E5=B9=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tvbox/osc/player/IjkMediaPlayer.java | 7 + .../osc/player/controller/VodController.java | 5 + .../subtitle/widget/SimpleSubtitleView.java | 5 + .../tvbox/osc/ui/activity/PlayActivity.java | 356 +++++++++++------- .../tvbox/osc/ui/dialog/SubtitleDialog.java | 11 + .../tvbox/osc/ui/fragment/PlayFragment.java | 356 +++++++++++------- app/src/main/res/layout/dialog_subtitle.xml | 33 ++ .../res/layout/player_vod_control_view.xml | 3 +- 8 files changed, 520 insertions(+), 256 deletions(-) diff --git a/app/src/main/java/com/github/tvbox/osc/player/IjkMediaPlayer.java b/app/src/main/java/com/github/tvbox/osc/player/IjkMediaPlayer.java index 5ebe9fcc..2fde582f 100644 --- a/app/src/main/java/com/github/tvbox/osc/player/IjkMediaPlayer.java +++ b/app/src/main/java/com/github/tvbox/osc/player/IjkMediaPlayer.java @@ -9,6 +9,7 @@ import com.github.tvbox.osc.bean.IJKCode; import java.util.LinkedHashMap; import java.util.Map; +import tv.danmaku.ijk.media.player.IMediaPlayer; import tv.danmaku.ijk.media.player.misc.ITrackInfo; import tv.danmaku.ijk.media.player.misc.IjkTrackInfo; import xyz.doikki.videoplayer.ijk.IjkPlayer; @@ -41,6 +42,8 @@ public class IjkMediaPlayer extends IjkPlayer { } } } + //开启内置字幕 + mMediaPlayer.setOption(tv.danmaku.ijk.media.player.IjkMediaPlayer.OPT_CATEGORY_PLAYER, "subtitle", 1); } @Override @@ -90,4 +93,8 @@ public class IjkMediaPlayer extends IjkPlayer { mMediaPlayer.selectTrack(trackIndex); } + public void setOnTimedTextListener(IMediaPlayer.OnTimedTextListener listener) { + mMediaPlayer.setOnTimedTextListener(listener); + } + } diff --git a/app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java b/app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java index 90c2c0d7..0f6444f7 100644 --- a/app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java +++ b/app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java @@ -640,6 +640,8 @@ public class VodController extends BaseController { void playPre(); + void prepared(); + void changeParse(ParseBean pb); void updatePlayerCfg(); @@ -761,6 +763,9 @@ public class VodController extends BaseController { listener.errReplay(); break; case VideoView.STATE_PREPARED: + mPlayLoadNetSpeed.setVisibility(GONE); + listener.prepared(); + break; case VideoView.STATE_BUFFERED: mPlayLoadNetSpeed.setVisibility(GONE); break; diff --git a/app/src/main/java/com/github/tvbox/osc/subtitle/widget/SimpleSubtitleView.java b/app/src/main/java/com/github/tvbox/osc/subtitle/widget/SimpleSubtitleView.java index f3357a5e..e71ba214 100644 --- a/app/src/main/java/com/github/tvbox/osc/subtitle/widget/SimpleSubtitleView.java +++ b/app/src/main/java/com/github/tvbox/osc/subtitle/widget/SimpleSubtitleView.java @@ -55,6 +55,10 @@ public class SimpleSubtitleView extends TextView private SubtitleEngine mSubtitleEngine; + public boolean isInternal = false; + + public boolean hasInternal = false; + public SimpleSubtitleView(final Context context) { super(context); init(); @@ -93,6 +97,7 @@ public class SimpleSubtitleView extends TextView @Override public void setSubtitlePath(final String path) { + isInternal = false; mSubtitleEngine.setSubtitlePath(path); } diff --git a/app/src/main/java/com/github/tvbox/osc/ui/activity/PlayActivity.java b/app/src/main/java/com/github/tvbox/osc/ui/activity/PlayActivity.java index a21528ea..49d8b142 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/activity/PlayActivity.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/activity/PlayActivity.java @@ -93,6 +93,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import me.jessyan.autosize.AutoSize; +import tv.danmaku.ijk.media.player.IMediaPlayer; +import tv.danmaku.ijk.media.player.IjkTimedText; import xyz.doikki.videoplayer.player.AbstractPlayer; import xyz.doikki.videoplayer.player.ProgressManager; @@ -202,120 +204,17 @@ public class PlayActivity extends BaseActivity { @Override public void selectSubtitle() { - SubtitleDialog subtitleDialog = new SubtitleDialog(PlayActivity.this); - subtitleDialog.setSubtitleViewListener(new SubtitleDialog.SubtitleViewListener() { - @Override - public void setTextSize(int size) { - mController.mSubtitleView.setTextSize(size); - } - @Override - public void setSubtitleDelay(int milliseconds) { - mController.mSubtitleView.setSubtitleDelay(milliseconds); - } - }); - subtitleDialog.setSearchSubtitleListener(new SubtitleDialog.SearchSubtitleListener() { - @Override - public void openSearchSubtitleDialog() { - SearchSubtitleDialog searchSubtitleDialog = new SearchSubtitleDialog(PlayActivity.this); - searchSubtitleDialog.setSubtitleLoader(new SearchSubtitleDialog.SubtitleLoader() { - @Override - public void loadSubtitle(Subtitle subtitle) { - runOnUiThread(new Runnable() { - @Override - public void run() { - String zimuUrl = subtitle.getUrl(); - LOG.i("Remote Subtitle Url: " + zimuUrl); - setSubtitle(zimuUrl);//设置字幕 - if (searchSubtitleDialog != null) { - searchSubtitleDialog.dismiss(); - } - } - }); - } - }); - searchSubtitleDialog.setSearchWord(mVodInfo.playNote); - searchSubtitleDialog.show(); - } - }); - subtitleDialog.setLocalFileChooserListener(new SubtitleDialog.LocalFileChooserListener() { - @Override - public void openLocalFileChooserDialog() { - new ChooserDialog(PlayActivity.this) - .withFilter(false, false, "srt", "ass", "scc", "stl", "ttml") - .withStartFile("/storage/emulated/0/Download") - .withChosenListener(new ChooserDialog.Result() { - @Override - public void onChoosePath(String path, File pathFile) { - LOG.i("Local Subtitle Path: " + path); - setSubtitle(path);//设置字幕 - } - }) - .build() - .show(); - } - }); - subtitleDialog.show(); + selectMySubtitle(); } @Override public void selectAudioTrack() { - AbstractPlayer mediaPlayer = mVideoView.getMediaPlayer(); - if (!(mediaPlayer instanceof IjkMediaPlayer)) { - return; - } - TrackInfo trackInfo = null; - if (mediaPlayer instanceof IjkMediaPlayer) { - trackInfo = ((IjkMediaPlayer)mediaPlayer).getTrackInfo(); - } - if (trackInfo == null) { - Toast.makeText(mContext, "没有音轨", Toast.LENGTH_SHORT).show(); - return; - } - List bean = trackInfo.getAudio(); - if (bean.size() < 1) return; - SelectDialog dialog = new SelectDialog<>(PlayActivity.this); - dialog.setTip("切换音轨"); - dialog.setAdapter(new SelectDialogAdapter.SelectDialogInterface() { - @Override - public void click(TrackInfoBean value, int pos) { - try { - for (TrackInfoBean audio : bean) { - audio.selected = audio.index == value.index; - } - mediaPlayer.pause(); - long progress = mediaPlayer.getCurrentPosition();//保存当前进度,ijk 切换轨道 会有快进几秒 - if (mediaPlayer instanceof IjkMediaPlayer) { - ((IjkMediaPlayer)mediaPlayer).setTrack(value.index); - } - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - mediaPlayer.seekTo(progress); - mediaPlayer.start(); - } - }, 800); - dialog.dismiss(); - } catch (Exception e) { - LOG.e("切换音轨出错"); - } - } - - @Override - public String getDisplay(TrackInfoBean val) { - return val.index + " : " + val.language; - } - }, new DiffUtil.ItemCallback() { - @Override - public boolean areItemsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { - return oldItem.index == newItem.index; - } + selectMyAudioTrack(); + } - @Override - public boolean areContentsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { - return oldItem.index == newItem.index; - } - }, bean, trackInfo.getAudioSelected(false)); - dialog.show(); + @Override + public void prepared() { + initSubtitleView(); } }); mVideoView.setVideoController(mController); @@ -331,6 +230,191 @@ public class PlayActivity extends BaseActivity { } } + void selectMySubtitle() { + SubtitleDialog subtitleDialog = new SubtitleDialog(PlayActivity.this); + if (mController.mSubtitleView.hasInternal) { + subtitleDialog.selectInternal.setVisibility(View.VISIBLE); + } + subtitleDialog.setSubtitleViewListener(new SubtitleDialog.SubtitleViewListener() { + @Override + public void setTextSize(int size) { + mController.mSubtitleView.setTextSize(size); + } + @Override + public void setSubtitleDelay(int milliseconds) { + mController.mSubtitleView.setSubtitleDelay(milliseconds); + } + @Override + public void selectInternalSubtitle() { + selectMyInternalSubtitle(); + } + }); + subtitleDialog.setSearchSubtitleListener(new SubtitleDialog.SearchSubtitleListener() { + @Override + public void openSearchSubtitleDialog() { + SearchSubtitleDialog searchSubtitleDialog = new SearchSubtitleDialog(PlayActivity.this); + searchSubtitleDialog.setSubtitleLoader(new SearchSubtitleDialog.SubtitleLoader() { + @Override + public void loadSubtitle(Subtitle subtitle) { + runOnUiThread(new Runnable() { + @Override + public void run() { + String zimuUrl = subtitle.getUrl(); + LOG.i("Remote Subtitle Url: " + zimuUrl); + setSubtitle(zimuUrl);//设置字幕 + if (searchSubtitleDialog != null) { + searchSubtitleDialog.dismiss(); + } + } + }); + } + }); + searchSubtitleDialog.setSearchWord(mVodInfo.playNote); + searchSubtitleDialog.show(); + } + }); + subtitleDialog.setLocalFileChooserListener(new SubtitleDialog.LocalFileChooserListener() { + @Override + public void openLocalFileChooserDialog() { + new ChooserDialog(PlayActivity.this) + .withFilter(false, false, "srt", "ass", "scc", "stl", "ttml") + .withStartFile("/storage/emulated/0/Download") + .withChosenListener(new ChooserDialog.Result() { + @Override + public void onChoosePath(String path, File pathFile) { + LOG.i("Local Subtitle Path: " + path); + setSubtitle(path);//设置字幕 + } + }) + .build() + .show(); + } + }); + subtitleDialog.show(); + } + + void selectMyAudioTrack() { + AbstractPlayer mediaPlayer = mVideoView.getMediaPlayer(); + if (!(mediaPlayer instanceof IjkMediaPlayer)) { + return; + } + TrackInfo trackInfo = null; + if (mediaPlayer instanceof IjkMediaPlayer) { + trackInfo = ((IjkMediaPlayer)mediaPlayer).getTrackInfo(); + } + if (trackInfo == null) { + Toast.makeText(mContext, "没有音轨", Toast.LENGTH_SHORT).show(); + return; + } + List bean = trackInfo.getAudio(); + if (bean.size() < 1) return; + SelectDialog dialog = new SelectDialog<>(PlayActivity.this); + dialog.setTip("切换音轨"); + dialog.setAdapter(new SelectDialogAdapter.SelectDialogInterface() { + @Override + public void click(TrackInfoBean value, int pos) { + try { + for (TrackInfoBean audio : bean) { + audio.selected = audio.index == value.index; + } + mediaPlayer.pause(); + long progress = mediaPlayer.getCurrentPosition();//保存当前进度,ijk 切换轨道 会有快进几秒 + if (mediaPlayer instanceof IjkMediaPlayer) { + ((IjkMediaPlayer)mediaPlayer).setTrack(value.index); + } + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + mediaPlayer.seekTo(progress); + mediaPlayer.start(); + } + }, 800); + dialog.dismiss(); + } catch (Exception e) { + LOG.e("切换音轨出错"); + } + } + + @Override + public String getDisplay(TrackInfoBean val) { + return val.index + " : " + val.language; + } + }, new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { + return oldItem.index == newItem.index; + } + + @Override + public boolean areContentsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { + return oldItem.index == newItem.index; + } + }, bean, trackInfo.getAudioSelected(false)); + dialog.show(); + } + + void selectMyInternalSubtitle() { + AbstractPlayer mediaPlayer = mVideoView.getMediaPlayer(); + if (!(mediaPlayer instanceof IjkMediaPlayer)) { + return; + } + TrackInfo trackInfo = null; + if (mediaPlayer instanceof IjkMediaPlayer) { + trackInfo = ((IjkMediaPlayer)mediaPlayer).getTrackInfo(); + } + if (trackInfo == null) { + Toast.makeText(mContext, "没有内置字幕", Toast.LENGTH_SHORT).show(); + return; + } + List bean = trackInfo.getSubtitle(); + if (bean.size() < 1) return; + SelectDialog dialog = new SelectDialog<>(PlayActivity.this); + dialog.setTip("切换内置字幕"); + dialog.setAdapter(new SelectDialogAdapter.SelectDialogInterface() { + @Override + public void click(TrackInfoBean value, int pos) { + try { + for (TrackInfoBean subtitle : bean) { + subtitle.selected = subtitle.index == value.index; + } + mediaPlayer.pause(); + long progress = mediaPlayer.getCurrentPosition();//保存当前进度,ijk 切换轨道 会有快进几秒 + if (mediaPlayer instanceof IjkMediaPlayer) { + ((IjkMediaPlayer)mediaPlayer).setTrack(value.index); + mController.mSubtitleView.isInternal = true; + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + mediaPlayer.seekTo(progress); + mediaPlayer.start(); + } + }, 800); + } + + dialog.dismiss(); + } catch (Exception e) { + LOG.e("切换内置字幕出错"); + } + } + + @Override + public String getDisplay(TrackInfoBean val) { + return val.index + " : " + val.language; + } + }, new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { + return oldItem.index == newItem.index; + } + + @Override + public boolean areContentsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { + return oldItem.index == newItem.index; + } + }, bean, trackInfo.getSubtitleSelected(false)); + dialog.show(); + } + void setTip(String msg, boolean loading, boolean err) { runOnUiThread(new Runnable() {//影魔 解决解析偶发闪退 @Override @@ -398,30 +482,48 @@ public class PlayActivity extends BaseActivity { } mVideoView.start(); mController.resetSpeed(); - - //加载字幕开始 - // 绑定MediaPlayer - mController.mSubtitleView.bindToMediaPlayer(mVideoView.getMediaPlayer()); - mController.mSubtitleView.setVisibility(View.GONE); - mController.mSubtitleView.setPlaySubtitleCacheKey(subtitleCacheKey); - if (playSubtitle != null && playSubtitle .length() > 0) { - // 设置字幕 - mController.mSubtitleView.setSubtitlePath(playSubtitle); - mController.mSubtitleView.setVisibility(View.VISIBLE); - } else { - String subtitlePathCache = (String)CacheManager.getCache(MD5.string2MD5(subtitleCacheKey)); - if (subtitlePathCache != null && !subtitlePathCache.isEmpty()) { - mController.mSubtitleView.setSubtitlePath(subtitlePathCache); - mController.mSubtitleView.setVisibility(View.VISIBLE); - } - } - //加载字幕结束 } } } }); } + private void initSubtitleView() { + if (mVideoView.getMediaPlayer() instanceof IjkMediaPlayer) { + TrackInfo trackInfo = null; + trackInfo = ((IjkMediaPlayer)(mVideoView.getMediaPlayer())).getTrackInfo(); + if (trackInfo != null && trackInfo.getSubtitle().size() > 0) { + mController.mSubtitleView.isInternal = true; + mController.mSubtitleView.hasInternal = true; + + } + ((IjkMediaPlayer)(mVideoView.getMediaPlayer())).setOnTimedTextListener(new IMediaPlayer.OnTimedTextListener() { + @Override + public void onTimedText(IMediaPlayer mp, IjkTimedText text) { + if (mController.mSubtitleView.isInternal) { + com.github.tvbox.osc.subtitle.model.Subtitle subtitle = new com.github.tvbox.osc.subtitle.model.Subtitle(); + subtitle.content = text.getText(); + mController.mSubtitleView.onSubtitleChanged(subtitle); + } + } + }); + } + + mController.mSubtitleView.bindToMediaPlayer(mVideoView.getMediaPlayer()); + mController.mSubtitleView.setPlaySubtitleCacheKey(subtitleCacheKey); + if (!mController.mSubtitleView.isInternal) { + if (playSubtitle != null && playSubtitle .length() > 0) { + // 设置字幕 + mController.mSubtitleView.setSubtitlePath(playSubtitle); + } else { + String subtitlePathCache = (String)CacheManager.getCache(MD5.string2MD5(subtitleCacheKey)); + if (subtitlePathCache != null && !subtitlePathCache.isEmpty()) { + mController.mSubtitleView.setSubtitlePath(subtitlePathCache); + } + } + } + } + private void initViewModel() { sourceViewModel = new ViewModelProvider(this).get(SourceViewModel.class); sourceViewModel.playResult.observe(this, new Observer() { diff --git a/app/src/main/java/com/github/tvbox/osc/ui/dialog/SubtitleDialog.java b/app/src/main/java/com/github/tvbox/osc/ui/dialog/SubtitleDialog.java index 719a7f5f..364d360a 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/dialog/SubtitleDialog.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/dialog/SubtitleDialog.java @@ -15,6 +15,7 @@ import org.jetbrains.annotations.NotNull; public class SubtitleDialog extends BaseDialog { + public TextView selectInternal; private TextView selectLocal; private TextView selectRemote; private TextView subtitleSizeMinus; @@ -38,6 +39,7 @@ public class SubtitleDialog extends BaseDialog { } private void initView(Context context) { + selectInternal = findViewById(R.id.selectInternal); selectLocal = findViewById(R.id.selectLocal); selectRemote = findViewById(R.id.selectRemote); subtitleSizeMinus = findViewById(R.id.subtitleSizeMinus); @@ -143,6 +145,14 @@ public class SubtitleDialog extends BaseDialog { mSubtitleViewListener.setSubtitleDelay(mseconds); } }); + selectInternal.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + FastClickCheckUtil.check(view); + dismiss(); + mSubtitleViewListener.selectInternalSubtitle(); + } + }); } public void setLocalFileChooserListener(LocalFileChooserListener localFileChooserListener) { @@ -168,5 +178,6 @@ public class SubtitleDialog extends BaseDialog { public interface SubtitleViewListener { void setTextSize(int size); void setSubtitleDelay(int milliseconds); + void selectInternalSubtitle(); } } diff --git a/app/src/main/java/com/github/tvbox/osc/ui/fragment/PlayFragment.java b/app/src/main/java/com/github/tvbox/osc/ui/fragment/PlayFragment.java index 60d2d5ce..c6e9a332 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/fragment/PlayFragment.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/fragment/PlayFragment.java @@ -92,6 +92,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import me.jessyan.autosize.AutoSize; +import tv.danmaku.ijk.media.player.IMediaPlayer; +import tv.danmaku.ijk.media.player.IjkTimedText; import xyz.doikki.videoplayer.player.AbstractPlayer; import xyz.doikki.videoplayer.player.ProgressManager; @@ -201,120 +203,17 @@ public class PlayFragment extends BaseLazyFragment { @Override public void selectSubtitle() { - SubtitleDialog subtitleDialog = new SubtitleDialog(getActivity()); - subtitleDialog.setSubtitleViewListener(new SubtitleDialog.SubtitleViewListener() { - @Override - public void setTextSize(int size) { - mController.mSubtitleView.setTextSize(size); - } - @Override - public void setSubtitleDelay(int milliseconds) { - mController.mSubtitleView.setSubtitleDelay(milliseconds); - } - }); - subtitleDialog.setSearchSubtitleListener(new SubtitleDialog.SearchSubtitleListener() { - @Override - public void openSearchSubtitleDialog() { - SearchSubtitleDialog searchSubtitleDialog = new SearchSubtitleDialog(getContext()); - searchSubtitleDialog.setSubtitleLoader(new SearchSubtitleDialog.SubtitleLoader() { - @Override - public void loadSubtitle(Subtitle subtitle) { - requireActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - String zimuUrl = subtitle.getUrl(); - LOG.i("Remote Subtitle Url: " + zimuUrl); - setSubtitle(zimuUrl);//设置字幕 - if (searchSubtitleDialog != null) { - searchSubtitleDialog.dismiss(); - } - } - }); - } - }); - searchSubtitleDialog.setSearchWord(mVodInfo.playNote); - searchSubtitleDialog.show(); - } - }); - subtitleDialog.setLocalFileChooserListener(new SubtitleDialog.LocalFileChooserListener() { - @Override - public void openLocalFileChooserDialog() { - new ChooserDialog(getActivity()) - .withFilter(false, false, "srt", "ass", "scc", "stl", "ttml") - .withStartFile("/storage/emulated/0/Download") - .withChosenListener(new ChooserDialog.Result() { - @Override - public void onChoosePath(String path, File pathFile) { - LOG.i("Local Subtitle Path: " + path); - setSubtitle(path);//设置字幕 - } - }) - .build() - .show(); - } - }); - subtitleDialog.show(); + selectMySubtitle(); } @Override public void selectAudioTrack() { - AbstractPlayer mediaPlayer = mVideoView.getMediaPlayer(); - if (!(mediaPlayer instanceof IjkMediaPlayer)) { - return; - } - TrackInfo trackInfo = null; - if (mediaPlayer instanceof IjkMediaPlayer) { - trackInfo = ((IjkMediaPlayer)mediaPlayer).getTrackInfo(); - } - if (trackInfo == null) { - Toast.makeText(mContext, "没有音轨", Toast.LENGTH_SHORT).show(); - return; - } - List bean = trackInfo.getAudio(); - if (bean.size() < 1) return; - SelectDialog dialog = new SelectDialog<>(getActivity()); - dialog.setTip("切换音轨"); - dialog.setAdapter(new SelectDialogAdapter.SelectDialogInterface() { - @Override - public void click(TrackInfoBean value, int pos) { - try { - for (TrackInfoBean audio : bean) { - audio.selected = audio.index == value.index; - } - mediaPlayer.pause(); - long progress = mediaPlayer.getCurrentPosition();//保存当前进度,ijk 切换轨道 会有快进几秒 - if (mediaPlayer instanceof IjkMediaPlayer) { - ((IjkMediaPlayer)mediaPlayer).setTrack(value.index); - } - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - mediaPlayer.seekTo(progress); - mediaPlayer.start(); - } - }, 800); - dialog.dismiss(); - } catch (Exception e) { - LOG.e("切换音轨出错"); - } - } - - @Override - public String getDisplay(TrackInfoBean val) { - return val.index + " : " + val.language; - } - }, new DiffUtil.ItemCallback() { - @Override - public boolean areItemsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { - return oldItem.index == newItem.index; - } + selectMyAudioTrack(); + } - @Override - public boolean areContentsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { - return oldItem.index == newItem.index; - } - }, bean, trackInfo.getAudioSelected(false)); - dialog.show(); + @Override + public void prepared() { + initSubtitleView(); } }); mVideoView.setVideoController(mController); @@ -330,6 +229,192 @@ public class PlayFragment extends BaseLazyFragment { } } + void selectMySubtitle() { + SubtitleDialog subtitleDialog = new SubtitleDialog(getActivity()); + if (mController.mSubtitleView.hasInternal) { + subtitleDialog.selectInternal.setVisibility(View.VISIBLE); + } + subtitleDialog.setSubtitleViewListener(new SubtitleDialog.SubtitleViewListener() { + @Override + public void setTextSize(int size) { + mController.mSubtitleView.setTextSize(size); + } + @Override + public void setSubtitleDelay(int milliseconds) { + mController.mSubtitleView.setSubtitleDelay(milliseconds); + } + + @Override + public void selectInternalSubtitle() { + selectMyInternalSubtitle(); + } + }); + subtitleDialog.setSearchSubtitleListener(new SubtitleDialog.SearchSubtitleListener() { + @Override + public void openSearchSubtitleDialog() { + SearchSubtitleDialog searchSubtitleDialog = new SearchSubtitleDialog(getActivity()); + searchSubtitleDialog.setSubtitleLoader(new SearchSubtitleDialog.SubtitleLoader() { + @Override + public void loadSubtitle(Subtitle subtitle) { + requireActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + String zimuUrl = subtitle.getUrl(); + LOG.i("Remote Subtitle Url: " + zimuUrl); + setSubtitle(zimuUrl);//设置字幕 + if (searchSubtitleDialog != null) { + searchSubtitleDialog.dismiss(); + } + } + }); + } + }); + searchSubtitleDialog.setSearchWord(mVodInfo.playNote); + searchSubtitleDialog.show(); + } + }); + subtitleDialog.setLocalFileChooserListener(new SubtitleDialog.LocalFileChooserListener() { + @Override + public void openLocalFileChooserDialog() { + new ChooserDialog(getActivity()) + .withFilter(false, false, "srt", "ass", "scc", "stl", "ttml") + .withStartFile("/storage/emulated/0/Download") + .withChosenListener(new ChooserDialog.Result() { + @Override + public void onChoosePath(String path, File pathFile) { + LOG.i("Local Subtitle Path: " + path); + setSubtitle(path);//设置字幕 + } + }) + .build() + .show(); + } + }); + subtitleDialog.show(); + } + + + void selectMyAudioTrack() { + AbstractPlayer mediaPlayer = mVideoView.getMediaPlayer(); + if (!(mediaPlayer instanceof IjkMediaPlayer)) { + return; + } + TrackInfo trackInfo = null; + if (mediaPlayer instanceof IjkMediaPlayer) { + trackInfo = ((IjkMediaPlayer)mediaPlayer).getTrackInfo(); + } + if (trackInfo == null) { + Toast.makeText(mContext, "没有音轨", Toast.LENGTH_SHORT).show(); + return; + } + List bean = trackInfo.getAudio(); + if (bean.size() < 1) return; + SelectDialog dialog = new SelectDialog<>(getActivity()); + dialog.setTip("切换音轨"); + dialog.setAdapter(new SelectDialogAdapter.SelectDialogInterface() { + @Override + public void click(TrackInfoBean value, int pos) { + try { + for (TrackInfoBean audio : bean) { + audio.selected = audio.index == value.index; + } + mediaPlayer.pause(); + long progress = mediaPlayer.getCurrentPosition();//保存当前进度,ijk 切换轨道 会有快进几秒 + if (mediaPlayer instanceof IjkMediaPlayer) { + ((IjkMediaPlayer)mediaPlayer).setTrack(value.index); + } + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + mediaPlayer.seekTo(progress); + mediaPlayer.start(); + } + }, 800); + dialog.dismiss(); + } catch (Exception e) { + LOG.e("切换音轨出错"); + } + } + + @Override + public String getDisplay(TrackInfoBean val) { + return val.index + " : " + val.language; + } + }, new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { + return oldItem.index == newItem.index; + } + + @Override + public boolean areContentsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { + return oldItem.index == newItem.index; + } + }, bean, trackInfo.getAudioSelected(false)); + dialog.show(); + } + + void selectMyInternalSubtitle() { + AbstractPlayer mediaPlayer = mVideoView.getMediaPlayer(); + if (!(mediaPlayer instanceof IjkMediaPlayer)) { + return; + } + TrackInfo trackInfo = null; + if (mediaPlayer instanceof IjkMediaPlayer) { + trackInfo = ((IjkMediaPlayer)mediaPlayer).getTrackInfo(); + } + if (trackInfo == null) { + Toast.makeText(mContext, "没有内置字幕", Toast.LENGTH_SHORT).show(); + return; + } + List bean = trackInfo.getSubtitle(); + if (bean.size() < 1) return; + SelectDialog dialog = new SelectDialog<>(getActivity()); + dialog.setTip("切换内置字幕"); + dialog.setAdapter(new SelectDialogAdapter.SelectDialogInterface() { + @Override + public void click(TrackInfoBean value, int pos) { + try { + for (TrackInfoBean subtitle : bean) { + subtitle.selected = subtitle.index == value.index; + } + mediaPlayer.pause(); + long progress = mediaPlayer.getCurrentPosition();//保存当前进度,ijk 切换轨道 会有快进几秒 + if (mediaPlayer instanceof IjkMediaPlayer) { + ((IjkMediaPlayer)mediaPlayer).setTrack(value.index); + mController.mSubtitleView.isInternal = true; + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + mediaPlayer.seekTo(progress); + mediaPlayer.start(); + } + }, 800); + } + dialog.dismiss(); + } catch (Exception e) { + LOG.e("切换内置字幕出错"); + } + } + + @Override + public String getDisplay(TrackInfoBean val) { + return val.index + " : " + val.language; + } + }, new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { + return oldItem.index == newItem.index; + } + + @Override + public boolean areContentsTheSame(@NonNull @NotNull TrackInfoBean oldItem, @NonNull @NotNull TrackInfoBean newItem) { + return oldItem.index == newItem.index; + } + }, bean, trackInfo.getSubtitleSelected(false)); + dialog.show(); + } + void setTip(String msg, boolean loading, boolean err) { requireActivity().runOnUiThread(new Runnable() { //影魔 @Override @@ -396,30 +481,47 @@ public class PlayFragment extends BaseLazyFragment { } mVideoView.start(); mController.resetSpeed(); - - //加载字幕开始 - // 绑定MediaPlayer - mController.mSubtitleView.bindToMediaPlayer(mVideoView.getMediaPlayer()); - mController.mSubtitleView.setVisibility(View.GONE); - mController.mSubtitleView.setPlaySubtitleCacheKey(subtitleCacheKey); - if (playSubtitle != null && playSubtitle .length() > 0) { - // 设置字幕 - mController.mSubtitleView.setSubtitlePath(playSubtitle); - mController.mSubtitleView.setVisibility(View.VISIBLE); - } else { - String subtitlePathCache = (String)CacheManager.getCache(MD5.string2MD5(subtitleCacheKey)); - if (subtitlePathCache != null && !subtitlePathCache.isEmpty()) { - mController.mSubtitleView.setSubtitlePath(subtitlePathCache); - mController.mSubtitleView.setVisibility(View.VISIBLE); - } - } - //加载字幕结束 } } } }); } + private void initSubtitleView() { + if (mVideoView.getMediaPlayer() instanceof IjkMediaPlayer) { + TrackInfo trackInfo = null; + trackInfo = ((IjkMediaPlayer)(mVideoView.getMediaPlayer())).getTrackInfo(); + if (trackInfo != null && trackInfo.getSubtitle().size() > 0) { + mController.mSubtitleView.isInternal = true; + mController.mSubtitleView.hasInternal = true; + } + ((IjkMediaPlayer)(mVideoView.getMediaPlayer())).setOnTimedTextListener(new IMediaPlayer.OnTimedTextListener() { + @Override + public void onTimedText(IMediaPlayer mp, IjkTimedText text) { + if (mController.mSubtitleView.isInternal) { + com.github.tvbox.osc.subtitle.model.Subtitle subtitle = new com.github.tvbox.osc.subtitle.model.Subtitle(); + subtitle.content = text.getText(); + mController.mSubtitleView.onSubtitleChanged(subtitle); + } + } + }); + } + + mController.mSubtitleView.bindToMediaPlayer(mVideoView.getMediaPlayer()); + mController.mSubtitleView.setPlaySubtitleCacheKey(subtitleCacheKey); + if (!mController.mSubtitleView.isInternal) { + if (playSubtitle != null && playSubtitle .length() > 0) { + // 设置字幕 + mController.mSubtitleView.setSubtitlePath(playSubtitle); + } else { + String subtitlePathCache = (String)CacheManager.getCache(MD5.string2MD5(subtitleCacheKey)); + if (subtitlePathCache != null && !subtitlePathCache.isEmpty()) { + mController.mSubtitleView.setSubtitlePath(subtitlePathCache); + } + } + } + } + private void initViewModel() { sourceViewModel = new ViewModelProvider(this).get(SourceViewModel.class); sourceViewModel.playResult.observe(this, new Observer() { diff --git a/app/src/main/res/layout/dialog_subtitle.xml b/app/src/main/res/layout/dialog_subtitle.xml index 380727cd..e3e65569 100644 --- a/app/src/main/res/layout/dialog_subtitle.xml +++ b/app/src/main/res/layout/dialog_subtitle.xml @@ -19,12 +19,26 @@ android:layout_gravity="center" android:orientation="vertical"> + + + + + + +