From b0eb4b92dc3f126b1d14af55a36604e863cf1408 Mon Sep 17 00:00:00 2001 From: grandiloquent <1785907865@qq.com> Date: Wed, 27 Oct 2021 11:30:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3Iqiyi=E6=92=AD=E6=94=BE?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/euphoria/psycho/PlayerActivity.java | 232 ++++++++++++++---- .../java/euphoria/psycho/explorer/Helper.java | 8 +- .../psycho/explorer/MainActivity.java | 3 +- .../psycho/explorer/VideoListActivity.java | 6 +- .../java/euphoria/psycho/videos/Twitter.java | 6 +- app/src/main/res/layout/activity_player.xml | 4 +- 6 files changed, 189 insertions(+), 70 deletions(-) diff --git a/app/src/main/java/euphoria/psycho/PlayerActivity.java b/app/src/main/java/euphoria/psycho/PlayerActivity.java index 3e6cf226..8ca84a61 100644 --- a/app/src/main/java/euphoria/psycho/PlayerActivity.java +++ b/app/src/main/java/euphoria/psycho/PlayerActivity.java @@ -1,6 +1,8 @@ package euphoria.psycho; import android.app.Activity; +import android.content.Context; +import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.SurfaceTexture; @@ -28,8 +30,15 @@ import android.widget.LinearLayout; import android.widget.TextView; +import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Formatter; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; @@ -44,27 +53,40 @@ import euphoria.psycho.player.TimeBar; import euphoria.psycho.player.TimeBar.OnScrubListener; import euphoria.psycho.share.DateTimeShare; +import euphoria.psycho.share.KeyShare; +import euphoria.psycho.share.WebViewShare; + +import static euphoria.psycho.videos.VideosHelper.USER_AGENT; public class PlayerActivity extends Activity { + public static final int DEFAULT_HIDE_TIME_DELAY = 5000; + public static final String KEY_VIDEO_FILE = "VideoFile"; + public static final String KEY_WEB_VIDEO = "WebVideo"; + public static final String KEY_M3U8 = "m3u8"; TextureView mTextureView; MediaPlayer mMediaPlayer; Surface mSurface; SurfaceTexture mSurfaceTexture; private FrameLayout mRoot; private boolean mLayout = false; - StringBuilder mStringBuilder = new StringBuilder(); - Formatter mFormatter = new Formatter(mStringBuilder); - private FrameLayout mExoBottomBar; + private StringBuilder mStringBuilder = new StringBuilder(); + private Formatter mFormatter = new Formatter(mStringBuilder); + private FrameLayout mBottomBar; private TextView mDuration; private SimpleTimeBar mTimeBar; private Handler mHandler = new Handler(); private TextView mPosition; private ImageButton mActionFullscreen; private ImageButton mActionFileDownload; - private Button mExoFfwdWithAmount; - private Button mExoRewWithAmount; - private LinearLayout mExoCenterControls; + private Button mFfwdWithAmount; + private Button mRewWithAmount; + private LinearLayout mCenterControls; + private ImageButton mNext; + private ImageButton mPrev; + private Runnable mHideAction = this::hiddenControls; + private List mPlayList; + private int mPlayIndex; static int calculateScreenOrientation(Activity activity) { int displayRotation = getDisplayRotation(activity); @@ -96,6 +118,36 @@ static int getDisplayRotation(Activity activity) { return 0; } + static File[] getVideos(String videoPath) { + if (videoPath == null) { + return null; + } + File dir = new File(videoPath).getParentFile(); + if (dir == null) { + return null; + } + return listVideoFiles(dir.getAbsolutePath()); + } + + static File[] listVideoFiles(String dir) { + File directory = new File(dir); + Pattern pattern = Pattern.compile("\\.(?:mp4|vm|crdownload)$"); + File[] files = directory.listFiles(file -> + file.isFile() && pattern.matcher(file.getName()).find()); + if (files == null || files.length == 0) return null; + Arrays.sort(files, (o1, o2) -> { + final long result = o2.lastModified() - o1.lastModified(); + if (result < 0) { + return -1; + } else if (result > 0) { + return 1; + } else { + return 0; + } + }); + return files; + } + private void clearSurface() { if (mSurface == null) { return; @@ -134,8 +186,8 @@ private void clearSurface() { private void hiddenControls() { mTimeBar.setVisibility(View.GONE); - mExoBottomBar.setVisibility(View.GONE); - mExoCenterControls.setVisibility(View.GONE); + mBottomBar.setVisibility(View.GONE); + mCenterControls.setVisibility(View.GONE); } private void hideSystemUI() { @@ -148,11 +200,6 @@ private void hideSystemUI() { View.SYSTEM_UI_FLAG_IMMERSIVE); } - private void hideUI() { - mHandler.postDelayed(this::hiddenControls, 5000); - hideSystemUI(); - } - private void initializePlayer() { mMediaPlayer = new MediaPlayer(); try { @@ -171,15 +218,26 @@ private void initializePlayer() { mMediaPlayer.setOnTimedMetaDataAvailableListener(this::onTimedMetaDataAvailable); mMediaPlayer.setOnTimedTextListener(this::onTimedText); mMediaPlayer.setOnVideoSizeChangedListener(this::onVideoSizeChanged); - mMediaPlayer.setDataSource(this, getIntent().getData()); mMediaPlayer.setSurface(mSurface); - mMediaPlayer.prepareAsync(); + play(); } catch (IOException e) { e.printStackTrace(); } } + private void play() throws IOException { + mMediaPlayer.setDataSource(mPlayList.get(mPlayIndex)); + mMediaPlayer.prepareAsync(); + } + private void onActionFileDownload(View view) { + boolean isM3u8 = getIntent().getBooleanExtra(KEY_M3U8, false); + if (!isM3u8) { + WebViewShare.downloadFile(this, + KeyShare.toHex(mPlayList.get(mPlayIndex).getBytes(StandardCharsets.UTF_8)) + + ".mp4" + , mPlayList.get(mPlayIndex), USER_AGENT); + } } private void onActionFullscreen(View view) { @@ -207,9 +265,6 @@ private void onActionFullscreen(View view) { FrameLayout.LayoutParams layoutParams = new LayoutParams(mRoot.getMeasuredHeight(), height); layoutParams.topMargin = top; mTextureView.setLayoutParams(layoutParams); - Log.e("B5aOx2", String.format("onActionFullscreen, mMediaPlayer.getVideoWidth() = %s;\n mMediaPlayer.getVideoHeight() = %s;\n getResources().getDisplayMetrics().widthPixels = %s;\n getResources().getDisplayMetrics().heightPixels = %s;\n mRoot.getMeasuredWidth() = %s;\n mRoot.getMeasuredHeight() = %s;\n ratio = %s\n left = %s", - mMediaPlayer.getVideoWidth(), mMediaPlayer.getVideoHeight(), getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels, mRoot.getMeasuredWidth(), mRoot.getMeasuredHeight(), ratio, top - )); } } @@ -247,6 +302,21 @@ private boolean onInfo(MediaPlayer mediaPlayer, int i, int i1) { private void onMediaTimeDiscontinuity(MediaPlayer mediaPlayer, MediaTimestamp mediaTimestamp) { } + private void onNext(View view) { + if (mPlayList.size() < 2) return; + if (mPlayIndex + 1 < mPlayList.size()) { + mPlayIndex++; + } else { + mPlayIndex = 0; + } + mMediaPlayer.reset(); + try { + play(); + } catch (IOException e) { + e.printStackTrace(); + } + } + private void onPrepared(MediaPlayer mediaPlayer) { Log.e("B5aOx2", "onPrepared"); mDuration.setText(DateTimeShare.getStringForTime(mStringBuilder, mFormatter, mediaPlayer.getDuration())); @@ -256,9 +326,24 @@ private void onPrepared(MediaPlayer mediaPlayer) { hiddenControls(); } + private void onPrev(View view) { + if (mPlayList.size() < 2) return; + if (mPlayIndex - 1 > -1) { + mPlayIndex--; + } else { + mPlayIndex = 0; + } + mMediaPlayer.reset(); + try { + play(); + } catch (IOException e) { + e.printStackTrace(); + } + } + private void onRoot(View view) { showControls(); - mHandler.postDelayed(this::hiddenControls, 5000); + scheduleHideControls(); } private void onSeekComplete(MediaPlayer mediaPlayer) { @@ -292,14 +377,19 @@ private void onVideoSizeChanged(MediaPlayer mediaPlayer, int videoWidth, int vid mTextureView.setLayoutParams(layoutParams); } + private void scheduleHideControls() { + mHandler.removeCallbacks(mHideAction); + mHandler.postDelayed(mHideAction, DEFAULT_HIDE_TIME_DELAY); + } + private void showControls() { mTimeBar.setVisibility(View.VISIBLE); - mExoBottomBar.setVisibility(View.VISIBLE); - mExoCenterControls.setVisibility(View.VISIBLE); + mBottomBar.setVisibility(View.VISIBLE); + mCenterControls.setVisibility(View.VISIBLE); } private void updateProgress() { - if (mMediaPlayer == null) { + if (mMediaPlayer == null || mBottomBar.getVisibility() != View.VISIBLE) { return; } mTimeBar.setPosition(mMediaPlayer.getCurrentPosition()); @@ -315,27 +405,24 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { hideSystemUI(); View decorView = getWindow().getDecorView(); decorView.setOnSystemUiVisibilityChangeListener - (new View.OnSystemUiVisibilityChangeListener() { - @Override - public void onSystemUiVisibilityChange(int visibility) { - // Note that system bars will only be "visible" if none of the - // LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set. - if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { - // TODO: The system bars are visible. Make any desired - // adjustments to your UI, such as showing the action bar or - // other navigational controls. - mHandler.postDelayed(() -> hideSystemUI(), 5000); - } else { - // TODO: The system bars are NOT visible. Make any desired - // adjustments to your UI, such as hiding the action bar or - // other navigational controls. - } + (visibility -> { + // Note that system bars will only be "visible" if none of the + // LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set. + if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { + // TODO: The system bars are visible. Make any desired + // adjustments to your UI, such as showing the action bar or + // other navigational controls. + mHandler.postDelayed(this::hideSystemUI, DEFAULT_HIDE_TIME_DELAY); + } else { + // TODO: The system bars are NOT visible. Make any desired + // adjustments to your UI, such as hiding the action bar or + // other navigational controls. } }); - mExoCenterControls = findViewById(R.id.exo_center_controls); + mCenterControls = findViewById(R.id.exo_center_controls); mTextureView = findViewById(R.id.texture_view); mPosition = findViewById(R.id.position); - mExoBottomBar = findViewById(R.id.exo_bottom_bar); + mBottomBar = findViewById(R.id.exo_bottom_bar); mDuration = findViewById(R.id.duration); mTextureView.setSurfaceTextureListener(new SurfaceTextureListener() { @Override @@ -363,12 +450,11 @@ public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) { @Override public void onScrubMove(TimeBar timeBar, long position) { mPosition.setText(DateTimeShare.getStringForTime(mStringBuilder, mFormatter, position)); - mHandler.removeCallbacks(null); } @Override public void onScrubStart(TimeBar timeBar, long position) { - mHandler.removeCallbacks(null); + mHandler.removeCallbacks(mHideAction); mPosition.setText(DateTimeShare.getStringForTime(mStringBuilder, mFormatter, position)); } @@ -376,16 +462,16 @@ public void onScrubStart(TimeBar timeBar, long position) { public void onScrubStop(TimeBar timeBar, long position, boolean canceled) { mMediaPlayer.seekTo((int) position); updateProgress(); - hideUI(); + scheduleHideControls(); } }); - mExoRewWithAmount = findViewById(R.id.exo_rew_with_amount); + mRewWithAmount = findViewById(R.id.exo_rew_with_amount); Typeface typeface = ResourcesCompat.getFont(this, com.google.android.exoplayer2.ui.R.font.roboto_medium_numbers); - mExoRewWithAmount.setTypeface(typeface); - mExoRewWithAmount.setText("5"); - mExoRewWithAmount.setOnClickListener(v -> { + mRewWithAmount.setTypeface(typeface); + mRewWithAmount.setText("5"); + mRewWithAmount.setOnClickListener(v -> { mHandler.removeCallbacks(null); int dif = mMediaPlayer.getCurrentPosition() - 5000; if (dif < 0) { @@ -394,10 +480,10 @@ public void onScrubStop(TimeBar timeBar, long position, boolean canceled) { mMediaPlayer.seekTo(dif); updateProgress(); }); - mExoFfwdWithAmount = findViewById(R.id.exo_ffwd_with_amount); - mExoFfwdWithAmount.setTypeface(typeface); - mExoFfwdWithAmount.setText("15"); - mExoFfwdWithAmount.setOnClickListener(v -> { + mFfwdWithAmount = findViewById(R.id.exo_ffwd_with_amount); + mFfwdWithAmount.setTypeface(typeface); + mFfwdWithAmount.setText("15"); + mFfwdWithAmount.setOnClickListener(v -> { mHandler.removeCallbacks(null); int dif = mMediaPlayer.getCurrentPosition() + 15000; if (dif > mMediaPlayer.getDuration()) { @@ -407,12 +493,36 @@ public void onScrubStop(TimeBar timeBar, long position, boolean canceled) { updateProgress(); }); mActionFileDownload = findViewById(R.id.action_file_download); - mActionFileDownload.setOnClickListener(this::onActionFileDownload); - mActionFileDownload.setAlpha(75); mActionFullscreen = findViewById(R.id.action_fullscreen); mActionFullscreen.setOnClickListener(this::onActionFullscreen); mRoot.setOnClickListener(this::onRoot); - + mPrev = findViewById(R.id.prev); + mNext = findViewById(R.id.next); + String videoFile = getIntent().getStringExtra(KEY_VIDEO_FILE); + if (videoFile != null) { + mActionFileDownload.setAlpha(75); + mPlayList = Arrays.stream(getVideos(videoFile)).map(File::getAbsolutePath) + .collect(Collectors.toList()); + if (mPlayList.size() < 2) { + mPrev.setAlpha(75); + mNext.setAlpha(75); + mPlayIndex = 0; + } else { + mPrev.setOnClickListener(this::onPrev); + mNext.setOnClickListener(this::onNext); + mPlayIndex = mPlayList.indexOf(videoFile); + } + return; + } + String webVideo = getIntent().getStringExtra(KEY_WEB_VIDEO); + if (webVideo != null) { + mPrev.setAlpha(75); + mNext.setAlpha(75); + mActionFileDownload.setOnClickListener(this::onActionFileDownload); + mPlayList = new ArrayList<>(); + mPlayList.add(webVideo); + mPlayIndex = 0; + } } @Override @@ -433,5 +543,19 @@ protected void onStop() { } clearSurface(); } + + public static void launchActivity(Context context, File videoFile) { + Intent intent = new Intent(context, PlayerActivity.class); + intent.putExtra(KEY_VIDEO_FILE, videoFile.getAbsolutePath()); + context.startActivity(intent); + } + + public static void launchActivity(Context context, String webVideo, boolean isM3u8) { + Intent intent = new Intent(context, PlayerActivity.class); + intent.putExtra(KEY_WEB_VIDEO, webVideo); + if (isM3u8) { + intent.putExtra(KEY_WEB_VIDEO, isM3u8); + } + context.startActivity(intent); + } } - \ No newline at end of file diff --git a/app/src/main/java/euphoria/psycho/explorer/Helper.java b/app/src/main/java/euphoria/psycho/explorer/Helper.java index 654ce8c4..078ce2dd 100644 --- a/app/src/main/java/euphoria/psycho/explorer/Helper.java +++ b/app/src/main/java/euphoria/psycho/explorer/Helper.java @@ -5,7 +5,6 @@ import android.app.AlertDialog.Builder; import android.content.Context; import android.content.Intent; -import android.net.Uri; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.webkit.DownloadListener; @@ -104,12 +103,13 @@ static void loadStartPage(Activity activity, WebView webView) { .getString(KEY_LAST_ACCESSED, ListenerDelegate.HELP_URL)); } } -// + + // static void tryPlayVideo(Context context) { Intent intent = new Intent(context, PlayerActivity.class); if (VERSION.SDK_INT >= VERSION_CODES.O) { try { - intent.setData(Uri.fromFile(Files.list(Paths.get("/storage/emulated/0/Android/data/euphoria.psycho.explorer/files/Download")) + intent.putExtra(PlayerActivity.KEY_VIDEO_FILE, Files.list(Paths.get("/storage/emulated/0/Android/data/euphoria.psycho.explorer/files/Download")) .filter(path -> path.getFileName().toAbsolutePath().toString().endsWith(".mp4")) .sorted((o1, o2) -> { long result = 0; @@ -125,7 +125,7 @@ static void tryPlayVideo(Context context) { return 0; } }) - .findFirst().get().toFile())); + .findFirst().get().toFile().getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } diff --git a/app/src/main/java/euphoria/psycho/explorer/MainActivity.java b/app/src/main/java/euphoria/psycho/explorer/MainActivity.java index 621d61cd..2f17de22 100644 --- a/app/src/main/java/euphoria/psycho/explorer/MainActivity.java +++ b/app/src/main/java/euphoria/psycho/explorer/MainActivity.java @@ -24,7 +24,6 @@ import static euphoria.psycho.explorer.Helper.checkUnfinishedVideoTasks; import static euphoria.psycho.explorer.Helper.configureWebView; import static euphoria.psycho.explorer.Helper.loadStartPage; -import static euphoria.psycho.explorer.Helper.tryPlayVideo; public class MainActivity extends Activity implements ClientInterface { @@ -80,7 +79,7 @@ private void initialize() { checkUnfinishedVideoTasks(this); checkUpdate(); - tryPlayVideo(this); + //tryPlayVideo(this); } diff --git a/app/src/main/java/euphoria/psycho/explorer/VideoListActivity.java b/app/src/main/java/euphoria/psycho/explorer/VideoListActivity.java index 695ce5d3..f21e0136 100644 --- a/app/src/main/java/euphoria/psycho/explorer/VideoListActivity.java +++ b/app/src/main/java/euphoria/psycho/explorer/VideoListActivity.java @@ -15,7 +15,7 @@ import java.util.List; import androidx.annotation.NonNull; -import euphoria.psycho.player.VideoActivity; +import euphoria.psycho.PlayerActivity; import euphoria.psycho.share.ContextShare; import euphoria.psycho.share.FileShare; import euphoria.psycho.share.IntentShare; @@ -88,9 +88,7 @@ private void initialize() { // mVideoAdapter.update(videos); ContextShare.initialize(this); mGridView.setOnItemClickListener((parent, view, position, id) -> { - IntentShare.launchActivity(VideoListActivity.this, - VideoActivity.class, - Uri.fromFile(mVideoAdapter.getItem(position))); + PlayerActivity.launchActivity(VideoListActivity.this,mVideoAdapter.getItem(position)); }); } diff --git a/app/src/main/java/euphoria/psycho/videos/Twitter.java b/app/src/main/java/euphoria/psycho/videos/Twitter.java index a496cd9b..ce07e00c 100644 --- a/app/src/main/java/euphoria/psycho/videos/Twitter.java +++ b/app/src/main/java/euphoria/psycho/videos/Twitter.java @@ -1,7 +1,6 @@ package euphoria.psycho.videos; import android.app.AlertDialog; -import android.net.Uri; import org.json.JSONArray; import org.json.JSONException; @@ -28,12 +27,11 @@ import java.util.zip.GZIPInputStream; import androidx.annotation.NonNull; +import euphoria.psycho.PlayerActivity; import euphoria.psycho.explorer.MainActivity; import euphoria.psycho.share.FileShare; import euphoria.psycho.videos.Twitter.TwitterVideo; -import static euphoria.psycho.videos.VideosHelper.invokeVideoPlayer; - public class Twitter extends BaseExtractor> { private static final Pattern MATCH_TWITTER = Pattern.compile("twitter\\.com/.+/status/(\\d+)"); @@ -142,7 +140,7 @@ protected void processVideo(List videoList) { } new AlertDialog.Builder(mMainActivity) .setItems(names, (dialog, which) -> { - invokeVideoPlayer(mMainActivity, Uri.parse(videoList.get(which).url)); + PlayerActivity.launchActivity(mMainActivity, videoList.get(which).url, false); }) .show(); } diff --git a/app/src/main/res/layout/activity_player.xml b/app/src/main/res/layout/activity_player.xml index 694808b6..9aade698 100644 --- a/app/src/main/res/layout/activity_player.xml +++ b/app/src/main/res/layout/activity_player.xml @@ -118,7 +118,7 @@ android:padding="@dimen/exo_styled_controls_padding">