Articles of mediacodec

如何使用Android MediaCodec生成AAC ADTS基本流

我要做的是:使用Android的MediaCodec将原始PCM音频样本编码为原始AAC文件。 我遇到的问题:当我使用FFMPEG将生成的原始AAC文件打包到M4A容器中时,FFMPEG抱怨文件中缺少编解码器参数。 细节: 由于我找不到生成输出AAC文件的音频编码器的任何MediaCodec示例代码,我尝试将video编码器修改为音频编码器。 原始代码在这里: source_code 我配置了这样的音频编码器: mEncoderFormat = MediaFormat.createAudioFormat(“audio/mp4a-latm”, (int)mAudioSampleRate, 2); // redundant? mEncoderFormat.setString(MediaFormat.KEY_MIME, “audio/mp4a-latm”); mEncoderFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectELD); mEncoderFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, kSampleRates); mEncoderFormat.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates); mEncoderFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 2); testEncoderWithFormat(“audio/mp4a-latm”, mEncoderFormat); try { codec.configure( mEncoderFormat, null /* surface */, null /* crypto */, MediaCodec.CONFIGURE_FLAG_ENCODE); } catch (IllegalStateException e) { Log.e(TAG, “codec ‘” + componentName + “‘ failed configuration.”); return; } […]

MediaCodec getInputImage在某些设备上返回null

我想通过将颜色格式设置为COLOR_FormatYUV420Flexible来使用MediaCodec进行编码。 我的输入缓冲区是yuv420p。当我像这样输入缓冲区时: int inputBufferIndex = mEncoder.dequeueInputBuffer(-1); mCurrentBufferIndex = inputBufferIndex; if (inputBufferIndex >= 0) { ByteBuffer inputBuffer = inputBuffers[inputBufferIndex]; //if(VERBOSE) Log.i(TAG,”pos:”+inputBuffer.position()+”\tlimit:”+inputBuffer.limit()); inputBuffer.clear(); return inputBuffer; } 但有些设备颜色错误。 所以我试试这个: int inputBufferIndex = mEncoder.dequeueInputBuffer(-1); mCurrentBufferIndex = inputBufferIndex; if (inputBufferIndex >= 0) { Image img = mEncoder.getInputImage(inputBufferIndex); if(img==null) return null; //mCurrentInputPlanes = img.getPlanes(); ByteBuffer buffers[]={img.getPlanes()[0].getBuffer(), img.getPlanes()[1].getBuffer(), img.getPlanes()[2].getBuffer()}; 我将缓冲区填充到YUV通道。它可以在某些设备上运行。 但是当调用getInputImage时,moto X […]

SurfaceTexture的onFrameAvailable()方法总是调用得太迟了

我正在尝试使用以下MediaExtractor示例: http://bigflake.com/mediacodec/ – ExtractMpegFramesTest.java(需要4.1,API 16) 我遇到的问题是outputSurface.awaitNewImage(); 似乎总是抛出RuntimeException(“帧等待超时”),每当mFrameSyncObject.wait(TIMEOUT_MS)调用超时时抛出它。 无论我将TIMEOUT_MS设置为什么, onFrameAvailable()总是在超时发生后立即被调用。 我尝试了50毫秒和30000毫秒,它是相同的。 似乎在线程繁忙时无法完成onFrameAvailable()调用,并且一旦超时发生并结束线程代码执行,它就可以解析onFrameAvailable()调用。 有没有人设法让这个例子工作,或者知道MediaExtractor应该如何使用GL纹理? 编辑:在使用API​​ 4.4和4.1.1的设备上尝试此操作,两者都发生了同样的情况。 编辑2: 得益于fadden 4.4。 问题是th.join();方法名为th.join(); 它阻止了主线程并阻止了onFrameAvailable()调用的处理。 有一次我评论了th.join(); 它适用于4.4。 我想也许ExtractMpegFramesWrapper.runTest()本身应该在另一个线程上运行,所以主线程没有被阻止。 在调用codec.configure() ,4.1.2上还有一个小问题,它给出了错误: A/ACodec(2566): frameworks/av/media/libstagefright/ACodec.cpp:1041 CHECK(def.nBufferSize >= size) failed. A/libc(2566): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 2625 (CodecLooper) 通过在通话前添加以下内容我解决了这个问题: format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 0); 然而,我现在在4.1.1(Galaxy S2 GT-I9100)和4.1.2(三星Galaxy Tab GT-P3110)上的问题是它们都始终将info.size设置为0以用于所有帧。 这是日志输出: loop input buffer not available […]

Android MediaCodec AAC编码器

我使用Android SDK提供的MediaCodec类,因为API级别16与OMX.SEC.aac.enc编码器一起将音频编码为文件。 我从AudioRecord类中获取音频输入。 我的AudioRecord类的实例配置如下: bufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT); recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_DEFAULT, bufferSize); 我能够从AudioRecord实例播放原始数据,因此问题不在那里。 我将AudioRecord实例的输出写入ByteBuffer实例,并将其传递给编码器的可用输入缓冲区。 编码器的输出写入SD卡上的文件。 这些是我的MediaCodec实例的配置参数: codec = MediaCodec.createEncoderByType(“audio/mp4a-latm”); MediaFormat format = new MediaFormat(); format.setString(MediaFormat.KEY_MIME, “audio/mp4a-latm”); format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024); format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 2); format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100); format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectHE); codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); VLC告诉我,我的aac文件中没有流。 命令FFMPEG -i @filename@给出了以下错误: 处理输入时发现无效数据 。 我测试过的所有媒体播放器都无法播放我的文件。 为什么我无法播放我的文件? 我在LogCat没有收到OpenMAX错误,并且编码时应用程序不会崩溃。 我写了一个video编码器,它的工作原理与之相同。 […]

如何在没有MediaExtractor的情况下为H264使用MediaCodec

我需要在没有MediaExtractor的情况下使用MediaCodec,我正在使用FileInputStream读取文件。 目前它不起作用,它在屏幕上显示绿色的乱码图像。 这是完整的源代码: FileInputStream in = new FileInputStream(“/sdcard/sample.ts”); String mimeType = “video/avc”; MediaCodec decoder = MediaCodec.createDecoderByType(mimeType); MediaFormat format = MediaFormat.createVideoFormat(mimeType, 1920, 1080); byte[] header_sps = { 0, 0, 0, 1, 103, 100, 0, 40, -84, 52, -59, 1, -32, 17, 31, 120, 11, 80, 16, 16, 31, 0, 0, 3, 3, -23, 0, 0, -22, […]

在android中添加水印位图:4.3的MediaMuxer或ffmpeg

这是我的情景: 从网上下载avi电影 打开位图资源 在背景中的所有帧上将此位图叠加在电影的底部 将video保存在extarnal存储上 video长度通常为15秒 这可能是使用MediaMuxer实现的吗? 很高兴收到有关此事的任何信息 我一直在寻找http://bigflake.com/mediacodec/#DecodeEditEncodeTest (谢谢@fadden),它说: “解码帧并将其复制到带有glReadPixels()的ByteBuffer,在Nexus 5上大约需要8ms,速度足够快以跟上30fps的输入速度,但将其作为PNG保存到磁盘所需的额外步骤很昂贵(大约一半)一秒)” 所以几乎1秒/帧是不可接受的。 根据我的想法,一种方法是将每个帧保存为PNG,打开它,在其上添加位图叠加然后保存它。 然而,这将花费大量时间来完成。 我想知道是否有办法做这样的事情: 从外部存储打开video文件 开始解码它 每个解码帧将通过内存中的位图叠加进行更改 帧被发送到编码器。 在iOS上,我看到有一种方法可以将原始音频+原始video+图像添加到一个容器中,然后对整个事物进行编码…… 我应该切换到ffmpeg吗? ffmpeg的稳定性和兼容性如何? 我冒着与Android 4.0+设备兼容性问题的风险吗? 有没有办法用ffmpeg来实现这个? 我是这个领域的新手,还在做研究。 多年后编辑: 自问题出现以来已经过去了很多年,并且ffmpeg在许可方面很难添加到商业软件中。 这是如何演变的? 较新版本的android在默认的sdk上更有能力吗?

解码audio文件并重新编码为所需的PCM格式:44,100 kHz,2个通道,16位

我想将audio文件解码为原始PCM数据,将其stream式传输到本地networking中的播放设备。 我使用了API级别为16的新MediaExtractor和MediaCodec类。 该设备要求PCM数据在44100kHz,具有2个通道和16位样本大小 。 只要input文件大致符合这些要求,这工作正常。 但是,无论何时我正在解码一个MP3文件,例如,使用32,000 kHz的采样率,也许只有一个通道,那么我不会从MediaCodec类获得所需的输出。 看来我不能指定MediaCodec类的输出格式 。 所以我决定实例化另一个MediaCodec对象,将原始数据重新编码成我想要的格式。 根据Android 4.1 支持的媒体格式列表,Android支持编码PCM / Wave。 但是, 我无法创build一个MediaCodec对象,编码PCM / Wave 。 我试着将各种MIMEtypes传递给MediaCodec.createEncoderByType(type); 但是我总是以IOExceptionexception失败: java.io.IOException: Failed to allocate component instance at android.media.MediaCodec.native_setup(Native Method) at android.media.MediaCodec.<init>(MediaCodec.java:210) at android.media.MediaCodec.createEncoderByType(MediaCodec.java:194) [..] 有没有人能够成功地创build一个MediaCodec实例,编码为PCM / Wave,并可以提供一个工作的例子?

我无法使用adb屏幕logging工具捕捉android屏幕

我有一个与Android KitKat nexus 4。 我尝试使用以下命令进行屏幕录制: adb shell screenrecord –verbose /sdcard/demo.mp4 adb shell screenrecord –bit-rate 8000000 –time-limit 30 /sdcard/kitkat.mp4 两次,这些命令都返回了这条消息: Main display is 768×1280 @60.00fps (orientation=0) Configuring recorder for 768×1280 video at 4.00Mbps ERROR: unable to create video/avc codec instance 在AndroidStudio中打开的debugging控制台中,显示了以下日志消息: 02-02 18:16:29.058 176-4045/? E/OMX-VENC-720p﹕ Is component secure 0 02-02 18:16:29.058 176-4045/? E/OMX-VENC-720p﹕ ERROR: Omx_venc::Comp Init […]

Android相机上的预览帧率不一致

我试图通过相机的PreviewCall(onPreviewFrame)使用MediaCodec对每秒30帧的video进行编码。 我编码的video总是播放速度非常快(这是不希望的)。 所以,我试图通过设置一个int frameCountvariables来记住我的相机的预览帧数,以记住它的计数。 我期望的是每秒30帧,因为我设置我的相机的预览有30帧预览(如下所示)。 我得到的结果是不一样的。 我调用了onPreviewFramecallback10秒,我得到的frameCount的数量只有大约100帧。 这是不好的,因为我期待300帧。 我的相机参数设置是否正确? 这是Android的Camera预览callback的限制吗? 如果这是Android Camera预览callback的限制,那么是否还有其他相机callback,可以每秒30帧的速度返回相机的图像数据(nv21,yuv,yv12)? 感谢您的阅读,并花时间来帮忙。 我将不胜感激任何意见和意见。 以下是使用Camera的onPreviewFrame编码的video示例: http://www.youtube.com/watch?v=I1Eg2bvrHLM&feature=youtu.be Camera.Parameters parameters = mCamera.getParameters(); parameters.setPreviewFormat(ImageFormat.NV21); parameters.setPictureSize(previewWidth,previewHeight); parameters.setPreviewSize(previewWidth, previewHeight); // parameters.setPreviewFpsRange(30000,30000); parameters.setPreviewFrameRate(30); mCamera.setParameters(parameters); mCamera.setPreviewCallback(previewCallback); mCamera.setPreviewDisplay(holder);

带声音的Androidvideo循环缓冲区

我正在使用Google的开源示例: Grafika 。 我正在使用它的ContinuousCaptureActivity.java CircularBuffer的实现演示在这个活动,但没有audio包括在最终的video文件。 我想在此活动中添加audio录制function,并将录制的audio以相同的循环缓冲方式添加到video中。 为了实现这一点,我已经探索了4.3 +版本中引入的MediaCodec库。 我也使用MediaMuxer捕捉video和audiostream,并将它们混合成一个video。 但是,我不确定如何将audio录制function实现到ContinuousCaptureActivity.java类中。 任何帮助,高度赞赏。