Android media projection生成一个空电影文件
我正在尝试创建一个简单的screencast应用程序,它将捕获屏幕并保存到电影文件中。到目前为止,我的应用程序只生成正确长度和大小的空电影文件(黑屏)。我不确定这是否有帮助,但当我运行应用程序时,我会在logcat中收到这些消息Android media projection生成一个空电影文件,android,android-5.0-lollipop,android-mediacodec,android-mediaprojection,Android,Android 5.0 Lollipop,Android Mediacodec,Android Mediaprojection,我正在尝试创建一个简单的screencast应用程序,它将捕获屏幕并保存到电影文件中。到目前为止,我的应用程序只生成正确长度和大小的空电影文件(黑屏)。我不确定这是否有帮助,但当我运行应用程序时,我会在logcat中收到这些消息 08-29 14:47:57.722 1973-1991/com.example.stw.myapplication W/EGL_emulation﹕ eglSurfaceAttrib not implemented 08-29 14:47:57.722 1
08-29 14:47:57.722 1973-1991/com.example.stw.myapplication W/EGL_emulation﹕ eglSurfaceAttrib not implemented
08-29 14:47:57.722 1973-1991/com.example.stw.myapplication W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xabdbee60, error=EGL_SUCCESS
08-29 14:47:58.870 1973-1991/com.example.stw.myapplication E/Surface﹕ getSlotFromBufferLocked: unknown buffer: 0xab659760
08-29 14:47:58.875 1973-1991/com.example.kamil.myapplication D/OpenGLRenderer﹕ endAllStagingAnimators on 0xab32c580 (ListPopupWindow$DropDownListView) with handle 0xa333d8d0
08-29 14:48:00.652 1973-1973/com.example.kamil.myapplication D/MPEG4Writer﹕ Video track stopping
08-29 14:48:00.652 1973-1973/com.example.kamil.myapplication D/MPEG4Writer﹕ Video track source stopping
08-29 14:48:00.652 1973-1973/com.example.kamil.myapplication D/MPEG4Writer﹕ Video track source stopped
除此之外,这些信息似乎无关紧要。
我会发布一些代码,也许会有帮助。
我得到了表面
mInputSurface = mVideoEncoder.createInputSurface();
因此,我正在创建虚拟显示:
mMediaProjection.createVirtualDisplay("Recording Display", screenWidth,
screenHeight, screenDensity, 0 /* flags */, mInputSurface,
null /* callback */, null /* handler */);
然后调用此方法:
private void prepareVideoEncoder() {
mVideoBufferInfo = new MediaCodec.BufferInfo();
MediaFormat format = MediaFormat.createVideoFormat(VIDEO_MIME_TYPE, VIDEO_WIDTH, VIDEO_HEIGHT);
int frameRate = 30; // 30 fps
// Set some required properties. The media codec may fail if these aren't defined.
format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
format.setInteger(MediaFormat.KEY_BIT_RATE, 6000000); // 6Mbps
format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
format.setInteger(MediaFormat.KEY_CAPTURE_RATE, frameRate);
format.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 1000000 / frameRate);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); // 1 seconds between I-frames
// Create a MediaCodec encoder and configure it. Get a Surface we can use for recording into.
try {
mVideoEncoder = MediaCodec.createEncoderByType(VIDEO_MIME_TYPE);
mVideoEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mInputSurface = mVideoEncoder.createInputSurface();
mVideoEncoder.start();
} catch (IOException e) {
releaseEncoders();
}
}
然后,当用户单击停止录制时,我会释放编码器,如下所示:
private void releaseEncoders() {
mDrainHandler.removeCallbacks(mDrainEncoderRunnable);
if (mMuxer != null) {
if (mMuxerStarted) {
mMuxer.stop();
}
mMuxer.release();
mMuxer = null;
mMuxerStarted = false;
}
if (mVideoEncoder != null) {
mVideoEncoder.stop();
mVideoEncoder.release();
mVideoEncoder = null;
}
if (mInputSurface != null) {
mInputSurface.release();
mInputSurface = null;
}
if (mMediaProjection != null) {
mMediaProjection.stop();
mMediaProjection = null;
}
mVideoBufferInfo = null;
mDrainEncoderRunnable = null;
mTrackIndex = -1;
}
谢谢你的帮助。希望你们能发现我漏掉的东西。如果你的描述是真的,你应该在某个地方遇到
NullPointerException
。您指示在prepareVideoEncoder()
之前调用mVideoEncoder.createInputSurface()
,但它在prepareVideoEncoder()
中填充mVideoEncoder
。我没有播放屏幕录音,只是屏幕截图。然而,Jake Wharton的电视电影没有使用MediaCodec
,而是使用MediaRecorder
:啊,对不起,我的问题有点误导,我只在方法prepareVideoEncoder()中使用了mvideEncoder.createInputSurface(),我不知道为什么我在那里插入了第一行。你找到了解决方案吗?我面临着类似的问题,这仅仅是因为它不能在模拟器上工作,在真实的设备上测试你的应用程序,它应该可以工作。显然,模拟器上的视频编码还不能正常工作。这对全屏分辨率的编码有效吗?我听说MediaCodec太慢了,应该使用MediaRecorder。如果你的描述是真的,你应该在某个地方遇到NullPointerException
。您指示在prepareVideoEncoder()
之前调用mVideoEncoder.createInputSurface()
,但它在prepareVideoEncoder()
中填充mVideoEncoder
。我没有播放屏幕录音,只是屏幕截图。然而,Jake Wharton的电视电影没有使用MediaCodec
,而是使用MediaRecorder
:啊,对不起,我的问题有点误导,我只在方法prepareVideoEncoder()中使用了mvideEncoder.createInputSurface(),我不知道为什么我在那里插入了第一行。你找到了解决方案吗?我面临着类似的问题,这仅仅是因为它不能在模拟器上工作,在真实的设备上测试你的应用程序,它应该可以工作。显然,模拟器上的视频编码还不能正常工作。这对全屏分辨率的编码有效吗?我听说MediaCodec太慢了,应该使用MediaRecorder。