M4A音频文件和AAC音频文件之间是否有区别,或者它们是完全相同但具有不同的文件扩展名?
我在Android(Jelly Bean)中使用媒体编解码器类将PCM格式编码为AAC.该文件已编码,但没有音乐播放器能够播放该文件.我无法在网上找到任何工作代码或适当的文档.
这是我的代码:
public void doConvert()
{
new AsyncTask<Void, Void, Void>()
{
@Override
protected Void doInBackground(Void... params)
{
try
{
int codecCount = MediaCodecList.getCodecCount();
for ( int i=0; i < codecCount; i++)
{
MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
Logger.getLogger(MainActivity.class.getSimpleName()).log(Level.INFO, info.getName());
for ( String type : info.getSupportedTypes() )
{
Logger.getLogger(MainActivity.class.getSimpleName()).log(Level.INFO, type);
}
}
File inputFile = new File( Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/Ghajini27_Mono_8Khz.wav");
//File inputFile = new File( sampleFD.get);
Log.e("File", String.valueOf(inputFile.length()));
FileInputStream fis = new FileInputStream(inputFile);
fis.skip(44);//remove wav header
File outputFile = new File( Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/out.m4a");
if …Run Code Online (Sandbox Code Playgroud) 我使用MediaCodecAndroid SDK提供的类,因为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);
Run Code Online (Sandbox Code Playgroud)
我能够从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);
Run Code Online (Sandbox Code Playgroud)
VLC告诉我,我的aac文件中没有流.该命令FFMPEG -i @filename@给出了以下错误:处理输入时找到无效数据.我测试过的所有媒体播放器都无法播放我的文件.
为什么我无法播放我的文件?我没有收到OpenMAX错误,LogCat应用程序在编码时不会崩溃.我写了一个视频编码器,它的工作原理与之相同.
这是将数据从AudioRecord实例读取到缓冲区的代码:
new Thread() {
public void run() { …Run Code Online (Sandbox Code Playgroud) 我正在努力实施
AudioRecord (MIC) ->
PCM -> AAC Encoder
AAC -> PCM Decode
-> AudioTrack?? (SPEAKER)
Run Code Online (Sandbox Code Playgroud)
与MediaCodec在Android 4.1+(API16).
首先,我成功(但不知道正确优化)实现PCM -> AAC Encoder由 MediaCodec为如下预期
private boolean setEncoder(int rate)
{
encoder = MediaCodec.createEncoderByType("audio/mp4a-latm");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024);//AAC-HE 64kbps
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectHE);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
return true;
}
Run Code Online (Sandbox Code Playgroud)
INPUT:PCM比特率= 44100(Hz)x 16(比特)×1(等值)= 705600比特/秒
输出:AAC-HE比特率= 64 x 1024(比特)= 65536比特/秒
因此,数据大小近似被压缩x11,我通过观察日志确认了这一点
数据大小近似压缩x11,到目前为止一直很好.
现在,我有一个UDP服务器来接收编码数据,然后解码它.
解码器配置文件设置如下:
private …Run Code Online (Sandbox Code Playgroud) 据我了解,如果编码为MPEG-4或3GPP,Android将只播放AAC格式的音频.
当它在应用程序的本地时,我能够播放编码为M4A的AAC音频,但是当从服务器获取它时它会失败.
以下工作,因为m4a文件本地保存在res/raw目录中.
MediaPlayer mp = MediaPlayer.create(this, R.raw.*file*);
mp.start();
Run Code Online (Sandbox Code Playgroud)
以下不起作用.(但MP3的确如此).
Uri uri = Uri.parse("http://*example.com*/blah.m4a");
MediaPlayer mp = MediaPlayer.create(this, uri);
mp.start();
Run Code Online (Sandbox Code Playgroud)
当m4a音频文件不是本地时,任何人都可以解释它失败的原因吗?
这是(一些)错误......
ERROR/PlayerDriver(542): Command PLAYER_INIT completed with an error or info UNKNOWN PVMFStatus
ERROR/MediaPlayer(769): error (200, -32)
WARN/PlayerDriver(542): PVMFInfoErrorHandlingComplete
DEBUG/MediaPlayer(769): create failed:
DEBUG/MediaPlayer(769): java.io.IOException: Prepare failed.: status=0xC8
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.prepare(Native Method)
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.create(MediaPlayer.java:530)
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.create(MediaPlayer.java:507)
...
Run Code Online (Sandbox Code Playgroud)
我的目标是SDK 1.6.
这个问题从以下问题溢出:
如何以编程方式将mp3转换为itunes-playable aac/m4a文件?
无论如何,我学会了如何创建aac文件,然后我发现aac不仅仅是一个具有不同文件扩展名的m4a文件.事实上,我需要以某种方式将aac包装到m4a容器中.理想情况下,我只需调用命令行即可.
我正在尝试使用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) 如果我使用iPhoneOS中包含的音频解码库(例如AVAudioPlayer).我还需要支付Thomson或VIA Licensing的许可证才能合法解码我的应用程序中的AAC或MP3文件吗?
编辑:
我无法找到ADC的确切答案(他们不知道),我也对其他平台上的音频库感到好奇(Windows,Mac,Android ......)所以我在这个问题上添加了一笔赏金.
我目前正在开发一种应用程序,它需要记录音频,将其编码为AAC,对其进行流式传输,并在反向中执行相同的操作 - 接收流,解码AAC和播放音频.
我使用MediaRecorder成功录制了AAC(包装在MP4容器中),并使用AudioRecord类成功上传了音频.但是,我需要能够在流式传输时对音频进行编码,但这些类似乎都没有帮助我这样做.
我研究了一下,发现大多数有这个问题的人最终都使用像ffmpeg这样的本地库.
但我想知道,因为Android已经包含StageFright,它具有可以进行编码和解码的本机代码(例如,AAC编码和AAC解码),有没有办法在我的应用程序上使用这些本机代码?我怎样才能做到这一点?
如果我只需要用他们的本机代码实现一些JNI类,那就太好了.另外,因为它是一个Android库,所以不会出现许可问题(如果我错了,请纠正我).
我们在Mac OS X上使用ffmpeg实现了一个编码过程.此过程将从以下内容获取源视频和几个文件:.m3u8视频,.mp4视频和.mp3音频文件.
默认情况下,我们使用了m3u8进程中的视频,这是一个带有AAC(通过libfaac)音频的h264(通过libx264)视频.
我们主要在移动设备上使用这些视频(因此是m3u8文件),但我们也使用Android,Windows Phone等的.mp4文件.越来越多的我们还需要通过Flash播放器在网络上提供这些相同的视频或HTML5播放器.
因此,我们希望为所有这些用途提供最好的音频/视频编解码器组合...我很困惑的是.mp4文件的"标准"是什么?
如果.mp4使用mp3编解码器,那么除了QuickTime之外它在任何地方播放都很好,在QuickTime中视频播放但没有音频(在VLC播放器中工作得很好).
我被告知这是由于QuickTime如何使用文件扩展来假设有关视频的信息而不是试图从文件中实际获取编解码器数据?这确实有道理,如果我们编码相同的文件但是使用AAC作为音频编解码器,那么它在QuickTime中工作得很好.
那么---什么是"正确的"或"理想的"音频/视频编解码器组合---使用AAC是最好和最安全的(即它可以在各种设备上工作),即使它不是"免费"编解码器?
aac ×10
android ×6
audiorecord ×3
m4a ×3
mediacodec ×3
audio ×2
ffmpeg ×2
mp3 ×2
pcm ×2
containers ×1
h.264 ×1
iphone ×1
licensing ×1
mp4 ×1
native ×1
openmax ×1
stagefright ×1
stream ×1