version:
update:更改app名称,视频播放完成自动播放下一个,所有播放结束退出播放界面,增加全屏退出时根据方向旋转屏幕。 fix bug:
This commit is contained in:
@@ -18,11 +18,40 @@ android {
|
||||
// add support lib
|
||||
abiFilters 'armeabi-v7a' //, 'arm64-v8a'//, "mips" //,'armeabi''x86',, 'x86_64',
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
//签名
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file("src/doc/xueshibaoos.jks")
|
||||
storePassword "123456"
|
||||
keyAlias "xueshibaoos"
|
||||
keyPassword "123456"
|
||||
v2SigningEnabled false
|
||||
}
|
||||
release {// 签名文件
|
||||
storeFile file("src/doc/xueshibaoos.jks")
|
||||
storePassword "123456"
|
||||
keyAlias "xueshibaoos"
|
||||
keyPassword "123456"
|
||||
v2SigningEnabled false
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
zipAlignEnabled true
|
||||
signingConfig signingConfigs.release
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
debug {
|
||||
minifyEnabled false
|
||||
zipAlignEnabled false
|
||||
signingConfig signingConfigs.release
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
BIN
app/src/doc/xueshibaoos.jks
Normal file
BIN
app/src/doc/xueshibaoos.jks
Normal file
Binary file not shown.
@@ -2,11 +2,16 @@ package com.uiui.videoplayer.CustomJzvd;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import cn.jzvd.JzvdStd;
|
||||
|
||||
|
||||
public class JzvdStdAssert extends JzvdStd {
|
||||
private onVideoCompletionListener onVideoCompletionListener;
|
||||
private ScreenOrientationChangeListener changeListener;
|
||||
private GotoFullScreenListener gotoFullScreenListener;
|
||||
|
||||
public JzvdStdAssert(Context context) {
|
||||
super(context);
|
||||
}
|
||||
@@ -18,6 +23,7 @@ public class JzvdStdAssert extends JzvdStd {
|
||||
|
||||
@Override
|
||||
public void onPrepared() {
|
||||
Log.e("onStateChanged", "onPrepared");
|
||||
state = STATE_PREPARED;
|
||||
if (!preloading) {
|
||||
mediaInterface.start();
|
||||
@@ -26,9 +32,51 @@ public class JzvdStdAssert extends JzvdStd {
|
||||
onStatePlaying();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCompletion() {
|
||||
super.onCompletion();
|
||||
onVideoCompletionListener.onVideoComplet();
|
||||
Log.e("onStateChanged", "onCompletion");
|
||||
}
|
||||
|
||||
public void setOnCompletionListener(onVideoCompletionListener listener) {
|
||||
this.onVideoCompletionListener = listener;
|
||||
}
|
||||
|
||||
public void setScreenOrientationChangeListener(ScreenOrientationChangeListener listener) {
|
||||
this.changeListener = listener;
|
||||
}
|
||||
|
||||
public void setGotoFullScreenListener(GotoFullScreenListener listener) {
|
||||
this.gotoFullScreenListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gotoNormalScreen() {
|
||||
super.gotoNormalScreen();
|
||||
changeListener.onOrientationChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gotoFullscreen() {
|
||||
super.gotoFullscreen();
|
||||
|
||||
gotoFullScreenListener.onGotoFullScreen();
|
||||
}
|
||||
|
||||
//视频播放完成回调
|
||||
public interface onVideoCompletionListener {
|
||||
void onVideoComplet();
|
||||
}
|
||||
|
||||
//退出全屏回调
|
||||
public interface ScreenOrientationChangeListener {
|
||||
void onOrientationChange();
|
||||
}
|
||||
|
||||
//进入全屏回调
|
||||
public interface GotoFullScreenListener {
|
||||
void onGotoFullScreen();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,22 +13,20 @@ 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;
|
||||
|
||||
import com.uiui.videoplayer.CustomJzvd.JzvdStdAssert;
|
||||
import com.uiui.videoplayer.CustomJzvd.JzvdStdTikTok;
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.uiui.videoplayer.adapter.TikTokRecyclerViewAdapter;
|
||||
import com.uiui.videoplayer.base.ViewPagerLayoutManager;
|
||||
import com.uiui.videoplayer.listener.OnViewPagerListener;
|
||||
import com.uiui.videoplayer.utils.ToastUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.jzvd.Jzvd;
|
||||
import cn.jzvd.JzvdStd;
|
||||
|
||||
public class ActivityTikTok extends AppCompatActivity {
|
||||
|
||||
@@ -40,6 +38,7 @@ public class ActivityTikTok extends AppCompatActivity {
|
||||
private int position = 0;
|
||||
private List<String> videoPath = new ArrayList<>();
|
||||
private int onGlobalLayout = -1;
|
||||
private int oldOrientation = 0;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -49,15 +48,40 @@ public class ActivityTikTok extends AppCompatActivity {
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
|
||||
setContentView(R.layout.activity_tiktok);
|
||||
Configuration config = getResources().getConfiguration();
|
||||
oldOrientation = config.orientation;
|
||||
Log.e(TAG, "orientation first:" + oldOrientation);
|
||||
|
||||
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.setVideoCompletListener(() -> {
|
||||
if (mCurrentPosition + 1 < videoPath.size()) {
|
||||
rvTiktok.smoothScrollToPosition(mCurrentPosition + 1);
|
||||
} else {
|
||||
ToastUtil.show("播放完成");
|
||||
finish();
|
||||
}
|
||||
});
|
||||
mAdapter.setOrientationChangeListener(new TikTokRecyclerViewAdapter.onOrientationChangeListener() {
|
||||
@Override
|
||||
public void onOrientationChange() {
|
||||
Configuration config = getResources().getConfiguration();
|
||||
Log.e(TAG, "orientation onOrientationChange:" + config.orientation);
|
||||
}
|
||||
});
|
||||
mAdapter.setGotoFullScreenListener(new TikTokRecyclerViewAdapter.onGotoFullScreenListener() {
|
||||
@Override
|
||||
public void gotoFullScreen() {
|
||||
Configuration config = getResources().getConfiguration();
|
||||
oldOrientation = config.orientation;
|
||||
Log.e(TAG, "orientation gotoFullScreen:" + config.orientation);
|
||||
}
|
||||
});
|
||||
mViewPagerLayoutManager = new ViewPagerLayoutManager(this, OrientationHelper.VERTICAL);
|
||||
rvTiktok.setLayoutManager(mViewPagerLayoutManager);
|
||||
rvTiktok.setNestedScrollingEnabled(false);
|
||||
@@ -76,8 +100,7 @@ public class ActivityTikTok extends AppCompatActivity {
|
||||
@Override
|
||||
public void onInitComplete() {
|
||||
//自动播放第一条
|
||||
Log.e(TAG, "autoPlayVideo: " + "onInitComplete");
|
||||
autoPlayVideo(position);
|
||||
autoPlayVideo();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,8 +115,7 @@ public class ActivityTikTok extends AppCompatActivity {
|
||||
if (mCurrentPosition == position) {
|
||||
return;
|
||||
}
|
||||
Log.e(TAG, "autoPlayVideo: " + "onPageSelected");
|
||||
autoPlayVideo(position);
|
||||
autoPlayVideo();
|
||||
mCurrentPosition = position;
|
||||
}
|
||||
});
|
||||
@@ -121,6 +143,19 @@ public class ActivityTikTok extends AppCompatActivity {
|
||||
public void onConfigurationChanged(@NonNull Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
Configuration config = getResources().getConfiguration();
|
||||
if (oldOrientation != config.orientation) {
|
||||
if (oldOrientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
// 设为竖屏
|
||||
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
oldOrientation = Configuration.ORIENTATION_LANDSCAPE;
|
||||
}
|
||||
// 如果当前是竖屏
|
||||
if (oldOrientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
// 设为横屏
|
||||
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||
oldOrientation = Configuration.ORIENTATION_PORTRAIT;
|
||||
}
|
||||
}
|
||||
// 如果当前是横屏
|
||||
// if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
// // 设为竖屏
|
||||
@@ -133,37 +168,15 @@ public class ActivityTikTok extends AppCompatActivity {
|
||||
// this.setRequestedOrientation(
|
||||
// ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||
// }
|
||||
Log.e(TAG, "orientation oldOrientation:" + config.orientation);
|
||||
|
||||
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) {
|
||||
private void autoPlayVideo() {
|
||||
// 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);
|
||||
|
||||
@@ -2,27 +2,43 @@ package com.uiui.videoplayer.adapter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.uiui.videoplayer.CustomJzvd.JzvdStdAssert;
|
||||
import com.uiui.videoplayer.R;
|
||||
import com.uiui.videoplayer.utils.Utils;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cn.jzvd.JZDataSource;
|
||||
import cn.jzvd.Jzvd;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.ObservableEmitter;
|
||||
import io.reactivex.ObservableOnSubscribe;
|
||||
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 TikTokRecyclerViewAdapter extends RecyclerView.Adapter<TikTokRecyclerViewAdapter.MyViewHolder> {
|
||||
|
||||
public static final String TAG = "AdapterTikTokRecyclerView";
|
||||
private List<String> videoPath;
|
||||
private Context context;
|
||||
private onVideoCompletListener completListener;
|
||||
private onOrientationChangeListener onOrientationChangeListener;
|
||||
private onGotoFullScreenListener gotoFullScreenListener;
|
||||
|
||||
public TikTokRecyclerViewAdapter(Context context) {
|
||||
this.context = context;
|
||||
@@ -33,6 +49,29 @@ public class TikTokRecyclerViewAdapter extends RecyclerView.Adapter<TikTokRecycl
|
||||
this.videoPath = list;
|
||||
}
|
||||
|
||||
public void setVideoCompletListener(onVideoCompletListener listener) {
|
||||
this.completListener = listener;
|
||||
}
|
||||
|
||||
public interface onVideoCompletListener {
|
||||
void onVideoComplet();
|
||||
}
|
||||
|
||||
public void setOrientationChangeListener(onOrientationChangeListener listener) {
|
||||
this.onOrientationChangeListener = listener;
|
||||
}
|
||||
|
||||
public void setGotoFullScreenListener(onGotoFullScreenListener listener) {
|
||||
this.gotoFullScreenListener = listener;
|
||||
}
|
||||
|
||||
public interface onOrientationChangeListener {
|
||||
void onOrientationChange();
|
||||
}
|
||||
public interface onGotoFullScreenListener {
|
||||
void gotoFullScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
|
||||
@@ -47,9 +86,58 @@ public class TikTokRecyclerViewAdapter extends RecyclerView.Adapter<TikTokRecycl
|
||||
Log.i(TAG, "onBindViewHolder [" + holder.jzvdStdAssert.hashCode() + "] position=" + position);
|
||||
final String path = videoPath.get(position);
|
||||
JZDataSource jzDataSource = new JZDataSource(path, getFileName(path));
|
||||
jzDataSource.looping = true;
|
||||
jzDataSource.looping = false;
|
||||
holder.jzvdStdAssert.setUp(jzDataSource, Jzvd.SCREEN_NORMAL);
|
||||
// Glide.with(holder.jzvdStd.getContext()).load(UrlsKt.getPl3()[position]).into(holder.jzvdStd.posterImageView);
|
||||
Observable.create((ObservableOnSubscribe<Bitmap>) emitter -> {
|
||||
FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
|
||||
mmr.setDataSource(path);
|
||||
Bitmap bitmap = mmr.getFrameAtTime();//获得视频第一帧的Bitmap对象.
|
||||
mmr.release();
|
||||
emitter.onNext(bitmap);
|
||||
}).subscribeOn(Schedulers.newThread())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Bitmap>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(Bitmap bitmap) {
|
||||
try {
|
||||
holder.jzvdStdAssert.posterImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||
Glide.with(holder.jzvdStdAssert.posterImageView).load(bitmap).into(holder.jzvdStdAssert.posterImageView);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
|
||||
}
|
||||
});
|
||||
holder.jzvdStdAssert.setOnCompletionListener(() -> {
|
||||
completListener.onVideoComplet();
|
||||
});
|
||||
holder.jzvdStdAssert.setScreenOrientationChangeListener(new JzvdStdAssert.ScreenOrientationChangeListener() {
|
||||
@Override
|
||||
public void onOrientationChange() {
|
||||
onOrientationChangeListener.onOrientationChange();
|
||||
}
|
||||
});
|
||||
holder.jzvdStdAssert.setGotoFullScreenListener(new JzvdStdAssert.GotoFullScreenListener() {
|
||||
@Override
|
||||
public void onGotoFullScreen() {
|
||||
gotoFullScreenListener.gotoFullScreen();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">视频播放器</string>
|
||||
<string name="app_name">快易播放器</string>
|
||||
</resources>
|
||||
|
||||
@@ -11,7 +11,7 @@ public class JZDataSource {
|
||||
public LinkedHashMap urlsMap = new LinkedHashMap();
|
||||
public String title = "";
|
||||
public HashMap<String, String> headerMap = new HashMap<>();
|
||||
public boolean looping = false;
|
||||
public boolean looping = false;//循环播放
|
||||
public Object[] objects;
|
||||
|
||||
public JZDataSource(String url) {
|
||||
|
||||
@@ -60,6 +60,7 @@ public abstract class Jzvd extends FrameLayout implements View.OnClickListener,
|
||||
public static boolean TOOL_BAR_EXIST = true;
|
||||
public static int FULLSCREEN_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
|
||||
public static int NORMAL_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||
public static int NORMAL_SENSOR= ActivityInfo.SCREEN_ORIENTATION_SENSOR;
|
||||
public static boolean SAVE_PROGRESS = true;
|
||||
public static boolean WIFI_TIP_DIALOG_SHOWED = false;
|
||||
public static int VIDEO_IMAGE_DISPLAY_TYPE = 0;
|
||||
@@ -1013,7 +1014,7 @@ public abstract class Jzvd extends FrameLayout implements View.OnClickListener,
|
||||
|
||||
setScreenNormal();//这块可以放到jzvd中
|
||||
JZUtils.showStatusBar(jzvdContext);
|
||||
JZUtils.setRequestedOrientation(jzvdContext, NORMAL_ORIENTATION);
|
||||
JZUtils.setRequestedOrientation(jzvdContext, NORMAL_SENSOR);
|
||||
JZUtils.showSystemUI(jzvdContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
rootProject.name='视频播放器'
|
||||
rootProject.name='快易播放器'
|
||||
include ':app', ':library'
|
||||
|
||||
Reference in New Issue
Block a user