Android使用MediaCodec录屏、录音小结

Android使用MediaCodec录屏、录音小结

MediaCode录屏、录音更灵活,尤其是对录音有要求的场景


大致思路

创建MediaCodec 分别对音频、视频编码,最终通过MediaMuxer进行混合保存;其中音频通过AudioRecord获取数据、视频通过MediaProjection创建虚拟屏并传入MediaCodec创建的Surface获取视频数据。

踩过的坑

1、通过MediaMuxer保存时一定要先将音频、视频两个轨道通过MediaMuxer.addTrack添加完成后,再执行MediaMuxer的start动作;
2、通过MediaMuxer.writeSampleData数据时,注意一定不能保存的时间戳信息后一次比前一次要小,这时录屏直接失败:
比如上一次是39000045,而这一次是39000000,这是不允许,我这里的解决办法是忽略掉这一次信息;
3、音频、视频一起录制时注意时间戳信息一定要从0开始,否则视频无法显示:

    public void writeSampleData(int trackIndex, @NonNull ByteBuffer byteBuf,
            @NonNull BufferInfo bufferInfo) {

这里bufferInfo中的presentationTimeUs一定要从0开始。

[1]https://blog.csdn.net/luoyouren/article/details/52135476,这里是有位大神的完整的录屏、录音demo(GitHub连接)。

使用Android MediaCodec录屏时,可以通过以下方式获取实时的文件大小: 1. 在MediaMuxer中创建一个MuxerRunnable线程,负责将编码后的视频数据和音频数据写入到文件中。 2. 在MuxerRunnable线程中,可以使用File.length()方法获取已经写入文件的大小,即实时的文件大小。 3. 可以在MuxerRunnable线程中定时打印或者通过广播等方式通知主线程实时的文件大小。 示例代码如下: ```java public class MuxerRunnable implements Runnable { private MediaMuxer mMuxer; private boolean mIsStarted; private boolean mIsVideoTrackAdded; private boolean mIsAudioTrackAdded; private int mVideoTrackIndex = -1; private int mAudioTrackIndex = -1; private long mLastFileSize = 0; private File mOutputFile; private Handler mHandler; private static final int MSG_UPDATE_FILE_SIZE = 1; private static final long UPDATE_FILE_SIZE_INTERVAL = 1000; // 1秒更新一次文件大小 public MuxerRunnable(MediaMuxer muxer, File outputFile, Handler handler) { mMuxer = muxer; mOutputFile = outputFile; mHandler = handler; } @Override public void run() { try { while (!mIsStarted || !mIsVideoTrackAdded || !mIsAudioTrackAdded) { Thread.sleep(10); } while (mIsStarted) { long currentFileSize = mOutputFile.length(); if (currentFileSize != mLastFileSize) { mLastFileSize = currentFileSize; mHandler.sendEmptyMessage(MSG_UPDATE_FILE_SIZE); } Thread.sleep(UPDATE_FILE_SIZE_INTERVAL); } } catch (InterruptedException e) { e.printStackTrace(); } finally { if (mMuxer != null) { mMuxer.stop(); mMuxer.release(); } } } public void start() { mIsStarted = true; new Thread(this).start(); } public void stop() { mIsStarted = false; } public void addVideoTrack(MediaFormat format) { if (mMuxer != null) { mVideoTrackIndex = mMuxer.addTrack(format); if (mAudioTrackIndex != -1) { mMuxer.start(); } mIsVideoTrackAdded = true; } } public void addAudioTrack(MediaFormat format) { if (mMuxer != null) { mAudioTrackIndex = mMuxer.addTrack(format); if (mVideoTrackIndex != -1) { mMuxer.start(); } mIsAudioTrackAdded = true; } } } ``` 在主线程中,可以创建一个Handler来接收MuxerRunnable线程发送的文件大小更新消息,并更新UI界面。 ```java private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == MSG_UPDATE_FILE_SIZE) { long fileSize = mOutputFile.length(); mFileSizeTextView.setText(String.format(Locale.getDefault(), "文件大小:%d KB", fileSize / 1024)); } } }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值