fix [修复-修改视频框架]

This commit is contained in:
hch 2024-04-01 18:20:10 +08:00
parent 962a07d6d1
commit 97c692d41d
15 changed files with 316 additions and 169 deletions

View File

@ -242,4 +242,8 @@ dependencies {
api 'com.github.xuexiangjys:XUI:1.1.6' api 'com.github.xuexiangjys:XUI:1.1.6'
api 'com.github.xuexiangjys.XUtil:xutil-core:2.0.0' api 'com.github.xuexiangjys.XUtil:xutil-core:2.0.0'
//ExoPlayer,
api 'com.google.android.exoplayer:exoplayer:2.18.2'
api 'com.google.android.exoplayer:exoplayer-core:2.18.2@aar'
} }

View File

@ -59,12 +59,12 @@ public class RouteUtil {
public static final String PATH_VIDEO_NEW_PLAY = "/video/VideoPlayNewActivity"; public static final String PATH_VIDEO_NEW_PLAY = "/video/VideoPlayNewActivity";
/* public static void forwardVideoPlayActivity(ActiveBean bean) { public static void forwardVideoPlayNewActivity(ActiveBean bean) {
ARouter.getInstance().build(PATH_VIDEO_PLAY) ARouter.getInstance().build(PATH_VIDEO_NEW_PLAY)
.withParcelable("ActiveBean", bean) .withParcelable("ActiveBean", bean)
.withString(Constants.VIDEO_KEY, Constants.VIDEO_SINGLE) .withString(Constants.VIDEO_KEY, Constants.VIDEO_SINGLE)
.navigation(); .navigation();
}*/ }
public static void forwardUserHome(String uid) { public static void forwardUserHome(String uid) {
ARouter.getInstance().build(PATH_USER_HOME) ARouter.getInstance().build(PATH_USER_HOME)

View File

@ -24,6 +24,7 @@
android:id="@+id/avatar" android:id="@+id/avatar"
android:layout_width="50dp" android:layout_width="50dp"
android:layout_height="50dp" android:layout_height="50dp"
android:scaleType="centerCrop"
android:src="@mipmap/icon_data_empty" android:src="@mipmap/icon_data_empty"
app:riv_oval="true" /> app:riv_oval="true" />

View File

@ -1 +1 @@
apply plugin: 'com.android.library' apply plugin: 'img-optimizer' apply plugin: 'kotlin-android' android { namespace "com.yunbao.live" compileSdk rootProject.ext.android.compileSdkVersion aaptOptions.cruncherEnabled = false aaptOptions.useNewCruncher = false packagingOptions { pickFirst "lib/armeabi/libyuvutils.so" pickFirst "lib/arm64-v8a/libyuvutils.so" pickFirst "lib/armeabi-v7a/libyuvutils.so" pickFirst "lib/armeabi/libyuvtools.so" pickFirst "lib/arm64-v8a/libyuvtools.so" pickFirst "lib/armeabi-v7a/libyuvtools.so" exclude "lib/arm64-v8a/libmmcv_api_handgesture.so" exclude "lib/arm64-v8a/libmmcv_api_express.so" exclude "lib/arm64-v8a/libMediaEncoder.so" exclude "lib/arm64-v8a/libarcore_sdk_c.so" exclude "lib/arm64-v8a/libmediadecoder.so" exclude "lib/arm64-v8a/libMediaMuxer.so" exclude "lib/arm64-v8a/libarcore_sdk_jni.so" exclude "lib/arm64-v8a/libMediaUtils.so" exclude "lib/arm64-v8a/libcosmosffmpeg.so" } defaultConfig { minSdkVersion rootProject.ext.android.minSdkVersion targetSdkVersion rootProject.ext.android.targetSdkVersion versionCode rootProject.ext.android.versionCode versionName rootProject.ext.android.versionName manifestPlaceholders = rootProject.ext.manifestPlaceholders ndk { abiFilters "armeabi-v7a", "arm64-v8a" } javaCompileOptions { annotationProcessorOptions { arguments = [AROUTER_MODULE_NAME: project.getName()] } } } aaptOptions { cruncherEnabled = false useNewCruncher = false } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } kotlinOptions { allWarningsAsErrors = true } compileOptions { sourceCompatibility JavaVersion.VERSION_18 targetCompatibility JavaVersion.VERSION_18 } } repositories { flatDir { dirs 'libs', '../libs' } mavenCentral() } dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.0' implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) implementation (name:'../libs/beautysdk-202202241203',ext:'aar') implementation (name:'../libs/svgaplayer-release-v1.2.1',ext:'aar') //socket.io implementation('io.socket:socket.io-client:1.0.0') { exclude group: 'org.json', module: 'json' } //common api project(path: ':common') api project(path:':FaceUnity')//新娱美颜 api project(':Share')//分享 annotationProcessor rootProject.ext.dependencies["arouter-compiler"] //工具 api rootProject.ext.dependencies["blank-utilcode"] implementation 'com.eightbitlab:blurview:1.6.6' implementation 'com.google.code.gson:gson:2.8.6' implementation "com.getkeepsafe.relinker:relinker:1.4.4" //ExoPlayer,腾讯的播放器不支持无缝切换 implementation 'com.google.android.exoplayer:exoplayer:2.18.2' implementation 'com.google.android.exoplayer:exoplayer-core:2.18.2@aar' } apply plugin: 'com.android.library' apply plugin: 'img-optimizer' apply plugin: 'kotlin-android' android { namespace "com.yunbao.live" compileSdk rootProject.ext.android.compileSdkVersion aaptOptions.cruncherEnabled = false aaptOptions.useNewCruncher = false packagingOptions { pickFirst "lib/armeabi/libyuvutils.so" pickFirst "lib/arm64-v8a/libyuvutils.so" pickFirst "lib/armeabi-v7a/libyuvutils.so" pickFirst "lib/armeabi/libyuvtools.so" pickFirst "lib/arm64-v8a/libyuvtools.so" pickFirst "lib/armeabi-v7a/libyuvtools.so" exclude "lib/arm64-v8a/libmmcv_api_handgesture.so" exclude "lib/arm64-v8a/libmmcv_api_express.so" exclude "lib/arm64-v8a/libMediaEncoder.so" exclude "lib/arm64-v8a/libarcore_sdk_c.so" exclude "lib/arm64-v8a/libmediadecoder.so" exclude "lib/arm64-v8a/libMediaMuxer.so" exclude "lib/arm64-v8a/libarcore_sdk_jni.so" exclude "lib/arm64-v8a/libMediaUtils.so" exclude "lib/arm64-v8a/libcosmosffmpeg.so" } defaultConfig { minSdkVersion rootProject.ext.android.minSdkVersion targetSdkVersion rootProject.ext.android.targetSdkVersion versionCode rootProject.ext.android.versionCode versionName rootProject.ext.android.versionName manifestPlaceholders = rootProject.ext.manifestPlaceholders ndk { abiFilters "armeabi-v7a", "arm64-v8a" } javaCompileOptions { annotationProcessorOptions { arguments = [AROUTER_MODULE_NAME: project.getName()] } } } aaptOptions { cruncherEnabled = false useNewCruncher = false } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } kotlinOptions { allWarningsAsErrors = true } compileOptions { sourceCompatibility JavaVersion.VERSION_18 targetCompatibility JavaVersion.VERSION_18 } } repositories { flatDir { dirs 'libs', '../libs' } mavenCentral() } dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.0' implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) implementation (name:'../libs/beautysdk-202202241203',ext:'aar') implementation (name:'../libs/svgaplayer-release-v1.2.1',ext:'aar') //socket.io implementation('io.socket:socket.io-client:1.0.0') { exclude group: 'org.json', module: 'json' } //common api project(path: ':common') api project(path:':FaceUnity')//新娱美颜 api project(':Share')//分享 annotationProcessor rootProject.ext.dependencies["arouter-compiler"] //工具 api rootProject.ext.dependencies["blank-utilcode"] implementation 'com.eightbitlab:blurview:1.6.6' implementation 'com.google.code.gson:gson:2.8.6' implementation "com.getkeepsafe.relinker:relinker:1.4.4" }

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools">
>
<!--com.kugou.fanxing.allinone.watch.liveroominone.media.FALiveRoomInOneActivity"--> <!--com.kugou.fanxing.allinone.watch.liveroominone.media.FALiveRoomInOneActivity"-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
@ -11,8 +10,8 @@
<application <application
android:allowBackup="true" android:allowBackup="true"
tools:replace="allowBackup" android:theme="@style/AppTheme"
android:theme="@style/AppTheme"> tools:replace="allowBackup">
<activity android:name=".activity.LiveTRTCAnchorActivity" /> <activity android:name=".activity.LiveTRTCAnchorActivity" />
<activity <activity
android:name=".activity.LiveAnchorActivity" android:name=".activity.LiveAnchorActivity"
@ -124,6 +123,10 @@
<activity <activity
android:name=".activity.CompensateActivity" android:name=".activity.CompensateActivity"
android:screenOrientation="portrait" /> android:screenOrientation="portrait" />
<activity
android:name=".activity.VideoPlayActivity"
android:screenOrientation="portrait" />
</application> </application>
</manifest> </manifest>

View File

@ -0,0 +1,121 @@
package com.yunbao.live.activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentTransaction;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.lxj.xpopup.XPopup;
import com.makeramen.roundedimageview.RoundedImageView;
import com.yunbao.common.Constants;
import com.yunbao.common.activity.AbsActivity;
import com.yunbao.common.event.GiftWallItemEvent;
import com.yunbao.common.event.LiveGiftDialogEvent;
import com.yunbao.common.fragment.AllServiceChampionFragment;
import com.yunbao.common.fragment.GiftWithoutWallFragment;
import com.yunbao.common.glide.ImgLoader;
import com.yunbao.common.utils.Bus;
import com.yunbao.common.utils.L;
import com.yunbao.common.utils.RouteUtil;
import com.yunbao.common.utils.StringUtil;
import com.yunbao.common.utils.ToastUtil;
import com.yunbao.common.views.weight.ViewClicksAntiShake;
import com.yunbao.live.R;
import com.yunbao.live.dialog.CodexDialog;
import com.yunbao.live.dialog.GiftWallItemPopup;
import com.yunbao.live.dialog.MedalAchievementPopup;
import com.yunbao.live.views.GiftAlreadyWallFragment;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.List;
public class VideoPlayActivity extends AbsActivity {
private PlayerView placeholderView;
private ExoPlayer player1;
@Override
protected int getLayoutId() {
return R.layout.activity_google_play;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DefaultLoadControl control = new DefaultLoadControl.Builder()
.setPrioritizeTimeOverSizeThresholds(false)
.setBackBuffer(10_000, true)
.setBufferDurationsMs(500,
5_000,
150,
200)
.build();
placeholderView = findViewById(R.id.placeholderView);
player1 = new ExoPlayer.Builder(mContext).setLoadControl(control).build();
player1.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
placeholderView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);
placeholderView.requestLayout();
placeholderView.setKeepContentOnPlayerReset(true);
placeholderView.setPlayer(player1);
placeholderView.setShowRewindButton(false);
placeholderView.setShowFastForwardButton(false);
placeholderView.setShowPreviousButton(false);
placeholderView.setShowNextButton(false);
placeholderView.setShowShuffleButton(false);
placeholderView.setShowMultiWindowTimeBar(false);
placeholderView.setControllerAutoShow(false);
placeholderView.setUseController(false);
player1.addListener(new Player.Listener() {
@Override
public void onPlaybackStateChanged(int playbackState) {
Player.Listener.super.onPlaybackStateChanged(playbackState);
switch (playbackState) {
case ExoPlayer.STATE_IDLE:
L.e("ExoPlayer.STATE_IDLE-播放器已实例化,但尚未准备就绪。");
break;
case ExoPlayer.STATE_BUFFERING:
L.e("ExoPlayer.STATE_BUFFERING-播放器无法从当前位置开始播放,因为已缓冲的数据不足。");
break;
case ExoPlayer.STATE_READY:
L.e("ExoPlayer.STATE_READY-播放器可以立即从当前位置开始播放。这意味着如果播放器的 playWhenReady 属性为 true播放器将自动开始播放媒体。如果该属性为 false播放器会暂停播放。");
break;
case ExoPlayer.STATE_ENDED:
L.e("ExoPlayer.STATE_ENDED-播放器已完成媒体播放。");
break;
}
}
});
player1.setMediaItem(createMediaItem("https://downs.yaoulive.com/userhome/2024-03-29/98918_r3a5urihjf7qmlnkhdr5ak5ir1.MP4"));
player1.prepare();
player1.play();
}
private MediaItem createMediaItem(String url) {
return MediaItem.fromUri(url);
}
@Override
protected void onDestroy() {
super.onDestroy();
Bus.getOff(this);
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background_gift_wall_shape"
android:orientation="vertical">
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/placeholderView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>

View File

@ -3,6 +3,7 @@ package com.yunbao.main.views;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -93,7 +94,7 @@ public class MainHomeNewViewHolder extends AbsMainHomeChildViewHolder implements
@Override @Override
public void init() { public void init() {
List<NewCommunityType> list = CommonAppConfig.getCommunityTypeList(true,mContext); List<NewCommunityType> list = CommonAppConfig.getCommunityTypeList(true, mContext);
typeHot = list.get(0).getTalk_name(); typeHot = list.get(0).getTalk_name();
select = list.get(0).getId(); select = list.get(0).getId();
@ -253,6 +254,10 @@ public class MainHomeNewViewHolder extends AbsMainHomeChildViewHolder implements
VideoStorge.getInstance().put(Constants.VIDEO_HOME, videoList); VideoStorge.getInstance().put(Constants.VIDEO_HOME, videoList);
VideoPlayActivity.forward(mContext, playPosition, Constants.VIDEO_HOME, 1); VideoPlayActivity.forward(mContext, playPosition, Constants.VIDEO_HOME, 1);
} }
/*Intent intent = new Intent(mContext, com.yunbao.live.activity.VideoPlayActivity.class);
mContext.startActivity(intent);*/
} }
/** /**

View File

@ -43,7 +43,6 @@ public class VideoPlayNewActivity extends AbsVideoPlayActivity {
context.startActivity(intent); context.startActivity(intent);
} }
public static void forwardSingle(Context context, ActiveBean videoBean) { public static void forwardSingle(Context context, ActiveBean videoBean) {
if (videoBean == null) { if (videoBean == null) {
return; return;
@ -80,7 +79,6 @@ public class VideoPlayNewActivity extends AbsVideoPlayActivity {
} }
@Override @Override
protected int getLayoutId() { protected int getLayoutId() {
return R.layout.activity_video_play; return R.layout.activity_video_play;

View File

@ -0,0 +1,37 @@
package com.yunbao.video.views;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class MyImageView extends androidx.appcompat.widget.AppCompatImageView {
public MyImageView(@NonNull Context context) {
super(context);
}
public MyImageView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyImageView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Drawable drawable = getDrawable();
if (drawable != null) {
//图片 使用android:layout_width="match_parent"得到的是整个屏幕宽
int width = MeasureSpec.getSize(widthMeasureSpec);
// 根据图片的宽度填充屏幕后 计算得到自适应的图片高度
int height = (int) Math.ceil((float) width * (float) drawable.getIntrinsicHeight() / (float) drawable.getIntrinsicWidth());
setMeasuredDimension(width, height);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}

View File

@ -3,23 +3,23 @@ package com.yunbao.video.views;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder; import android.animation.PropertyValuesHolder;
import android.content.Context; import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator; import android.view.animation.AccelerateInterpolator;
import android.widget.RelativeLayout;
import com.tencent.rtmp.ITXVodPlayListener; import com.google.android.exoplayer2.C;
import com.tencent.rtmp.TXLiveConstants; import com.google.android.exoplayer2.DefaultLoadControl;
import com.tencent.rtmp.TXVodPlayConfig; import com.google.android.exoplayer2.ExoPlayer;
import com.tencent.rtmp.TXVodPlayer; import com.google.android.exoplayer2.MediaItem;
import com.tencent.rtmp.ui.TXCloudVideoView; import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.yunbao.common.bean.ActiveBean; import com.yunbao.common.bean.ActiveBean;
import com.yunbao.common.utils.L; import com.yunbao.common.utils.L;
import com.yunbao.common.utils.ToastUtil;
import com.yunbao.common.views.AbsViewHolder; import com.yunbao.common.views.AbsViewHolder;
import com.yunbao.video.R; import com.yunbao.video.R;
import com.yunbao.common.bean.VideoBean;
import com.yunbao.video.http.VideoHttpConsts; import com.yunbao.video.http.VideoHttpConsts;
import com.yunbao.video.http.VideoHttpUtil; import com.yunbao.video.http.VideoHttpUtil;
@ -28,21 +28,18 @@ import com.yunbao.video.http.VideoHttpUtil;
* 视频播放器 * 视频播放器
*/ */
public class VideoPlayViewHolder extends AbsViewHolder implements ITXVodPlayListener, View.OnClickListener { public class VideoPlayViewHolder extends AbsViewHolder implements View.OnClickListener {
private StyledPlayerView placeholderView;
private TXCloudVideoView mTXCloudVideoView; private ExoPlayer mPlayer;
private View mVideoCover; private View mVideoCover;
private TXVodPlayer mPlayer;
private boolean mPaused;//生命周期暂停 private boolean mPaused;//生命周期暂停
private boolean mClickPaused;//点击暂停 private boolean mClickPaused;//点击暂停
private ActionListener mActionListener;
private View mPlayBtn; private View mPlayBtn;
private ActionListener mActionListener;
private ObjectAnimator mPlayBtnAnimator;//暂停按钮的动画 private ObjectAnimator mPlayBtnAnimator;//暂停按钮的动画
private boolean mStartPlay; private boolean mStartPlay;
private boolean mEndPlay; private boolean mEndPlay;
private ActiveBean mVideoBean; private ActiveBean mVideoBean;
private String mCachePath;
private TXVodPlayConfig mTXVodPlayConfig;
public VideoPlayViewHolder(Context context, ViewGroup parentView) { public VideoPlayViewHolder(Context context, ViewGroup parentView) {
super(context, parentView); super(context, parentView);
@ -55,19 +52,69 @@ public class VideoPlayViewHolder extends AbsViewHolder implements ITXVodPlayList
@Override @Override
public void init() { public void init() {
mCachePath = mContext.getCacheDir().getAbsolutePath(); placeholderView = findViewById(R.id.placeholderView);
mTXCloudVideoView = (TXCloudVideoView) findViewById(R.id.video_view); intiPlayView();
mTXCloudVideoView.setRenderMode(TXLiveConstants.RENDER_ROTATION_PORTRAIT); }
mPlayer = new TXVodPlayer(mContext);
mTXVodPlayConfig = new TXVodPlayConfig(); private void intiPlayView() {
mTXVodPlayConfig.setMaxCacheItems(15); DefaultLoadControl control = new DefaultLoadControl.Builder()
mTXVodPlayConfig.setProgressInterval(200); .setPrioritizeTimeOverSizeThresholds(false)
mPlayer.setConfig(mTXVodPlayConfig); .setBackBuffer(10_000, true)
mPlayer.setAutoPlay(true); .setBufferDurationsMs(500,
mPlayer.setVodListener(this); 5_000,
mPlayer.setPlayerView(mTXCloudVideoView); 150,
findViewById(R.id.root).setOnClickListener(this); 200)
.build();
mPlayer = new ExoPlayer.Builder(mContext).setLoadControl(control).build();
placeholderView = findViewById(com.yunbao.live.R.id.placeholderView);
mPlayer = new ExoPlayer.Builder(mContext).setLoadControl(control).build();
mPlayer.setVideoScalingMode(C.VIDEO_SCALING_MODE_DEFAULT);
mPlayer.addListener(new Player.Listener() {
@Override
public void onPlaybackStateChanged(int playbackState) {
Player.Listener.super.onPlaybackStateChanged(playbackState);
switch (playbackState) {
case Player.STATE_IDLE://这是初始状态播放器停止时以及播放失败时的状态在此状态下播放器将仅保留有限的资源
break;
case Player.STATE_BUFFERING://播放器无法立即从当前位置开始播放这主要是因为需要加载更多数据
break;
case Player.STATE_READY://播放器能够从当前位置立即播放
if (mActionListener != null) {
mActionListener.onFirstFrame();
}
break;
case Player.STATE_ENDED://播放器完整播放了所有媒体
replay();
break;
}
}
@Override
public void onPlayerError(PlaybackException error) {
Player.Listener.super.onPlayerError(error);
ToastUtil.show(mContext.getResources().getString(R.string.live_play_error));
}
});
placeholderView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH);
placeholderView.requestLayout();
placeholderView.setKeepContentOnPlayerReset(false);
placeholderView.setPlayer(mPlayer);
placeholderView.setKeepContentOnPlayerReset(true);
placeholderView.setShowRewindButton(false);
placeholderView.setShowFastForwardButton(false);
placeholderView.setShowPreviousButton(false);
placeholderView.setShowNextButton(false);
placeholderView.setShowShuffleButton(false);
placeholderView.setShowMultiWindowTimeBar(false);
placeholderView.setControllerAutoShow(false);
placeholderView.setUseController(false);
mVideoCover = findViewById(R.id.video_cover); mVideoCover = findViewById(R.id.video_cover);
mVideoCover.setOnClickListener(this);
mPlayBtn = findViewById(R.id.btn_play); mPlayBtn = findViewById(R.id.btn_play);
//暂停按钮动画 //暂停按钮动画
mPlayBtnAnimator = ObjectAnimator.ofPropertyValuesHolder(mPlayBtn, PropertyValuesHolder.ofFloat("scaleX", 4f, 0.8f, 1f), PropertyValuesHolder.ofFloat("scaleY", 4f, 0.8f, 1f), PropertyValuesHolder.ofFloat("alpha", 0f, 1f)); mPlayBtnAnimator = ObjectAnimator.ofPropertyValuesHolder(mPlayBtn, PropertyValuesHolder.ofFloat("scaleX", 4f, 0.8f, 1f), PropertyValuesHolder.ofFloat("scaleY", 4f, 0.8f, 1f), PropertyValuesHolder.ofFloat("alpha", 0f, 1f));
@ -75,102 +122,15 @@ public class VideoPlayViewHolder extends AbsViewHolder implements ITXVodPlayList
mPlayBtnAnimator.setInterpolator(new AccelerateInterpolator()); mPlayBtnAnimator.setInterpolator(new AccelerateInterpolator());
} }
/** private MediaItem createMediaItem(String url) {
* 播放器事件回调 return MediaItem.fromUri(url);
*/
@Override
public void onPlayEvent(TXVodPlayer txVodPlayer, int e, Bundle bundle) {
switch (e) {
case TXLiveConstants.PLAY_EVT_PLAY_BEGIN://加载完成开始播放的回调
mStartPlay = true;
if (mActionListener != null) {
mActionListener.onPlayBegin(txVodPlayer.getDuration());
}
if (mActionListener != null) {
mActionListener.onFirstFrame();
}
break;
case TXLiveConstants.PLAY_EVT_PLAY_LOADING: //开始加载的回调
if (mActionListener != null) {
mActionListener.onPlayLoading();
}
break;
case TXLiveConstants.PLAY_EVT_PLAY_END://获取到视频播放完毕的回调
replay();
if (!mEndPlay) {
mEndPlay = true;
if (mVideoBean != null) {
VideoHttpUtil.videoWatchEnd(mVideoBean.getUser_id(), mVideoBean.getId());
}
}
break;
case TXLiveConstants.PLAY_EVT_RCV_FIRST_I_FRAME://获取到视频首帧回调
if (mActionListener != null) {
mActionListener.onFirstFrame();
}
if (mPaused && mPlayer != null) {
mPlayer.pause();
}
break;
case TXLiveConstants.PLAY_EVT_CHANGE_RESOLUTION://获取到视频宽高回调
onVideoSizeChanged( bundle.getInt("EVT_PARAM2", 0),bundle.getInt("EVT_PARAM1", 0));
break;
case TXLiveConstants.PLAY_EVT_PLAY_PROGRESS:
if (mActionListener != null) {
int progress = bundle.getInt(TXLiveConstants.EVT_PLAY_PROGRESS_MS);
int duration = bundle.getInt(TXLiveConstants.EVT_PLAY_DURATION_MS);
mActionListener.onProgress(progress, duration);
}
break;
}
}
@Override
public void onNetStatus(TXVodPlayer txVodPlayer, Bundle bundle) {
}
/**
* 获取到视频宽高回调
*/
public void onVideoSizeChanged(float videoWidth, float videoHeight) {
if (mTXCloudVideoView != null && videoWidth > 0 && videoHeight > 0) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mTXCloudVideoView.getLayoutParams();
/*
int videoViewHeight = params.height;
int videoViewWidth = params.width;
if (videoWidth < videoViewWidth && videoHeight >= videoViewHeight) {
params.width = (int) (videoViewHeight / (videoHeight / videoViewHeight));
} else if (videoWidth > videoViewWidth && videoHeight >= videoViewHeight) {
params.width = (int) (videoViewHeight / (videoHeight / videoWidth));
}
mTXCloudVideoView.requestLayout();
if (mVideoCover != null && mVideoCover.getVisibility() == View.VISIBLE) {
mVideoCover.setVisibility(View.INVISIBLE);
}*/
int targetH = 0;
if (videoWidth / videoHeight > 0.5625f) {//横屏 9:16=0.5625
/*targetH = (int) (videoHeight*(videoWidth/videoHeight));*/
targetH = (int) (mTXCloudVideoView.getWidth() / videoWidth * videoHeight);
} else {
targetH = ViewGroup.LayoutParams.MATCH_PARENT;
}
if (targetH != params.height) {
params.height = targetH;
mTXCloudVideoView.requestLayout();
}
if (mVideoCover != null && mVideoCover.getVisibility() == View.VISIBLE) {
mVideoCover.setVisibility(View.INVISIBLE);
}
}
} }
/** /**
* 开始播放 * 开始播放
*/ */
public void startPlay(ActiveBean videoBean) { public void startPlay(ActiveBean videoBean) {
mStartPlay = false; mStartPlay = true;
mClickPaused = false; mClickPaused = false;
mEndPlay = false; mEndPlay = false;
mVideoBean = videoBean; mVideoBean = videoBean;
@ -178,28 +138,14 @@ public class VideoPlayViewHolder extends AbsViewHolder implements ITXVodPlayList
mVideoCover.setVisibility(View.VISIBLE); mVideoCover.setVisibility(View.VISIBLE);
} }
hidePlayBtn(); hidePlayBtn();
if (mPlayer.isPlaying()) {
mPlayer.stop();
}
L.e("播放视频--->" + videoBean); L.e("播放视频--->" + videoBean);
if (videoBean == null) { mPlayer.setMediaItem(createMediaItem(videoBean.getVideo()));
return; mPlayer.prepare();
} mPlayer.play();
String url = videoBean.getVideo();
if (TextUtils.isEmpty(url)) {
return;
}
if (mTXVodPlayConfig == null) {
mTXVodPlayConfig = new TXVodPlayConfig();
mTXVodPlayConfig.setMaxCacheItems(15);
mTXVodPlayConfig.setProgressInterval(200);
}
if (url.endsWith(".m3u8")) {
mTXVodPlayConfig.setCacheFolderPath(null);
} else {
mTXVodPlayConfig.setCacheFolderPath(mCachePath);
}
mPlayer.setConfig(mTXVodPlayConfig);
if (mPlayer != null) {
mPlayer.startPlay(url);
}
VideoHttpUtil.videoWatchStart(videoBean.getUser_id(), videoBean.getId()); VideoHttpUtil.videoWatchStart(videoBean.getUser_id(), videoBean.getId());
} }
@ -208,7 +154,7 @@ public class VideoPlayViewHolder extends AbsViewHolder implements ITXVodPlayList
*/ */
public void stopPlay() { public void stopPlay() {
if (mPlayer != null) { if (mPlayer != null) {
mPlayer.stopPlay(false); mPlayer.stop();
} }
} }
@ -217,8 +163,7 @@ public class VideoPlayViewHolder extends AbsViewHolder implements ITXVodPlayList
*/ */
private void replay() { private void replay() {
if (mPlayer != null) { if (mPlayer != null) {
mPlayer.seek(0); startPlay(mVideoBean);
mPlayer.resume();
} }
} }
@ -226,8 +171,7 @@ public class VideoPlayViewHolder extends AbsViewHolder implements ITXVodPlayList
VideoHttpUtil.cancel(VideoHttpConsts.VIDEO_WATCH_START); VideoHttpUtil.cancel(VideoHttpConsts.VIDEO_WATCH_START);
VideoHttpUtil.cancel(VideoHttpConsts.VIDEO_WATCH_END); VideoHttpUtil.cancel(VideoHttpConsts.VIDEO_WATCH_END);
if (mPlayer != null) { if (mPlayer != null) {
mPlayer.stopPlay(false); mPlayer.stop();
mPlayer.setPlayListener(null);
} }
mPlayer = null; mPlayer = null;
mActionListener = null; mActionListener = null;
@ -249,7 +193,7 @@ public class VideoPlayViewHolder extends AbsViewHolder implements ITXVodPlayList
public void resumePlay() { public void resumePlay() {
if (mPaused) { if (mPaused) {
if (!mClickPaused && mPlayer != null) { if (!mClickPaused && mPlayer != null) {
mPlayer.resume(); mPlayer.play();
} }
} }
mPaused = false; mPaused = false;
@ -283,7 +227,7 @@ public class VideoPlayViewHolder extends AbsViewHolder implements ITXVodPlayList
} }
if (mPlayer != null) { if (mPlayer != null) {
if (mClickPaused) { if (mClickPaused) {
mPlayer.resume(); mPlayer.play();
} else { } else {
mPlayer.pause(); mPlayer.pause();
} }
@ -302,7 +246,7 @@ public class VideoPlayViewHolder extends AbsViewHolder implements ITXVodPlayList
@Override @Override
public void onClick(View v) { public void onClick(View v) {
int i = v.getId(); int i = v.getId();
if (i == R.id.root) { if (i == R.id.video_cover) {
clickTogglePlay(); clickTogglePlay();
} }
} }

View File

@ -57,7 +57,7 @@ import java.util.List;
public class VideoPlayWrapViewHolder extends AbsViewHolder implements View.OnClickListener { public class VideoPlayWrapViewHolder extends AbsViewHolder implements View.OnClickListener {
private ViewGroup mVideoContainer; private ViewGroup mVideoContainer;
private ImageView mCover; private MyImageView mCover;
private ImageView mAvatar; private ImageView mAvatar;
private TextView mName; private TextView mName;
private TextView mTitle; private TextView mTitle;
@ -101,7 +101,7 @@ public class VideoPlayWrapViewHolder extends AbsViewHolder implements View.OnCli
progressCount = (TextView) findViewById(R.id.progressCount); progressCount = (TextView) findViewById(R.id.progressCount);
mVideoContainer = (ViewGroup) findViewById(R.id.video_container); mVideoContainer = (ViewGroup) findViewById(R.id.video_container);
mCover = (ImageView) findViewById(R.id.cover); mCover = (MyImageView) findViewById(R.id.cover);
mAvatar = (ImageView) findViewById(R.id.avatar); mAvatar = (ImageView) findViewById(R.id.avatar);
mName = (TextView) findViewById(R.id.name); mName = (TextView) findViewById(R.id.name);
mTitle = (TextView) findViewById(R.id.title); mTitle = (TextView) findViewById(R.id.title);
@ -303,6 +303,20 @@ public class VideoPlayWrapViewHolder extends AbsViewHolder implements View.OnCli
mCover.requestLayout(); mCover.requestLayout();
} }
mCover.setImageDrawable(drawable); mCover.setImageDrawable(drawable);
/*
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mCover.getLayoutParams();
int imageWidth = drawable.getIntrinsicWidth();
int imageHeight = drawable.getIntrinsicHeight();
//宽度固定,然后根据原始宽高比得到此固定宽度需要的高度
//screenWidth 是屏幕宽度
int height = mCover.getWidth() * imageHeight / imageWidth;
ViewGroup.LayoutParams para = mCover.getLayoutParams();
para.height = height;
para.width = mCover.getWidth();*/
//mCover.setImageDrawable(drawable);
} }
} }

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>

View File

@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root" android:id="@+id/root"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<com.tencent.rtmp.ui.TXCloudVideoView <com.google.android.exoplayer2.ui.StyledPlayerView
android:id="@+id/video_view" android:id="@+id/placeholderView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent" />
android:layout_centerInParent="true" />
<View <View
android:id="@+id/video_cover" android:id="@+id/video_cover"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#000" /> android:background="@color/transparent" />
<ImageView <ImageView
android:id="@+id/btn_play" android:id="@+id/btn_play"
@ -24,5 +24,4 @@
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:src="@mipmap/icon_video_play" android:src="@mipmap/icon_video_play"
android:visibility="invisible" /> android:visibility="invisible" />
</RelativeLayout> </RelativeLayout>

View File

@ -10,12 +10,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<ImageView <com.yunbao.video.views.MyImageView
android:id="@+id/cover" android:id="@+id/cover"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_centerInParent="true" android:layout_centerInParent="true" />
android:scaleType="centerCrop" />
<RelativeLayout <RelativeLayout
android:layout_width="50dp" android:layout_width="50dp"