Skip to content

Commit 05e956a

Browse files
committed
Add keep last frame demo
1 parent 54de87b commit 05e956a

7 files changed

Lines changed: 349 additions & 0 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@
106106
android:name=".DetailControlActivity"
107107
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
108108
android:screenOrientation="portrait" />
109+
<activity
110+
android:name=".KeepLastFrameDemoActivity"
111+
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
112+
android:screenOrientation="portrait" />
109113
<activity
110114
android:name=".DetailTransparentActivity"
111115
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package com.example.gsyvideoplayer;
2+
3+
import android.os.Bundle;
4+
import android.view.View;
5+
import android.widget.ImageView;
6+
7+
import com.example.gsyvideoplayer.databinding.ActivityKeepLastFrameDemoBinding;
8+
import com.example.gsyvideoplayer.video.KeepLastFrameVideo;
9+
import com.shuyu.gsyvideoplayer.GSYBaseActivityDetail;
10+
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder;
11+
12+
public class KeepLastFrameDemoActivity extends GSYBaseActivityDetail<KeepLastFrameVideo> {
13+
14+
private static final String DEMO_VIDEO_URL = "https://www.w3schools.com/html/mov_bbb.mp4";
15+
16+
private ActivityKeepLastFrameDemoBinding binding;
17+
18+
private boolean keepLastFrameWhenComplete = true;
19+
20+
@Override
21+
protected void onCreate(Bundle savedInstanceState) {
22+
super.onCreate(savedInstanceState);
23+
24+
binding = ActivityKeepLastFrameDemoBinding.inflate(getLayoutInflater());
25+
setContentView(binding.getRoot());
26+
27+
binding.detailPlayer.setKeepLastFrameWhenComplete(keepLastFrameWhenComplete);
28+
resolveNormalVideoUI();
29+
initVideoBuilderMode();
30+
updateModeText();
31+
32+
binding.keepToggle.setOnClickListener(new View.OnClickListener() {
33+
@Override
34+
public void onClick(View v) {
35+
keepLastFrameWhenComplete = !keepLastFrameWhenComplete;
36+
binding.detailPlayer.setKeepLastFrameWhenComplete(keepLastFrameWhenComplete);
37+
updateModeText();
38+
}
39+
});
40+
41+
binding.replay.setOnClickListener(new View.OnClickListener() {
42+
@Override
43+
public void onClick(View v) {
44+
binding.status.setText("重新开始播放");
45+
binding.detailPlayer.startPlayLogic();
46+
}
47+
});
48+
}
49+
50+
@Override
51+
public KeepLastFrameVideo getGSYVideoPlayer() {
52+
return binding.detailPlayer;
53+
}
54+
55+
@Override
56+
public GSYVideoOptionBuilder getGSYVideoOptionBuilder() {
57+
ImageView imageView = new ImageView(this);
58+
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
59+
imageView.setImageResource(R.mipmap.xxx1);
60+
61+
return new GSYVideoOptionBuilder()
62+
.setThumbImageView(imageView)
63+
.setUrl(DEMO_VIDEO_URL)
64+
.setCacheWithPlay(false)
65+
.setVideoTitle("最后一帧 Demo")
66+
.setIsTouchWiget(true)
67+
.setRotateViewAuto(false)
68+
.setLockLand(false)
69+
.setShowFullAnimation(false)
70+
.setNeedLockFull(true);
71+
}
72+
73+
@Override
74+
public void clickForFullScreen() {
75+
76+
}
77+
78+
@Override
79+
public boolean getDetailOrientationRotateAuto() {
80+
return false;
81+
}
82+
83+
@Override
84+
public void onPrepared(String url, Object... objects) {
85+
super.onPrepared(url, objects);
86+
binding.status.setText("播放中");
87+
}
88+
89+
@Override
90+
public void onClickStartIcon(String url, Object... objects) {
91+
binding.status.setText("开始播放");
92+
}
93+
94+
@Override
95+
public void onAutoComplete(String url, Object... objects) {
96+
boolean retained = isRetainedSurface(objects);
97+
if (keepLastFrameWhenComplete && retained) {
98+
binding.status.setText("播放完成:保留最后一帧");
99+
} else if (keepLastFrameWhenComplete) {
100+
binding.status.setText("播放完成:已开启保留,但当前渲染层没有可保留画面");
101+
} else {
102+
binding.status.setText("播放完成:默认封面态");
103+
}
104+
}
105+
106+
@Override
107+
public void onPlayError(String url, Object... objects) {
108+
binding.status.setText("播放失败");
109+
}
110+
111+
private void resolveNormalVideoUI() {
112+
binding.detailPlayer.getTitleTextView().setVisibility(View.GONE);
113+
binding.detailPlayer.getBackButton().setVisibility(View.GONE);
114+
}
115+
116+
private void updateModeText() {
117+
binding.keepToggle.setText(keepLastFrameWhenComplete ? "保留最后一帧:开" : "保留最后一帧:关");
118+
binding.status.setText(keepLastFrameWhenComplete ? "当前模式:完成后保留最后一帧" : "当前模式:完成后显示封面");
119+
}
120+
121+
private boolean isRetainedSurface(Object... objects) {
122+
if (objects != null) {
123+
for (Object object : objects) {
124+
if (object instanceof KeepLastFrameVideo) {
125+
return ((KeepLastFrameVideo) object).isLastAutoCompleteRetainedSurface();
126+
}
127+
}
128+
}
129+
return binding.detailPlayer.isLastAutoCompleteRetainedSurface();
130+
}
131+
}

app/src/main/java/com/example/gsyvideoplayer/MainActivity.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ protected void onCreate(Bundle savedInstanceState) {
6666
binding.inputType.setOnClickListener(this);
6767
binding.openBtnEmpty.setOnClickListener(this);
6868
binding.openControl.setOnClickListener(this);
69+
binding.keepLastFrameDemo.setOnClickListener(this);
6970
binding.openFilter.setOnClickListener(this);
7071
binding.openBtnPick.setOnClickListener(this);
7172
binding.openBtnAuto.setOnClickListener(this);
@@ -174,6 +175,9 @@ public void onClick(View view) {
174175
case R.id.open_control:
175176
JumpUtils.gotoControl(this);
176177
break;
178+
case R.id.keep_last_frame_demo:
179+
JumpUtils.gotoKeepLastFrameDemo(this);
180+
break;
177181
case R.id.open_filter:
178182
JumpUtils.gotoFilter(this);
179183
break;

app/src/main/java/com/example/gsyvideoplayer/utils/JumpUtils.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.example.gsyvideoplayer.DetailTransparentActivity;
2626
import com.example.gsyvideoplayer.FragmentVideoActivity;
2727
import com.example.gsyvideoplayer.InputUrlDetailActivity;
28+
import com.example.gsyvideoplayer.KeepLastFrameDemoActivity;
2829
import com.example.gsyvideoplayer.ListADVideoActivity2;
2930
import com.example.gsyvideoplayer.ListMultiVideoActivity;
3031
import com.example.gsyvideoplayer.ListVideo2Activity;
@@ -423,6 +424,11 @@ public static void gotoControl(Activity activity) {
423424
activity.startActivity(intent);
424425
}
425426

427+
public static void gotoKeepLastFrameDemo(Activity activity) {
428+
Intent intent = new Intent(activity, KeepLastFrameDemoActivity.class);
429+
activity.startActivity(intent);
430+
}
431+
426432
public static void gotoDetailTransparentActivity(Activity activity) {
427433
Intent intent = new Intent(activity, DetailTransparentActivity.class);
428434
activity.startActivity(intent);
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package com.example.gsyvideoplayer.video;
2+
3+
import android.app.Activity;
4+
import android.content.Context;
5+
import android.util.AttributeSet;
6+
import android.view.WindowManager;
7+
8+
import com.shuyu.gsyvideoplayer.utils.Debuger;
9+
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer;
10+
import com.shuyu.gsyvideoplayer.video.base.GSYBaseVideoPlayer;
11+
12+
import moe.codeest.enviews.ENDownloadView;
13+
14+
/**
15+
* Demo-only player that keeps the current render view on natural playback completion.
16+
*/
17+
public class KeepLastFrameVideo extends StandardGSYVideoPlayer {
18+
19+
private boolean mKeepLastFrameWhenComplete = true;
20+
21+
private boolean mLastAutoCompleteRetainedSurface;
22+
23+
public KeepLastFrameVideo(Context context, Boolean fullFlag) {
24+
super(context, fullFlag);
25+
}
26+
27+
public KeepLastFrameVideo(Context context) {
28+
super(context);
29+
}
30+
31+
public KeepLastFrameVideo(Context context, AttributeSet attrs) {
32+
super(context, attrs);
33+
}
34+
35+
@Override
36+
public void onAutoCompletion() {
37+
if (!mKeepLastFrameWhenComplete) {
38+
mLastAutoCompleteRetainedSurface = false;
39+
super.onAutoCompletion();
40+
return;
41+
}
42+
43+
mLastAutoCompleteRetainedSurface = mTextureViewContainer != null
44+
&& mTextureViewContainer.getChildCount() > 0;
45+
46+
setStateAndUi(CURRENT_STATE_AUTO_COMPLETE);
47+
48+
mSaveChangeViewTIme = 0;
49+
mCurrentPosition = 0;
50+
51+
if (!mIfCurrentIsFullscreen) {
52+
getGSYVideoManager().setLastListener(null);
53+
}
54+
55+
if (mAudioFocusManager != null) {
56+
mAudioFocusManager.abandonAudioFocus();
57+
}
58+
if (mContext instanceof Activity) {
59+
try {
60+
((Activity) mContext).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
61+
} catch (Exception e) {
62+
e.printStackTrace();
63+
}
64+
}
65+
releaseNetWorkState();
66+
67+
if (mVideoAllCallBack != null && isCurrentMediaListener()) {
68+
Debuger.printfLog("onAutoComplete keepLastFrame");
69+
mVideoAllCallBack.onAutoComplete(mOriginUrl, mTitle, this);
70+
}
71+
mHadPlay = false;
72+
}
73+
74+
@Override
75+
public void onCompletion() {
76+
mLastAutoCompleteRetainedSurface = false;
77+
super.onCompletion();
78+
}
79+
80+
@Override
81+
protected void startButtonLogic() {
82+
mLastAutoCompleteRetainedSurface = false;
83+
super.startButtonLogic();
84+
}
85+
86+
@Override
87+
protected void changeUiToCompleteShow() {
88+
if (!mKeepLastFrameWhenComplete) {
89+
super.changeUiToCompleteShow();
90+
return;
91+
}
92+
93+
Debuger.printfLog("changeUiToCompleteShow keepLastFrame");
94+
95+
setViewShowState(mTopContainer, VISIBLE);
96+
setViewShowState(mBottomContainer, VISIBLE);
97+
setViewShowState(mStartButton, VISIBLE);
98+
setViewShowState(mLoadingProgressBar, INVISIBLE);
99+
setViewShowState(mThumbImageViewLayout, INVISIBLE);
100+
setViewShowState(mBottomProgressBar, INVISIBLE);
101+
setViewShowState(mLockScreen, (mIfCurrentIsFullscreen && mNeedLockFull) ? VISIBLE : GONE);
102+
103+
if (mLoadingProgressBar instanceof ENDownloadView) {
104+
((ENDownloadView) mLoadingProgressBar).reset();
105+
}
106+
updateStartImage();
107+
}
108+
109+
@Override
110+
protected void cloneParams(GSYBaseVideoPlayer from, GSYBaseVideoPlayer to) {
111+
if (from instanceof KeepLastFrameVideo && to instanceof KeepLastFrameVideo) {
112+
KeepLastFrameVideo fromPlayer = (KeepLastFrameVideo) from;
113+
KeepLastFrameVideo toPlayer = (KeepLastFrameVideo) to;
114+
toPlayer.mKeepLastFrameWhenComplete = fromPlayer.mKeepLastFrameWhenComplete;
115+
toPlayer.mLastAutoCompleteRetainedSurface = fromPlayer.mLastAutoCompleteRetainedSurface;
116+
}
117+
super.cloneParams(from, to);
118+
if (from instanceof KeepLastFrameVideo && to instanceof KeepLastFrameVideo) {
119+
KeepLastFrameVideo fromPlayer = (KeepLastFrameVideo) from;
120+
KeepLastFrameVideo toPlayer = (KeepLastFrameVideo) to;
121+
toPlayer.mKeepLastFrameWhenComplete = fromPlayer.mKeepLastFrameWhenComplete;
122+
toPlayer.mLastAutoCompleteRetainedSurface = fromPlayer.mLastAutoCompleteRetainedSurface;
123+
}
124+
}
125+
126+
public void setKeepLastFrameWhenComplete(boolean keepLastFrameWhenComplete) {
127+
this.mKeepLastFrameWhenComplete = keepLastFrameWhenComplete;
128+
}
129+
130+
public boolean isKeepLastFrameWhenComplete() {
131+
return mKeepLastFrameWhenComplete;
132+
}
133+
134+
public boolean isLastAutoCompleteRetainedSurface() {
135+
return mLastAutoCompleteRetainedSurface;
136+
}
137+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:id="@+id/activity_keep_last_frame_demo"
4+
android:layout_width="match_parent"
5+
android:layout_height="match_parent"
6+
android:fitsSystemWindows="true">
7+
8+
<com.example.gsyvideoplayer.video.KeepLastFrameVideo
9+
android:id="@+id/detail_player"
10+
android:layout_width="match_parent"
11+
android:layout_height="@dimen/post_media_height" />
12+
13+
<LinearLayout
14+
android:id="@+id/control_panel"
15+
android:layout_width="match_parent"
16+
android:layout_height="wrap_content"
17+
android:layout_below="@id/detail_player"
18+
android:orientation="vertical"
19+
android:padding="12dp">
20+
21+
<LinearLayout
22+
android:layout_width="match_parent"
23+
android:layout_height="wrap_content"
24+
android:orientation="horizontal">
25+
26+
<Button
27+
android:id="@+id/keep_toggle"
28+
android:layout_width="wrap_content"
29+
android:layout_height="wrap_content"
30+
android:text="保留最后一帧:开" />
31+
32+
<Button
33+
android:id="@+id/replay"
34+
android:layout_width="wrap_content"
35+
android:layout_height="wrap_content"
36+
android:layout_marginLeft="12dp"
37+
android:layout_marginStart="12dp"
38+
android:text="重新播放" />
39+
40+
</LinearLayout>
41+
42+
<TextView
43+
android:id="@+id/status"
44+
android:layout_width="match_parent"
45+
android:layout_height="wrap_content"
46+
android:layout_marginTop="12dp"
47+
android:text="当前模式:完成后保留最后一帧"
48+
android:textColor="#333333"
49+
android:textSize="16sp" />
50+
51+
<TextView
52+
android:layout_width="match_parent"
53+
android:layout_height="wrap_content"
54+
android:layout_marginTop="12dp"
55+
android:text="这个页面只验证自然播放完成。退出、返回、错误释放仍然走原播放器释放逻辑。"
56+
android:textColor="#666666"
57+
android:textSize="14sp" />
58+
59+
</LinearLayout>
60+
</RelativeLayout>

app/src/main/res/layout/activity_main.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@
3636
android:layout_marginTop="20dp"
3737
android:text="带控制DEMO" />
3838

39+
<Button
40+
android:id="@+id/keep_last_frame_demo"
41+
android:layout_width="240dp"
42+
android:layout_height="wrap_content"
43+
android:layout_marginTop="20dp"
44+
android:text="完成保留最后一帧" />
45+
3946
<Button
4047
android:id="@+id/transparent"
4148
android:layout_width="240dp"

0 commit comments

Comments
 (0)