Commit af53ca93dcfc093e9d9dd06573a2909d5f078e2e

Authored by 韩亚云
2 parents cd0d79d4 73f4bf09

Merge branch 'master' of bj.gitlab.cnlive.com:cnlive-team/newModuleStrike

Showing 25 changed files with 360 additions and 151 deletions
app/strike/src/main/java/com/cnlive/strike/demo/activity/tiktok/TikTokRecycleActivity.java
@@ -13,6 +13,7 @@ import com.cnlive.strike.demo.util.DataUtil; @@ -13,6 +13,7 @@ import com.cnlive.strike.demo.util.DataUtil;
13 import com.libs.video.util.cache.PreloadManager; 13 import com.libs.video.util.cache.PreloadManager;
14 import com.libs.video.video.exoplayer.controller.TikTokController; 14 import com.libs.video.video.exoplayer.controller.TikTokController;
15 import com.libs.video.video.exoplayer.play.CNVideoView; 15 import com.libs.video.video.exoplayer.play.CNVideoView;
  16 +import com.libs.video.video.exoplayer.render.TikTokRenderViewFactory;
16 import com.libs.video.video.exoplayer.util.L; 17 import com.libs.video.video.exoplayer.util.L;
17 import com.libs.video.video.exoplayer.util.PlayerUtils; 18 import com.libs.video.video.exoplayer.util.PlayerUtils;
18 19
@@ -53,6 +54,8 @@ public class TikTokRecycleActivity extends BaseActivity { @@ -53,6 +54,8 @@ public class TikTokRecycleActivity extends BaseActivity {
53 @Override 54 @Override
54 protected void initView() { 55 protected void initView() {
55 mVideoView = new CNVideoView(this); 56 mVideoView = new CNVideoView(this);
  57 + //以下只能二选一,看你的需求
  58 +// mVideoView.setRenderViewFactory(TikTokRenderViewFactory.create());
56 mVideoView.setScreenScaleType(CNVideoView.SCREEN_SCALE_CENTER_CROP); 59 mVideoView.setScreenScaleType(CNVideoView.SCREEN_SCALE_CENTER_CROP);
57 mVideoView.setLooping(true); 60 mVideoView.setLooping(true);
58 mController = new TikTokController(this); 61 mController = new TikTokController(this);
app/strike/src/main/java/com/cnlive/strike/demo/activity/tiktok/TikTokVerticalViewPagerActivity.java
@@ -14,6 +14,7 @@ import com.libs.video.util.cache.PreloadManager; @@ -14,6 +14,7 @@ import com.libs.video.util.cache.PreloadManager;
14 import com.libs.video.util.cache.ProxyVideoCacheManager; 14 import com.libs.video.util.cache.ProxyVideoCacheManager;
15 import com.libs.video.video.exoplayer.controller.TikTokController; 15 import com.libs.video.video.exoplayer.controller.TikTokController;
16 import com.libs.video.video.exoplayer.play.CNVideoView; 16 import com.libs.video.video.exoplayer.play.CNVideoView;
  17 +import com.libs.video.video.exoplayer.render.TikTokRenderViewFactory;
17 import com.libs.video.video.exoplayer.util.L; 18 import com.libs.video.video.exoplayer.util.L;
18 import com.libs.video.video.exoplayer.util.PlayerUtils; 19 import com.libs.video.video.exoplayer.util.PlayerUtils;
19 import com.libs.video.video.exoplayer.widget.VerticalViewPager; 20 import com.libs.video.video.exoplayer.widget.VerticalViewPager;
@@ -84,6 +85,8 @@ public class TikTokVerticalViewPagerActivity extends BaseActivity { @@ -84,6 +85,8 @@ public class TikTokVerticalViewPagerActivity extends BaseActivity {
84 private void initVideoView() { 85 private void initVideoView() {
85 mVideoView = new CNVideoView(this); 86 mVideoView = new CNVideoView(this);
86 mVideoView.setLooping(true); 87 mVideoView.setLooping(true);
  88 + //以下只能二选一,看你的需求
  89 +// mVideoView.setRenderViewFactory(TikTokRenderViewFactory.create());
87 mVideoView.setScreenScaleType(CNVideoView.SCREEN_SCALE_CENTER_CROP); 90 mVideoView.setScreenScaleType(CNVideoView.SCREEN_SCALE_CENTER_CROP);
88 mController = new TikTokController(this); 91 mController = new TikTokController(this);
89 mVideoView.setVideoController(mController); 92 mVideoView.setVideoController(mController);
app/strike/src/main/java/com/cnlive/strike/demo/activity/tiktok/TikTokViewPager2Activity.java
@@ -13,6 +13,7 @@ import com.libs.video.util.cache.PreloadManager; @@ -13,6 +13,7 @@ import com.libs.video.util.cache.PreloadManager;
13 import com.libs.video.util.cache.ProxyVideoCacheManager; 13 import com.libs.video.util.cache.ProxyVideoCacheManager;
14 import com.libs.video.video.exoplayer.controller.TikTokController; 14 import com.libs.video.video.exoplayer.controller.TikTokController;
15 import com.libs.video.video.exoplayer.play.CNVideoView; 15 import com.libs.video.video.exoplayer.play.CNVideoView;
  16 +import com.libs.video.video.exoplayer.render.TikTokRenderViewFactory;
16 import com.libs.video.video.exoplayer.util.L; 17 import com.libs.video.video.exoplayer.util.L;
17 import com.libs.video.video.exoplayer.util.PlayerUtils; 18 import com.libs.video.video.exoplayer.util.PlayerUtils;
18 import com.libs.video.video.exoplayer.widget.VerticalViewPager; 19 import com.libs.video.video.exoplayer.widget.VerticalViewPager;
@@ -84,6 +85,8 @@ public class TikTokViewPager2Activity extends BaseActivity { @@ -84,6 +85,8 @@ public class TikTokViewPager2Activity extends BaseActivity {
84 private void initVideoView() { 85 private void initVideoView() {
85 mVideoView = new CNVideoView(this); 86 mVideoView = new CNVideoView(this);
86 mVideoView.setLooping(true); 87 mVideoView.setLooping(true);
  88 + //以下只能二选一,看你的需求
  89 +// mVideoView.setRenderViewFactory(TikTokRenderViewFactory.create());
87 mVideoView.setScreenScaleType(CNVideoView.SCREEN_SCALE_CENTER_CROP); 90 mVideoView.setScreenScaleType(CNVideoView.SCREEN_SCALE_CENTER_CROP);
88 91
89 mController = new TikTokController(this); 92 mController = new TikTokController(this);
cloud/video/build.gradle
@@ -9,6 +9,7 @@ dependencies { @@ -9,6 +9,7 @@ dependencies {
9 api fileTree(include: ['*.jar'], dir: 'libs') 9 api fileTree(include: ['*.jar'], dir: 'libs')
10 // api project(':lib_cnutil') 10 // api project(':lib_cnutil')
11 // api project(':lib_cnchat_tc') 11 // api project(':lib_cnchat_tc')
  12 + //3.2.5
12 //友盟 13 //友盟
13 implementation "com.umeng.umsdk:analytics:8.0.0" 14 implementation "com.umeng.umsdk:analytics:8.0.0"
14 implementation "com.umeng.umsdk:common:2.0.0" 15 implementation "com.umeng.umsdk:common:2.0.0"
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/DefaultCompleteView.java
@@ -104,14 +104,12 @@ public class DefaultCompleteView extends FrameLayout implements IControlComponen @@ -104,14 +104,12 @@ public class DefaultCompleteView extends FrameLayout implements IControlComponen
104 if (activity != null && mControlWrapper.hasCutout()) { 104 if (activity != null && mControlWrapper.hasCutout()) {
105 int orientation = activity.getRequestedOrientation(); 105 int orientation = activity.getRequestedOrientation();
106 int cutoutHeight = mControlWrapper.getCutoutHeight(); 106 int cutoutHeight = mControlWrapper.getCutoutHeight();
  107 + LayoutParams sflp = (LayoutParams) mStopFullscreen.getLayoutParams();
107 if (orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { 108 if (orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
108 - LayoutParams sflp = (LayoutParams) mStopFullscreen.getLayoutParams();  
109 sflp.setMargins(0, 0, 0, 0); 109 sflp.setMargins(0, 0, 0, 0);
110 } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { 110 } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
111 - LayoutParams sflp = (LayoutParams) mStopFullscreen.getLayoutParams();  
112 sflp.setMargins(cutoutHeight, 0, 0, 0); 111 sflp.setMargins(cutoutHeight, 0, 0, 0);
113 } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE) { 112 } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE) {
114 - LayoutParams sflp = (LayoutParams) mStopFullscreen.getLayoutParams();  
115 sflp.setMargins(0, 0, 0, 0); 113 sflp.setMargins(0, 0, 0, 0);
116 } 114 }
117 } 115 }
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/DefaultTitleView.java
@@ -35,7 +35,7 @@ public class DefaultTitleView extends FrameLayout implements IControlComponent { @@ -35,7 +35,7 @@ public class DefaultTitleView extends FrameLayout implements IControlComponent {
35 private ControlWrapper mControlWrapper; 35 private ControlWrapper mControlWrapper;
36 36
37 private LinearLayout mTitleContainer; 37 private LinearLayout mTitleContainer;
38 - private MarqueeTextView mTitle; 38 + private TextView mTitle;
39 private TextView mSysTime;//系统当前时间 39 private TextView mSysTime;//系统当前时间
40 40
41 private BatteryReceiver mBatteryReceiver; 41 private BatteryReceiver mBatteryReceiver;
@@ -121,8 +121,8 @@ public class DefaultTitleView extends FrameLayout implements IControlComponent { @@ -121,8 +121,8 @@ public class DefaultTitleView extends FrameLayout implements IControlComponent {
121 } 121 }
122 } else { 122 } else {
123 if (getVisibility() == VISIBLE) { 123 if (getVisibility() == VISIBLE) {
  124 + setVisibility(GONE);
124 if (anim != null) { 125 if (anim != null) {
125 - setVisibility(GONE);  
126 startAnimation(anim); 126 startAnimation(anim);
127 } 127 }
128 } 128 }
@@ -150,10 +150,10 @@ public class DefaultTitleView extends FrameLayout implements IControlComponent { @@ -150,10 +150,10 @@ public class DefaultTitleView extends FrameLayout implements IControlComponent {
150 setVisibility(VISIBLE); 150 setVisibility(VISIBLE);
151 mSysTime.setText(PlayerUtils.getCurrentSystemTime()); 151 mSysTime.setText(PlayerUtils.getCurrentSystemTime());
152 } 152 }
153 - mTitle.setNeedFocus(true); 153 + mTitle.setSelected(true);
154 } else { 154 } else {
155 setVisibility(GONE); 155 setVisibility(GONE);
156 - mTitle.setNeedFocus(false); 156 + mTitle.setSelected(false);
157 } 157 }
158 158
159 Activity activity = PlayerUtils.scanForActivity(getContext()); 159 Activity activity = PlayerUtils.scanForActivity(getContext());
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/MarqueeTextView.java deleted 100644 → 0
1 -package com.libs.video.video.exoplayer.component;  
2 -  
3 -import android.content.Context;  
4 -import android.util.AttributeSet;  
5 -import android.widget.TextView;  
6 -  
7 -/**  
8 - * 实现跑马灯效果的TextView  
9 - */  
10 -public class MarqueeTextView extends TextView {  
11 - private boolean mNeedFocus;  
12 - public MarqueeTextView(Context context) {  
13 - super(context);  
14 - }  
15 - public MarqueeTextView(Context context, AttributeSet attrs) {  
16 - super(context, attrs);  
17 - }  
18 - public MarqueeTextView(Context context, AttributeSet attrs, int defStyleAttr) {  
19 - super(context, attrs, defStyleAttr);  
20 - }  
21 - //返回textview是否处在选中的状态  
22 - //而只有选中的textview才能够实现跑马灯效果  
23 - @Override  
24 - public boolean isFocused() {  
25 - if (mNeedFocus) {  
26 - return false;  
27 - }  
28 - return super.isFocused();  
29 - }  
30 -  
31 - public void setNeedFocus(boolean needFocus) {  
32 - mNeedFocus = needFocus;  
33 - }  
34 -}  
35 \ No newline at end of file 0 \ No newline at end of file
cloud/video/src/main/java/com/libs/video/video/exoplayer/controller/BaseVideoController.java
@@ -30,6 +30,14 @@ import androidx.annotation.Nullable; @@ -30,6 +30,14 @@ import androidx.annotation.Nullable;
30 30
31 /** 31 /**
32 * 控制器基类 32 * 控制器基类
  33 + * 此类集成各种事件的处理逻辑,包括
  34 + * 1.播放器状态改变: {@link #handlePlayerStateChanged(int)}
  35 + * 2.播放状态改变: {@link #handlePlayStateChanged(int)}
  36 + * 3.控制视图的显示和隐藏: {@link #handleVisibilityChanged(boolean, Animation)}
  37 + * 4.播放进度改变: {@link #handleSetProgress(int, int)}
  38 + * 5.锁定状态改变: {@link #handleLockStateChanged(boolean)}
  39 + * 6.设备方向监听: {@link #onOrientationChanged(int)}
  40 + * Created by dueeeke on 2017/4/12.
33 */ 41 */
34 public abstract class BaseVideoController extends FrameLayout 42 public abstract class BaseVideoController extends FrameLayout
35 implements IVideoController, 43 implements IVideoController,
@@ -253,7 +261,7 @@ public abstract class BaseVideoController extends FrameLayout @@ -253,7 +261,7 @@ public abstract class BaseVideoController extends FrameLayout
253 /** 261 /**
254 * 隐藏播放视图Runnable 262 * 隐藏播放视图Runnable
255 */ 263 */
256 - public final Runnable mFadeOut = new Runnable() { 264 + protected final Runnable mFadeOut = new Runnable() {
257 @Override 265 @Override
258 public void run() { 266 public void run() {
259 hide(); 267 hide();
@@ -294,7 +302,7 @@ public abstract class BaseVideoController extends FrameLayout @@ -294,7 +302,7 @@ public abstract class BaseVideoController extends FrameLayout
294 /** 302 /**
295 * 刷新进度Runnable 303 * 刷新进度Runnable
296 */ 304 */
297 - private Runnable mShowProgress = new Runnable() { 305 + protected Runnable mShowProgress = new Runnable() {
298 @Override 306 @Override
299 public void run() { 307 public void run() {
300 int pos = setProgress(); 308 int pos = setProgress();
cloud/video/src/main/java/com/libs/video/video/exoplayer/controller/ControlWrapper.java
@@ -112,6 +112,10 @@ public class ControlWrapper implements MediaPlayerControl, IVideoController { @@ -112,6 +112,10 @@ public class ControlWrapper implements MediaPlayerControl, IVideoController {
112 } 112 }
113 113
114 @Override 114 @Override
  115 + public float getSpeed() {
  116 + return mPlayerControl.getSpeed();
  117 + }
  118 + @Override
115 public long getTcpSpeed() { 119 public long getTcpSpeed() {
116 return mPlayerControl.getTcpSpeed(); 120 return mPlayerControl.getTcpSpeed();
117 } 121 }
cloud/video/src/main/java/com/libs/video/video/exoplayer/controller/GestureVideoController.java
@@ -33,8 +33,7 @@ public abstract class GestureVideoController extends BaseVideoController impleme @@ -33,8 +33,7 @@ public abstract class GestureVideoController extends BaseVideoController impleme
33 private boolean mIsGestureEnabled = true; 33 private boolean mIsGestureEnabled = true;
34 private int mStreamVolume; 34 private int mStreamVolume;
35 private float mBrightness; 35 private float mBrightness;
36 - private int mPosition;  
37 - private boolean mNeedSeek; 36 + private int mSeekPosition;
38 private boolean mFirstTouch; 37 private boolean mFirstTouch;
39 private boolean mChangePosition; 38 private boolean mChangePosition;
40 private boolean mChangeBrightness; 39 private boolean mChangeBrightness;
@@ -228,8 +227,7 @@ public abstract class GestureVideoController extends BaseVideoController impleme @@ -228,8 +227,7 @@ public abstract class GestureVideoController extends BaseVideoController impleme
228 ((IGestureComponent) component).onPositionChange(position, currentPosition, duration); 227 ((IGestureComponent) component).onPositionChange(position, currentPosition, duration);
229 } 228 }
230 } 229 }
231 - mPosition = position;  
232 - mNeedSeek = true; 230 + mSeekPosition = position;
233 } 231 }
234 232
235 protected void slideToChangeBrightness(float deltaY) { 233 protected void slideToChangeBrightness(float deltaY) {
@@ -274,22 +272,35 @@ public abstract class GestureVideoController extends BaseVideoController impleme @@ -274,22 +272,35 @@ public abstract class GestureVideoController extends BaseVideoController impleme
274 272
275 @Override 273 @Override
276 public boolean onTouchEvent(MotionEvent event) { 274 public boolean onTouchEvent(MotionEvent event) {
277 - boolean detectedUp = event.getAction() == MotionEvent.ACTION_UP;  
278 - if (!mGestureDetector.onTouchEvent(event) && detectedUp) {  
279 - for (Map.Entry<IControlComponent, Boolean> next : mControlComponents.entrySet()) {  
280 - IControlComponent component = next.getKey();  
281 - if (component instanceof IGestureComponent) {  
282 - ((IGestureComponent) component).onStopSlide();  
283 - }  
284 - }  
285 - if (mNeedSeek) {  
286 - mControlWrapper.seekTo(mPosition);  
287 - mNeedSeek = false; 275 + //滑动结束时事件处理
  276 + if (!mGestureDetector.onTouchEvent(event)) {
  277 + int action = event.getAction();
  278 + switch (action) {
  279 + case MotionEvent.ACTION_UP:
  280 + stopSlide();
  281 + if (mSeekPosition > 0) {
  282 + mControlWrapper.seekTo(mSeekPosition);
  283 + mSeekPosition = 0;
  284 + }
  285 + break;
  286 + case MotionEvent.ACTION_CANCEL:
  287 + stopSlide();
  288 + mSeekPosition = 0;
  289 + break;
288 } 290 }
289 } 291 }
290 return super.onTouchEvent(event); 292 return super.onTouchEvent(event);
291 } 293 }
292 294
  295 + private void stopSlide() {
  296 + for (Map.Entry<IControlComponent, Boolean> next : mControlComponents.entrySet()) {
  297 + IControlComponent component = next.getKey();
  298 + if (component instanceof IGestureComponent) {
  299 + ((IGestureComponent) component).onStopSlide();
  300 + }
  301 + }
  302 + }
  303 +
293 @Override 304 @Override
294 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 305 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
295 return false; 306 return false;
cloud/video/src/main/java/com/libs/video/video/exoplayer/controller/MediaPlayerControl.java
@@ -38,6 +38,8 @@ public interface MediaPlayerControl { @@ -38,6 +38,8 @@ public interface MediaPlayerControl {
38 38
39 void setSpeed(float speed); 39 void setSpeed(float speed);
40 40
  41 + float getSpeed();
  42 +
41 long getTcpSpeed(); 43 long getTcpSpeed();
42 44
43 void replay(boolean resetPosition); 45 void replay(boolean resetPosition);
cloud/video/src/main/java/com/libs/video/video/exoplayer/controller/StandardVideoController.java
@@ -32,6 +32,8 @@ import androidx.annotation.Nullable; @@ -32,6 +32,8 @@ import androidx.annotation.Nullable;
32 32
33 /** 33 /**
34 * 直播/点播控制器 34 * 直播/点播控制器
  35 + * 注意:此控制器仅做一个参考,如果想定制ui,你可以直接继承GestureVideoController或者BaseVideoController实现
  36 + * 你自己的控制器
35 */ 37 */
36 38
37 public class StandardVideoController extends GestureVideoController implements View.OnClickListener, AbstractPlayer.PlayerEventListener { 39 public class StandardVideoController extends GestureVideoController implements View.OnClickListener, AbstractPlayer.PlayerEventListener {
@@ -207,7 +209,7 @@ public class StandardVideoController extends GestureVideoController implements V @@ -207,7 +209,7 @@ public class StandardVideoController extends GestureVideoController implements V
207 209
208 @Override 210 @Override
209 public void onError(PlayErrorException playErrorException) { 211 public void onError(PlayErrorException playErrorException) {
210 - Log.e("测试", "onError: " ); 212 + Log.e("测试", "onError: ");
211 } 213 }
212 214
213 @Override 215 @Override
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/AbstractPlayer.java
@@ -163,6 +163,11 @@ public abstract class AbstractPlayer { @@ -163,6 +163,11 @@ public abstract class AbstractPlayer {
163 public abstract void setSpeed(float speed); 163 public abstract void setSpeed(float speed);
164 164
165 /** 165 /**
  166 + * 获取播放速度
  167 + */
  168 + public abstract float getSpeed();
  169 +
  170 + /**
166 * 获取当前缓冲的网速 171 * 获取当前缓冲的网速
167 */ 172 */
168 public abstract long getTcpSpeed(); 173 public abstract long getTcpSpeed();
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/CNVideoView.java
@@ -656,6 +656,14 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout @@ -656,6 +656,14 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
656 } 656 }
657 } 657 }
658 658
  659 + @Override
  660 + public float getSpeed() {
  661 + if (isInPlaybackState()) {
  662 + return mMediaPlayer.getSpeed();
  663 + }
  664 + return 1f;
  665 + }
  666 +
659 /** 667 /**
660 * 设置视频地址 668 * 设置视频地址
661 */ 669 */
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/PlayerFactory.java
@@ -3,9 +3,10 @@ package com.libs.video.video.exoplayer.play; @@ -3,9 +3,10 @@ package com.libs.video.video.exoplayer.play;
3 import android.content.Context; 3 import android.content.Context;
4 4
5 /** 5 /**
6 - * 创建播放器核心  
7 - *  
8 - * @param <P> 6 + * 此接口使用方法:
  7 + * 1.继承{@link AbstractPlayer}扩展自己的播放器。
  8 + * 2.继承此接口并实现${@link #createPlayer(Context)},返回步骤1中的播放器。
  9 + * 可参照{@link com.libs.video.video.exoplayer.playerCore.mediaplayer.AndroidMediaPlayer}和{@link com.libs.video.video.exoplayer.playerCore.mediaplayer.AndroidMediaPlayerFactory}的实现。
9 */ 10 */
10 public abstract class PlayerFactory<P extends AbstractPlayer> { 11 public abstract class PlayerFactory<P extends AbstractPlayer> {
11 12
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/ProgressManager.java
1 package com.libs.video.video.exoplayer.play; 1 package com.libs.video.video.exoplayer.play;
2 2
3 /** 3 /**
4 - * 进度管理 4 + * 播放进度管理器,继承此接口实现自己的进度管理器。
5 */ 5 */
6 public abstract class ProgressManager { 6 public abstract class ProgressManager {
7 7
  8 + /**
  9 + * 此方法用于实现保存进度的逻辑
  10 + * @param url 播放地址
  11 + * @param progress 播放进度
  12 + */
8 public abstract void saveProgress(String url, long progress); 13 public abstract void saveProgress(String url, long progress);
9 14
  15 + /**
  16 + * 此方法用于实现获取保存的进度的逻辑
  17 + * @param url 播放地址
  18 + * @return 保存的播放进度
  19 + */
10 public abstract long getSavedProgress(String url); 20 public abstract long getSavedProgress(String url);
11 21
12 } 22 }
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/VideoViewConfig.java
@@ -23,8 +23,6 @@ public class VideoViewConfig { @@ -23,8 +23,6 @@ public class VideoViewConfig {
23 23
24 public final boolean mEnableAudioFocus; 24 public final boolean mEnableAudioFocus;
25 25
26 - public final boolean mEnableParallelPlay;  
27 -  
28 public final boolean mIsEnableLog; 26 public final boolean mIsEnableLog;
29 27
30 public final ProgressManager mProgressManager; 28 public final ProgressManager mProgressManager;
@@ -43,7 +41,6 @@ public class VideoViewConfig { @@ -43,7 +41,6 @@ public class VideoViewConfig {
43 mPlayOnMobileNetwork = builder.mPlayOnMobileNetwork; 41 mPlayOnMobileNetwork = builder.mPlayOnMobileNetwork;
44 mEnableAudioFocus = builder.mEnableAudioFocus; 42 mEnableAudioFocus = builder.mEnableAudioFocus;
45 mProgressManager = builder.mProgressManager; 43 mProgressManager = builder.mProgressManager;
46 - mEnableParallelPlay = builder.mEnableParallelPlay;  
47 mScreenScaleType = builder.mScreenScaleType; 44 mScreenScaleType = builder.mScreenScaleType;
48 if (builder.mPlayerFactory == null) { 45 if (builder.mPlayerFactory == null) {
49 //默认为AndroidMediaPlayer 46 //默认为AndroidMediaPlayer
@@ -67,7 +64,6 @@ public class VideoViewConfig { @@ -67,7 +64,6 @@ public class VideoViewConfig {
67 private boolean mPlayOnMobileNetwork; 64 private boolean mPlayOnMobileNetwork;
68 private boolean mEnableOrientation; 65 private boolean mEnableOrientation;
69 private boolean mEnableAudioFocus = true; 66 private boolean mEnableAudioFocus = true;
70 - private boolean mEnableParallelPlay;  
71 private ProgressManager mProgressManager; 67 private ProgressManager mProgressManager;
72 private PlayerFactory mPlayerFactory; 68 private PlayerFactory mPlayerFactory;
73 private int mScreenScaleType; 69 private int mScreenScaleType;
@@ -107,16 +103,6 @@ public class VideoViewConfig { @@ -107,16 +103,6 @@ public class VideoViewConfig {
107 } 103 }
108 104
109 /** 105 /**
110 - * 支持多开  
111 - * @deprecated 此api已经无效,你需要自己去控制同时只有一个VideoView在播放的效果  
112 - */  
113 - @Deprecated  
114 - public Builder setEnableParallelPlay(boolean enableParallelPlay) {  
115 - mEnableParallelPlay = enableParallelPlay;  
116 - return this;  
117 - }  
118 -  
119 - /**  
120 * 是否打印日志 106 * 是否打印日志
121 */ 107 */
122 public Builder setLogEnabled(boolean enableLog) { 108 public Builder setLogEnabled(boolean enableLog) {
cloud/video/src/main/java/com/libs/video/video/exoplayer/playerCore/exoplayer/ExoMediaPlayer.java
@@ -332,6 +332,13 @@ public class ExoMediaPlayer extends AbstractPlayer implements VideoListener, Pla @@ -332,6 +332,13 @@ public class ExoMediaPlayer extends AbstractPlayer implements VideoListener, Pla
332 } 332 }
333 } 333 }
334 334
  335 + @Override
  336 + public float getSpeed() {
  337 + if (mSpeedPlaybackParameters != null) {
  338 + return mSpeedPlaybackParameters.speed;
  339 + }
  340 + return 1f;
  341 + }
335 /** 342 /**
336 * 不支持 343 * 不支持
337 * 344 *
cloud/video/src/main/java/com/libs/video/video/exoplayer/playerCore/mediaplayer/AndroidMediaPlayer.java
@@ -20,6 +20,11 @@ import com.libs.video.video.exoplayer.util.PlayCacheUtils; @@ -20,6 +20,11 @@ import com.libs.video.video.exoplayer.util.PlayCacheUtils;
20 import java.io.IOException; 20 import java.io.IOException;
21 import java.util.Map; 21 import java.util.Map;
22 22
  23 +import static com.libs.video.video.exoplayer.PlayErrorException.TYPE_UNEXPECTED_ERROR;
  24 +
  25 +/**
  26 + * 封装系统的MediaPlayer,不推荐,系统的MediaPlayer兼容性较差,建议使用ExoPlayer
  27 + */
23 public class AndroidMediaPlayer extends AbstractPlayer { 28 public class AndroidMediaPlayer extends AbstractPlayer {
24 29
25 protected MediaPlayer mMediaPlayer; 30 protected MediaPlayer mMediaPlayer;
@@ -57,7 +62,7 @@ public class AndroidMediaPlayer extends AbstractPlayer { @@ -57,7 +62,7 @@ public class AndroidMediaPlayer extends AbstractPlayer {
57 public void setDataSource(String path, Map<String, String> headers, boolean isCache) { 62 public void setDataSource(String path, Map<String, String> headers, boolean isCache) {
58 try { 63 try {
59 if (isCache) { 64 if (isCache) {
60 - mMediaPlayer.setDataSource(mAppContext, Uri.parse(PlayCacheUtils.getCachePath(mAppContext,path)), headers); 65 + mMediaPlayer.setDataSource(mAppContext, Uri.parse(PlayCacheUtils.getCachePath(mAppContext, path)), headers);
61 } else { 66 } else {
62 //不缓存 67 //不缓存
63 mMediaPlayer.setDataSource(mAppContext, Uri.parse(path), headers); 68 mMediaPlayer.setDataSource(mAppContext, Uri.parse(path), headers);
@@ -94,7 +99,7 @@ public class AndroidMediaPlayer extends AbstractPlayer { @@ -94,7 +99,7 @@ public class AndroidMediaPlayer extends AbstractPlayer {
94 } else if (e instanceof IllegalStateException) { 99 } else if (e instanceof IllegalStateException) {
95 errorException = new PlayErrorException(PlayErrorException.TYPE_IllegalStateException, e.getMessage()); 100 errorException = new PlayErrorException(PlayErrorException.TYPE_IllegalStateException, e.getMessage());
96 } else { 101 } else {
97 - errorException = new PlayErrorException(PlayErrorException.TYPE_UNEXPECTED_ERROR, e.getMessage()); 102 + errorException = new PlayErrorException(TYPE_UNEXPECTED_ERROR, e.getMessage());
98 } 103 }
99 mPlayerEventListener.onError(errorException); 104 mPlayerEventListener.onError(errorException);
100 } 105 }
@@ -239,6 +244,19 @@ public class AndroidMediaPlayer extends AbstractPlayer { @@ -239,6 +244,19 @@ public class AndroidMediaPlayer extends AbstractPlayer {
239 } 244 }
240 245
241 @Override 246 @Override
  247 + public float getSpeed() {
  248 + // only support above Android M
  249 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  250 + try {
  251 + return mMediaPlayer.getPlaybackParams().getSpeed();
  252 + } catch (Exception e) {
  253 + mPlayerEventListener.onError(new PlayErrorException(TYPE_UNEXPECTED_ERROR,e.getMessage()));
  254 + }
  255 + }
  256 + return 1f;
  257 + }
  258 +
  259 + @Override
242 public long getTcpSpeed() { 260 public long getTcpSpeed() {
243 // no support 261 // no support
244 return 0; 262 return 0;
cloud/video/src/main/java/com/libs/video/video/exoplayer/playerCore/mediaplayer/AndroidMediaPlayerFactory.java
@@ -3,7 +3,9 @@ package com.libs.video.video.exoplayer.playerCore.mediaplayer; @@ -3,7 +3,9 @@ package com.libs.video.video.exoplayer.playerCore.mediaplayer;
3 import android.content.Context; 3 import android.content.Context;
4 4
5 import com.libs.video.video.exoplayer.play.PlayerFactory; 5 import com.libs.video.video.exoplayer.play.PlayerFactory;
6 - 6 +/**
  7 + * 创建{@link AndroidMediaPlayer}的工厂类,不推荐,系统的MediaPlayer兼容性较差,建议使用ExoPlayer
  8 + */
7 public class AndroidMediaPlayerFactory extends PlayerFactory<AndroidMediaPlayer> { 9 public class AndroidMediaPlayerFactory extends PlayerFactory<AndroidMediaPlayer> {
8 10
9 public static AndroidMediaPlayerFactory create() { 11 public static AndroidMediaPlayerFactory create() {
cloud/video/src/main/java/com/libs/video/video/exoplayer/render/MeasureHelper.java
@@ -9,7 +9,6 @@ import com.libs.video.video.exoplayer.play.CNVideoView; @@ -9,7 +9,6 @@ import com.libs.video.video.exoplayer.play.CNVideoView;
9 * 测量工具 9 * 测量工具
10 */ 10 */
11 public class MeasureHelper { 11 public class MeasureHelper {
12 -  
13 private int mVideoWidth; 12 private int mVideoWidth;
14 13
15 private int mVideoHeight; 14 private int mVideoHeight;
@@ -22,7 +21,6 @@ public class MeasureHelper { @@ -22,7 +21,6 @@ public class MeasureHelper {
22 mVideoRotationDegree = videoRotationDegree; 21 mVideoRotationDegree = videoRotationDegree;
23 } 22 }
24 23
25 -  
26 public void setVideoSize(int width, int height) { 24 public void setVideoSize(int width, int height) {
27 mVideoWidth = width; 25 mVideoWidth = width;
28 mVideoHeight = height; 26 mVideoHeight = height;
@@ -32,6 +30,9 @@ public class MeasureHelper { @@ -32,6 +30,9 @@ public class MeasureHelper {
32 mCurrentScreenScale = screenScale; 30 mCurrentScreenScale = screenScale;
33 } 31 }
34 32
  33 + /**
  34 + * 注意:VideoView的宽高一定要定死,否者以下算法不成立
  35 + */
35 public int[] doMeasure(int widthMeasureSpec, int heightMeasureSpec) { 36 public int[] doMeasure(int widthMeasureSpec, int heightMeasureSpec) {
36 if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) { // 软解码时处理旋转信息,交换宽高 37 if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) { // 软解码时处理旋转信息,交换宽高
37 widthMeasureSpec = widthMeasureSpec + heightMeasureSpec; 38 widthMeasureSpec = widthMeasureSpec + heightMeasureSpec;
@@ -39,11 +40,23 @@ public class MeasureHelper { @@ -39,11 +40,23 @@ public class MeasureHelper {
39 widthMeasureSpec = widthMeasureSpec - heightMeasureSpec; 40 widthMeasureSpec = widthMeasureSpec - heightMeasureSpec;
40 } 41 }
41 42
42 - int width = View.getDefaultSize(mVideoWidth, widthMeasureSpec);  
43 - int height = View.getDefaultSize(mVideoHeight, heightMeasureSpec); 43 + int width = View.MeasureSpec.getSize(widthMeasureSpec);
  44 + int height = View.MeasureSpec.getSize(heightMeasureSpec);
  45 +
  46 + if (mVideoHeight == 0 || mVideoWidth == 0) {
  47 + return new int[]{width, height};
  48 + }
44 49
45 //如果设置了比例 50 //如果设置了比例
46 switch (mCurrentScreenScale) { 51 switch (mCurrentScreenScale) {
  52 + case CNVideoView.SCREEN_SCALE_DEFAULT:
  53 + default:
  54 + if (mVideoWidth * height < width * mVideoHeight) {
  55 + width = height * mVideoWidth / mVideoHeight;
  56 + } else if (mVideoWidth * height > width * mVideoHeight) {
  57 + height = width * mVideoHeight / mVideoWidth;
  58 + }
  59 + break;
47 case CNVideoView.SCREEN_SCALE_ORIGINAL: 60 case CNVideoView.SCREEN_SCALE_ORIGINAL:
48 width = mVideoWidth; 61 width = mVideoWidth;
49 height = mVideoHeight; 62 height = mVideoHeight;
@@ -61,80 +74,146 @@ public class MeasureHelper { @@ -61,80 +74,146 @@ public class MeasureHelper {
61 } else { 74 } else {
62 width = height / 3 * 4; 75 width = height / 3 * 4;
63 } 76 }
64 -// Log.d("@@@@", "onMeasure 4:3 : width" + width + " height:" + height);  
65 break; 77 break;
66 case CNVideoView.SCREEN_SCALE_MATCH_PARENT: 78 case CNVideoView.SCREEN_SCALE_MATCH_PARENT:
67 width = widthMeasureSpec; 79 width = widthMeasureSpec;
68 height = heightMeasureSpec; 80 height = heightMeasureSpec;
69 break; 81 break;
70 case CNVideoView.SCREEN_SCALE_CENTER_CROP: 82 case CNVideoView.SCREEN_SCALE_CENTER_CROP:
71 - if (mVideoWidth > 0 && mVideoHeight > 0) {  
72 - if (mVideoWidth * height > width * mVideoHeight) {  
73 - width = height * mVideoWidth / mVideoHeight;  
74 - } else {  
75 - height = width * mVideoHeight / mVideoWidth;  
76 - }  
77 - }  
78 - break;  
79 - case CNVideoView.SCREEN_SCALE_DEFAULT:  
80 - default:  
81 - if (mVideoWidth > 0 && mVideoHeight > 0) {  
82 -  
83 - int widthSpecMode = View.MeasureSpec.getMode(widthMeasureSpec);  
84 - int widthSpecSize = View.MeasureSpec.getSize(widthMeasureSpec);  
85 - int heightSpecMode = View.MeasureSpec.getMode(heightMeasureSpec);  
86 - int heightSpecSize = View.MeasureSpec.getSize(heightMeasureSpec);  
87 -  
88 - if (widthSpecMode == View.MeasureSpec.EXACTLY && heightSpecMode == View.MeasureSpec.EXACTLY) {  
89 - // the size is fixed  
90 - width = widthSpecSize;  
91 - height = heightSpecSize;  
92 -  
93 - // for compatibility, we adjust size based on aspect ratio  
94 - if (mVideoWidth * height < width * mVideoHeight) {  
95 - //Log.i("@@@", "image too wide, correcting");  
96 - width = height * mVideoWidth / mVideoHeight;  
97 - } else if (mVideoWidth * height > width * mVideoHeight) {  
98 - //Log.i("@@@", "image too tall, correcting");  
99 - height = width * mVideoHeight / mVideoWidth;  
100 - }  
101 - } else if (widthSpecMode == View.MeasureSpec.EXACTLY) {  
102 - // only the width is fixed, adjust the height to match aspect ratio if possible  
103 - width = widthSpecSize;  
104 - height = width * mVideoHeight / mVideoWidth;  
105 - if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) {  
106 - // couldn't match aspect ratio within the constraints  
107 - height = heightSpecSize;  
108 - }  
109 - } else if (heightSpecMode == View.MeasureSpec.EXACTLY) {  
110 - // only the height is fixed, adjust the width to match aspect ratio if possible  
111 - height = heightSpecSize;  
112 - width = height * mVideoWidth / mVideoHeight;  
113 - if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) {  
114 - // couldn't match aspect ratio within the constraints  
115 - width = widthSpecSize;  
116 - }  
117 - } else {  
118 - // neither the width nor the height are fixed, try to use actual video size  
119 - width = mVideoWidth;  
120 - height = mVideoHeight;  
121 - if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) {  
122 - // too tall, decrease both width and height  
123 - height = heightSpecSize;  
124 - width = height * mVideoWidth / mVideoHeight;  
125 - }  
126 - if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) {  
127 - // too wide, decrease both width and height  
128 - width = widthSpecSize;  
129 - height = width * mVideoHeight / mVideoWidth;  
130 - }  
131 - } 83 + if (mVideoWidth * height > width * mVideoHeight) {
  84 + width = height * mVideoWidth / mVideoHeight;
132 } else { 85 } else {
133 - // no size yet, just adopt the given spec sizes 86 + height = width * mVideoHeight / mVideoWidth;
134 } 87 }
135 break; 88 break;
136 } 89 }
137 -  
138 return new int[]{width, height}; 90 return new int[]{width, height};
139 } 91 }
  92 +// private int mVideoWidth;
  93 +//
  94 +// private int mVideoHeight;
  95 +//
  96 +// private int mCurrentScreenScale;
  97 +//
  98 +// private int mVideoRotationDegree;
  99 +//
  100 +// public void setVideoRotation(int videoRotationDegree) {
  101 +// mVideoRotationDegree = videoRotationDegree;
  102 +// }
  103 +//
  104 +//
  105 +// public void setVideoSize(int width, int height) {
  106 +// mVideoWidth = width;
  107 +// mVideoHeight = height;
  108 +// }
  109 +//
  110 +// public void setScreenScale(int screenScale) {
  111 +// mCurrentScreenScale = screenScale;
  112 +// }
  113 +//
  114 +// public int[] doMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  115 +// if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) { // 软解码时处理旋转信息,交换宽高
  116 +// widthMeasureSpec = widthMeasureSpec + heightMeasureSpec;
  117 +// heightMeasureSpec = widthMeasureSpec - heightMeasureSpec;
  118 +// widthMeasureSpec = widthMeasureSpec - heightMeasureSpec;
  119 +// }
  120 +//
  121 +// int width = View.getDefaultSize(mVideoWidth, widthMeasureSpec);
  122 +// int height = View.getDefaultSize(mVideoHeight, heightMeasureSpec);
  123 +//
  124 +// //如果设置了比例
  125 +// switch (mCurrentScreenScale) {
  126 +// case CNVideoView.SCREEN_SCALE_ORIGINAL:
  127 +// width = mVideoWidth;
  128 +// height = mVideoHeight;
  129 +// break;
  130 +// case CNVideoView.SCREEN_SCALE_16_9:
  131 +// if (height > width / 16 * 9) {
  132 +// height = width / 16 * 9;
  133 +// } else {
  134 +// width = height / 9 * 16;
  135 +// }
  136 +// break;
  137 +// case CNVideoView.SCREEN_SCALE_4_3:
  138 +// if (height > width / 4 * 3) {
  139 +// height = width / 4 * 3;
  140 +// } else {
  141 +// width = height / 3 * 4;
  142 +// }
  143 +//// Log.d("@@@@", "onMeasure 4:3 : width" + width + " height:" + height);
  144 +// break;
  145 +// case CNVideoView.SCREEN_SCALE_MATCH_PARENT:
  146 +// width = widthMeasureSpec;
  147 +// height = heightMeasureSpec;
  148 +// break;
  149 +// case CNVideoView.SCREEN_SCALE_CENTER_CROP:
  150 +// if (mVideoWidth > 0 && mVideoHeight > 0) {
  151 +// if (mVideoWidth * height > width * mVideoHeight) {
  152 +// width = height * mVideoWidth / mVideoHeight;
  153 +// } else {
  154 +// height = width * mVideoHeight / mVideoWidth;
  155 +// }
  156 +// }
  157 +// break;
  158 +// case CNVideoView.SCREEN_SCALE_DEFAULT:
  159 +// default:
  160 +// if (mVideoWidth > 0 && mVideoHeight > 0) {
  161 +//
  162 +// int widthSpecMode = View.MeasureSpec.getMode(widthMeasureSpec);
  163 +// int widthSpecSize = View.MeasureSpec.getSize(widthMeasureSpec);
  164 +// int heightSpecMode = View.MeasureSpec.getMode(heightMeasureSpec);
  165 +// int heightSpecSize = View.MeasureSpec.getSize(heightMeasureSpec);
  166 +//
  167 +// if (widthSpecMode == View.MeasureSpec.EXACTLY && heightSpecMode == View.MeasureSpec.EXACTLY) {
  168 +// // the size is fixed
  169 +// width = widthSpecSize;
  170 +// height = heightSpecSize;
  171 +//
  172 +// // for compatibility, we adjust size based on aspect ratio
  173 +// if (mVideoWidth * height < width * mVideoHeight) {
  174 +// //Log.i("@@@", "image too wide, correcting");
  175 +// width = height * mVideoWidth / mVideoHeight;
  176 +// } else if (mVideoWidth * height > width * mVideoHeight) {
  177 +// //Log.i("@@@", "image too tall, correcting");
  178 +// height = width * mVideoHeight / mVideoWidth;
  179 +// }
  180 +// } else if (widthSpecMode == View.MeasureSpec.EXACTLY) {
  181 +// // only the width is fixed, adjust the height to match aspect ratio if possible
  182 +// width = widthSpecSize;
  183 +// height = width * mVideoHeight / mVideoWidth;
  184 +// if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) {
  185 +// // couldn't match aspect ratio within the constraints
  186 +// height = heightSpecSize;
  187 +// }
  188 +// } else if (heightSpecMode == View.MeasureSpec.EXACTLY) {
  189 +// // only the height is fixed, adjust the width to match aspect ratio if possible
  190 +// height = heightSpecSize;
  191 +// width = height * mVideoWidth / mVideoHeight;
  192 +// if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) {
  193 +// // couldn't match aspect ratio within the constraints
  194 +// width = widthSpecSize;
  195 +// }
  196 +// } else {
  197 +// // neither the width nor the height are fixed, try to use actual video size
  198 +// width = mVideoWidth;
  199 +// height = mVideoHeight;
  200 +// if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) {
  201 +// // too tall, decrease both width and height
  202 +// height = heightSpecSize;
  203 +// width = height * mVideoWidth / mVideoHeight;
  204 +// }
  205 +// if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) {
  206 +// // too wide, decrease both width and height
  207 +// width = widthSpecSize;
  208 +// height = width * mVideoHeight / mVideoWidth;
  209 +// }
  210 +// }
  211 +// } else {
  212 +// // no size yet, just adopt the given spec sizes
  213 +// }
  214 +// break;
  215 +// }
  216 +//
  217 +// return new int[]{width, height};
  218 +// }
140 } 219 }
cloud/video/src/main/java/com/libs/video/video/exoplayer/render/RenderViewFactory.java
@@ -2,8 +2,16 @@ package com.libs.video.video.exoplayer.render; @@ -2,8 +2,16 @@ package com.libs.video.video.exoplayer.render;
2 2
3 import android.content.Context; 3 import android.content.Context;
4 4
  5 +/**
  6 + * 此接口用于扩展自己的渲染View。使用方法如下:
  7 + * 1.继承IRenderView实现自己的渲染View。
  8 + * 2.重写createRenderView返回步骤1的渲染View。
  9 + * 可参考{@link com.libs.video.video.exoplayer.render.texture.TextureRenderView}
  10 + * 和
  11 + * {@link com.libs.video.video.exoplayer.render.texture.TextureRenderViewFactory}的实现。
  12 + */
5 public abstract class RenderViewFactory { 13 public abstract class RenderViewFactory {
6 14
7 public abstract IRenderView createRenderView(Context context); 15 public abstract IRenderView createRenderView(Context context);
8 16
9 -} 17 -}
  18 +}
10 \ No newline at end of file 19 \ No newline at end of file
cloud/video/src/main/java/com/libs/video/video/exoplayer/render/TikTokRenderView.java 0 → 100644
  1 +package com.libs.video.video.exoplayer.render;
  2 +
  3 +import android.graphics.Bitmap;
  4 +import android.view.View;
  5 +
  6 +import androidx.annotation.NonNull;
  7 +
  8 +import com.libs.video.video.exoplayer.play.AbstractPlayer;
  9 +import com.libs.video.video.exoplayer.play.CNVideoView;
  10 +
  11 +
  12 +/**
  13 + * TikTok专用RenderView,横屏视频默认显示,竖屏视频居中裁剪
  14 + * 使用代理模式实现
  15 + */
  16 +public class TikTokRenderView implements IRenderView {
  17 +
  18 + private IRenderView mProxyRenderView;
  19 +
  20 + TikTokRenderView(@NonNull IRenderView renderView) {
  21 + this.mProxyRenderView = renderView;
  22 + }
  23 +
  24 + @Override
  25 + public void attachToPlayer(@NonNull AbstractPlayer player) {
  26 + mProxyRenderView.attachToPlayer(player);
  27 + }
  28 +
  29 + @Override
  30 + public void setVideoSize(int videoWidth, int videoHeight) {
  31 + if (videoWidth > 0 && videoHeight > 0) {
  32 + mProxyRenderView.setVideoSize(videoWidth, videoHeight);
  33 + if (videoHeight > videoWidth) {
  34 + //竖屏视频,使用居中裁剪
  35 + mProxyRenderView.setScaleType(CNVideoView.SCREEN_SCALE_CENTER_CROP);
  36 + } else {
  37 + //横屏视频,使用默认模式
  38 + mProxyRenderView.setScaleType(CNVideoView.SCREEN_SCALE_DEFAULT);
  39 + }
  40 + }
  41 + }
  42 +
  43 + @Override
  44 + public void setVideoRotation(int degree) {
  45 + mProxyRenderView.setVideoRotation(degree);
  46 + }
  47 +
  48 + @Override
  49 + public void setScaleType(int scaleType) {
  50 + // 置空,不要让外部去设置ScaleType
  51 + }
  52 +
  53 + @Override
  54 + public View getView() {
  55 + return mProxyRenderView.getView();
  56 + }
  57 +
  58 + @Override
  59 + public Bitmap doScreenShot() {
  60 + return mProxyRenderView.doScreenShot();
  61 + }
  62 +
  63 + @Override
  64 + public void release() {
  65 + mProxyRenderView.release();
  66 + }
  67 +}
0 \ No newline at end of file 68 \ No newline at end of file
cloud/video/src/main/java/com/libs/video/video/exoplayer/render/TikTokRenderViewFactory.java 0 → 100644
  1 +package com.libs.video.video.exoplayer.render;
  2 +
  3 +import android.content.Context;
  4 +
  5 +import com.libs.video.video.exoplayer.render.texture.TextureRenderView;
  6 +
  7 +
  8 +public class TikTokRenderViewFactory extends RenderViewFactory {
  9 +
  10 + public static TikTokRenderViewFactory create() {
  11 + return new TikTokRenderViewFactory();
  12 + }
  13 +
  14 + @Override
  15 + public IRenderView createRenderView(Context context) {
  16 + return new TikTokRenderView(new TextureRenderView(context));
  17 + }
  18 +}
cloud/video/src/main/res/layout/cnvideo_layout_title_view.xml
@@ -21,14 +21,12 @@ @@ -21,14 +21,12 @@
21 android:padding="@dimen/cnvideo_controller_icon_padding" 21 android:padding="@dimen/cnvideo_controller_icon_padding"
22 android:src="@drawable/cnvideo_ic_action_arrow_back" /> 22 android:src="@drawable/cnvideo_ic_action_arrow_back" />
23 23
24 - <com.libs.video.video.exoplayer.component.MarqueeTextView 24 + <TextView
25 android:id="@+id/title" 25 android:id="@+id/title"
26 android:layout_width="0dp" 26 android:layout_width="0dp"
27 android:layout_height="wrap_content" 27 android:layout_height="wrap_content"
28 android:layout_weight="1" 28 android:layout_weight="1"
29 android:ellipsize="marquee" 29 android:ellipsize="marquee"
30 - android:focusable="true"  
31 - android:focusableInTouchMode="true"  
32 android:marqueeRepeatLimit="marquee_forever" 30 android:marqueeRepeatLimit="marquee_forever"
33 android:paddingLeft="6dp" 31 android:paddingLeft="6dp"
34 android:paddingRight="6dp" 32 android:paddingRight="6dp"