android 音频播放pts,android - 使用MediaCodec和MediaMuxer录制视频,但是pts和pts_delta存在一些问题 - 堆栈内存溢出...

W / MPEG4Writer:等待视频轨道到达最终音频时间戳的超时!

D/MPEG4Writer: Video track source stopping

D/MPEG4Writer: Video track source stopped

D/MPEG4Writer: Video track stopped. Stop source

D/MPEG4Writer: Duration from tracks range is [16440617, 32620406] us

D/MPEG4Writer: Stopping writer thread

D/MPEG4Writer: 0 chunks are written in the last batch

D/MPEG4Writer: Writer thread stopped

I/MPEG4Writer: Ajust the moov start time from 311268925895 us -> 311268925895 us

I/MPEG4Writer: The mp4 file will not be streamable.

D/MPEG4Writer: Video track stopping. Stop source

D/MPEG4Writer: Audio track stopping. Stop source

D/MediaEncoder: Encoder thread exiting

上面的日志显示mp4文件不可流式传输,当我将mp4转换为hls时,这是事实,最终流中的音频有很多问题(流行,点击等声音)

我在编码中使用以下方法来计算pts

protected long getPTSUs() {

long result = System

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android录制屏幕并同时录制系统音频可以通过使用 MediaCodecMediaProjection 来实现。下面是一个简单的示例代码: ```java public class ScreenRecorder { private static final String TAG = "ScreenRecorder"; private static final String MIME_TYPE = "video/avc"; private static final int FRAME_RATE = 30; private static final int I_FRAME_INTERVAL = 10; private static final int BIT_RATE = 6000000; private static final int TIMEOUT_US = 10000; private MediaProjection mMediaProjection; private MediaCodec mMediaCodec; private VirtualDisplay mVirtualDisplay; private Surface mInputSurface; private boolean mIsRecording; private AudioRecord mAudioRecord; private Thread mAudioThread; private boolean mIsAudioRecording; public void startRecording(Context context, MediaProjection mediaProjection) throws IOException { mMediaProjection = mediaProjection; // 初始化 MediaCodec MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, displayWidth, displayHeight); format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE); format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE); format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, I_FRAME_INTERVAL); mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE); mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); mInputSurface = mMediaCodec.createInputSurface(); mMediaCodec.start(); // 创建 VirtualDisplay mVirtualDisplay = mMediaProjection.createVirtualDisplay(TAG, displayWidth, displayHeight, displayDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC, mInputSurface, null, null); // 启动音频录制 startAudioRecording(); mIsRecording = true; } public void stopRecording() { mIsRecording = false; // 停止音频录制 stopAudioRecording(); if (mMediaProjection != null) { mMediaProjection.stop(); mMediaProjection = null; } if (mVirtualDisplay != null) { mVirtualDisplay.release(); mVirtualDisplay = null; } if (mMediaCodec != null) { mMediaCodec.stop(); mMediaCodec.release(); mMediaCodec = null; } if (mInputSurface != null) { mInputSurface.release(); mInputSurface = null; } } private void startAudioRecording() { int sampleRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_SYSTEM); int minBufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT); mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.REMOTE_SUBMIX, sampleRate, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize); mIsAudioRecording = true; mAudioThread = new Thread(new Runnable() { @Override public void run() { byte[] buffer = new byte[minBufferSize]; while (mIsAudioRecording) { int readSize = mAudioRecord.read(buffer, 0, minBufferSize); if (readSize > 0) { ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers(); int inputBufferIndex = mMediaCodec.dequeueInputBuffer(TIMEOUT_US); if (inputBufferIndex >= 0) { ByteBuffer inputBuffer = inputBuffers[inputBufferIndex]; inputBuffer.clear(); inputBuffer.put(buffer); long pts = System.nanoTime() / 1000; mMediaCodec.queueInputBuffer(inputBufferIndex, 0, readSize, pts, 0); } } } mAudioRecord.stop(); mAudioRecord.release(); mAudioRecord = null; } }); mAudioThread.start(); mAudioRecord.startRecording(); } private void stopAudioRecording() { mIsAudioRecording = false; try { mAudioThread.join(); } catch (InterruptedException e) { Log.e(TAG, "stopAudioRecording: ", e); } } } ``` 需要注意的是,上述代码中的 `AudioRecord` 使用了 `MediaRecorder.AudioSource.REMOTE_SUBMIX`,这是一种特殊的音频源,可以录制系统音频。但是并不是所有的设备都支持 `REMOTE_SUBMIX`,如果你的设备不支持,那么你就无法录制系统音频了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值