iOS仿微信小視頻功能開發(fā)優(yōu)化記錄
【如何快速的開發(fā)一個(gè)完整的iOS直播app】(原理篇)
iOS動(dòng)手做一個(gè)直播(原理篇)
iOS RTMP 視頻直播開發(fā)筆記(3)- 了解 H.264 編碼
視頻方向問(wèn)題處理
http://stackoverflow.com/questions/26932794/square-cropping-and-fixing-the-video-orientation-in-ios
https://github.com/rs/SDAVAssetExportSession
">"
- "-" + "空格"xulie
- 1 dfsf
高亮語(yǔ)法為
"高亮
"
[添加超鏈接](http://jianshu.io)
![](網(wǎng)絡(luò)圖片連接) == 插入圖片
音頻錄制#
背景知識(shí)###
錄音功能生成的目標(biāo)音頻格式是PCM格式塔粒,對(duì)于PCM的定義橄仆,維基百科上是這么寫到的:"Pulse-code modulation (PCM) is a method used to digitally represent sampled analog signals. It is the standard form of digital audio in computers, Compact Discs, digital telephony and other digital audio applications. In a PCM stream, the amplitude of the analog signal is sampled regularly at uniform intervals, and each sample is quantized to the nearest value within a range of digital steps."新娜,大致意思是PCM是用來(lái)采樣模擬信號(hào)的一種方法僧著,是現(xiàn)在數(shù)字音頻應(yīng)用中數(shù)字音頻的標(biāo)準(zhǔn)格式,而PCM采樣的原理类咧,是均勻間隔的將模擬信號(hào)的振幅量化成指定數(shù)據(jù)范圍內(nèi)最貼近的數(shù)值馒铃。
PCM文件存儲(chǔ)的數(shù)據(jù)是不經(jīng)壓縮的純音頻數(shù)據(jù)蟹腾,當(dāng)然只是這么說(shuō)可能有些抽象,我們拉上大家熟知的MP3文件進(jìn)行對(duì)比区宇,MP3文件存儲(chǔ)的是壓縮后的音頻娃殖,PCM與MP3兩者之間的關(guān)系簡(jiǎn)單說(shuō)就是:PCM文件經(jīng)過(guò)MP3壓縮算法處理后生成的文件就是MP3文件。我們簡(jiǎn)單比較一下雙方存儲(chǔ)所消耗的空間萧锉,1分鐘的每采樣點(diǎn)16位的雙聲道的44.1kHz采樣率PCM文件大小為:16016/8244100/1024=10335.9375KB珊随,約為10MB,而對(duì)應(yīng)的128kps的MP3文件大小僅為1MB左右柿隙,既然PCM文件占用存儲(chǔ)空間這么大,我們是不是應(yīng)該放棄使用PCM格式存儲(chǔ)錄音鲫凶,恰恰相反禀崖,注意第一句話:"PCM文件存儲(chǔ)的數(shù)據(jù)是不經(jīng)壓縮的純音頻數(shù)據(jù)",這意味只有PCM格式的音頻數(shù)據(jù)是可以用來(lái)直接進(jìn)行聲音處理螟炫,例如進(jìn)行音量調(diào)節(jié)波附,聲音濾鏡等操作,相對(duì)的其他的音頻編碼格式都是必須解碼后才能進(jìn)行處理(PCM編碼的WAV文件也得先讀取文件頭)昼钻,當(dāng)然這不代表PCM文件就好用掸屡,因?yàn)闆](méi)有文件頭,所以進(jìn)行處理或者播放之前我們必須事先知道PCM文件的聲道數(shù)然评,采樣點(diǎn)字節(jié)數(shù)仅财,采樣率,編碼大小端碗淌,這在大多數(shù)情況下都是不可能的盏求,事實(shí)上就我所知沒(méi)有播放器是直接支持PCM文件的播放。不過(guò)現(xiàn)在錄音的各項(xiàng)系數(shù)都是我們定義的亿眠,所以我們就不用擔(dān)心這個(gè)問(wèn)題
源自:詳解如何使用代碼進(jìn)行音頻合成
MP3格式中的碼率(BitRate)代表了MP3數(shù)據(jù)的壓縮質(zhì)量碎罚,現(xiàn)在常用的碼率有128kbit/s、160kbit/s纳像、320kbit/s等等荆烈,這個(gè)值越高聲音質(zhì)量也就越高。MP3編碼方式常用的有兩種固定碼率(Constant bitrate竟趾,CBR)和可變碼率(Variable bitrate憔购,VBR)阵赠。
MP3格式中的數(shù)據(jù)通常由兩部分組成就乓,一部分為ID3用來(lái)存儲(chǔ)歌名立帖、演唱者趁矾、專輯叽唱、音軌數(shù)等信息哮独,另一部分為音頻數(shù)據(jù)荚虚。音頻數(shù)據(jù)部分以幀(frame)為單位存儲(chǔ)秒裕,每個(gè)音頻都有自己的幀頭,如圖所示就是一個(gè)MP3文件幀結(jié)構(gòu)圖(圖片同樣來(lái)自互聯(lián)網(wǎng))枚碗。MP3中的每一個(gè)幀都有自己的幀頭逾一,其中存儲(chǔ)了采樣率等解碼必須的信息,所以每一個(gè)幀都可以獨(dú)立于文件存在和播放肮雨,這個(gè)特性加上高壓縮比使得MP3文件成為了音頻流播放的主流格式遵堵。幀頭之后存儲(chǔ)著音頻數(shù)據(jù),這些音頻數(shù)據(jù)是若干個(gè)PCM數(shù)據(jù)幀經(jīng)過(guò)壓縮算法壓縮得到的怨规,對(duì)CBR的MP3數(shù)據(jù)來(lái)說(shuō)每個(gè)幀中包含的PCM數(shù)據(jù)幀是固定的陌宿,而VBR是可變的。
AAC簡(jiǎn)介###
采樣率Sample Rate指單位時(shí)間內(nèi)對(duì)媒體對(duì)象的采樣次數(shù)波丰,單位Hz(這句話好像和原來(lái)不太一樣壳坪,郁悶)。
幀率(Frame per second掰烟,fps)爽蝴,單位時(shí)間內(nèi)媒體幀的個(gè)數(shù)。
這兩個(gè)概念都描述了媒體的“連續(xù)”性纫骑,二者的區(qū)別在于一個(gè)Frame可能包含多個(gè)Sample蝎亚。一般每個(gè)視頻幀中只包含一個(gè)視頻采樣,而音頻幀中會(huì)包含多個(gè)音頻采樣先馆。如1個(gè)AAC幀中包含1024個(gè)采樣发框。所以,幀率常用在視頻方面磨隘,采樣率常用于音頻方面缤底。采樣率(幀率)越高,媒體越流暢番捂,當(dāng)然人的感受就越過(guò)癮个唧。但是,由于人的視/聽器官分辨能力的局限设预,往往這些數(shù)值達(dá)到末各程度就可以滿足人對(duì)“連續(xù)”性的需求了徙歼。比如,對(duì)采樣率高于44.1kHz的聲音鳖枕,人很難聽出區(qū)別了魄梯。對(duì)幀率高于30的視頻,人很難看出幀率的區(qū)別宾符。
比特率(bps或kbps)酿秸,與前面兩個(gè)概念不同,它描述了單位時(shí)間長(zhǎng)度的媒體內(nèi)容需要空間魏烫。當(dāng)然該值越高辣苏,每個(gè)采樣的信息量就越大肝箱,對(duì)這個(gè)采樣的描述就越精確。
對(duì)于人的感受來(lái)說(shuō)稀蟋,當(dāng)然上述數(shù)值越大越好煌张,但是這總是會(huì)受到網(wǎng)絡(luò)帶寬和處理設(shè)備能力的限制。所以退客,媒體工程師會(huì)取一個(gè)折中的數(shù)值來(lái)制作媒體內(nèi)容骏融,在符合能力的范圍內(nèi),提供最佳的體驗(yàn)萌狂。
例子:一張CD档玻,雙聲道,采樣率44.1kHz每個(gè)采樣13bit粥脚,時(shí)長(zhǎng)74分鐘(4440秒)窃肠,則CD的容量為13244100*4440約等于640MB
在AAC媒體文件中,以Sampling Frequency Index的方式記錄AAC的采樣率刷允,下面的數(shù)組為對(duì)應(yīng)表:AAC_Sampling_Frequency_Table[16] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0}
AAC媒體文件的時(shí)長(zhǎng)難為了我不少時(shí)間,現(xiàn)在終于明白了如何計(jì)算碧囊。
首先要明確一點(diǎn)树灶,AAC的每幀采樣個(gè)數(shù)為1024,即每個(gè)AAC幀中包含1024個(gè)采樣糯而。
這樣Frame_duration(s/f)=1024(Sample/f)/Sampling_Rate(Sample/s)天通,F(xiàn)ile_duration(s)=Frame_duration(s/f)*Frame_count(f)。
例子熄驼,某個(gè)AAC媒體像寒,采樣率16000Hz,938幀瓜贾,時(shí)長(zhǎng)=(1024/16000)*938約為60秒诺祸。
AAC-Advanced Audio Coding高級(jí)音頻編碼,目前漸成主流的音頻編碼祭芦,是有損音頻壓縮格式筷笨。已被MPEG4標(biāo)準(zhǔn)的文件容器格式采用,估計(jì)MP3后的音頻霸主就是它了龟劲。
AAC幀首部7個(gè)字節(jié):
AAC與MPEG4封裝AAC媒體幀的方式存在相當(dāng)?shù)膮^(qū)別胃夏,盡管記錄的信息相似。
在AAC文件中昌跌,幀播放的配置信息存儲(chǔ)于幀首部(7-8個(gè)字節(jié)仰禀,ID=0時(shí)為7,否則為8)蚕愤。而在MPEG4中答恶,由于他采用box的一對(duì)象的方式封裝媒體饺蚊,故其AAC音頻播放信息也被封裝于box中。僅使用2個(gè)字節(jié)亥宿。AAC幀首部參看過(guò)去的文章卸勺,AAC decoder config layout如下:
@struct AudioStreamBasicDescription
@abstract This structure encapsulates all the information for describing the basic
format properties of a stream of audio data.(這個(gè)結(jié)構(gòu)體將所有描述基本格式屬性的音頻數(shù)據(jù)流信息裝入內(nèi)部)
@discussion This structure is sufficient to describe any constant bit rate format that has
channels that are the same size.(這種結(jié)構(gòu)能充分描述任何恒定比特率格式,那些有聲軌,大小一樣) Extensions are required for variable bit rate
data and for constant bit rate data where the channels have unequal sizes.(在那些音軌大小不相等的地方烫扼,可變比特率和恒定比特率的擴(kuò)展是被需要的)
However, where applicable, the appropriate fields will be filled out correctly
for these kinds of formats (the extra data is provided via separate properties).(然而,在適用情況下,適當(dāng)?shù)淖侄螌⒈灰赃@些格式正確填寫)
In all fields, a value of 0 indicates that the field is either unknown, not
applicable or otherwise is inapproprate for the format and should be ignored.
Note that 0 is still a valid value for most formats in the mFormatFlags field.
In audio data a frame is one sample across all channels. In non-interleaved
audio, the per frame fields identify one channel. In interleaved audio, the per
frame fields identify the set of n channels. In uncompressed audio, a Packet is
one frame, (mFramesPerPacket == 1). In compressed audio, a Packet is an
indivisible chunk of compressed data, for example an AAC packet will contain
1024 sample frames.
@field mSampleRate
The number of sample frames per second of the data in the stream.(每秒對(duì)原始數(shù)據(jù)的取樣數(shù)曙求,即采樣率單位Hz)
@field mFormatID
The AudioFormatID indicating the general kind of data in the stream.(表明數(shù)據(jù)類型)
@field mFormatFlags
The AudioFormatFlags for the format indicated by mFormatID.(AudioFormatFlags的格式被mFormatID定義)
@field mBytesPerPacket
The number of bytes in a packet of data.(一個(gè)數(shù)據(jù)包多少字節(jié))
@field mFramesPerPacket
The number of sample frames in each packet of data.(每個(gè)數(shù)據(jù)包里多少個(gè)取樣幀)
@field mBytesPerFrame
The number of bytes in a single sample frame of data.(一個(gè)取樣幀有多少字節(jié))
@field mChannelsPerFrame
The number of channels in each frame of data.(每一幀的聲道數(shù),1為單聲道)
@field mBitsPerChannel
The number of bits of sample data for each channel in a frame of data.(一幀數(shù)據(jù)的一個(gè)聲道采樣數(shù)據(jù)的位數(shù)8為映企,16位或32位)
@field mReserved
Pads the structure out to force an even 8 byte alignment.(猜測(cè):不滿8為補(bǔ)足八位)
- 對(duì)于音頻數(shù)據(jù)的所有聲道來(lái)說(shuō)一幀(frame)就是一次采樣數(shù)據(jù)(sample)悟狱。在非交錯(cuò)封包模式的音頻數(shù)據(jù)中,一個(gè)聲道的音頻數(shù)據(jù)存在在一個(gè)平面內(nèi)堰氓,在交錯(cuò)封包模式中挤渐,以立體聲為例就是聲道1、聲道2双絮、聲道1浴麻、聲道2,循環(huán)囤攀。在未壓縮的音頻數(shù)據(jù)中软免,一個(gè)數(shù)據(jù)包(packet)就是一幀(frame)。在壓縮過(guò)的音頻數(shù)據(jù)中焚挠,一個(gè)數(shù)據(jù)包(packet)是不可分割的一塊壓縮數(shù)據(jù)膏萧,比如一個(gè)AAC(一種音頻壓縮格式)數(shù)據(jù)包將會(huì)包含有1024分采樣幀。
struct AudioStreamBasicDescription
{
Float64 mSampleRate;
AudioFormatID mFormatID;
AudioFormatFlags mFormatFlags;
UInt32 mBytesPerPacket;
UInt32 mFramesPerPacket;
UInt32 mBytesPerFrame;
UInt32 mChannelsPerFrame;
UInt32 mBitsPerChannel;
UInt32 mReserved;
};
//視頻格式對(duì)于linear PCM蝌衔,僅支持interleaved格式榛泛;支持壓縮格式
const AudioStreamBasicDescription *inFormat,
//視頻隊(duì)列的一塊緩沖區(qū)填滿的回調(diào)函數(shù)
AudioQueueInputCallback inCallbackProc,
//A value or pointer to data that you specify to be passed to the callback function.
void * __nullable inUserData,
CFRunLoopRef __nullable inCallbackRunLoop,
CFStringRef __nullable inCallbackRunLoopMode,
UInt32 inFlags,
AudioQueueRef __nullable * __nonnull outAQ)
定義一個(gè)回調(diào)函數(shù)的指針,當(dāng)錄制音頻的隊(duì)列填滿一個(gè)視頻緩沖區(qū)時(shí)會(huì)被調(diào)用
typedef void (*AudioQueueInputCallback)(
void * __nullable inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp * inStartTime,
UInt32 inNumberPacketDescriptions,
const AudioStreamPacketDescription * __nullable inPacketDescs);
inUserData:
inStartTime:指向音頻時(shí)間戳結(jié)構(gòu)體的一個(gè)指針噩斟,之歌時(shí)間戳對(duì)應(yīng)著緩沖區(qū)第一個(gè)樣本
inNumberPacketDescriptions:提供給回調(diào)函數(shù)的數(shù)據(jù)內(nèi)包含的packet數(shù)
inPacketDescs:packet descriptions
片曹锨、場(chǎng)、幀亩冬、片的概念###
H264結(jié)構(gòu)中艘希,一個(gè)視頻圖像編碼后的數(shù)據(jù)叫做一幀,一幀由一個(gè)片(slice)或多個(gè)片組成硅急,一個(gè)片由一個(gè)或多個(gè)宏塊(MB)組成覆享,一個(gè)宏塊由16×16的yuv數(shù)據(jù)組成。宏塊作為H264編碼的基本單位营袜。
1幀 = n個(gè)片
1片 = n個(gè)宏塊
1宏塊 = 16x16yuv數(shù)據(jù)
場(chǎng)和幀:視頻的一場(chǎng)或一幀可用來(lái)產(chǎn)生一個(gè)編碼圖像撒顿。在電視中,為減少大面積閃爍現(xiàn)象荚板,把一幀分成兩個(gè)隔行的場(chǎng)凤壁。
宏塊:一個(gè)編碼圖像通常劃分成若干宏塊組成吩屹,一個(gè)宏塊由一個(gè)16×16亮度像素和附加的一個(gè)8×8 Cb和一個(gè)8×8 Cr彩色像素塊組成。
片:每個(gè)圖象中拧抖,若干宏塊被排列成片的形式煤搜。片分為I片、B片唧席、P片和其他一些片擦盾。
- I片只包含I宏塊,P片可包含P和I宏塊淌哟,而B片可包含B和I宏塊迹卢。
- I宏塊利用從當(dāng)前片中已解碼的像素作為參考進(jìn)行幀內(nèi)預(yù)測(cè)。
- P宏塊利用前面已編碼圖象作為參考圖象進(jìn)行幀內(nèi)預(yù)測(cè)徒仓。
- B宏塊則利用雙向的參考圖象(前一幀和后一幀)進(jìn)行幀內(nèi)預(yù)測(cè)腐碱。