Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用AudioToolbox编码AAC

使用AudioToolbox编码AAC

作者头像
落影
发布于 2018-04-27 08:51:35
发布于 2018-04-27 08:51:35
2.1K00
代码可运行
举报
文章被收录于专栏:落影的专栏落影的专栏
运行总次数:0
代码可运行

前言

使用VideoToolbox硬编码H.264

使用VideoToolbox硬解码H.264

这次在编码H.264视频流的同时,录制并编码AAC音频流。

介绍

自然界中的声音非常复杂,波形极其复杂,通常我们采用的是脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。

  • 抽样:对模拟信号进行周期性扫描,把时间上连续的信号变成时间上离散的信号;
  • 量化:用一组规定的电平,把瞬时抽样值用最接近的电平值来表示,通常是用二进制表示;
  • 编码:用一组二进制码组来表示每一个有固定电平的量化值;

PCM介绍:百度百科

容易知道,采样后的数据大小 = 采样率值×采样大小值×声道数 bps。

一个采样率为44.1KHz,采样大小为16bit,双声道的PCM编码的WAV文件,它的数据速率=44.1K×16×2 bps=1411.2 Kbps= 176.4 KB/s。

这个速率和压缩后的视频数据速率差不多!

延伸出来AAC高级音频编码。

AAC高级音频编码

AAC(Advanced Audio Coding),中文名:高级音频编码,出现于1997年,基于MPEG-2的音频编码技术。由Fraunhofer IIS、杜比实验室、AT&T、Sony等公司共同开发,目的是取代MP3格式。

AAC的维基百科 音频压缩编码原理看这里

AAC音频格式

AAC音频格式有ADIF和ADTS:

  • ADIF:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。
  • ADTS:Audio Data Transport Stream 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。

iOS上把PCM音频编码成AAC音频流

  • 1、设置编码器(codec),并开始录制;
  • 2、收集到PCM数据,传给编码器;
  • 3、编码完成回调callback,写入文件。

具体步骤

1、创建并配置AVCaptureSession

创建AVCaptureSession,然后找到音频的AVCaptureDevice,根据音频device创建输入并添加到session,最后添加output到session。

audioFileHandle是NSFileHandle,用户写入编码后的AAC音频到文件。 demo中,此段代码还包括Video的设置。为了缩短篇幅,去掉了video相关的配置。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (void)startCapture {
    self.mCaptureSession = [[AVCaptureSession alloc] init];
    mCaptureQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    mEncodeQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
    AVCaptureDevice *audioDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] lastObject];
    self.mCaptureAudioDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:audioDevice error:nil];
    if ([self.mCaptureSession canAddInput:self.mCaptureAudioDeviceInput]) {
        [self.mCaptureSession addInput:self.mCaptureAudioDeviceInput];
    }
    self.mCaptureAudioOutput = [[AVCaptureAudioDataOutput alloc] init];
    
    if ([self.mCaptureSession canAddOutput:self.mCaptureAudioOutput]) {
        [self.mCaptureSession addOutput:self.mCaptureAudioOutput];
    }
    [self.mCaptureAudioOutput setSampleBufferDelegate:self queue:mCaptureQueue];
       
    NSString *audioFile = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"abc.aac"];
    [[NSFileManager defaultManager] removeItemAtPath:audioFile error:nil];
    [[NSFileManager defaultManager] createFileAtPath:audioFile contents:nil attributes:nil];
    audioFileHandle = [NSFileHandle fileHandleForWritingAtPath:audioFile];
    
    [self.mCaptureSession startRunning];
}
2、创建转换器

AudioStreamBasicDescription是输出流的结构体描述,

配置好outAudioStreamBasicDescription后,

根据AudioClassDescription(编码器),

调用AudioConverterNewSpecific创建转换器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 *  设置编码参数
 *
 *  @param sampleBuffer 音频
 */
- (void) setupEncoderFromSampleBuffer:(CMSampleBufferRef)sampleBuffer {
    AudioStreamBasicDescription inAudioStreamBasicDescription = *CMAudioFormatDescriptionGetStreamBasicDescription((CMAudioFormatDescriptionRef)CMSampleBufferGetFormatDescription(sampleBuffer));
    
    AudioStreamBasicDescription outAudioStreamBasicDescription = {0}; // 初始化输出流的结构体描述为0. 很重要。
    outAudioStreamBasicDescription.mSampleRate = inAudioStreamBasicDescription.mSampleRate; // 音频流,在正常播放情况下的帧率。如果是压缩的格式,这个属性表示解压缩后的帧率。帧率不能为0。
    outAudioStreamBasicDescription.mFormatID = kAudioFormatMPEG4AAC; // 设置编码格式
    outAudioStreamBasicDescription.mFormatFlags = kMPEG4Object_AAC_LC; // 无损编码 ,0表示没有
    outAudioStreamBasicDescription.mBytesPerPacket = 0; // 每一个packet的音频数据大小。如果的动态大小,设置为0。动态大小的格式,需要用AudioStreamPacketDescription 来确定每个packet的大小。
    outAudioStreamBasicDescription.mFramesPerPacket = 1024; // 每个packet的帧数。如果是未压缩的音频数据,值是1。动态帧率格式,这个值是一个较大的固定数字,比如说AAC的1024。如果是动态大小帧数(比如Ogg格式)设置为0。
    outAudioStreamBasicDescription.mBytesPerFrame = 0; //  每帧的大小。每一帧的起始点到下一帧的起始点。如果是压缩格式,设置为0 。
    outAudioStreamBasicDescription.mChannelsPerFrame = 1; // 声道数
    outAudioStreamBasicDescription.mBitsPerChannel = 0; // 压缩格式设置为0
    outAudioStreamBasicDescription.mReserved = 0; // 8字节对齐,填0.
    AudioClassDescription *description = [self
                                          getAudioClassDescriptionWithType:kAudioFormatMPEG4AAC
                                          fromManufacturer:kAppleSoftwareAudioCodecManufacturer]; //软编
    
    OSStatus status = AudioConverterNewSpecific(&inAudioStreamBasicDescription, &outAudioStreamBasicDescription, 1, description, &_audioConverter); // 创建转换器
    if (status != 0) {
        NSLog(@"setup converter: %d", (int)status);
    }
}

获取编码器的方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 *  获取编解码器
 *
 *  @param type         编码格式
 *  @param manufacturer 软/硬编
 *
 编解码器(codec)指的是一个能够对一个信号或者一个数据流进行变换的设备或者程序。这里指的变换既包括将 信号或者数据流进行编码(通常是为了传输、存储或者加密)或者提取得到一个编码流的操作,也包括为了观察或者处理从这个编码流中恢复适合观察或操作的形式的操作。编解码器经常用在视频会议和流媒体等应用中。
 *  @return 指定编码器
 */
- (AudioClassDescription *)getAudioClassDescriptionWithType:(UInt32)type
                                           fromManufacturer:(UInt32)manufacturer
{
    static AudioClassDescription desc;
    
    UInt32 encoderSpecifier = type;
    OSStatus st;
    
    UInt32 size;
    st = AudioFormatGetPropertyInfo(kAudioFormatProperty_Encoders,
                                    sizeof(encoderSpecifier),
                                    &encoderSpecifier,
                                    &size);
    if (st) {
        NSLog(@"error getting audio format propery info: %d", (int)(st));
        return nil;
    }
    
    unsigned int count = size / sizeof(AudioClassDescription);
    AudioClassDescription descriptions[count];
    st = AudioFormatGetProperty(kAudioFormatProperty_Encoders,
                                sizeof(encoderSpecifier),
                                &encoderSpecifier,
                                &size,
                                descriptions);
    if (st) {
        NSLog(@"error getting audio format propery: %d", (int)(st));
        return nil;
    }
    
    for (unsigned int i = 0; i < count; i++) {
        if ((type == descriptions[i].mSubType) &&
            (manufacturer == descriptions[i].mManufacturer)) {
            memcpy(&desc, &(descriptions[i]), sizeof(desc));
            return &desc;
        }
    }
    
    return nil;
}
3、获取到PCM数据并传入编码器

CMSampleBufferGetDataBuffer获取到CMSampleBufferRef里面的CMBlockBufferRef,再通过CMBlockBufferGetDataPointer获取到_pcmBufferSize和_pcmBuffer;

调用AudioConverterFillComplexBuffer传入数据,并在callBack函数调用填充buffer的方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);
        CFRetain(blockBuffer);
        OSStatus status = CMBlockBufferGetDataPointer(blockBuffer, 0, NULL, &_pcmBufferSize, &_pcmBuffer);
        NSError *error = nil;
        if (status != kCMBlockBufferNoErr) {
            error = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil];
        }
        memset(_aacBuffer, 0, _aacBufferSize);
        
        AudioBufferList outAudioBufferList = {0};
        outAudioBufferList.mNumberBuffers = 1;
        outAudioBufferList.mBuffers[0].mNumberChannels = 1;
        outAudioBufferList.mBuffers[0].mDataByteSize = (int)_aacBufferSize;
        outAudioBufferList.mBuffers[0].mData = _aacBuffer;
        AudioStreamPacketDescription *outPacketDescription = NULL;
        UInt32 ioOutputDataPacketSize = 1;
        // Converts data supplied by an input callback function, supporting non-interleaved and packetized formats.
        // Produces a buffer list of output data from an AudioConverter. The supplied input callback function is called whenever necessary.
        status = AudioConverterFillComplexBuffer(_audioConverter, inInputDataProc, (__bridge void *)(self), &ioOutputDataPacketSize, &outAudioBufferList, outPacketDescription);

Callback函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 *  A callback function that supplies audio data to convert. This callback is invoked repeatedly as the converter is ready for new input data.
 
 */
OSStatus inInputDataProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void *inUserData)
{
    AACEncoder *encoder = (__bridge AACEncoder *)(inUserData);
    UInt32 requestedPackets = *ioNumberDataPackets;
    
    size_t copiedSamples = [encoder copyPCMSamplesIntoBuffer:ioData];
    if (copiedSamples < requestedPackets) {
        //PCM 缓冲区还没满
        *ioNumberDataPackets = 0;
        return -1;
    }
    *ioNumberDataPackets = 1;
    
    return noErr;
}

/**
 *  填充PCM到缓冲区
 */
- (size_t) copyPCMSamplesIntoBuffer:(AudioBufferList*)ioData {
    size_t originalBufferSize = _pcmBufferSize;
    if (!originalBufferSize) {
        return 0;
    }
    ioData->mBuffers[0].mData = _pcmBuffer;
    ioData->mBuffers[0].mDataByteSize = (int)_pcmBufferSize;
    _pcmBuffer = NULL;
    _pcmBufferSize = 0;
    return originalBufferSize;
}
4、得到rawAAC码流,添加ADTS头,并写入文件

AudioConverterFillComplexBuffer返回的是AAC原始码流,需要在AAC每帧添加ADTS头,调用adtsDataForPacketLength方法生成,最后把数据写入audioFileHandle的文件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        if (status == 0) {
            NSData *rawAAC = [NSData dataWithBytes:outAudioBufferList.mBuffers[0].mData length:outAudioBufferList.mBuffers[0].mDataByteSize];
            NSData *adtsHeader = [self adtsDataForPacketLength:rawAAC.length];
            NSMutableData *fullData = [NSMutableData dataWithData:adtsHeader];
            [fullData appendData:rawAAC];
            data = fullData;
        } else {
            error = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil];
        }
        if (completionBlock) {
            dispatch_async(_callbackQueue, ^{
                completionBlock(data, error);
            });
        }

网上的ADTS头生成方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 *  Add ADTS header at the beginning of each and every AAC packet.
 *  This is needed as MediaCodec encoder generates a packet of raw
 *  AAC data.
 *
 *  Note the packetLen must count in the ADTS header itself.
 *  See: http://wiki.multimedia.cx/index.php?title=ADTS
 *  Also: http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Channel_Configurations
 **/
- (NSData*) adtsDataForPacketLength:(NSUInteger)packetLength {
    int adtsLength = 7;
    char *packet = malloc(sizeof(char) * adtsLength);
    // Variables Recycled by addADTStoPacket
    int profile = 2;  //AAC LC
    //39=MediaCodecInfo.CodecProfileLevel.AACObjectELD;
    int freqIdx = 4;  //44.1KHz
    int chanCfg = 1;  //MPEG-4 Audio Channel Configuration. 1 Channel front-center
    NSUInteger fullLength = adtsLength + packetLength;
    // fill in ADTS data
    packet[0] = (char)0xFF; // 11111111     = syncword
    packet[1] = (char)0xF9; // 1111 1 00 1  = syncword MPEG-2 Layer CRC
    packet[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));
    packet[3] = (char)(((chanCfg&3)<<6) + (fullLength>>11));
    packet[4] = (char)((fullLength&0x7FF) >> 3);
    packet[5] = (char)(((fullLength&7)<<5) + 0x1F);
    packet[6] = (char)0xFC;
    NSData *data = [NSData dataWithBytesNoCopy:packet length:adtsLength freeWhenDone:YES];
    return data;
}

总结

demo主要是为了熟悉AAC编码的格式,实现了从麦克风录制音频并编码成AAC码流。

下一篇介绍如何解码播放这次生成的AAC码流。

代码地址点这里

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016.09.14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
iOS下 AAC 音频编码
iOS下Apple为我们提供了非常方便的音频编解码工具AudioToolbox。该工具中包含了常见的编解码库,如AAC、iLBC、OPUS等。今天我们就介绍一下如何使用 AudioToolbox 进行AAC音频的编码工作。
音视频_李超
2020/04/02
2.2K0
iOS AVDemo(2):音频编码,采集 PCM 数据编码为 AAC丨音视频工程示例
iOS/Android 客户端开发同学如果想要开始学习音视频开发,最丝滑的方式是对音视频基础概念知识有一定了解后,再借助 本地平台的音视频能力上手去实践音视频的采集 → 编码 → 封装 → 解封装 → 解码 → 渲染过程,并借助音视频工具来分析和理解对应的音视频数据。
关键帧
2022/06/13
9550
iOS AVDemo(2):音频编码,采集 PCM 数据编码为 AAC丨音视频工程示例
iOS下解码AAC并播放
今天我们介绍一下如何在iOS进行AAC解码,并使用AudioUnit播放解码后的PCM数据。
音视频_李超
2020/04/01
3.5K0
iOS下解码AAC并播放
iOS AVDemo(5):音频解码,免费获得源码丨音视频工程示例
iOS/Android 客户端开发同学如果想要开始学习音视频开发,最丝滑的方式是对音视频基础概念知识有一定了解后,再借助本地平台的音视频能力上手去实践音视频的采集 → 编码 → 封装 → 解封装 → 解码 → 渲染过程,并借助音视频工具来分析和理解对应的音视频数据。
关键帧
2022/06/13
8350
iOS AVDemo(5):音频解码,免费获得源码丨音视频工程示例
Audio Unit播放aac/m4a/mp3等文件
前言 相关文章: 使用VideoToolbox硬编码H.264 使用VideoToolbox硬解码H.264 使用AudioToolbox编码AAC 使用AudioToolbox播放AAC HLS点播实现(H.264和AAC码流) HLS推流的实现(iOS和OS X系统) iOS在线音频流播放 Audio Unit播放PCM文件 Audio Unit录音(播放伴奏+耳返) 前面两篇介绍了Audio Unit播放PCM文件和边录边播,这次引入AudioConvert实现aac/m4a/mp
落影
2018/04/27
3.1K0
iOS AVDemo(6):音频渲染,免费获得源码丨音视频工程示例
iOS/Android 客户端开发同学如果想要开始学习音视频开发,最丝滑的方式是对音视频基础概念知识有一定了解后,再借助 iOS/Android 平台的音视频能力上手去实践音视频的采集 → 编码 → 封装 → 解封装 → 解码 → 渲染过程,并借助音视频工具来分析和理解对应的音视频数据。
关键帧
2022/06/13
9240
iOS AVDemo(6):音频渲染,免费获得源码丨音视频工程示例
iOS音频(2)——Audio Unit
相对于MacOS,Audio Unit在iOS上使用到的几率很小,AV Foundation 和Audio Toolbox提供的API已经满足我们平常开发中音视频的录制播放的需求点。Audio Unit几乎可以认为是对硬件驱动层的封装,通过它获取麦克风采集的音频数据或者将音频数据传输给扬声器播放。但是随着直播热对音视频的传输速度高要求,将PCM音频转换成AAC主要用到就是Audio Unit。
羊羽shine
2019/05/29
2.4K0
iOS音频(1)——AudioToolbox
AudioToolbox提供的API主要是C 使用起来相对晦涩,针对本文提供了简单的代码示例减小学习的阻力 AudioToolbox
羊羽shine
2019/05/29
2.2K0
iOS AVDemo(1):音频采集,免费获取全部源码丨音视频工程示例
iOS/Android 客户端开发同学如果想要开始学习音视频开发,最丝滑的方式是对音视频基础概念知识有一定了解后,再借助本地平台的音视频能力上手去实践音视频的采集 → 编码 → 封装 → 解封装 → 解码 → 渲染过程,并借助音视频工具来分析和理解对应的音视频数据。
关键帧
2022/06/13
1.1K0
iOS AVDemo(1):音频采集,免费获取全部源码丨音视频工程示例
AVPlayer+AudioUnit之播放视频音轨(AVAssetTrack)
VoIP应用中,需要在通话端进行视频播放,同时该视频又不进入到VoIP声音中,避免产生回音现象。
xferris
2020/11/03
2.7K1
AVPlayer+AudioUnit之播放视频音轨(AVAssetTrack)
MediaCodec进行AAC编解码(文件格式转换)
AAC,全称Advanced Audio Coding,是一种专为声音数据设计的文件压缩格式。与MP3不同,它采用了全新的算法进行编码,更加高效,具有更高的“性价比”。利用AAC格式,可使人感觉声音质量没有明显降低的前提下,更加小巧。至于AAC的其他特点网上资料就很多,就不多做介绍了。 在介绍AAC编解码之前,首先要先学习几个新知识MediaExtractor和ADTS格式 仓库源码FFmpegSample,对应版本代码v1.6
用户2929716
2018/08/23
2.1K0
MediaCodec进行AAC编解码(文件格式转换)
【Android RTMP】音频数据采集编码 ( FAAC 音频编码参数设置 | FAAC 编码器创建 | 获取编码器参数 | 设置 AAC 编码规格 | 设置编码器输入输出参数 )
Android 直播推流流程 : 手机采集视频 / 音频数据 , 视频数据使用 H.264 编码 , 音频数据使用 AAC 编码 , 最后将音视频数据都打包到 RTMP 数据包中 , 使用 RTMP 协议上传到 RTMP 服务器中 ;
韩曙亮
2023/03/27
4.5K0
Android AVDemo(2):音频编码,采集 PCM 数据编码为 AAC丨音视频工程示例
iOS/Android 客户端开发同学如果想要开始学习音视频开发,最丝滑的方式是对音视频基础概念知识有一定了解后,再借助 iOS/Android 平台的音视频能力上手去实践音视频的采集 → 编码 → 封装 → 解封装 → 解码 → 渲染过程,并借助音视频工具来分析和理解对应的音视频数据。
关键帧
2022/06/13
1.1K0
Android AVDemo(2):音频编码,采集 PCM 数据编码为 AAC丨音视频工程示例
Audio Unit播放PCM文件
前言 相关文章: 使用VideoToolbox硬编码H.264 使用VideoToolbox硬解码H.264 使用AudioToolbox编码AAC 使用AudioToolbox播放AAC HLS点播实现(H.264和AAC码流) HLS推流的实现(iOS和OS X系统) iOS在线音频流播放 最近对Audio Unit感兴趣,用几周的业余时间研究,顺利习得Audio Unit播放、录制声音,用AudioConvert转格式的技巧。 这是Audio Unit系列的第一篇,用Audio Uni
落影
2018/04/27
3.1K0
Audio Unit播放PCM文件
最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
本文介绍一个最简单的基于FFMPEG的音频编码器。该编码器实现了PCM音频採样数据编码为AAC的压缩编码数据。编码器代码十分简单,可是每一行代码都非常重要。通过看本编码器的源码。能够了解FFMPEG音频编码的流程。
全栈程序员站长
2022/07/08
1.3K0
最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
iOS AVDemo(4):音频解封装,从 MP4 中解封装出 AAC丨音视频工程示例
iOS/Android 客户端开发同学如果想要开始学习音视频开发,最丝滑的方式是对音视频基础概念知识有一定了解后,再借助本地平台的音视频能力上手去实践音视频的采集 → 编码 → 封装 → 解封装 → 解码 → 渲染过程,并借助音视频工具来分析和理解对应的音视频数据。
关键帧
2022/06/13
5270
iOS AVDemo(4):音频解封装,从 MP4 中解封装出 AAC丨音视频工程示例
安卓支持aac编码吗_aac音频格式
Android音视频编码分为软编和硬编两种。所谓的硬编是用设备GPU去实现编解码,从而减轻CPU的压力,让程序更加的健壮,自然而然你就知道了软编其实就是让CPU编码(其实是在c层通过c/c++进行编码,之所以这样是因为c/c++平台上已经有很多比较好的音视频编解码库。比如著名ffmpeg,搞过音视频的相信对这个库绝对不会陌生)。那么或许你心目中有一个小小的疑问?为什么要编解码了?原因就是让数据更小便于传输。编解码就好比是压缩与解压!本文是把PCM数据硬编成ACC格式数据。如果对音频的采集不熟悉,请查阅Android 音频采集。
全栈程序员站长
2022/09/27
1.2K0
安卓支持aac编码吗_aac音频格式
音视频封装:FLV格式详解和打包H264、AAC方案(下)
因表示了前一个Metadata Tag的长度是311字节,这跟上篇分析结果是一致的;
潇湘落木
2020/11/12
3.3K0
音视频封装:FLV格式详解和打包H264、AAC方案(下)
音频编码:入门看这篇就够了丨音视频基础
(本文基本逻辑:音频编码的理论基础 → PCM 编码 → AAC 编码工具集、编码流程、编码规格和数据格式)
关键帧
2022/06/13
4.5K0
音频编码:入门看这篇就够了丨音视频基础
音视频八股文(7)-- 音频aac adts
AAC(Advanced Audio Coding)是一种现代的音频编码技术,用于数字音频的传输和存储领域。AAC是MPEG-2和MPEG-4标准中的一部分,可提供更高质量的音频数据,并且相比于MP3等旧有音频格式,AAC需要更少的比特率。
福大大架构师每日一题
2023/04/27
1.1K0
推荐阅读
相关推荐
iOS下 AAC 音频编码
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验