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
參考資料: