ffmpeg實(shí)戰(zhàn)-音視頻基礎(chǔ)概念

轉(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ù)

  1. 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è)文件
  2. Metadata 表示視頻元信息
  3. Duration 這行包含了視頻的播放時(shí)長(zhǎng)是58.53秒,開(kāi)始播放時(shí)間是0,整個(gè)文件的比特率是1870kbit/s
  4. Stream #0:0(und): Video: h264,這行表示該文件的第一個(gè)流是視頻流,編碼格式是H264格式(封裝格式為AVC1),每一幀的數(shù)據(jù)表示為yuv420p,分辨率為544x960,視頻流的比特率是1732kbit/s,幀率為每秒鐘29.83幀。
  5. 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ǔ)充。

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

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

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