camera2 opengl实现滤镜效果录制视频 三 录音
来源:互联网 发布:facebook 聊天软件 编辑:程序博客网 时间:2024/06/08 12:45
本来是想用MediaRecorder直接录像的,可是好像参数设置错误总是报错就改用MediaCodec了
MediaCodec配合MediaMuxer进行录音,以后可以直接用来录像
public class AudioEncoder { private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO; //音频通道(单声道) private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; //音频格式 private static final int AUDIO_SOURCE = MediaRecorder.AudioSource.MIC; //音频源(麦克风) private static final String AUDIO_MIME_TYPE = "audio/mp4a-latm"; //音频类型 private static final int SAMPLE_RATE = 44100; //采样率(CD音质) private static final int BIT_RATE = 128000; //比特率 private static final int CHANNEL_COUNT = 1;//声道 private MediaCodec mAudioCodec; //音频编解码器 private MediaMuxer mMediaMuxer; //初始化 public void initAudio() { String path = "/storage/emulated/0/360/" + System.currentTimeMillis() + ".mp4"; MediaFormat mAudioFormat = new MediaFormat(); mAudioFormat.setString(MediaFormat.KEY_MIME, AUDIO_MIME_TYPE); mAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC); mAudioFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, SAMPLE_RATE); mAudioFormat.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE); mAudioFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, CHANNEL_COUNT); try { mAudioCodec = MediaCodec.createEncoderByType(AUDIO_MIME_TYPE); mAudioCodec.configure(mAudioFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); mAudioCodec.start(); mMediaMuxer = new MediaMuxer(path, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); } catch (IOException e) { e.printStackTrace(); } } private long audioStartTime; //开始 public void start() { //麦克风采集线程 Thread thread = new Thread() { @Override public void run() { super.run(); int bufferSizeInBytes = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT); AudioRecord audioRecord = new AudioRecord( AUDIO_SOURCE,//音频源 SAMPLE_RATE,//采样率 CHANNEL_CONFIG,//音频通道 AUDIO_FORMAT,//音频格式 bufferSizeInBytes//缓冲区 ); if (audioRecord.getState() != AudioRecord.STATE_INITIALIZED) { //麦克风被占用 return; } audioRecord.startRecording(); byte[] buffer = new byte[bufferSizeInBytes]; audioStartTime = System.nanoTime(); while (stop) { long audioPresentationTimeNs = System.nanoTime(); int bufferReadResult = audioRecord.read(buffer, 0, bufferSizeInBytes); if (bufferReadResult == AudioRecord.ERROR_BAD_VALUE || bufferReadResult == AudioRecord.ERROR_INVALID_OPERATION) { } //向MediaCodec传数据 audioInputBuffer(buffer, audioPresentationTimeNs, false); } long audioPresentationTimeNs = System.nanoTime(); int bufferReadResult = audioRecord.read(buffer, 0, bufferSizeInBytes); if (bufferReadResult == AudioRecord.ERROR_BAD_VALUE || bufferReadResult == AudioRecord.ERROR_INVALID_OPERATION) { } audioInputBuffer(buffer, audioPresentationTimeNs, true); audioRecord.stop(); audioRecord.release(); } }; //编码线程 Thread t = new Thread() { @Override public void run() { super.run(); offerAudioEncoder(); } }; //相互独立的线程 t.start(); thread.start(); } public void audioInputBuffer(byte[] buffer, long pts, boolean audioEnd) { int inputBufferIndex = mAudioCodec.dequeueInputBuffer(-1); if (inputBufferIndex >= 0) { ByteBuffer inputBuffer = mAudioCodec.getInputBuffer(inputBufferIndex); inputBuffer.clear(); inputBuffer.put(buffer); long presentationTimeUs = (pts - audioStartTime) / 1000; //MediaCodec接收数据 if (audioEnd) { mAudioCodec.queueInputBuffer(inputBufferIndex, 0, buffer.length, presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM); } else { mAudioCodec.queueInputBuffer(inputBufferIndex, 0, buffer.length, presentationTimeUs, 0); } } } private void offerAudioEncoder() { int mTrackIndex = -1; MediaCodec.BufferInfo mBufferInfo = new MediaCodec.BufferInfo(); while (true) { //阻塞线程等待数据,时间100毫秒 int encoderIndex = mAudioCodec.dequeueOutputBuffer(mBufferInfo, 100); if (encoderIndex == MediaCodec.INFO_TRY_AGAIN_LATER) { } else if (encoderIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { //开启MediaMuxer,因为只有录音所以只调用一次 MediaFormat mediaFormat = mAudioCodec.getOutputFormat(); mTrackIndex = mMediaMuxer.addTrack(mediaFormat); mMediaMuxer.start(); } else if (encoderIndex < 0) { } else { //有数据时进入这里取当前数据 ByteBuffer encodedData = mAudioCodec.getOutputBuffer(encoderIndex); if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { mBufferInfo.size = 0; } //将数据写入mMediaMuxer,结束写入开始下次循环 if (mBufferInfo.size != 0) { encodedData.position(mBufferInfo.offset); encodedData.limit(mBufferInfo.offset + mBufferInfo.size); mMediaMuxer.writeSampleData(mTrackIndex, encodedData, mBufferInfo); mAudioCodec.releaseOutputBuffer(encoderIndex, false); } //判断是否是关闭录音 if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { break; // out of while } } } //释放 release(); } public void release() { if (mAudioCodec != null) { mAudioCodec.stop(); mAudioCodec.release(); mAudioCodec = null; } if (mMediaMuxer != null) { mMediaMuxer.release(); mMediaMuxer = null; } } private boolean stop = true; //结束 public void stop() { stop = false; }}
阅读全文
0 0
- camera2 opengl实现滤镜效果录制视频 三 录音
- camera2 opengl实现滤镜效果录制视频 目录
- camera2 opengl实现滤镜效果录制视频 一 相机预览
- camera2 opengl实现滤镜效果录制视频 四 录像
- camera2 opengl实现滤镜效果录制视频 五 音视频合并
- camera2 opengl实现滤镜效果录制视频 二 双SurfaceView渲染
- camera2 opengl实现滤镜效果录制视频 六 摄像头方向(完)
- 用canvas实现图片滤镜效果详解之视频效果
- Android Camera2 Opengles2.0 预览图像实时滤镜 视频编码
- Android Camera2 Opengles2.0 图像实时滤镜 显示 视频编码
- openGL ES进阶教程(四)用openGL ES+MediaPlayer 渲染播放视频+滤镜效果
- Android视频编辑器(四)通过OpenGL给视频增加不同滤镜效果
- iOS 录音和视频录制播放
- OpenGL es 视频录制Library
- Android录制视频(三)
- android 实现滤镜效果
- GLSL实现滤镜效果
- 相机滤镜效果实现
- LeetCode题解(Golang实现)--Longest Substring Without Repeating Characters
- 在CentOS下搭建自己的Git服务器
- Java基础学习总结(四)—— 关键字介绍
- 第一篇:JAVA获得设备信息
- BigDecimal 加,减,乘,除 详解
- camera2 opengl实现滤镜效果录制视频 三 录音
- vue中使用百度地图
- codeforces #430 (div2)
- Kotlin 第八章:接口
- 解决matlab 2014b的Test checkout of feature 'Compiler' failed
- Hbase shell基本操作
- 解决键盘遮挡注册或登录按钮
- maven四
- Adaboost算法