横屏适配,跳转到指定地方进行播放

This commit is contained in:
2021-02-27 18:12:58 +08:00
parent a35d7977d5
commit 67727032eb
13 changed files with 245 additions and 28 deletions

View File

@@ -49,7 +49,7 @@ dependencies {
implementation 'io.reactivex.rxjava2:rxjava:2.1.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'cn.jzvd:jiaozivideoplayer:7.6.0'
// implementation 'cn.jzvd:jiaozivideoplayer:7.6.0'
implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-core:1.0.15'
implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-native:1.0.15'
implementation 'com.github.ittianyu:BottomNavigationViewEx:2.0.4'
@@ -64,4 +64,5 @@ dependencies {
implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3'
implementation project(path: ':library')
}

View File

@@ -13,7 +13,10 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".activity.PlayActivity"></activity>
<activity
android:name=".activity.PlayActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:screenOrientation="sensor" />
<activity android:name=".activity.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -21,9 +24,10 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".activity.ActivityTikTok"
<activity
android:name=".activity.ActivityTikTok"
android:configChanges="orientation|screenSize|keyboardHidden"
android:screenOrientation="portrait"
android:screenOrientation="sensor"
android:theme="@style/Theme.AppCompat.NoActionBar" />
</application>

View File

@@ -5,6 +5,7 @@ import android.util.AttributeSet;
import cn.jzvd.JzvdStd;
public class JzvdStdAssert extends JzvdStd {
public JzvdStdAssert(Context context) {
super(context);
@@ -24,4 +25,10 @@ public class JzvdStdAssert extends JzvdStd {
}
onStatePlaying();
}
@Override
public void gotoFullscreen() {
super.gotoFullscreen();
}
}

View File

@@ -1,14 +1,19 @@
package com.uiui.videoplayer.activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.OrientationHelper;
import androidx.recyclerview.widget.RecyclerView;
@@ -23,15 +28,18 @@ import java.util.ArrayList;
import java.util.List;
import cn.jzvd.Jzvd;
import cn.jzvd.JzvdStd;
public class ActivityTikTok extends AppCompatActivity {
private static final String TAG = "ActivityTikTok";
private RecyclerView rvTiktok;
private TikTokRecyclerViewAdapter mAdapter;
private ViewPagerLayoutManager mViewPagerLayoutManager;
private int mCurrentPosition = -1;
private int position = 0;
private List<String> videoPath = new ArrayList<>();
private int onGlobalLayout = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -44,24 +52,31 @@ public class ActivityTikTok extends AppCompatActivity {
Intent intent = getIntent();
if (null != intent) {
position = intent.getIntExtra("position", 0);
Log.e(TAG, "position: " + position);
videoPath = intent.getStringArrayListExtra("list");
}
rvTiktok = findViewById(R.id.rv_tiktok);
mAdapter = new TikTokRecyclerViewAdapter(this,videoPath );
mAdapter = new TikTokRecyclerViewAdapter(this, videoPath);
mViewPagerLayoutManager = new ViewPagerLayoutManager(this, OrientationHelper.VERTICAL);
rvTiktok.setLayoutManager(mViewPagerLayoutManager);
rvTiktok.setNestedScrollingEnabled(false);
rvTiktok.setAdapter(mAdapter);
rvTiktok.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (onGlobalLayout == -1) {
rvTiktok.scrollToPosition(position);
mCurrentPosition = position;
onGlobalLayout = 0;//只在第一次进行跳转
}
}
});
mViewPagerLayoutManager.setOnViewPagerListener(new OnViewPagerListener() {
@Override
public void onInitComplete() {
//自动播放第一条
Log.e(TAG, "autoPlayVideo: " + "onInitComplete");
autoPlayVideo(position);
}
@@ -77,6 +92,7 @@ public class ActivityTikTok extends AppCompatActivity {
if (mCurrentPosition == position) {
return;
}
Log.e(TAG, "autoPlayVideo: " + "onPageSelected");
autoPlayVideo(position);
mCurrentPosition = position;
}
@@ -101,8 +117,53 @@ public class ActivityTikTok extends AppCompatActivity {
});
}
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Configuration config = getResources().getConfiguration();
// 如果当前是横屏
// if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
// // 设为竖屏
// this.setRequestedOrientation(
// ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// }
// // 如果当前是竖屏
// if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
// // 设为横屏
// this.setRequestedOrientation(
// ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// }
Log.e(TAG, "orientation: " + config.orientation);
}
/**
* RecyclerView 移动到当前位置,
*
* @param manager 设置RecyclerView对应的manager
* @param mRecyclerView 当前的RecyclerView
* @param n 要跳转的位置
*/
public static void MoveToPosition(LinearLayoutManager manager, RecyclerView mRecyclerView, int n) {
int firstItem = manager.findFirstVisibleItemPosition();
int lastItem = manager.findLastVisibleItemPosition();
if (n <= firstItem) {
mRecyclerView.scrollToPosition(n);
} else if (n <= lastItem) {
int top = mRecyclerView.getChildAt(n - firstItem).getTop();
mRecyclerView.scrollBy(0, top);
} else {
mRecyclerView.scrollToPosition(n);
}
}
private void autoPlayVideo(int postion) {
if (rvTiktok == null || rvTiktok.getChildAt(0) == null) {
// mViewPagerLayoutManager.scrollToPositionWithOffset(postion, 0);
View child = rvTiktok.getChildAt(0);
if (rvTiktok == null || child == null) {
Log.e(TAG, "autoPlayVideo: " + "view is null");
return;
}
JzvdStdAssert player = rvTiktok.getChildAt(0).findViewById(R.id.videoplayer);
@@ -134,4 +195,15 @@ public class ActivityTikTok extends AppCompatActivity {
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (null != rvTiktok) {
rvTiktok = null;
}
if (null != mAdapter) {
mAdapter = null;
}
}
}

View File

@@ -8,7 +8,9 @@ import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;
import android.Manifest;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
@@ -45,8 +47,39 @@ public class MainActivity extends AppCompatActivity {
scanTask.execute();
}
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Configuration config = getResources().getConfiguration();
// 如果当前是横屏
if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
// 设为竖屏
mManager = new RecycleGridLayoutManager(MainActivity.this, 2);
recyclerView.setLayoutManager(mManager);
// MainActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
// 如果当前是竖屏
if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
// 设为横屏
mManager = new RecycleGridLayoutManager(MainActivity.this, 3);
recyclerView.setLayoutManager(mManager);
// MainActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
private void initView() {
recyclerView = findViewById(R.id.recyclerView);
int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
mManager = new RecycleGridLayoutManager(MainActivity.this, 3);
} else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
mManager = new RecycleGridLayoutManager(MainActivity.this, 2);
}
recyclerView.setLayoutManager(mManager);
recyclerView.setNestedScrollingEnabled(false);
recyclerView.addItemDecoration(new SpacesItemDecoration(getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x),
getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x)));
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
}
// private String[] getFolder(String folderPath) {
@@ -90,7 +123,7 @@ public class MainActivity extends AppCompatActivity {
}
private static final String[] extension = new String[]{
".3gp", ".flv", ".mkv", ".mov", ".mp4", ".webm"
".3gp", ".avi", ".flv", ".mkv", ".mov", ".mp4", ".webm"
};
private static boolean isVideoFormat(String filePath) {
@@ -154,12 +187,6 @@ public class MainActivity extends AppCompatActivity {
super.onPostExecute(strings);
Log.e("ScanTask", "onPostExecute: " + strings);
adapter = new VideoAdapter(MainActivity.this, strings);
mManager = new RecycleGridLayoutManager(MainActivity.this, 2);
recyclerView.setLayoutManager(mManager);
recyclerView.setNestedScrollingEnabled(false);
recyclerView.addItemDecoration(new SpacesItemDecoration(getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x),
getResources().getDimensionPixelSize(R.dimen.PX1x), getResources().getDimensionPixelSize(R.dimen.PX1x)));
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
// recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
recyclerView.setAdapter(adapter);
}

View File

@@ -1,11 +1,14 @@
package com.uiui.videoplayer.adapter;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.Image;
import android.media.MediaMetadataRetriever;
import android.os.AsyncTask;
import android.os.Build;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -21,9 +24,12 @@ import com.bumptech.glide.Glide;
import com.uiui.videoplayer.R;
import com.uiui.videoplayer.activity.ActivityTikTok;
import com.uiui.videoplayer.utils.ToastUtil;
import com.uiui.videoplayer.utils.Utils;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import io.reactivex.Observable;
@@ -33,6 +39,7 @@ import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import wseemann.media.FFmpegMediaMetadataRetriever;
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoHolder> {
private Context mContext;
@@ -52,6 +59,11 @@ public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoHolder>
this.videoPath = path;
}
private static class VideoResult {
long time;
Bitmap frame;
}
@NonNull
@Override
public VideoHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@@ -70,27 +82,37 @@ public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoHolder>
// Glide.with(holder.video_image).load(bitmap).into(holder.video_image);
// }
// };
Observable.create(new ObservableOnSubscribe<Bitmap>() {
Observable.create(new ObservableOnSubscribe<VideoResult>() {
@Override
public void subscribe(ObservableEmitter<Bitmap> emitter) throws Exception {
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
public void subscribe(ObservableEmitter<VideoResult> emitter) throws Exception {
FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
mmr.setDataSource(path);
String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
String duration = mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION);
Bitmap bitmap = mmr.getFrameAtTime();//获得视频第一帧的Bitmap对象.
Long time = Long.valueOf(duration);
Bitmap bitmap = mmr.getFrameAtTime();//获得视频第一帧的Bitmap对象
emitter.onNext(bitmap);
mmr.release();
VideoResult result = new VideoResult();
result.frame = bitmap;
result.time = time;
emitter.onNext(result);
}
}).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Bitmap>() {
.subscribe(new Observer<VideoResult>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Bitmap bitmap) {
Glide.with(holder.video_image).load(bitmap).into(holder.video_image);
public void onNext(VideoResult result) {
try {
Glide.with(holder.video_image).load(result.frame).into(holder.video_image);
holder.duration.setText(Utils.TimeFormat(result.time));
} catch (Exception e) {
}
}
@Override
@@ -106,6 +128,7 @@ public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoHolder>
// this.listener = bitmapRetultListener;
holder.title.setText(getFileName(path));
Log.e("title:", holder.title.getText().toString());
}
holder.root.setOnClickListener(new View.OnClickListener() {
@Override
@@ -125,18 +148,35 @@ public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoHolder>
}
private String getFileName(String path) {
return path.substring(path.lastIndexOf("/") + 1);
String name = path.substring(path.lastIndexOf("/") + 1);
Log.e("getFileName", "Name: " + name);
return name;
}
/**
* 判断Activity是否Destroy
*
* @param mActivity
* @return
*/
public static boolean isDestroy(Activity mActivity) {
if (mActivity == null || mActivity.isFinishing() || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && mActivity.isDestroyed())) {
return true;
} else {
return false;
}
}
static class VideoHolder extends RecyclerView.ViewHolder {
ImageView video_image;
TextView title;
TextView title, duration;
ConstraintLayout root;
public VideoHolder(@NonNull View itemView) {
super(itemView);
video_image = itemView.findViewById(R.id.video_image);
title = itemView.findViewById(R.id.title_text);
duration = itemView.findViewById(R.id.duration);
root = itemView.findViewById(R.id.root);
}

View File

@@ -0,0 +1,22 @@
package com.uiui.videoplayer.utils;
public class Utils {
public static String TimeFormat(long millisecond) {
int ss = 1000;
int mi = ss * 60;
int hh = mi * 60;
long hour = (millisecond) / hh;
long minute = (millisecond - hour * hh) / mi;
long second = (millisecond - hour * hh - minute * mi) / ss;
String strHour = hour < 10 ? "0" + hour : "" + hour;
String strMinute = minute < 10 ? "0" + minute : "" + minute;
String strSecond = second < 10 ? "0" + second : "" + second;
if (hour > 0) {
return strHour + ":" + strMinute + ":" + strSecond;
} else {
return strMinute + ":" + strSecond;
}
}
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#333333"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_tiktok"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" />
</RelativeLayout>

View File

@@ -12,18 +12,32 @@
android:layout_height="162dp"
android:layout_marginTop="4dp"
android:adjustViewBounds="true"
android:background="@color/black"
android:scaleType="fitCenter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:maxLines="1"
android:singleLine="true"
android:text="00:00"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="@+id/video_image"
app:layout_constraintEnd_toEndOf="@+id/video_image" />
<TextView
android:id="@+id/title_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:maxLines="2"
android:text="dsadasdadasdasdasddsadsadasdassdsad"
android:text=""
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="@+id/video_image"
app:layout_constraintStart_toStartOf="@+id/video_image"

View File

@@ -1,2 +1,2 @@
rootProject.name='视频播放器'
include ':app'
include ':app', ':library'