使用MediaProjection+MediaCodec+AudioRecord+MediaMuxer将屏幕内容录制成视频文件(完成度很差)
参考链接: 其中第三个最好
GitHub - ChinaZeng/SurfaceRecodeDemo
MediaCodec录制音视频,并将合成为一个文件 - 简书 (jianshu.com)
安卓录屏的解决方案:
adb shell命令screenrecord
MediaRecorder+MediaProjection
MediaProjection+MediaCodec+AudioRecord+MediaMuxer
此外:Android 为开发者提供了MediaRecorder的类,可以帮助录屏。但是重要的缺陷:
- MediaRecorder控制粒度很粗,无法完成更多的自定义功能,如对音频数据处理
- MediaRecorder录制的效果很差,特别是音频效果。
模块介绍
MediaProjection:Android提供的截图、录屏的模块,可以提供一个surface;
MediaProjection | Android Developers (google.cn)
28以后,不能在活动申请录屏对象,必须有前台服务,实现弹窗方法提示用户,还得有通知才能用。
AudioRecord : Android音频录制的重要的模块,可以读取到PCM裸流数据;
MediaCodec:音视频硬编解码的重要模块,这里负责两项工作:
将PCM音频硬编码压缩AAC格式
将提供的surface的视频数据硬编码成H264格式
MeidaMuxer:音视频混合器,负责将AAC、H264合成mp4格式;
BUG
- 像素奇数
android.media.MediaCodec$CodecException: Error 0xfffffc0e-CSDN博客
录屏的长宽中存在奇数。
-
录的视频无法播放
是因为编码原因:在MediaCodec的onOutputFormatChanged回调中调用这个
mVideoTrack = mMediaMuxer.addTrack(mediaFormat);
mMediaMuxer.start();在onOutputBufferAvailable回调中调用
mMediaMuxer.writeSampleData(mVideoTrack, byteBuffer, bufferInfo);
Code
代码基本参考GitHub - ChinaZeng/SurfaceRecodeDemo
所以没必要展示了
学习
1.
Android 屏幕直播分享之MediaProjection和MediaCodec分析 - 简书 (jianshu.com)
对于录屏,需要通过用户获取录屏权限,以及一个前台通知。
surface的创建:
在创建VirtualDisplay时,注意如下:
a.width、height分别代表录制display对应的宽和高像素大小;
b.surface传值不能为null,为null时,没有屏幕数据产出;
c.当surface为surfaceView.getHolder().getSurface()时,录屏会直接在surfaceView上显示,在加载surfaceview时,需要执行surfaceView.getHolder().setFixedSize(VIDEO_WIDTH, VIDEO_HEIGHT),VIDEO_WIDTH和VIDEO_HEIGHT需要跟createVirtualDisplay时传入的width和height保持一致,否则的话,surfaceview内的视频会有拉伸或位移 ;
d.当surface = vencoder.createInputSurface()时,获取MediaCodec的surface,这个surface其实就是一个入口,屏幕作为输入源就会进入这个入口,然后交给MediaCodec编码,可以将数据通过网络传输给其他设备显示。
2.
Camera2+MediaCodec+AudioRecord+MediaMuxer实现录制功能(带源码)_camera2 录制-CSDN博客
3.
这篇博客给了一个较好的模型设计,分析了不同模块间的关联