Browse Source

fix: ci

master
高志龙 6 months ago
parent
commit
8e6bada617
  1. 31
      app/build.gradle
  2. 1
      app/src/main/AndroidManifest.xml
  3. 108
      app/src/main/java/qianmu/container/activity/program/MyPresentation.java
  4. 132
      app/src/main/java/qianmu/container/activity/program/ViewScreenSaver.java
  5. 316
      app/src/main/java/qianmu/container/view/CustomerVideoView.java
  6. 6
      playerview/build.gradle

31
app/build.gradle

@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
buildToolsVersion "35.0.1"
buildFeatures {
dataBinding = true
}
@ -12,10 +12,11 @@ android {
minSdkVersion 24
targetSdkVersion 30
versionCode 6
versionName "V2.0.8.5"
versionName "V2.0.8.6"
// 2.0.8.2
// 2.0.8.3 mac修改
// V2.0.8.5
// 2.0.8.6
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
@ -92,19 +93,19 @@ dependencies {
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation files('libs\\ymeeting.jar')//亿
implementation files('libs/ymeeting.jar')//亿
implementation project(path: ':playerview')
implementation files('libs\\zckjAPI-2.2.jar')//
implementation files('libs\\jna-min.jar')
implementation files('libs\\toolbox_kit.jar')//
implementation files('libs\\shockman.jar')//
implementation files('libs/zckjAPI-2.2.jar')//
implementation files('libs/jna-min.jar')
implementation files('libs/toolbox_kit.jar')//
implementation files('libs/shockman.jar')//
implementation files('libs/signway.jar') //
implementation files('libs\\sdkapi.jar') //Bv-3588
implementation files('libs\\smdt.jar') //
implementation files('libs\\DUI-lite-SDK-for-Android-3.5.0-466a4c77.jar') //
implementation files('libs/sdkapi.jar') //Bv-3588
implementation files('libs/smdt.jar') //
implementation files('libs/DUI-lite-SDK-for-Android-3.5.0-466a4c77.jar') //
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
@ -117,8 +118,8 @@ dependencies {
implementation 'jp.wasabeef:glide-transformations:3.0.1'
annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'
implementation 'org.java-websocket:Java-WebSocket:1.5.1'
implementation 'com.google.android.exoplayer:exoplayer:2.11.4'
//
implementation 'com.google.android.exoplayer:exoplayer:2.15.1'
implementation 'com.yanzhenjie.andserver:api:2.0.4'
annotationProcessor 'com.yanzhenjie.andserver:processor:2.0.4'
implementation files('libs/java-unrar-1.7.0-8.jar') // rar解压
@ -128,7 +129,7 @@ dependencies {
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.59'
implementation 'com.android.support:support-v4:30.4.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
//json动图
implementation 'com.airbnb.android:lottie:4.2.2'

1
app/src/main/AndroidManifest.xml

@ -57,6 +57,7 @@
android:largeHeap="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:hardwareAccelerated="true"
android:sharedUserId="android.uid.system"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">

108
app/src/main/java/qianmu/container/activity/program/MyPresentation.java

@ -36,6 +36,7 @@ import com.airbnb.lottie.LottieAnimationView;
import com.alibaba.android.arouter.launcher.ARouter;
import com.bumptech.glide.Glide;
import com.dl7.player.media.IjkPlayerView;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.loopj.android.http.AsyncHttpClient;
@ -2661,46 +2662,17 @@ class MyPresentation extends Presentation {
layoutVideo2.bringToFront();
handler.sendEmptyMessage(TYPE_UPDATE_VIDEO0);
videoImg2.setVisibility(View.VISIBLE);
videoView2.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
videoView2.setOnPreparedListener(new CustomerVideoView.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
videoView2.setBackgroundColor(Color.TRANSPARENT);
videoImg2.setVisibility(View.GONE);
return true;
}
});
//视频准备完毕,可以进行播放
Log.e("(双面屏)TAG","准备好视频,开始播放");
if( isvideoPlay0 ){
handler.removeMessages(TYPE_STOP_VIDEO_PLAY0);
if(components.getConfig().isPlayAudio()){
mp.setVolume(15f,15f);
}else {
mp.setVolume(0f,0f);
}
mp.start();
}else{
Log.e("(双面屏)TAG","预加载播放暂停");
mp.start();
mp.setVolume(0f,0f);
//暂停播放
handler.removeMessages(TYPE_STOP_VIDEO_PLAY0);
handler.sendEmptyMessageDelayed(TYPE_STOP_VIDEO_PLAY0,5000);
}
public void onPrepared() {
videoStartPlay(videoView2, videoImg2, videoComponents0);
}
});
//视频播放发送错误时回调
videoView2.setOnErrorListener(new MediaPlayer.OnErrorListener() {
videoView2.setOnErrorListener(new CustomerVideoView.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
public boolean onError() {
//视频播放失败
return true;
}
@ -2730,54 +2702,52 @@ class MyPresentation extends Presentation {
videoComponents1 = components;
handler.sendEmptyMessage(TYPE_UPDATE_VIDEO1);
videoView3.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
videoView3.setOnPreparedListener(new CustomerVideoView.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
videoView3.setBackgroundColor(Color.TRANSPARENT);
videoImg3.setVisibility(View.GONE);
return true;
}
});
//视频准备完毕,可以进行播放
Log.e("(双面屏)TAG","准备好视频,开始播放");
if( isvideoPlay1 ){
handler.removeMessages(TYPE_STOP_VIDEO_PLAY1);
if(components.getConfig().isPlayAudio()){
mp.setVolume(15f,15f);
}else {
mp.setVolume(0f,0f);
}
mp.start();
}else {
Log.e("(双面屏)TAG","预加载播放暂停");
mp.start();
mp.setVolume(0f,0f);
//暂停播放
handler.removeMessages(TYPE_STOP_VIDEO_PLAY1);
handler.sendEmptyMessageDelayed(TYPE_STOP_VIDEO_PLAY1,5000);
}
public void onPrepared() {
videoStartPlay(videoView3, videoImg3, videoComponents1);
}
});
//视频播放发送错误时回调
videoView3.setOnErrorListener(new MediaPlayer.OnErrorListener() {
videoView3.setOnErrorListener(new CustomerVideoView.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
public boolean onError() {
//视频播放失败
return true;
}
});
}
}
private void videoStartPlay(CustomerVideoView vView, ImageView imgView, NewProgramBean.components components){
vView.setOnInfoListener(() -> {
// if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
vView.setBackgroundColor(Color.TRANSPARENT);
imgView.setVisibility(View.GONE);
});
//视频准备完毕,可以进行播放
Log.e("(双面屏)TAG","准备好视频,开始播放");
if( isvideoPlay0 ){
handler.removeMessages(TYPE_STOP_VIDEO_PLAY0);
if(components.getConfig().isPlayAudio()){
vView.setVolume(15f);
}else {
vView.setVolume(0f);
}
vView.start();
}else{
Log.e("(双面屏)TAG","预加载播放暂停");
vView.start();
vView.setVolume(0f);
//暂停播放
handler.removeMessages(TYPE_STOP_VIDEO_PLAY0);
handler.sendEmptyMessageDelayed(TYPE_STOP_VIDEO_PLAY0,5000);
}
}
/**
* 更新video
* */

132
app/src/main/java/qianmu/container/activity/program/ViewScreenSaver.java

@ -543,7 +543,7 @@ public class ViewScreenSaver extends ViewBase<ViewScreenSaverBinding> {
}
if(!isNextVideo){
Log.e("TAG","预览设置下个视频");
Log.e("TAG: ","预览设置下个视频");
isNextVideo=true;
if(components.getMaterials().get(0).getDuration()>0){
binding.videoView0.setVideoPath(localPath);
@ -551,7 +551,6 @@ public class ViewScreenSaver extends ViewBase<ViewScreenSaverBinding> {
//图片
Drawable drawable = new BitmapDrawable(localPath);
binding.videoView0.setBackground(drawable);
}
}
}else {
@ -576,7 +575,7 @@ public class ViewScreenSaver extends ViewBase<ViewScreenSaverBinding> {
}
if(!isNextVideo){
Log.e("TAG","预览设置下个视频");
Log.e("TAG: ","预览设置下个视频");
isNextVideo=true;
if(components.getMaterials().get(0).getDuration()>0){
binding.videoView0.setVideoPath(localPath);
@ -2740,7 +2739,6 @@ public class ViewScreenSaver extends ViewBase<ViewScreenSaverBinding> {
if(components == null ||components.getMaterials()==null || components.getMaterials().size() <= 0){
return;
}
RelativeLayout.LayoutParams lParams = new RelativeLayout.LayoutParams(components.getWidth(), components.getHeight());
lParams.setMargins(components.getOffsetX(), components.getOffsetY(), 0, 0);
if(position==0){
@ -2755,54 +2753,22 @@ public class ViewScreenSaver extends ViewBase<ViewScreenSaverBinding> {
layoutParams.height = components.getHeight();
layoutParams.width = components.getWidth();
videoComponents0 = components;
binding.layoutVideo0.setVisibility(View.VISIBLE);
binding.layoutVideo0.bringToFront();
handler.sendEmptyMessage(TYPE_UPDATE_VIDEO0);
binding.videoImg0.setVisibility(View.VISIBLE);
binding.videoView0.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
binding.videoView0.setOnPreparedListener(new CustomerVideoView.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
binding.videoView0.setBackgroundColor(Color.TRANSPARENT);
binding.videoImg0.setVisibility(View.GONE);
return true;
}
});
//视频准备完毕,可以进行播放
Log.e("TAG","准备好视频,开始播放");
if( isvideoPlay0 ){
handler.removeMessages(TYPE_STOP_VIDEO_PLAY0);
if(components.getConfig().isPlayAudio()){
mp.setVolume(15f,15f);
}else {
mp.setVolume(0f,0f);
}
mp.start();
}else{
Log.e("TAG","预加载播放暂停");
mp.start();
mp.setVolume(0f,0f);
//暂停播放
handler.removeMessages(TYPE_STOP_VIDEO_PLAY0);
handler.sendEmptyMessageDelayed(TYPE_STOP_VIDEO_PLAY0,5000);
}
public void onPrepared() {
videoStartPlay(binding.videoView0, binding.videoImg0, videoComponents0, isvideoPlay0);
}
});
// 视频播放完成时的操作
binding.videoView0.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
binding.videoView0.setOnCompletionListener(new CustomerVideoView.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
public void onCompletion() {
if(!LocSocCliManager.getLocalSocketState()){
LoggerUtil.e("TAG:: ","socket未连接,播放下一个");
// 视频播放完成时的操作
handler.sendEmptyMessage(TYPE_UPDATE_VIDEO0);
}
@ -2810,9 +2776,9 @@ public class ViewScreenSaver extends ViewBase<ViewScreenSaverBinding> {
});
//视频播放发送错误时回调
binding.videoView0.setOnErrorListener(new MediaPlayer.OnErrorListener() {
binding.videoView0.setOnErrorListener(new CustomerVideoView.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
public boolean onError() {
//视频播放失败
return true;
}
@ -2830,7 +2796,6 @@ public class ViewScreenSaver extends ViewBase<ViewScreenSaverBinding> {
binding.videoView1.seekTo(0);
binding.videoView1.setZOrderOnTop(true);
binding.videoView1.setZOrderMediaOverlay(true);
binding.videoView1.setVisibility(View.VISIBLE);
binding.layoutVideo1.setVisibility(View.VISIBLE);
binding.layoutVideo1.bringToFront();
@ -2839,46 +2804,17 @@ public class ViewScreenSaver extends ViewBase<ViewScreenSaverBinding> {
videoComponents1 = components;
handler.sendEmptyMessage(TYPE_UPDATE_VIDEO1);
binding.videoView1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
binding.videoView1.setOnPreparedListener(new CustomerVideoView.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
binding.videoView1.setBackgroundColor(Color.TRANSPARENT);
binding.videoImg1.setVisibility(View.GONE);
return true;
}
});
//视频准备完毕,可以进行播放
Log.e("TAG","准备好视频,开始播放");
if( isvideoPlay1 ){
handler.removeMessages(TYPE_STOP_VIDEO_PLAY1);
if(components.getConfig().isPlayAudio()){
mp.setVolume(15f,15f);
}else {
mp.setVolume(0f,0f);
}
mp.start();
}else {
Log.e("TAG","预加载播放暂停");
mp.start();
mp.setVolume(0f,0f);
//暂停播放
handler.removeMessages(TYPE_STOP_VIDEO_PLAY1);
handler.sendEmptyMessageDelayed(TYPE_STOP_VIDEO_PLAY1,5000);
}
public void onPrepared() {
videoStartPlay(binding.videoView1, binding.videoImg1, videoComponents1,isvideoPlay1);
}
});
// 视频播放完成时的操作
binding.videoView1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
binding.videoView1.setOnCompletionListener(new CustomerVideoView.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
public void onCompletion() {
if(!LocSocCliManager.getLocalSocketState()){
// 视频播放完成时的操作
handler.sendEmptyMessage(TYPE_UPDATE_VIDEO1);
@ -2886,9 +2822,9 @@ public class ViewScreenSaver extends ViewBase<ViewScreenSaverBinding> {
}
});
//视频播放发送错误时回调
binding.videoView1.setOnErrorListener(new MediaPlayer.OnErrorListener() {
binding.videoView1.setOnErrorListener(new CustomerVideoView.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
public boolean onError() {
//视频播放失败
return true;
}
@ -2896,6 +2832,41 @@ public class ViewScreenSaver extends ViewBase<ViewScreenSaverBinding> {
}
}
private void videoStartPlay(CustomerVideoView vView, ImageView imgView, NewProgramBean.components components, Boolean isPlay){
vView.setOnInfoListener(new CustomerVideoView.OnInfoListener() {
@Override
public void onInfo() {
//vView.clearBackground();
imgView.setVisibility(View.GONE);
}
});
//视频准备完毕,可以进行播放
if( isPlay ){
handler.removeMessages(TYPE_STOP_VIDEO_PLAY0);
handler.removeMessages(TYPE_STOP_VIDEO_PLAY1);
if(components.getConfig().isPlayAudio()){
vView.setVolume(15f);
}else {
vView.setVolume(0f);
}
vView.start();
}else {
vView.start();
vView.setVolume(0f);
//暂停播放
if(vView == binding.videoView0){
handler.removeMessages(TYPE_STOP_VIDEO_PLAY0);
handler.sendEmptyMessageDelayed(TYPE_STOP_VIDEO_PLAY0,5000);
}else{
handler.removeMessages(TYPE_STOP_VIDEO_PLAY1);
handler.sendEmptyMessageDelayed(TYPE_STOP_VIDEO_PLAY1,5000);
}
}
}
/**
* 更新video
* */
@ -2929,7 +2900,6 @@ public class ViewScreenSaver extends ViewBase<ViewScreenSaverBinding> {
if(materials0.getDuration()>0){
//视频
videoView.setVideoPath(localPath);
}else {
//图片
if(TYPE_UPDATE_VIDE==TYPE_UPDATE_VIDEO0){

316
app/src/main/java/qianmu/container/view/CustomerVideoView.java

@ -1,35 +1,347 @@
package qianmu.container.view;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.VideoView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.StyledPlayerView;
/**
* Created by Android Studio.
* User: linzhibin
* Date: 2021/5/19
* Time: 13:59
*/
public class CustomerVideoView extends VideoView {
public class CustomerVideoView extends FrameLayout {
private StyledPlayerView playerView;
private ExoPlayer player;
private OnCompletionListener onCompletionListener;
private OnErrorListener onErrorListener;
private OnPreparedListener onPreparedListener;
private OnInfoListener onInfoListener;
// 监听器接口,保持与 VideoView 兼容
public interface OnCompletionListener {
void onCompletion();
}
public interface OnErrorListener {
boolean onError();
}
public interface OnPreparedListener {
void onPrepared();
}
public interface OnInfoListener {
void onInfo();
}
public CustomerVideoView(Context context) {
super(context);
init(context);
}
public CustomerVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CustomerVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
// 创建 StyledPlayerView
playerView = new StyledPlayerView(context);
addView(playerView);
// 初始化 ExoPlayer
initializePlayer();
// 设置背景透明
playerView.setBackgroundColor(Color.TRANSPARENT);
playerView.setShutterBackgroundColor(Color.TRANSPARENT);
// 3. 设置使用透明背景
playerView.setUseArtwork(false); // 如果不需要 artwork
playerView.setDefaultArtwork(null); // 清除默认 artwork
// 4. 设置 SurfaceView 透明
View videoSurfaceView = playerView.getVideoSurfaceView();
if (videoSurfaceView != null) {
videoSurfaceView.setBackgroundColor(Color.TRANSPARENT);
// 如果使用 SurfaceView,设置格式支持透明
if (videoSurfaceView instanceof SurfaceView) {
SurfaceView surfaceView = (SurfaceView) videoSurfaceView;
surfaceView.setZOrderOnTop(true); // 必须设置为 true 才能使透明生效
surfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
}else if (videoSurfaceView instanceof TextureView) {
// TextureView 默认支持透明
videoSurfaceView.setBackgroundColor(Color.TRANSPARENT);
}
}
}
private void initializePlayer() {
// 创建 ExoPlayer 实例
player = new SimpleExoPlayer.Builder(getContext())
.setTrackSelector(new DefaultTrackSelector(getContext()))
.build();
player.setPlayWhenReady(false);
// 设置播放器到 PlayerView
playerView.setPlayer(player);
setupPlayerListeners();
// 默认设置(可以根据需要调整)
playerView.setUseController(false);
// 默认设置 Surface 在底部
setZOrderOnTop(false);
setZOrderMediaOverlay(false);
}
private void setupPlayerListeners() {
if (player == null) return;
// 播放完成监听
player.addListener(new Player.Listener() {
@Override
public void onPlaybackStateChanged(int playbackState) {
if (playbackState == Player.STATE_ENDED) {
if (onCompletionListener != null) {
onCompletionListener.onCompletion();
}
}
if(playbackState == Player.STATE_READY){
// 视频准备就绪
if (onPreparedListener != null) {
onPreparedListener.onPrepared();
}
if (playerView != null) {
playerView.setVisibility(VISIBLE);
playerView.setAlpha(0);
}
}
}
@Override
public void onPlayerError(@NonNull PlaybackException error) {
if (onErrorListener != null) {
onErrorListener.onError();
}
}
@Override
public void onRenderedFirstFrame() {
// 视频开始渲染第一帧
if (onInfoListener != null) {
onInfoListener.onInfo();
onInfoListener=null;
}
if(playerView != null){
playerView.setAlpha(1);
}
}
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 其实就是在这里做了一些处理。
// 保持原有的测量逻辑
int width = getDefaultSize(0, widthMeasureSpec);
int height = getDefaultSize(0, heightMeasureSpec);
setMeasuredDimension(width, height);
// 让 StyledPlayerView 填满整个父布局
if (playerView != null) {
playerView.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
// 布局 StyledPlayerView 使其填满整个控件
if (playerView != null) {
playerView.layout(0, 0, getWidth(), getHeight());
}
}
// ==================== 实现 VideoView 的常用方法 ====================
// 1. setBackground - 设置背景
@Override
public void setBackground(Drawable background) {
super.setBackground(background);
// 如果需要设置 PlayerView 的背景
if (playerView != null) {
playerView.setVisibility(GONE);
}
}
public void clearBackground(){
super.setBackground(null);
}
@Override
public void setBackgroundColor(int color) {
super.setBackgroundColor(color);
}
@Override
public void setBackgroundResource(int resid) {
super.setBackgroundResource(resid);
if (playerView != null) {
playerView.setVisibility(GONE);
}
}
// 2. setZOrderOnTop - 设置 Surface 是否在最顶层
public void setZOrderOnTop(boolean onTop) {
if (playerView != null) {
// 获取 PlayerView 内部的 SurfaceView
View videoSurfaceView = playerView.getVideoSurfaceView();
if (videoSurfaceView instanceof SurfaceView) {
SurfaceView surfaceView = (SurfaceView) videoSurfaceView;
surfaceView.setZOrderOnTop(onTop);
}
}
}
// 3. setZOrderMediaOverlay - 设置 Surface 作为媒体叠加层
public void setZOrderMediaOverlay(boolean isMediaOverlay) {
if (playerView != null) {
View videoSurfaceView = playerView.getVideoSurfaceView();
if (videoSurfaceView instanceof SurfaceView) {
SurfaceView surfaceView = (SurfaceView) videoSurfaceView;
surfaceView.setZOrderMediaOverlay(isMediaOverlay);
}
}
}
// 4. setVisibility - 设置可见性
@Override
public void setVisibility(int visibility) {
super.setVisibility(visibility);
if (playerView != null) {
playerView.setVisibility(visibility);
}
}
// 5. 视频控制相关方法
public void setVideoPath(String path) {
if (player != null && path != null) {
MediaItem mediaItem = MediaItem.fromUri(path);
player.setMediaItem(mediaItem);
player.prepare();
}
}
public void start() {
if (player != null) {
player.play();
}
}
public void pause() {
if (player != null) {
player.pause();
}
}
public void stopPlayback() {
if (player != null) {
player.stop();
}
}
public void seekTo(int position) {
if (player != null) {
player.seekTo(position);
}
}
public boolean isPlaying() {
return player != null && player.isPlaying();
}
// 6. 监听器设置
public void setOnCompletionListener(OnCompletionListener listener) {
this.onCompletionListener = listener;
}
public void setOnPreparedListener(OnPreparedListener listener) {
this.onPreparedListener = listener;
}
public void setOnInfoListener(OnInfoListener listener) {
this.onInfoListener = listener;
}
public void setOnErrorListener(OnErrorListener listener) {
this.onErrorListener = listener;
}
// 可选:添加与 ExoPlayer 兼容的错误监听器
public void setOnExoPlayerErrorListener(Player.Listener errorListener) {
if (player != null && errorListener != null) {
player.addListener(errorListener);
}
}
public void release() {
if (player != null) {
player.release();
player = null;
}
if (playerView != null) {
playerView.setPlayer(null);
}
onCompletionListener = null;
onErrorListener = null;
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
release();
}
// 重置播放器
public void reset() {
if (player != null) {
player.stop();
player.clearMediaItems();
}
}
// 设置音量
public void setVolume(float volume) {
if (player != null) {
player.setVolume(volume);
}
}
}

6
playerview/build.gradle

@ -3,12 +3,12 @@ apply plugin: 'com.github.dcendents.android-maven'
group='com.github.Rukey7'
android {
compileSdkVersion 30
compileSdkVersion 34
buildToolsVersion "30.0.3"
defaultConfig {
minSdkVersion 22
targetSdkVersion 24
targetSdkVersion 34
versionCode 4
versionName "1.0.3"
@ -29,7 +29,7 @@ dependencies {
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'com.android.support:appcompat-v7:24.2.1'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

Loading…
Cancel
Save