轉(zhuǎn)發(fā)自白狼棧:查看原文
關(guān)于音視頻,相信大家都看過(guò)電影(視頻),聽(tīng)過(guò)音樂(lè)(音頻),至少應(yīng)該都知道m(xù)p4是視頻文件,mp3是音頻文件。
對(duì)于一個(gè)音視頻文件,都有哪些屬性呢?以視頻為例,我們可以通過(guò) ffmpeg -i 命令查看媒體文件的信息。
? ffmpeg -i r1ori.mp4
ffmpeg version 4.1 Copyright (c) 2000-2018 the FFmpeg developers
built with Apple LLVM version 10.0.0 (clang-1000.10.44.4)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gpl --enable-libmp3lame --enable-libopus --enable-libsnappy --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-chromaprint --enable-frei0r --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfdk-aac --enable-libfontconfig --enable-libfreetype --enable-libgme --enable-libgsm --enable-libmodplug --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-librsvg --enable-librtmp --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtesseract --enable-libtwolame --enable-libvidstab --enable-libwavpack --enable-libwebp --enable-libzmq --enable-opencl --enable-openssl --enable-videotoolbox --enable-libopenjpeg --disable-decoder=jpeg2000 --extra-cflags=-I/usr/local/Cellar/openjpeg/2.3.0/include/openjpeg-2.3 --enable-nonfree
libavutil 56\. 22.100 / 56\. 22.100
libavcodec 58\. 35.100 / 58\. 35.100
libavformat 58\. 20.100 / 58\. 20.100
libavdevice 58\. 5.100 / 58\. 5.100
libavfilter 7\. 40.101 / 7\. 40.101
libavresample 4\. 0\. 0 / 4\. 0\. 0
libswscale 5\. 3.100 / 5\. 3.100
libswresample 3\. 3.100 / 3\. 3.100
libpostproc 55\. 3.100 / 55\. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1ori.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.20.100
Duration: 00:00:58.53, start: 0.000000, bitrate: 1870 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 544x960, 1732 kb/s, 29.83 fps, 29.83 tbr, 11456 tbn, 59.67 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 129 kb/s (default)
Metadata:
handler_name : SoundHandler
除了視頻的元信息,還包括了更多我們當(dāng)初編譯的配置,你可以選擇 -hide_banner 參數(shù)來(lái)隱藏這些信息,完整的命令如下
?ffmpeg -i r1ori.mp4 -hide_banner
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1ori.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.20.100
Duration: 00:00:58.53, start: 0.000000, bitrate: 1870 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 544x960, 1732 kb/s, 29.83 fps, 29.83 tbr, 11456 tbn, 59.67 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 129 kb/s (default)
Metadata:
handler_name : SoundHandler
At least one output file must be specified
我們主要看幾個(gè)數(shù)據(jù)
- Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1ori.mp4': # Input #0 表示我們通過(guò)ffmpeg -i 參數(shù)輸入的第一個(gè)文件,下標(biāo)從0開(kāi)始,也就是說(shuō)我們可以輸入多個(gè)文件,實(shí)際上ffmpeg還支持輸出多個(gè)文件
- Metadata 表示視頻元信息
- Duration 這行包含了視頻的播放時(shí)長(zhǎng)是58.53秒,開(kāi)始播放時(shí)間是0,整個(gè)文件的比特率是1870kbit/s
- Stream #0:0(und): Video: h264,這行表示該文件的第一個(gè)流是視頻流,編碼格式是H264格式(封裝格式為AVC1),每一幀的數(shù)據(jù)表示為yuv420p,分辨率為544x960,視頻流的比特率是1732kbit/s,幀率為每秒鐘29.83幀。
- Stream #0:1(und): Audio: aac,這行表示該文件的第二個(gè)流是音頻流,編碼格式為ACC(封裝格式為MP4A),并且采用的Profile是LC規(guī)格,采樣率是44.1KHz,聲道是立體聲(stereo),碼率是129kbit/s
開(kāi)始出現(xiàn)了一些陌生的名詞,我們依次介紹下。
容器
像上面這個(gè)視頻文件一樣,把不同的數(shù)據(jù)流(視頻流、音頻流,有的還有字幕流等)封裝在一個(gè)文件中,我們稱(chēng)之為容器。像我們熟悉的mp4、avi、rmvb等等都是多媒體容器格式,一般情況下,多媒體文件的后綴就是它的容器格式。
我們可以把容器理解為一個(gè)瓶子、罐子之類(lèi)的東西。
編碼和解碼(codec)
編碼:將視頻、音頻用某種格式或規(guī)范記錄下來(lái)并存儲(chǔ),稱(chēng)為編碼(codec)。編碼可以理解成是對(duì)容器內(nèi)的東西的加工處理。
常見(jiàn)的視頻編碼格式有 h264、h265等,常見(jiàn)的音頻編碼格式有 mp3、aac等。
解碼:就是將視頻、音頻壓縮的編碼數(shù)據(jù),解碼成為非壓縮的視頻、音頻原始數(shù)據(jù)。比如我們要對(duì)一段音頻增加回聲,就需要先對(duì)音頻文件先解碼再編碼。
軟解:即軟件解碼,通過(guò)軟件讓CPU對(duì)視頻文件進(jìn)行解碼操作。
硬解:即硬件解碼,為了減輕CPU的壓力,采用GPU來(lái)處理原來(lái)全部讓CPU處理的部分視頻數(shù)據(jù)。
軟解需要對(duì)大量的視頻信息進(jìn)行處理,所以軟解非常吃CPU,一條FFmpeg的命令都有可能把CPU干趴下了。
相比而言,硬解的效率非常高,但是硬解的缺點(diǎn)也顯而易見(jiàn),它不能像軟解那樣,對(duì)字幕、畫(huà)質(zhì)等的處理效果都不是很好。如果我沒(méi)記錯(cuò)的話(huà),七牛云平臺(tái)(一個(gè)相對(duì)專(zhuān)業(yè)的音視頻平臺(tái))現(xiàn)在還不支持硬解。
ffmpeg是最常見(jiàn)的軟解碼開(kāi)源庫(kù),它實(shí)際是通過(guò)比如 H264、H265、MPEG-4等編解碼算法進(jìn)行軟解。
在現(xiàn)如今的音視頻領(lǐng)域,ffmpeg 幾乎支持所有音視頻的編解碼,非常強(qiáng)大。
轉(zhuǎn)碼:即編碼轉(zhuǎn)換,是將視頻從一種格式轉(zhuǎn)換為另一種格式。比如將一個(gè)flv文件轉(zhuǎn)換為mp4文件。
ffmpeg -i input.flv output.mp4
比特率
比特率又稱(chēng)碼率,表示編碼器每秒輸出的字節(jié)數(shù),單位是 Kbps,b 為 比特(bit) 這個(gè)就是電腦文件大小的計(jì)量單位,1KB=8Kb,區(qū)分大小寫(xiě),s 為 秒(second) p 為 每(per) 。
比如
在相同的壓縮算法下(后面我們會(huì)介紹若干不同的壓縮算法),碼率越高,視頻的質(zhì)量也就越高。
對(duì)于壓縮文件,按照上面的理解,碼率的粗略計(jì)算方式=文件大小/時(shí)長(zhǎng)。
比如 r1ori.mp4 的大小是 13.7兆,時(shí)長(zhǎng)約59秒,那么它的碼率大約等于 (13.7 x 1024 x 8) / 59 = 1900 kb/s
公式:1MB=8Mb=1024KB=8192Kb
因?yàn)檫€有一些參數(shù)的影響,所以這個(gè)碼率我們也只能得到一個(gè)大約的數(shù)值。
固定碼率和可變碼率
早些年的時(shí)候,音頻編碼的時(shí)候選擇的都是固定碼率(Constant Bitrate, CBR),后面出現(xiàn)了可變碼率(Variable Bitrate, VBR),固定碼率指的是編碼器輸出的碼率固定,這樣就很難均衡“平靜的畫(huà)面”和“劇烈的畫(huà)面”,相對(duì)而言,可變碼率就可以很好的控制編碼器,在細(xì)節(jié)比較多,畫(huà)面相對(duì)劇烈的時(shí)候使用更多的比特位,對(duì)于相對(duì)平靜的畫(huà)面,使用更低的比特位。如此一來(lái),在輸出質(zhì)量一定的情況下,VBR更具優(yōu)勢(shì),存儲(chǔ)的話(huà)我們也會(huì)優(yōu)先選擇可變碼率。
幀和幀率
幀指的是一個(gè)畫(huà)面。
幀率(frames per second, fps),即每秒輸出多少幀,你也可以理解畫(huà)面每秒輸出多少次。
大家在玩游戲的時(shí)候一定深有體驗(yàn),游戲卡頓的時(shí)候,畫(huà)面都是幀與幀之間跳動(dòng)的,非常的不順暢。
幀率影響畫(huà)面的流暢度,幀率越高,畫(huà)面也就越流暢。
由于視覺(jué)暫留現(xiàn)象(即當(dāng)物體在快速運(yùn)動(dòng)時(shí), 人眼所看到的影像消失后,人眼仍能繼續(xù)保留其影像1/24秒左右的圖像)的存在,所以對(duì)于一般的電影視頻,要求最低幀率是24,也就是每幀曝光1/24 = 0.042秒。
分辨率
分辨率大家應(yīng)該都不陌生,比如某視頻網(wǎng)站常見(jiàn)的藍(lán)光1080P,超清720P,高清540P。
分辨率可以理解為視頻畫(huà)面的大小,即視頻的寬度和高度。720P指的就是高度是720像素。
了解過(guò)碼率和幀率我們發(fā)現(xiàn),不能絕對(duì)的說(shuō)分辨率越高視頻越清晰,更重要的是如何平衡好碼率、幀率以及分辨率三者的關(guān)系。
總的來(lái)說(shuō),我們更愿意接受視頻體積越小,清晰度越高的視頻,一來(lái)是存儲(chǔ)方便,二來(lái)是看起來(lái)爽。
有損和無(wú)損
首先我們說(shuō)一下什么是音視頻的原始數(shù)據(jù)?原始數(shù)據(jù)指的是通過(guò)音視頻設(shè)備采集的、沒(méi)有經(jīng)過(guò)任何加工的數(shù)據(jù)。音頻的原始數(shù)據(jù)是pcm格式,視頻的原始數(shù)據(jù)是yuv格式。
有損和無(wú)損,即有沒(méi)有損失,這里針對(duì)的是多媒體數(shù)據(jù)壓縮的一種說(shuō)法。有損壓縮又稱(chēng)之為破壞性壓縮,當(dāng)然并不是說(shuō)壓縮之后無(wú)法解壓的那種破壞。比如我們常見(jiàn)的mp3、mp4文件都是有損壓縮。
以音頻編碼為例,音頻里面的聲音來(lái)源于自然界,我們通過(guò)技術(shù)方案捕獲到聲音,然后根據(jù)一定的算法進(jìn)行存儲(chǔ)。
在現(xiàn)階段,我們存儲(chǔ)下來(lái)的聲音不能完全還原為自然界的聲音,任何音頻編碼都是有損的。
有同學(xué)可能要提出疑問(wèn)了,我看有文章介紹,音頻的原始數(shù)據(jù)不是pcm格式的嗎?
其實(shí)pcm編碼也只是無(wú)限接近于無(wú)損,它能夠達(dá)到信號(hào)的最高保真,因此,pcm編碼才被約定為無(wú)損壓縮。
好好的音頻,我想聽(tīng)最真實(shí)的從自然界采集的聲音,為什么要壓縮呢?
原始數(shù)據(jù)太大,不方便存儲(chǔ)
即使存儲(chǔ)下來(lái)了,也不方便傳輸,需要極大的帶寬
現(xiàn)在視頻的壓縮比很高,比如現(xiàn)如今大家耳熟能詳?shù)?k 8k,看起來(lái)完全能滿(mǎn)足需要
復(fù)用器和解復(fù)用器
對(duì)于容器而言,注意這里針對(duì)的是容器,我們經(jīng)常會(huì)有兩種頻繁的操作。
取出容器內(nèi)的音視頻數(shù)據(jù),我們稱(chēng)之為解封裝,由demuxer解封裝器(又稱(chēng)之為解復(fù)用器)完成。
把處理好的音視頻數(shù)據(jù)裝進(jìn)容器內(nèi)稱(chēng)之為封裝,由muxer封裝器(又稱(chēng)之為復(fù)用器)完成。
我們會(huì)在這邊文章下面持續(xù)更新音視頻相關(guān)的概念,如果你覺(jué)得有什么概念不好理解,可以給我留言,我會(huì)再收集并作補(bǔ)充。