Skip to content

Commit 5149f2c

Browse files
committed
Fix screenshot callbacks and composed capture
1 parent 05e956a commit 5149f2c

10 files changed

Lines changed: 424 additions & 55 deletions

File tree

app/src/main/java/com/example/gsyvideoplayer/mediacodec/MediaCodecTextureView.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ public Bitmap initCoverHigh() {
157157
*/
158158
@Override
159159
public void taskShotPic(GSYVideoShotListener gsyVideoShotListener, boolean shotHigh) {
160+
if (gsyVideoShotListener == null) {
161+
return;
162+
}
160163
if (shotHigh) {
161164
gsyVideoShotListener.getBitmap(initCoverHigh());
162165
} else {
@@ -174,11 +177,9 @@ public void saveFrame(final File file, final boolean high, final GSYVideoShotSav
174177
GSYVideoShotListener gsyVideoShotListener = new GSYVideoShotListener() {
175178
@Override
176179
public void getBitmap(Bitmap bitmap) {
177-
if (bitmap == null) {
178-
gsyVideoShotSaveListener.result(false, file);
179-
} else {
180-
FileUtils.saveBitmap(bitmap, file);
181-
gsyVideoShotSaveListener.result(true, file);
180+
boolean success = bitmap != null && FileUtils.saveBitmapToFile(bitmap, file);
181+
if (gsyVideoShotSaveListener != null) {
182+
gsyVideoShotSaveListener.result(success, file);
182183
}
183184
}
184185
};

app/src/main/java/com/example/gsyvideoplayer/view/CustomTextureSurface.java

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
import android.content.Context;
44
import android.graphics.Bitmap;
55
import android.graphics.Matrix;
6+
import android.os.Build;
7+
import android.os.Handler;
8+
import android.os.HandlerThread;
9+
import android.os.Looper;
610
import android.util.AttributeSet;
11+
import android.view.PixelCopy;
712
import android.view.SurfaceHolder;
813
import android.view.SurfaceView;
914
import android.view.View;
@@ -16,6 +21,8 @@
1621
import com.shuyu.gsyvideoplayer.render.view.GSYVideoGLView;
1722
import com.shuyu.gsyvideoplayer.render.view.IGSYRenderView;
1823
import com.shuyu.gsyvideoplayer.render.view.listener.IGSYSurfaceListener;
24+
import com.shuyu.gsyvideoplayer.utils.Debuger;
25+
import com.shuyu.gsyvideoplayer.utils.FileUtils;
1926
import com.shuyu.gsyvideoplayer.utils.MeasureHelper;
2027

2128
import java.io.File;
@@ -110,12 +117,69 @@ public int getSizeW() {
110117

111118
@Override
112119
public void taskShotPic(GSYVideoShotListener gsyVideoShotListener, boolean shotHigh) {
120+
if (gsyVideoShotListener == null) {
121+
return;
122+
}
123+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
124+
Debuger.printfLog(getClass().getSimpleName() +
125+
" Build.VERSION.SDK_INT < Build.VERSION_CODES.N not support taskShotPic now");
126+
gsyVideoShotListener.getBitmap(null);
127+
return;
128+
}
129+
130+
final Bitmap bitmap = shotHigh ? initCoverHigh() : initCover();
131+
if (bitmap == null || getHolder() == null || getHolder().getSurface() == null
132+
|| !getHolder().getSurface().isValid()) {
133+
gsyVideoShotListener.getBitmap(null);
134+
return;
135+
}
113136

137+
final Handler mainHandler = new Handler(Looper.getMainLooper());
138+
final HandlerThread handlerThread = new HandlerThread("GSY-CustomPixelCopy");
139+
try {
140+
handlerThread.start();
141+
PixelCopy.request(this, bitmap, new PixelCopy.OnPixelCopyFinishedListener() {
142+
@Override
143+
public void onPixelCopyFinished(int copyResult) {
144+
final Bitmap result;
145+
if (copyResult == PixelCopy.SUCCESS) {
146+
result = bitmap;
147+
} else {
148+
if (!bitmap.isRecycled()) {
149+
bitmap.recycle();
150+
}
151+
result = null;
152+
}
153+
handlerThread.quitSafely();
154+
mainHandler.post(new Runnable() {
155+
@Override
156+
public void run() {
157+
gsyVideoShotListener.getBitmap(result);
158+
}
159+
});
160+
}
161+
}, new Handler(handlerThread.getLooper()));
162+
} catch (Exception e) {
163+
e.printStackTrace();
164+
handlerThread.quitSafely();
165+
if (!bitmap.isRecycled()) {
166+
bitmap.recycle();
167+
}
168+
gsyVideoShotListener.getBitmap(null);
169+
}
114170
}
115171

116172
@Override
117173
public void saveFrame(File file, boolean high, GSYVideoShotSaveListener gsyVideoShotSaveListener) {
118-
174+
taskShotPic(new GSYVideoShotListener() {
175+
@Override
176+
public void getBitmap(Bitmap bitmap) {
177+
boolean success = bitmap != null && FileUtils.saveBitmapToFile(bitmap, file);
178+
if (gsyVideoShotSaveListener != null) {
179+
gsyVideoShotSaveListener.result(success, file);
180+
}
181+
}
182+
}, high);
119183
}
120184

121185
@Override
@@ -125,12 +189,18 @@ public View getRenderView() {
125189

126190
@Override
127191
public Bitmap initCover() {
128-
return null;
192+
if (getSizeW() <= 0 || getSizeH() <= 0) {
193+
return null;
194+
}
195+
return Bitmap.createBitmap(getSizeW(), getSizeH(), Bitmap.Config.RGB_565);
129196
}
130197

131198
@Override
132199
public Bitmap initCoverHigh() {
133-
return null;
200+
if (getSizeW() <= 0 || getSizeH() <= 0) {
201+
return null;
202+
}
203+
return Bitmap.createBitmap(getSizeW(), getSizeH(), Bitmap.Config.ARGB_8888);
134204
}
135205

136206
@Override

gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/render/GSYRenderView.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,11 @@ public void taskShotPic(GSYVideoShotListener gsyVideoShotListener) {
136136
* @param shotHigh 是否需要高清的
137137
*/
138138
public void taskShotPic(GSYVideoShotListener gsyVideoShotListener, boolean shotHigh) {
139-
if (mShowView != null)
139+
if (mShowView != null) {
140140
mShowView.taskShotPic(gsyVideoShotListener, shotHigh);
141+
} else if (gsyVideoShotListener != null) {
142+
gsyVideoShotListener.getBitmap(null);
143+
}
141144
}
142145

143146
/**
@@ -153,8 +156,11 @@ public void saveFrame(final File file, GSYVideoShotSaveListener gsyVideoShotSave
153156
* @param high 是否需要高清的
154157
*/
155158
public void saveFrame(final File file, final boolean high, final GSYVideoShotSaveListener gsyVideoShotSaveListener) {
156-
if (mShowView != null)
159+
if (mShowView != null) {
157160
mShowView.saveFrame(file, high, gsyVideoShotSaveListener);
161+
} else if (gsyVideoShotSaveListener != null) {
162+
gsyVideoShotSaveListener.result(false, file);
163+
}
158164
}
159165

160166
/**

gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/render/glrender/GSYVideoGLViewBaseRender.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public abstract class GSYVideoGLViewBaseRender implements GLSurfaceView.Renderer
5252

5353
protected GSYVideoGLRenderErrorListener mGSYVideoGLRenderErrorListener;
5454

55+
protected GSYVideoShotListener mGSYVideoShotListener;
56+
5557
protected Handler mHandler = new Handler();
5658

5759
public abstract void releaseAll();
@@ -191,12 +193,24 @@ public void setMVPMatrix(float[] MVPMatrix) {
191193
* 打开截图
192194
*/
193195
public void takeShotPic() {
196+
final GSYVideoShotListener listener = mGSYVideoShotListener;
197+
mGSYVideoShotListener = null;
198+
if (listener != null) {
199+
mHandler.post(new Runnable() {
200+
@Override
201+
public void run() {
202+
listener.getBitmap(null);
203+
}
204+
});
205+
}
194206
}
195207

196208
/**
197209
* 截图监听
198210
*/
199211
public void setGSYVideoShotListener(GSYVideoShotListener listener, boolean high) {
212+
this.mGSYVideoShotListener = listener;
213+
this.mHighShot = high;
200214
}
201215

202216
/**
@@ -257,4 +271,3 @@ public void setGSYVideoGLRenderErrorListener(GSYVideoGLRenderErrorListener video
257271
}
258272
}
259273

260-

gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/render/glrender/GSYVideoGLViewSimpleRender.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ public class GSYVideoGLViewSimpleRender extends GSYVideoGLViewBaseRender {
7777

7878
private SurfaceTexture mSurface;
7979

80-
private GSYVideoShotListener mGSYVideoShotListener;
81-
8280
private GSYVideoGLView.ShaderInterface mEffect = new NoEffect();
8381

8482
public GSYVideoGLViewSimpleRender() {
@@ -231,8 +229,25 @@ protected void takeBitmap(GL10 glUnused) {
231229
if (mTakeShotPic) {
232230
mTakeShotPic = false;
233231
if (mGSYVideoShotListener != null) {
234-
Bitmap bitmap = createBitmapFromGLSurface(0, 0, mSurfaceView.getWidth(), mSurfaceView.getHeight(), glUnused);
235-
mGSYVideoShotListener.getBitmap(bitmap);
232+
final GSYVideoShotListener listener = mGSYVideoShotListener;
233+
mGSYVideoShotListener = null;
234+
int width = mSurfaceView != null ? mSurfaceView.getWidth() : 0;
235+
int height = mSurfaceView != null ? mSurfaceView.getHeight() : 0;
236+
Bitmap bitmap = null;
237+
if (width > 0 && height > 0) {
238+
try {
239+
bitmap = createBitmapFromGLSurface(0, 0, width, height, glUnused);
240+
} catch (Exception e) {
241+
e.printStackTrace();
242+
}
243+
}
244+
final Bitmap result = bitmap;
245+
mHandler.post(new Runnable() {
246+
@Override
247+
public void run() {
248+
listener.getBitmap(result);
249+
}
250+
});
236251
}
237252
}
238253
}
@@ -311,9 +326,6 @@ public void takeShotPic() {
311326
* 截图监听
312327
*/
313328
public void setGSYVideoShotListener(GSYVideoShotListener listener, boolean high) {
314-
this.mGSYVideoShotListener = listener;
315-
this.mHighShot = high;
329+
super.setGSYVideoShotListener(listener, high);
316330
}
317331
}
318-
319-

gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/render/view/GSYSurfaceView.java

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import android.os.Build;
1212
import android.os.Handler;
1313
import android.os.HandlerThread;
14+
import android.os.Looper;
1415
import android.util.AttributeSet;
1516
import android.view.PixelCopy;
1617
import android.view.SurfaceHolder;
@@ -140,31 +141,61 @@ public Bitmap initCoverHigh() {
140141
* @param shotHigh 是否需要高清的
141142
*/
142143
public void taskShotPic(GSYVideoShotListener gsyVideoShotListener, boolean shotHigh) {
143-
Bitmap bitmap;
144+
if (gsyVideoShotListener == null) {
145+
return;
146+
}
147+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
148+
Debuger.printfLog(getClass().getSimpleName() +
149+
" Build.VERSION.SDK_INT < Build.VERSION_CODES.N not support taskShotPic now");
150+
gsyVideoShotListener.getBitmap(null);
151+
return;
152+
}
153+
154+
final Bitmap bitmap;
144155
if (shotHigh) {
145156
bitmap = initCoverHigh();
146157
} else {
147158
bitmap = initCover();
148159
}
160+
161+
if (bitmap == null || getHolder() == null || getHolder().getSurface() == null
162+
|| !getHolder().getSurface().isValid()) {
163+
gsyVideoShotListener.getBitmap(null);
164+
return;
165+
}
166+
167+
final Handler mainHandler = new Handler(Looper.getMainLooper());
168+
final HandlerThread handlerThread = new HandlerThread("GSY-PixelCopy");
149169
try {
150-
HandlerThread handlerThread = new HandlerThread("PixelCopier");
151170
handlerThread.start();
152-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
153-
PixelCopy.request(this, bitmap, new PixelCopy.OnPixelCopyFinishedListener() {
154-
@Override
155-
public void onPixelCopyFinished(int copyResult) {
156-
if (copyResult == PixelCopy.SUCCESS) {
157-
gsyVideoShotListener.getBitmap(bitmap);
171+
PixelCopy.request(this, bitmap, new PixelCopy.OnPixelCopyFinishedListener() {
172+
@Override
173+
public void onPixelCopyFinished(int copyResult) {
174+
final Bitmap result;
175+
if (copyResult == PixelCopy.SUCCESS) {
176+
result = bitmap;
177+
} else {
178+
if (!bitmap.isRecycled()) {
179+
bitmap.recycle();
158180
}
159-
handlerThread.quitSafely();
181+
result = null;
160182
}
161-
}, new Handler());
162-
} else {
163-
Debuger.printfLog(getClass().getSimpleName() +
164-
" Build.VERSION.SDK_INT < Build.VERSION_CODES.N not support taskShotPic now");
165-
}
183+
handlerThread.quitSafely();
184+
mainHandler.post(new Runnable() {
185+
@Override
186+
public void run() {
187+
gsyVideoShotListener.getBitmap(result);
188+
}
189+
});
190+
}
191+
}, new Handler(handlerThread.getLooper()));
166192
} catch (Exception e) {
167193
e.printStackTrace();
194+
handlerThread.quitSafely();
195+
if (!bitmap.isRecycled()) {
196+
bitmap.recycle();
197+
}
198+
gsyVideoShotListener.getBitmap(null);
168199
}
169200
}
170201

@@ -174,7 +205,15 @@ public void onPixelCopyFinished(int copyResult) {
174205
* @param high 是否需要高清的
175206
*/
176207
public void saveFrame(final File file, final boolean high, final GSYVideoShotSaveListener gsyVideoShotSaveListener) {
177-
Debuger.printfLog(getClass().getSimpleName() + " not support saveFrame now, use taskShotPic");
208+
taskShotPic(new GSYVideoShotListener() {
209+
@Override
210+
public void getBitmap(Bitmap bitmap) {
211+
boolean success = bitmap != null && FileUtils.saveBitmapToFile(bitmap, file);
212+
if (gsyVideoShotSaveListener != null) {
213+
gsyVideoShotSaveListener.result(success, file);
214+
}
215+
}
216+
}, high);
178217
}
179218

180219
@Override

gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/render/view/GSYTextureView.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ public Bitmap initCoverHigh() {
164164
*/
165165
@Override
166166
public void taskShotPic(GSYVideoShotListener gsyVideoShotListener, boolean shotHigh) {
167+
if (gsyVideoShotListener == null) {
168+
return;
169+
}
167170
if (shotHigh) {
168171
gsyVideoShotListener.getBitmap(initCoverHigh());
169172
} else {
@@ -181,11 +184,9 @@ public void saveFrame(final File file, final boolean high, final GSYVideoShotSav
181184
GSYVideoShotListener gsyVideoShotListener = new GSYVideoShotListener() {
182185
@Override
183186
public void getBitmap(Bitmap bitmap) {
184-
if (bitmap == null) {
185-
gsyVideoShotSaveListener.result(false, file);
186-
} else {
187-
FileUtils.saveBitmap(bitmap, file);
188-
gsyVideoShotSaveListener.result(true, file);
187+
boolean success = bitmap != null && FileUtils.saveBitmapToFile(bitmap, file);
188+
if (gsyVideoShotSaveListener != null) {
189+
gsyVideoShotSaveListener.result(success, file);
189190
}
190191
}
191192
};

0 commit comments

Comments
 (0)