既然 AAC 要比 MP3 好,且体积差不多,为什么网上不流行 AAC 格式的音频呢?

mp3与aac音频格式的比较

现状:MP3仍然是使用主流, 虽然AAC比MP3更加先进,但处于优势地位还是MP3。由于各种历史原因,环顾国内这么多音乐软件,它们所提供的大部分音乐还是MP3,就连美国的亚马逊数字音乐等提供的也是MP3音乐,所以相信很多人的便携设备里面放的都是MP3格式的音乐。(估计大部分人都是没有可选择的余地)

​而AAC则由苹果的iTunes Store使用最多。iTunes Store由于发展比较健全,建设比较完善,商店里面的数字音乐多是由母盘(24bit/192khz)转换而来(mp3音乐的来源则五花八门),并且歌曲写有正确完整无杂质的曲目ID3信息,内嵌官方唱片封面等等,会给人更加好的体验。

而AAC则由苹果的iTunes Store使用最多。iTunes Store由于发展比较健全,建设比较完善,商店里面的数字音乐多是由母盘(24bit/192khz)转换而来(mp3音乐的来源则五花八门),并且歌曲写有正确完整无杂质的曲目ID3信息,内嵌官方唱片封面等等,会给人更加好的体验。

利用ffmpeg转换的命令:

D:\srcVideo\testAudio>ffmpeg -i song.mp3 -strict -2 -ab96k -acodec aac song_aac.aac

1.68M的“music.mp4”文件转换后的比较:

下面是从名为“music.mp4”文件通过ffmpeg抽取出音频的结果,music.mp4的信息如下:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'music':

  Metadata:

    major_brand     : isom

    minor_version   : 512

    compatible_brands: isomiso2avc1mp41

    encoder         : Lavf53.32.100

    comment         : GIFSHOW WORK @P-1401696250-4089960-32@

  Duration: 00:00:25.03, start: 0.000000, bitrate: 552 kb/s

    Stream #0:0(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 127

kb/s (default)

    Metadata:

      handler_name    : SoundHandler

    Stream #0:1(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 240x320,

423 kb/s, 1 fps, 1 tbr, 1k tbn, 2 tbc (default)

    Metadata:

      handler_name    : VideoHandler

Aac格式的效果:

 Mp3格式的效果:

12.1M的“guxinglei.mp3”文件转换后的比较:

下面是从名为“guxinglei.mp3”文件通过ffmpeg转换音频的结果,guxinglei.mp3的信息如下:     

Input #0, mp3, from 'guxinglei.mp3':

  Metadata:

    artist          : xxx

    album           : xxxx

    title           : xxxx

    TYER            : 2003-01-29

    Tagging time    : 2013-01-05T08:25:35

  Duration: 00:05:07.96, start: 0.000000, bitrate: 321 kb/s

    Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 320 kb/s

    Stream #0:1: Video: mjpeg, yuvj420p(pc), 240x240 [SAR 1:1 DAR 1:1], 90k tbr,

 90k tbn, 90k tbc

    Metadata:

      title           : e

      comment         : Cover (front)

 Aac格式的效果:

Mp3格式的效果:

结论:48kbps的aac和mp3听起来音质稍微有一些不舒服,但是码率在64kps(包括)及以上的aac和mp3音频听起来效果差别不大(没有用专业的工具测试),针对我们的视频,可以使用 128kbps 的mp3格式存储。

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,编解码,推拉流,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

AAC编码的主要扩展名有三种:

(1).AAC
       使用MPEG-2 Audio Transport Stream(ADTS,参见MPEG-2)容器,区别于使用MPEG-4容器的MP4/M4A格式,属于传统的AAC编码(FAAC默认的封装,但FAAC亦可输出MPEG-4封装的AAC)

(2).MP4
       使用了MPEG-4 Part 14(第14部分)的简化版即3GPP Media Release 6 Basic(3gp6,参见3GP)进行封装的AAC编码(Nero AAC编码器仅能输出MPEG-4封装的AAC);

(3).M4A
       为了区别纯音频MP4文件和包含视频的MP4文件而由苹果(Apple)公司使用的扩展名,Apple iTunes对纯音频MP4文件采用了".M4A"命名。M4A的本质和音频MP4相同,故音频MP4文件亦可直接更改扩展名为M4A。

AAC特点

(1)AAC是一种高压缩比的音频压缩算法,但它的压缩比要远超过较老的音频压缩算法, 如AC-3、MP3等。并且其质量可以同未压缩的CD音质相媲美。

(2)同其他类似的音频编码算法一样,AAC也是采用了变换编码算法,但AAC使用了分辨率 更高的滤波器组,因此它可以达到更高的压缩比。

(3)AAC使用了临时噪声重整、后向自适应线性预测、联合立体声技术和量化哈夫曼编码等最新技术,这些新技术的使用都使压缩比得到进一步的提高。

(4)AAC支持更多种采样率和比特率、支持1个到48个音轨、支持多达15个低频音轨、具有多种语言的兼容能力、还有多达15个内嵌数据流。

(5)AAC支持更宽的声音频率范围,最高可达到96kHz,最低可达8KHz,远宽于MP3的16KHz-48kHz的范围。

(6)不同于MP3及WMA,AAC几乎不损失声音频率中的甚高、甚低频率成分,并且比WMA在频谱结构上更接近于原始音频,因而声音的保真度更好。专业评测中表明,AAC比WMA声音更清晰,而且更接近原音。

(7)AAC采用优化的算法达到了更高的解码效率,解码时只需较少的处理能力。

AAC的各种规格及适用场合

AAC共有9种规格,以适应不同的场合的需要:
MPEG-2 AAC LC 低复杂度规格(Low Complexity)--比较简单,没有增益控制,但提高了
编码效率,在中等码率的编码效率以及音质方面,都能找到平衡点
MPEG-2 AAC Main 主规格
MPEG-2 AAC SSR 可变采样率规格(Scaleable Sample Rate)
MPEG-4 AAC LC 低复杂度规格(Low Complexity)------现在的手机比较常见的MP4文件中的音频部份就包括了该规格音频文件
MPEG-4 AAC Main 主规格 ------包含了除增益控制之外的全部功能,其音质最好
MPEG-4 AAC SSR 可变采样率规格(Scaleable Sample Rate)
MPEG-4 AAC LTP 长时期预测规格(Long Term Predicition)
MPEG-4 AAC LD 低延迟规格(Low Delay)
MPEG-4 AAC HE 高效率规格(High Efficiency)-----这种规格适合用于低码率编码,有Nero ACC 编码器支持

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用AudioRecorder录制aac格式音频并实现暂停功能,需要使用MediaCodec进行编码。以下是一个简单的实现示例: ```java public class AacRecorder { private static final String TAG = AacRecorder.class.getSimpleName(); private static final int SAMPLE_RATE = 44100; private static final int BIT_RATE = 128000; private static final int CHANNEL_COUNT = 1; private static final int TIMEOUT_US = 10000; private static final int MAX_BUFFER_SIZE = 16384; private static final String MIME_TYPE = "audio/mp4a-latm"; private AudioRecord mAudioRecord; private MediaCodec mMediaCodec; private String mOutputFile; private FileOutputStream mFileOutputStream; private boolean mIsRecording = false; private boolean mIsPaused = false; private long mPresentationTimeUs = 0; public AacRecorder(String outputFile) { mOutputFile = outputFile; } public void start() { try { mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, CHANNEL_COUNT, AudioFormat.ENCODING_PCM_16BIT, AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_COUNT, AudioFormat.ENCODING_PCM_16BIT)); MediaFormat format = MediaFormat.createAudioFormat(MIME_TYPE, SAMPLE_RATE, CHANNEL_COUNT); format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE); format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC); mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE); mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); mMediaCodec.start(); mFileOutputStream = new FileOutputStream(mOutputFile); } catch (IOException | IllegalStateException e) { e.printStackTrace(); return; } mIsRecording = true; mIsPaused = false; new Thread(new Runnable() { @Override public void run() { try { ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers(); ByteBuffer[] outputBuffers = mMediaCodec.getOutputBuffers(); MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); while (mIsRecording) { if (!mIsPaused) { int inputBufferIndex = mMediaCodec.dequeueInputBuffer(TIMEOUT_US); if (inputBufferIndex >= 0) { ByteBuffer inputBuffer = inputBuffers[inputBufferIndex]; inputBuffer.clear(); int bytesRead = mAudioRecord.read(inputBuffer, MAX_BUFFER_SIZE); if (bytesRead > 0) { mMediaCodec.queueInputBuffer(inputBufferIndex, 0, bytesRead, mPresentationTimeUs, 0); mPresentationTimeUs += (long) (1.0f / SAMPLE_RATE * 1000000); } } int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_US); while (outputBufferIndex >= 0) { ByteBuffer outputBuffer = outputBuffers[outputBufferIndex]; outputBuffer.position(bufferInfo.offset); outputBuffer.limit(bufferInfo.offset + bufferInfo.size); byte[] data = new byte[bufferInfo.size]; outputBuffer.get(data); mFileOutputStream.write(data); Log.d(TAG, "Recorded " + data.length + " bytes"); mMediaCodec.releaseOutputBuffer(outputBufferIndex, false); outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_US); } } } mAudioRecord.stop(); mAudioRecord.release(); mMediaCodec.stop(); mMediaCodec.release(); mFileOutputStream.flush(); mFileOutputStream.close(); } catch (IOException | IllegalStateException e) { e.printStackTrace(); } } }).start(); mAudioRecord.startRecording(); } public void pause() { mIsPaused = true; } public void resume() { mIsPaused = false; } public void stop() { mIsRecording = false; } public boolean isRecording() { return mIsRecording; } public boolean isPaused() { return mIsPaused; } } ``` 在这个示例中,我们创建了一个AacRecorder类来封装录制AAC音频的功能。在start()方法中,我们创建了一个AudioRecord实例来录制音频,并创建了一个MediaCodec实例来进行AAC编码。在录音任务中,我们使用一个while循环来读取录音数据,并将其传递给MediaCodec进行编码。在编码完成后,我们将编码后的数据写入文件中。 在pause()和resume()方法中,我们分别设置mIsPaused标志为true和false,以控制录音任务的暂停和继续。 在stop()方法中,我们将mIsRecording标志设置为false,以停止录音任务,并释放AudioRecord和MediaCodec资源。 请注意,这只是一个简单的示例,实际应用中可能需要更复杂的逻辑来处理录音暂停和继续的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值