Android - 如何使用 MediaRecorder 实时获取屏幕录像的帧数
Android - How to get a screen recording's frames in real time using MediaRecorder
我正在尝试创建一个应用程序来记录设备的屏幕并将其逐帧显示到 ImageView。到目前为止,我只实现了一个来自这个 link 的屏幕录像机。当录制停止时,它被保存到一个文件中。我不想将记录保存到文件中,而是希望检索每一帧并显示到 ImageView。使用 MediaRecorder API,有什么办法可以做到这一点吗?
RecordingSession.java
class RecordingSession
implements MediaScannerConnection.OnScanCompletedListener {
static final int VIRT_DISPLAY_FLAGS=
DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY |
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
private RecordingConfig config;
private final File output;
private final Context ctxt;
private final ToneGenerator beeper;
private MediaRecorder recorder;
private MediaProjection projection;
private VirtualDisplay vdisplay;
RecordingSession(Context ctxt, RecordingConfig config,
MediaProjection projection) {
this.ctxt=ctxt.getApplicationContext();
this.config=config;
this.projection=projection;
this.beeper=new ToneGenerator(
AudioManager.STREAM_NOTIFICATION, 100);
output=new File(ctxt.getExternalFilesDir(null), "andcorder.mp4");
output.getParentFile().mkdirs();
}
void start() {
recorder=new MediaRecorder();
recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoFrameRate(config.frameRate);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setVideoSize(config.width, config.height);
recorder.setVideoEncodingBitRate(config.bitRate);
recorder.setOutputFile(output.getAbsolutePath());
try {
recorder.prepare();
vdisplay=projection.createVirtualDisplay("andcorder",
config.width, config.height, config.density,
VIRT_DISPLAY_FLAGS, recorder.getSurface(), null, null);
beeper.startTone(ToneGenerator.TONE_PROP_ACK);
recorder.start();
}
catch (IOException e) {
throw new RuntimeException("Exception preparing recorder", e);
}
}
void stop() {
projection.stop();
recorder.stop();
recorder.release();
vdisplay.release();
MediaScannerConnection.scanFile(ctxt,
new String[]{output.getAbsolutePath()}, null, this);
}
@Override
public void onScanCompleted(String path, Uri uri) {
beeper.startTone(ToneGenerator.TONE_PROP_NACK);
}
}
你不会为此做一个ImageView。您会使用 SurfaceView。它旨在用于媒体播放等用途。 https://developer.android.com/reference/android/view/SurfaceView?hl=en
您可以在 Google 上找到大量有关如何使用它的示例,例如 https://gist.github.com/scottgwald/7743453
我正在尝试创建一个应用程序来记录设备的屏幕并将其逐帧显示到 ImageView。到目前为止,我只实现了一个来自这个 link 的屏幕录像机。当录制停止时,它被保存到一个文件中。我不想将记录保存到文件中,而是希望检索每一帧并显示到 ImageView。使用 MediaRecorder API,有什么办法可以做到这一点吗?
RecordingSession.java
class RecordingSession
implements MediaScannerConnection.OnScanCompletedListener {
static final int VIRT_DISPLAY_FLAGS=
DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY |
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
private RecordingConfig config;
private final File output;
private final Context ctxt;
private final ToneGenerator beeper;
private MediaRecorder recorder;
private MediaProjection projection;
private VirtualDisplay vdisplay;
RecordingSession(Context ctxt, RecordingConfig config,
MediaProjection projection) {
this.ctxt=ctxt.getApplicationContext();
this.config=config;
this.projection=projection;
this.beeper=new ToneGenerator(
AudioManager.STREAM_NOTIFICATION, 100);
output=new File(ctxt.getExternalFilesDir(null), "andcorder.mp4");
output.getParentFile().mkdirs();
}
void start() {
recorder=new MediaRecorder();
recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoFrameRate(config.frameRate);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setVideoSize(config.width, config.height);
recorder.setVideoEncodingBitRate(config.bitRate);
recorder.setOutputFile(output.getAbsolutePath());
try {
recorder.prepare();
vdisplay=projection.createVirtualDisplay("andcorder",
config.width, config.height, config.density,
VIRT_DISPLAY_FLAGS, recorder.getSurface(), null, null);
beeper.startTone(ToneGenerator.TONE_PROP_ACK);
recorder.start();
}
catch (IOException e) {
throw new RuntimeException("Exception preparing recorder", e);
}
}
void stop() {
projection.stop();
recorder.stop();
recorder.release();
vdisplay.release();
MediaScannerConnection.scanFile(ctxt,
new String[]{output.getAbsolutePath()}, null, this);
}
@Override
public void onScanCompleted(String path, Uri uri) {
beeper.startTone(ToneGenerator.TONE_PROP_NACK);
}
}
你不会为此做一个ImageView。您会使用 SurfaceView。它旨在用于媒体播放等用途。 https://developer.android.com/reference/android/view/SurfaceView?hl=en
您可以在 Google 上找到大量有关如何使用它的示例,例如 https://gist.github.com/scottgwald/7743453