我正在尝试使用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) 我正在尝试在Android上使用MediaCodec API来解码AAC流.(它是原始的AAC.)我尝试使用MediaFormat.createAudioFormat()创建格式对象以传递给MediaCodec.configure(),但是在使用AAC(audio/mp4a-latm)时我一直遇到错误.(它适用于MP3(音频/ mpeg)虽然...)
最后,我为AAC文件创建了一个MediaExtractor,并查看了它正在生成的格式对象.我看到它包含了一个ByteBuffer的密钥"csd-0",它由两个字节组成,值均为0x12.如果我在用于配置AAC编解码器的格式对象中包含该键和值,则一切正常.
有谁知道发生了什么?文档说明我不应该配置该密钥.有没有人有一个指向MediaCodec示例的指针来解码AAC文件而不使用MediaExtractor来生成格式对象?
我的StreamPlayer有一个奇怪的问题,我需要任何帮助.
我需要实现的主要目标是StreamPlayer,它能够以尽可能小的延迟回放MPEG-2传输流.为此,我遵循这种方法:
该流由基于Java的TS Parser解析.我已经实现了一个类似于MediaExtractor的TSExtractor,它工作正常.我可以像使用MediaExtractor一样接收选定轨道的所有媒体样本
extractor.readSampleData(...);
extractor.advance();
Run Code Online (Sandbox Code Playgroud)
要解码我想要创建和配置MediaCodec实例的AAC数据.使用MediaExtractor类通常由此完成
MediaFormat mediaFormat = extractor.getTrackFormat(i);
decoder = MediaCodec.createDecoderByType(mediaFormat.getString(MediaFormat.KEY_MIME));
decoder.configure(mediaFormat, null, null, 0);
Run Code Online (Sandbox Code Playgroud)
因为我必须在TSExtractor.getTrackFormat(int track)方法中初始化MediaFormat,所以我使用
MediaFormat mf = MediaFormat.createAudioFormat ("audio/mp4a-latm", getSampleRate(), getChannelCount());
Run Code Online (Sandbox Code Playgroud)
因为我的所有AAC样本都包括我做的ADTS
mediaFormat.setInteger(MediaFormat.KEY_IS_ADTS, 1);
Run Code Online (Sandbox Code Playgroud)
阅读这篇文章后,我终于使用"csd-0"键添加了ESDS帧
mediaFormat.setByteBuffer("csd-0", ByteBuffer.allocate(2).put(new byte[]{(byte) 0x11, (byte)0x90}));
Run Code Online (Sandbox Code Playgroud)
其中值0x11和0x90是从ADTS中提取的.
当我现在想要解码AAC样本时,解码器发布
AAC decoder returned error 4097, substituting silence
Run Code Online (Sandbox Code Playgroud)
到日志.
为了验证我的TSExtractor正确提取样本我使用VLC记录了相同的流,将其重新转换为mp4文件而不进行转码,因此原始流不变.现在我可以用记录的mp4文件初始化MediaExtractor,并比较我的TSExtractor和MediaExtractor创建的样本.使用跟踪和错误我发现了一个非常奇怪的行为:
当我使用MediaExtractor创建的mediaFormat配置MediaCodec时,MediaCodec会解码我的TSExtractor返回的AAC样本而没有任何问题.比较MediaFormat,它基本上包装了由我的TSExtractor创建的HashMap和由MediaExtractor创建的那个,给出了这些差异:
由MediaExtractor创建:
mediaFormat:{max-input-size = 1212,durationUs = 77428875,is-adts = 1,channel-count = 2,mime = audio/mp4a-latm,csd-0 = java.nio.ByteArrayBuffer [position = 0,limit = 2,容量= 2],采样率= 48000}
由TSExtractor创建:
mediaFormat:{is-adts = 1,channel-count = 2,mime = audio/mp4a-latm,csd-0 = …
我正在开发一个需要在 Android 上使用 OpenGL 处理视频的项目。我决定使用 MediaCodec,并在ExtractDecodeEditEncodeMuxTest的帮助下设法让它工作。结果非常好,我让它接收视频,提取轨道,解码视频轨道,使用 OpenGL 进行编辑,然后编码为视频文件。
问题是结果视频可以在Android上很好地播放,但是到了iOS时,屏幕的三分之二是绿色的。
我尝试使用此处、此处和此处的建议解决编码器的不同格式,但问题仍然相同。
有人可以告诉我可能导致此问题的原因以及如何解决吗?
这是编码器的配置
MediaCodec mediaCodec = MediaCodec.createEncoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 540, 960);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 2000000);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, CodecCapabilities.COLOR_FormatSurface);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
Run Code Online (Sandbox Code Playgroud)
更新 我想知道我是否对视频方向有任何错误,因为输出视频的工作部分与所需的输出分辨率具有相同的比率,但在水平方向上。输入是垂直记录的,所需的输出也是如此。这是解码器配置的代码:
inputFormat.setInteger(MediaFormat.KEY_WIDTH, 540);
inputFormat.setInteger(MediaFormat.KEY_HEIGHT, 960);
inputFormat.setInteger("rotation-degrees", 90);
String mime = inputFormat.getString(MediaFormat.KEY_MIME);
MediaCodec decoder = MediaCodec.createDecoderByType(mime);
decoder.configure(inputFormat, surface, null, 0);
Run Code Online (Sandbox Code Playgroud)
12 月 25 日更新:在配置编码器和解码器以检查视频的方向是否有问题时,我尝试了不同的分辨率和方向,但输出视频刚刚旋转,绿色问题仍然存在。我还为编码器尝试了“video/mp4v-es”,结果视频在 Mac 上可见,但 iPhone 甚至无法播放。
问题很简单,但我没有任何线索可以解决它:
我编写了一行代码来在我的 Nexus 4 (Android 4.4.2) 上创建一个 AAC 编码器
MediaCodec codec = MediaCodec.createEncoderByType("audio/mp4a-latm");
Run Code Online (Sandbox Code Playgroud)
“codec”中保存的返回值不为空,但在Logcat中出现红色错误信息:
03-20 15:25:08.985: E/OMXMaster(24517): A component of name 'OMX.qcom.audio.decoder.aac' already exists, ignoring this one.
Run Code Online (Sandbox Code Playgroud)
我也试过另一行:
MediaCodec codec = MediaCodec.createByCodecName("OMX.google.aac.encoder");
Run Code Online (Sandbox Code Playgroud)
并得到相同的错误结果。
在使用 MediaCodec 之前,我是否错过了任何初始化步骤?我在官方文档中没有找到任何关于此的信息。
有没有人遇到过这个问题?
实际上我正在尝试将 PCM 编码为 AAC 文件。我已经阅读了@hubeir这篇文章。看来他已经做到了。我做了同样的事情:(1)设置媒体编解码器并输入 PCM 数据以获得编码帧。为此,我从cts 中读取了代码。每个编码的帧长度约为 371-379。(2)将adts标题添加到框架中,然后保存到文件。我一点一点地检查了头部,它是正确的。但该文件仍然无法播放。所以我想也许错误日志是问题所在。
以下是我的全部代码,供参考:
MediaCodec codec = MediaCodec.createByCodecName("OMX.google.aac.encoder");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_AAC_PROFILE,
MediaCodecInfo.CodecProfileLevel.AACObjectELD);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, nSamplerate);
format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, nChannels);
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用媒体记录器在 android 中录制音频。它适用于 3gp 音频,但是当我尝试使用 aac 格式的相同代码时,它失败了。(这是我的 aac 格式代码):
final String outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.acc";
final MediaRecorder myAudioRecorder = new MediaRecorder();
myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AAC_ADTS);
myAudioRecorder.setOutputFile(outputFile);
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(outputFile);
mediaPlayer.prepare();
mediaPlayer.start();
Run Code Online (Sandbox Code Playgroud)
我已经添加了权限,我正在使用按钮正确触发这些功能。我在这里只写了主要代码只是为了简单 我的问题:
以 aac 格式录制和播放声音的正确方法是什么?
使用媒体记录器和媒体播放器在 android 中录制和播放音频的最佳格式是什么,我该如何实现?我尝试使用 3gp,但它的声音质量很低。
android android-layout android-mediaplayer android-mediarecorder android-studio