美文网首页视频音视频
音视频开发基础理论-音频篇

音视频开发基础理论-音频篇

作者: _小沫 | 来源:发表于2022-07-30 22:59 被阅读0次
    11

    使用AVFoundation处理视频
    使用AVAssetReader、AVAssetWriter编解码视频

    之前的两篇文章浅略讲了iOS音视频开发相关代码实现;
    在编码时关于音视频的相关参数比较多,这些参数不是随便什么数值就能行的;如果不理解缘由,而填写了不合适的参数,容易导致音视频处理过程中出现各种奇怪的问题;
    只有明白了音视频相关的原理,才能理解各种参数的含义,才能更好的实现开发;

    现在,就从音频入手,总结下音频相关的理论知识;

    声音的本质

    声音是如何产生的?

    声音是由物体振动而产生的,一切正在发声的物体都在振动

    sound

    当小球撞击到音叉的时候,音叉会发生振动,对周围的空气产生挤压,然后导致更大范围的空气跟着一起振动,最后我们耳朵旁边的空气也开始振动;这是因为空气产生了疏密变化,形成疏密相间的纵波,由此就产生了声波,声波一直延续到振动消失为止; 声波一直传入我们耳朵,就听到了声音;
    我们说话时的声音,也是声带振动的结果;
    声音的本质就是声波;

    我们听到声音的过程:
    声波 --> 耳廓(收集声波)--> 外耳道(传递声波) --> 鼓膜(将声波转换成振动) --> 听小骨(放大振动) --> 耳蜗(将振动转换成电信号) --> 听觉神经(传递电信号) --> 大脑(形成听觉)

    ear

    声波的三要素

    声波的三要素是频率、振幅和波形;频率代表音阶的高低,振幅代表响度,波形代表音色。

    bxing

    横坐标为时间,纵坐标为受振动的物体分子来回振动产生的位移;随着时间推移,分子的来回振动的轨迹,就是一个正弦或余弦函数的波形图;

    频率

    受振动的物体分子每秒来回振动的次数,叫做频率;单位是秒分之一(1/s),也称为赫兹(Hz);频率用来表示振动的快慢
    (如441Hz代表每秒来回振动441次)

    频率越高,波长就越短。反之频率越低波长则越长,低频率可以更容易地绕过障碍物,因此能量衰减就小,声音就会传得更远。

    人类耳朵的听力有一个频率范围,大约是20Hz~20kHz,不过,即使是在这个频率范围内,不同的频率,听力的感觉也会不一样

    xx
    振幅

    物体未受到振动影响时的位置(横轴上)称为平衡位置;
    从平衡位置到最大位移位置之间的距离,就叫做振幅
    振幅代表响度,振幅越大表示响度越大能量越大,我们听到的声音就越大;

    波形

    上面我们说声波是正弦或余弦函数的图;但这是在单一频率的声波的情况下的;
    事实上,声源的振动产生的并不是单一频率的声波,而是由基音和不同频率的泛音组成的复合声音;当声源的主体振动时会发出一个基音;同时其余各部分也有复合的声源,这些声源组合产生泛音(其实就是物理学上的谐波)
    泛音决定了不同的音色,不同的声源由于其材料、结构不同,泛音不同,则发出声音的音色也不同;

    不同谐波不同的波形

    最后用一张图总结三要素

    声波三要素

    音频数字化

    上面讲到声音的本质是声波的形式,声音属于模拟信号,但便于计算机处理和存储的是数字信号;所以需要将模拟信号(转成数字信号后进行存储。这一过程,即为音频数字化。
    我们在互联网上听到的声音,都是先经过录制后转为了数字音频,再传输到互联网上的;

    音频数字化的常见技术方案是脉冲编码调制(PCM,Pulse Code Modulation);
    主要过程:采样 、量化 、编码。

    采样

    所谓采样就是 在时间轴上对信号进行数字化

    模拟信号的波形是无限光滑的,可以看成由无数个点组成,由于存储空间是相对有限的,数字编码过程中,必须要对波形的点进行采样。采样就是每隔一段时间采集一次模拟信号的样本,在时间上将模拟信号离散化的过程。

    根据采样定理(奈奎斯特–香农采样定理),只有当采样率高于声音信号最高频率的2倍时,才能把采集的声音信号唯一地还原成原来的声音;因此要按比声音最高频率高2倍以上的频率对声音进行采样;人耳能够听到的频率范围是20Hz~20kHz,所以采样频率一般为 44.1kHz,这样就可以保证采样声音达到20kHz也能被数字化,从而使得经过数字化处理之后,人耳听到的声音质量不会被降低。采样率表示每秒采集的样本数量,44.1kHz就是代表1秒会采样44100次;

    samping
    量化

    量化是指在幅度轴上对信号进行数字化,将每一个采样点的样本值数字化

    比如用16比特的二进制信号来表示声音的一个采样,而16比特所表示的 范围是[-32768,32767],共有2^16=625536个可能取值,因此最终模拟的音频信号在幅度上也分为了65536层

    format

    这里的16bit即为位深度(采样精度/采样大小):使用多少个二进制位来存储一个采样点的样本值;位深度越高,表示的振幅越精确;

    编码

    所谓编码,就是按照一定的格式记录采样和量化后的数字数据,比如顺序存储或压缩存储,等等。

    编码涉及了很多种格式,通常说的音频裸数据格式就是PCM(脉冲编码调制)数据。PCM需要以下几个概念:采样格式(sampleFormat)采样率 (sampleRate)声道数(channel)

    采样格式:包含采样位深度、大小端模式、数据排列方式等;
    以FFmpeg定义的sampleFormat为例:

    enum AVSampleFormat {
        AV_SAMPLE_FMT_NONE = -1,
        AV_SAMPLE_FMT_U8,          ///< unsigned 8 bits
        AV_SAMPLE_FMT_S16,         ///< signed 16 bits
        AV_SAMPLE_FMT_S32,         ///< signed 32 bits
        AV_SAMPLE_FMT_FLT,         ///< float
        AV_SAMPLE_FMT_DBL,         ///< double
        AV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planar
        AV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planar
        AV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planar
        AV_SAMPLE_FMT_FLTP,        ///< float, planar
        AV_SAMPLE_FMT_DBLP,        ///< double, planar
        AV_SAMPLE_FMT_S64,         ///< signed 64 bits
        AV_SAMPLE_FMT_S64P,        ///< signed 64 bits, planar
        AV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
    };�����������������
    

    其中U,S,F,D表示存储的类型,对应unsigned、signed、float和double类型;
    数值表示位深度;
    P表示声道数据排列方式为Planar,还有排列方式为Packed
    对于双声道音频来说,Packed表示两个声道的数据交错存储,交织在一起,即:
    LRLRLRLR 的存储方式;
    Planar 表示两个声道分开存储,也就是平铺分开,即:
    LLLLRRRR 的存储方式;
    以Packed存储方式为例 大端模式不同位深度数据存储如下:

    数据存储

    声道:单声道产生一组声波数据,双声道(立体声)产生两组声波数据。
    对于声音格式,还有一个概念用来描述它的大小,称为比特率(byteRate),即指单位时间内传输或处理的比特数量;单位是:比特每秒(bps),还有:千比特每秒(Kbps)、兆比特每秒(Mbps)等等;

    以CD的音质为例:位深度为16比特(2字节),采样率为44.1kHZ,声道数为2,这些信息就描述了CD的音质。对于1分钟CD音质的数据,比特率为:

    44100 * 16 * 2 = 1378.125 Kbps
    

    存储空间为:

    1378.125 * 60 / 8 / 1024 = 10.09MB
    

    通常,采样率、位深度越高,数字化音频的质量就越好。从比特率的特性可以看得出来:比特率越高,数字化音频的质量也越好;我们所说的无损音乐,就是采样率、位深度都很高的,没有进行压缩处理的数字化声音;

    最后还是用一张图总结数字化过程:

    process

    音频编解码

    编码

    前面计算了每分钟CD音质的数据采样格式,需要的存储空间约为10.1MB;在网络中传播的话,数据量太大了;
    为了更便于存储和传输,一般都会使用某种音频编码对它进行编码压缩,然后再存成某种音频文件格式。

    压缩分为无损压缩和有损压缩。
    无损压缩:解压后可以完全还原出原始数据;
    有损压缩:解压后不能完全还原出原始数据,会丢失一部分信息;一般是压缩掉冗余信号(冗余信号是指不能被人耳感知到的信号,包含人耳听觉范围之外的音频信号以及被掩蔽掉的音频信号等),不进行编码处理。

    解码

    当需要播放音频时,得先解码(解压缩)出PCM数据,然后再进行播放。

    常见的编码格式:
    code

    WAV编码
    WAV(Waveform Audio File Format),是由IBM和Microsoft开发的音频文件格式,扩展名是.wav,通常采用PCM编码,常用于Windows系统中;编码的一种实现就是在PCM数据格式的前面加上44字节,分别用来描述PCM的采样率、声道数、数据格式等信息。

    • 特点:音质非常好,大量软件都支持。
    • 适用场合:多媒体开发的中间文件、保存音乐和音效素材。

    MP3编码
    MP3(MPEG Audio Layer III)具有不错的压缩比,使用LAME编码的中高码率的MP3文件,听感上非常接近源WAV文件。

    • 特点: 压缩比比较高,大量软件和硬件都支持,兼容性好。
    • 适用场合:高比特率下对兼容性有要求的音乐欣赏。

    AAC编码
    AAC(Advanced Audio Coding)是新一代的音频有损压缩技术;

    AAC编码的文件扩展名主要有3种:

    • .acc:传统的AAC编码,使用MPEG-2 Audio Transport Stream(ADTS)容器
    • .mp4:使用了MPEG-4 Part 14的简化版即3GPP Media Release 6 Basic(3gp6)进行封装的AAC编码
    • .m4a:为了区别纯音频MP4文件和包含视频的MP4文件而由Apple公司使用的扩展名;

    • 特点:在小于128Kbit/s的码率下表现优异,并且多用于视频中的音频编码。
    • 适用场合:128Kbit/s以下的音频编码,多用于视频中音频轨的编码。

    代码实现

    • AVFoundation 音频编码
    // -----解码----
    // AVAssetReader
    do {
        reader = try AVAssetReader(asset: composition)
    } catch let e {
        callback(false, e)
        return
    }
    reader.timeRange = CMTimeRange(start: .zero, duration: composition.duration)
    // AVAssetReaderOutput
    audioOutput = AVAssetReaderAudioMixOutput(audioTracks: audioTracks, audioSettings: nil)
    audioOutput.alwaysCopiesSampleData = false
    audioOutput.audioMix = audioMix
    if reader.canAdd(audioOutput) {
        reader.add(audioOutput)
    }
    if !reader.startReading() {
        callback(false, reader.error)
        return
    }
    
    // -----编码----
    // AVAssetWriter
    do {
        writer = try AVAssetWriter(outputURL: outputUrl, fileType: .mp3)
    } catch let e {
        callback(false, e)
        return
    }
    writer.shouldOptimizeForNetworkUse = true
    let audioOutputSettings: [String : Any] = [
        AVFormatIDKey: NSNumber(value: kAudioFormatMPEGLayer3),
        AVNumberOfChannelsKey: NSNumber(value: 2),
        AVSampleRateKey: NSNumber(value: 44100),
        AVEncoderBitRateKey: NSNumber(value: 128000)
    ]
    // AVAssetWriterInput
    audioInput = AVAssetWriterInput(mediaType: .audio, outputSettings: audioOutputSettings)
    if writer.canAdd(audioInput) {
        writer.add(audioInput)
    }
    writer.startWriting()
    writer.startSession(atSourceTime: .zero)
    // 准备写入数据
    videoInput.requestMediaDataWhenReady(on: inputQueue) { [weak self] in
        ...
    }
    

    其中audioOutputSettings的4项就对应上面分析过的: 编码格式,声道数,采样率,比特率;这些设置最终决定了编码后音频的格式、音频的存储空间及音质;
    而且这些设置都是固定组合的,不同编码格式Format所需的Key有所不一样;

    wav/pcm 格式设置(需要pcm相关设置):

    let audioOutputSettings: [String : Any] = [
            AVFormatIDKey: NSNumber(value: kAudioFormatLinearPCM),
            AVNumberOfChannelsKey: NSNumber(value: 2),
            AVSampleRateKey: NSNumber(value: 44100),
            AVLinearPCMBitDepthKey: NSNumber(value: 16),
            AVLinearPCMIsBigEndianKey: NSNumber(value: false),
            AVLinearPCMIsFloatKey: NSNumber(value: false),
            AVLinearPCMIsNonInterleaved: NSNumber(value: false)
        ]
    
    • FFmpeg

    相关文章

      网友评论

        本文标题:音视频开发基础理论-音频篇

        本文链接:https://www.haomeiwen.com/subject/iafhwrtx.html