AudioFileStream學(xué)習(xí)

AudioFileStream介紹

  • AudioFileStreamer是用來讀取采樣率、碼率、時長等基本信息以及分離音頻幀。

  • AudioFileStreamer用在流播放中,當(dāng)然不僅限于網(wǎng)絡(luò)流,本地文件同樣可以用它來讀取信息和分離音頻幀。

  • AudioFileStreamer的主要數(shù)據(jù)是文件數(shù)據(jù),支持的文件格式有:

    • MPEG-1 Audio Layer 3, used for .mp3 files
    • MPEG-2 ADTS, used for the .aac audio data format
    • AIFC
    • AIFF
    • CAF
    • MPEG-4, used for .m4a, .mp4, and .3gp files
    • NeXT
    • WAVE

AudioFileStreamOpen

初始化AudioFileStream,創(chuàng)建一個音頻流解析器,生成一個AudioFileStream示例。

函數(shù)示例

extern OSStatus 
AudioFileStreamOpen (
                            void * __nullable                       inClientData,
                            AudioFileStream_PropertyListenerProc    inPropertyListenerProc,
                            AudioFileStream_PacketsProc             inPacketsProc,
                            AudioFileTypeID                         inFileTypeHint,
                            AudioFileStreamID __nullable * __nonnull outAudioFileStream)
                                                                        __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_2_0);

參數(shù)列表:

  • inClientData 上下文對象

  • AudioFileStream_PropertyListenerProc 歌曲信息解析的回調(diào),每次解析出一個歌曲信息,都會執(zhí)行一次回調(diào)。

  • AudioFileStream_PacketsProc 分離幀的回調(diào),每解析出一部分幀就會進行一次回調(diào)

  • AudioFileTypeID 是文件類型的提示,創(chuàng)建指定文件格式的音頻流解析器。AudioFileTypeID對應(yīng)的枚舉

      enum { 
          kAudioFileAIFFType             = 'AIFF', 
          kAudioFileAIFCType             = 'AIFC', 
          kAudioFileWAVEType             = 'WAVE', 
          kAudioFileSoundDesigner2Type   = 'Sd2f', 
          kAudioFileNextType             = 'NeXT', 
          kAudioFileMP3Type              = 'MPG3',    // mpeg layer 3 
          kAudioFileMP2Type              = 'MPG2',    // mpeg layer 2 
          kAudioFileMP1Type              = 'MPG1',    // mpeg layer 1 
          kAudioFileAC3Type              = 'ac-3', 
          kAudioFileAAC_ADTSType         = 'adts', 
          kAudioFileMPEG4Type            = 'mp4f', 
          kAudioFileM4AType              = 'm4af', 
          kAudioFileM4BType              = 'm4bf', 
          kAudioFileCAFType              = 'caff', 
          kAudioFile3GPType              = '3gpp', 
          kAudioFile3GP2Type             = '3gp2',         
          kAudioFileAMRType              = 'amrf'         
      }; 
    
  • outAudioFileStream AudioFileStream實例對應(yīng)的AudioFileStreamID,AudioFileStream其他函數(shù)需要使用。

返回值

返回值用來判斷是否成功初始化(OSSStatus == noErr)

AudioFileStreamParseBytes

解析數(shù)據(jù),在初始化完成之后,調(diào)用該方法解析文件數(shù)據(jù)。

函數(shù)示例

extern OSStatus AudioFileStreamParseBytes(AudioFileStreamID inAudioFileStream, 
                                          UInt32 inDataByteSize, 
                                          const void* inData, 
                                          UInt32 inFlags); 

參數(shù)列表

  • inAudioFileStream 初始化成功后返回的 AudioFileStreamID
  • inDataByteSize 本次解析的文件長度
  • inData 本次解析的數(shù)據(jù)
  • inFlags 標(biāo)志位,標(biāo)識本次的解析和上一次解析是否是連續(xù)的關(guān)系,默認0表示連續(xù),否則傳入kAudioFileStreamParseFlag_Discontinuity。

返回值

OSStatus的值不是noErr則表示解析不成功,對應(yīng)的錯誤碼:

enum 
{ 
  kAudioFileStreamError_UnsupportedFileType        = 'typ?', 
  kAudioFileStreamError_UnsupportedDataFormat      = 'fmt?', 
  kAudioFileStreamError_UnsupportedProperty        = 'pty?', 
  kAudioFileStreamError_BadPropertySize            = '!siz', 
  kAudioFileStreamError_NotOptimized               = 'optm', 
  kAudioFileStreamError_InvalidPacketOffset        = 'pck?', 
  kAudioFileStreamError_InvalidFile                = 'dta?', 
  kAudioFileStreamError_ValueUnknown               = 'unk?', 
  kAudioFileStreamError_DataUnavailable            = 'more', 
  kAudioFileStreamError_IllegalOperation           = 'nope', 
  kAudioFileStreamError_UnspecifiedError           = 'wht?', 
  kAudioFileStreamError_DiscontinuityCantRecover   = 'dsc!' 
}; 

每次調(diào)用成功后應(yīng)該注意返回值,一旦出現(xiàn)錯誤就不必要進行后續(xù)的解析。

AudioFileStream_PropertyListenerProc

解析文件格式信息的回調(diào),在調(diào)用AudioFileStreamParseBytes方法進行解析時會首先讀取格式信息,并同步的進入AudioFileStream_PropertyListenerProc回調(diào)方法。

函數(shù)示例

typedef void (*AudioFileStream_PropertyListenerProc)(
                                            void *                          inClientData,
                                            AudioFileStreamID               inAudioFileStream,
                                            AudioFileStreamPropertyID       inPropertyID,
                                            AudioFileStreamPropertyFlags *  ioFlags);

參數(shù)列表

  • inClientData 得到上下文

  • inAudioFileStream 表示當(dāng)前的FileStream的AudioFileStreamID

  • inPropertyID 表示此次回調(diào)解析的AudioFileStreamPropertyID,

    • 支持的AudioFileStreamPropertyID枚舉:

          enum 
          { 
            kAudioFileStreamProperty_ReadyToProducePackets           =    'redy', 
            kAudioFileStreamProperty_FileFormat                      =    'ffmt', 
            kAudioFileStreamProperty_DataFormat                      =    'dfmt', 
            kAudioFileStreamProperty_FormatList                      =    'flst', 
            kAudioFileStreamProperty_MagicCookieData                 =    'mgic', 
            kAudioFileStreamProperty_AudioDataByteCount              =    'bcnt', 
            kAudioFileStreamProperty_AudioDataPacketCount            =    'pcnt', 
            kAudioFileStreamProperty_MaximumPacketSize               =    'psze', 
            kAudioFileStreamProperty_DataOffset                      =    'doff', 
            kAudioFileStreamProperty_ChannelLayout                   =    'cmap', 
            kAudioFileStreamProperty_PacketToFrame                   =    'pkfr', 
            kAudioFileStreamProperty_FrameToPacket                   =    'frpk', 
            kAudioFileStreamProperty_PacketToByte                    =    'pkby', 
            kAudioFileStreamProperty_ByteToPacket                    =    'bypk', 
            kAudioFileStreamProperty_PacketTableInfo                 =    'pnfo', 
            kAudioFileStreamProperty_PacketSizeUpperBound            =    'pkub', 
            kAudioFileStreamProperty_AverageBytesPerPacket           =    'abpp', 
            kAudioFileStreamProperty_BitRate                         =    'brat', 
            kAudioFileStreamProperty_InfoDictionary                  =    'info' 
          }; 
      
  • 當(dāng)前PropertyID對應(yīng)的信息已經(jīng)解析完成信息,可以通過AudioFileStreamGetProperty接口獲取PropertyID對應(yīng)的值或者數(shù)據(jù)結(jié)構(gòu);

         extern OSStatus AudioFileStreamGetProperty(AudioFileStreamID inAudioFileStream, 
                                            AudioFileStreamPropertyID inPropertyID, 
                                            UInt32 * ioPropertyDataSize, 
                                            void * outPropertyData); 
    
  • ioFlags 表示這個property是否需要被緩存。

AudioFileStreamPropertyID解析

  • kAudioFileStreamProperty_BitRate 音頻數(shù)據(jù)的碼率,通過碼率可以計算音視頻的總時長

  • kAudioFileStreamProperty_DataOffset 表示音頻數(shù)據(jù)在整個音頻文件中的offset

    因為大多數(shù)音頻文件都會有一個文件頭之后才使真正的音頻數(shù)據(jù)),這個值在seek時會發(fā)揮比較大的作用,音頻的seek并不是直接seek文件位置而seek時間(比如seek到2分10秒的位置),seek時會根據(jù)時間計算出音頻數(shù)據(jù)的字節(jié)offset然后需要再加上音頻數(shù)據(jù)的offset才能得到在文件中的真正offset

  • kAudioFileStreamProperty_DataFormat 表示音頻文件結(jié)構(gòu)信息,是一個AudioStreamBasicDescription的結(jié)構(gòu)

  • kAudioFileStreamProperty_FormatList 作用和kAudioFileStreamProperty_DataFormat是一樣的,區(qū)別在于用這個PropertyID獲取到是一個AudioStreamBasicDescription的數(shù)組

  • kAudioFileStreamProperty_AudioDataByteCount 音頻文件中音頻數(shù)據(jù)的總量。這個Property的作用一是用來計算音頻的總時長,二是可以在seek時用來計算時間對應(yīng)的字節(jié)offset

  • kAudioFileStreamProperty_ReadyToProducePackets 一旦回調(diào)中這個PropertyID出現(xiàn)就代表解析完成,接下來可以對音頻數(shù)據(jù)進行幀分離了

計算時長Duration

double duration = (audioDataByteCount * 8) / bitRate

音頻數(shù)據(jù)的字節(jié)總量audioDataByteCount可以通過kAudioFileStreamProperty_AudioDataByteCount獲取,
碼率bitRate可以通過kAudioFileStreamProperty_BitRate獲取

AudioFileStream_PacketsProc

分離音頻幀回調(diào),讀取格式信息完成之后,繼續(xù)調(diào)用AudioFileStreamParseBytes方法可以對幀進行分離,并同步的進入AudioFileStream_PacketsProc回調(diào)方法

函數(shù)示例

typedef void (*AudioFileStream_PacketsProc)(
                                            void *                          inClientData,
                                            UInt32                          inNumberBytes,
                                            UInt32                          inNumberPackets,
                                            const void *                    inInputData,
                                            AudioStreamPacketDescription    *inPacketDescriptions);

參數(shù)列表

  • inClientData 得到上下文
  • inNumberBytes 表示本次處理的數(shù)據(jù)大小
  • inNumberPackets 本次總共處理了多少幀AudioFileStreamPropertyID
  • inInputData 本次處理的所有數(shù)據(jù)
  • AudioStreamPacketDescription AudioStreamPacketDescription數(shù)組,存儲了每一幀數(shù)據(jù)是從第幾個字節(jié)開始的,這一幀總共多少字節(jié)。

AudioFileStreamSeek

seek操作

AudioFileStreamClose

AudioFileStream使用完畢后需要調(diào)用AudioFileStreamClose進行關(guān)閉

函數(shù)示例

extern OSStatus AudioFileStreamClose(AudioFileStreamID inAudioFileStream);  

參數(shù):inAudioFileStream 初始化時生成的AudioFileStreamID

參考資料:

  1. Using Audio
  2. AudioFileStream
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • AudioFileStream介紹 AudioFileStreamer時提到它的作用是用來讀取采樣率、碼率、時長等...
    VD2012閱讀 692評論 0 2
  • 教程一:視頻截圖(Tutorial 01: Making Screencaps) 首先我們需要了解視頻文件的一些基...
    90后的思維閱讀 4,987評論 0 3
  • 本篇我們介紹AudioFile和AudioFileStream。在第一篇技術(shù)棧的分析里,我們提到過AudioFil...
    anyoptional閱讀 3,019評論 0 5
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,001評論 25 709
  • 有十年沒有在高校迎新的銷售現(xiàn)場來過了,新部門,新要求,讓我有機會在近不惑之年重回高??纯?。 繁忙之于漫步在...
    童小咪閱讀 356評論 0 0

友情鏈接更多精彩內(nèi)容