相关疑难解决方法(0)

在Android上使用AudioRecord和MediaCodec编码AAC音频

我正在尝试使用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 aac audiorecord mediacodec

15
推荐指数
2
解决办法
2万
查看次数

在Android上使用MediaCodec API解码AAC

我正在尝试在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来生成格式对象?

android aac

11
推荐指数
1
解决办法
1万
查看次数

如何初始化MediaFormat以配置MediaCodec以解码原始AAC数据?

我的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 mediacodec

5
推荐指数
2
解决办法
7750
查看次数

使用 MediaCodec 编码时三分之二的屏幕为绿色

我正在开发一个需要在 Android 上使用 OpenGL 处理视频的项目。我决定使用 MediaCodec,并在ExtractDecodeEditEncodeMuxTest的帮助下设法让它工作。结果非常好,我让它接收视频,提取轨道,解码视频轨道,使用 OpenGL 进行编辑,然后编码为视频文件。

问题是结果视频可以在Android上很好地播放,但是到了iOS时,屏幕的三分之二是绿色的。

我尝试使用此处此处此处的建议解决编码器的不同格式,但问题仍然相同。

有人可以告诉我可能导致此问题的原因以及如何解决吗?

这是在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 甚至无法播放。

video android ios android-mediacodec

5
推荐指数
1
解决办法
1970
查看次数

使用 MediaCodec 创建 AAC 编码器时出错

问题很简单,但我没有任何线索可以解决它:

我编写了一行代码来在我的 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 encode aac android-mediacodec

4
推荐指数
1
解决办法
1万
查看次数

如何在android中使用MediaRecoder录制高质量的音频?

我正在尝试使用媒体记录器在 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

0
推荐指数
1
解决办法
2661
查看次数