我正在尝试使用Android AudioRecord和MediaCodec编码aac音频.我创建了一个非常类似的编码器类(使用Android MediaCodec从相机编码H.264).通过这个类,我创建了一个AudioRecord实例,并告诉它将其byte []数据读出到AudioEncoder(audioEncoder.offerEncoder(Data)).
while(isRecording)
{
audioRecord.read(Data, 0, Data.length);
audioEncoder.offerEncoder(Data);
}
Run Code Online (Sandbox Code Playgroud)
这是我的AudioRecord设置
int audioSource = MediaRecorder.AudioSource.MIC;
int sampleRateInHz = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
Run Code Online (Sandbox Code Playgroud)
我成功收集了一些byte []数组数据并将其写入本地文件.不幸的是,该文件无法播放.我做了一些在线搜索,发现了一个相关的帖子(如何使用Android MediaCodec生成AAC ADTS基本流).因此,遇到类似问题的其他人说主要问题是"MediaCodec编码器生成原始AAC流.原始AAC流需要转换为可播放格式,例如ADTS流".所以我尝试添加ADTS标头.然而,在我添加了ADTS头之后(我在下面的代码中注释掉了),我的AudioEncoder甚至都不会写输出音频文件.有什么我想念的吗?我的设置是否正确?
欢迎任何建议,意见和意见,非常感谢.多谢你们!
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.os.Environment;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class AudioEncoder {
private MediaCodec mediaCodec;
private BufferedOutputStream outputStream;
private String mediaType = "audio/mp4a-latm";
public AudioEncoder() …Run Code Online (Sandbox Code Playgroud) 通过参考Aegonis的工作1和工作2,我也得到了H.264流,但颜色不正确.我正在使用HTC Butterfly进行开发.这是我的代码的一部分:
相机:
parameters.setPreviewSize(width, height);
parameters.setPreviewFormat(ImageFormat.YV12);
parameters.setPreviewFrameRate(frameRate);
Run Code Online (Sandbox Code Playgroud)
MediaCodec:
mediaCodec = MediaCodec.createEncoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 320, 240);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 500000);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mediaCodec.start();
Run Code Online (Sandbox Code Playgroud)
使用COLOR_FormatYUV420Planar时,错误显示"[OMX.qcom.video.encoder.avc]不支持颜色格式19",因此我只能使用" COLOR_FormatYUV420SemiPlanar ".有谁知道为什么没有支持?
通过使用得到它:
int colorFormat = 0;
MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType);
for (int i = 0; i < capabilities.colorFormats.length && colorFormat == 0; i++) {
int format = capabilities.colorFormats[i];
Log.e(TAG, "Using color format " + format);
}
Run Code Online (Sandbox Code Playgroud)
我们可以有21种颜色格式(COLOR_FormatYUV420SemiPlanar)和2130708361(没有相应的格式),我认为格式会改变取决于设备.
然后,我尝试了 …
我来自使用Android MediaCodec从相机编码H.264的线程。我的设置非常相似。但是,我尝试使用javacv编写编码帧的多路复用,并通过rtmp广播它们。
RtmpClient.java
...
private volatile BlockingQueue<byte[]> mFrameQueue = new LinkedBlockingQueue<byte[]>(MAXIMUM_VIDEO_FRAME_BACKLOG);
...
private void startStream() throws FrameRecorder.Exception, IOException {
if (TextUtils.isEmpty(mDestination)) {
throw new IllegalStateException("Cannot start RtmpClient without destination");
}
if (mCamera == null) {
throw new IllegalStateException("Cannot start RtmpClient without camera.");
}
Camera.Parameters cameraParams = mCamera.getParameters();
mRecorder = new FFmpegFrameRecorder(
mDestination,
mVideoQuality.resX,
mVideoQuality.resY,
(mAudioQuality.channelType.equals(AudioQuality.CHANNEL_TYPE_STEREO) ? 2 : 1));
mRecorder.setFormat("flv");
mRecorder.setFrameRate(mVideoQuality.frameRate);
mRecorder.setVideoBitrate(mVideoQuality.bitRate);
mRecorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
mRecorder.setSampleRate(mAudioQuality.samplingRate);
mRecorder.setAudioBitrate(mAudioQuality.bitRate);
mRecorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
mVideoStream = new VideoStream(mRecorder, mVideoQuality, mFrameQueue, mCamera);
mAudioStream = new AudioStream(mRecorder, mAudioQuality); …Run Code Online (Sandbox Code Playgroud) 我想使用MediaCodec对来自摄像头的数据进行编码(原因:它更低级,所以希望比使用MediaRecorder更快).使用Camera.PreviewCallBack,我将数据从相机捕获到一个字节缓冲区,以便将其传递给MediaCodec对象.
要做到这一点,我需要填写一个MediaFormat -object,如果我知道来自摄像头的数据的MIME代码,这将是相当容易的.我可以使用setPreviewFormat()选择te ImageFormat -class中声明的常量之一来选择这种格式.
因此我的问题是:给定ImageFormat类提供的不同选项来设置相机预览格式,相应的MIME类型代码是什么?
非常感谢提前.
背景:
我一直在实施Vine这样的录像机,已有两天了。首先,我尝试了MediaRecorder。但是我需要的视频可能由小视频片段组成。此类不能用于录制短时视频剪辑。然后我找到了MediaCodec,FFmpeg和JavaCV。FFmpeg和JavaCV可以解决此问题。但是我必须使用许多库文件来编译我的项目。它将生成一个非常大的APK文件。所以我更喜欢通过MediaCodec实现它,尽管此类只能在Android 4.1之后使用。90%的用户将感到满意。
结果:
我终于得到了编码文件,但是无法播放。我通过FFprobe检查了信息,结果像:
输入0,h264,来自'test.mp4':持续时间:不适用,比特率:不适用流#0:0:视频:h264(基线),yuv420p,640x480,25 fps,25 tbr,1200k tbn, 50吨
我对H.264编码的机制了解不多。
码:
从此链接修改
public class AvcEncoder {
private static String TAG = AvcEncoder.class.getSimpleName();
private MediaCodec mediaCodec;
private BufferedOutputStream outputStream;
private int mWidth, mHeight;
private byte[] mDestData;
public AvcEncoder(int w, int h) {
mWidth = w;
mHeight = h;
Log.d(TAG, "Thread Id: " + Thread.currentThread().getId());
File f = new File("/sdcard/videos/test.mp4");
try {
outputStream = new BufferedOutputStream(new FileOutputStream(f));
Log.i("AvcEncoder", "outputStream initialized");
} catch (Exception e) {
e.printStackTrace();
}
try { …Run Code Online (Sandbox Code Playgroud) 我正在使用相机的 setPreviewCallback 使用 MediaCodec 编码视频。(我按照这个示例使用 Android MediaCodec 从相机编码 H.264)。我对 MediaCodec 使用以下设置:
mediaCodec = MediaCodec.createEncoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 1280, 720);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 8000000);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mediaCodec.start();
Run Code Online (Sandbox Code Playgroud)
我的相机设置是:
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewFormat(ImageFormat.NV21);
parameters.setPictureSize(previewWidth, 1280);
parameters.setPreviewSize(previewWidth, 720);
parameters.setPreviewFrameRate(30);
parameters.setPreviewFpsRange(5000,30000);
mCamera.setParameters(parameters);
Run Code Online (Sandbox Code Playgroud)
我有视频,但有两个问题:
这是一个示例视频
http://www.youtube.com/watch?v=I1Eg2bvrHLM&feature=youtu.be
有谁知道这两个问题的原因是什么吗?可能会告诉我一些解决这个问题的方法,因为我现在完全迷失/困惑了。感谢您的阅读,并感谢任何评论和意见。