zoukankan      html  css  js  c++  java
  • ffmpeg实战-音视频基础概念

    转发自白狼栈:查看原文

    关于音视频,相信大家都看过电影(视频),听过音乐(音频),至少应该都知道mp4是视频文件,mp3是音频文件。

    对于一个音视频文件,都有哪些属性呢?以视频为例,我们可以通过 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
    

      

    除了视频的元信息,还包括了更多我们当初编译的配置,你可以选择 -hide_banner 参数来隐藏这些信息,完整的命令如下

    »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
    

      

    我们主要看几个数据

    1. Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1ori.mp4': # Input #0 表示我们通过ffmpeg -i 参数输入的第一个文件,下标从0开始,也就是说我们可以输入多个文件,实际上ffmpeg还支持输出多个文件
    2. Metadata 表示视频元信息
    3. Duration 这行包含了视频的播放时长是58.53秒,开始播放时间是0,整个文件的比特率是1870kbit/s
    4. Stream #0:0(und): Video: h264,这行表示该文件的第一个流是视频流,编码格式是H264格式(封装格式为AVC1),每一帧的数据表示为yuv420p,分辨率为544x960,视频流的比特率是1732kbit/s,帧率为每秒钟29.83帧。
    5. Stream #0:1(und): Audio: aac,这行表示该文件的第二个流是音频流,编码格式为ACC(封装格式为MP4A),并且采用的Profile是LC规格,采样率是44.1KHz,声道是立体声(stereo),码率是129kbit/s

    开始出现了一些陌生的名词,我们依次介绍下。

    容器

    像上面这个视频文件一样,把不同的数据流(视频流、音频流,有的还有字幕流等)封装在一个文件中,我们称之为容器。像我们熟悉的mp4、avi、rmvb等等都是多媒体容器格式,一般情况下,多媒体文件的后缀就是它的容器格式。

    我们可以把容器理解为一个瓶子、罐子之类的东西。

    编码和解码(codec)

    编码:将视频、音频用某种格式或规范记录下来并存储,称为编码(codec)。编码可以理解成是对容器内的东西的加工处理。

    常见的视频编码格式有 h264、h265等,常见的音频编码格式有 mp3、aac等。

    解码:就是将视频、音频压缩的编码数据,解码成为非压缩的视频、音频原始数据。比如我们要对一段音频增加回声,就需要先对音频文件先解码再编码。

    软解:即软件解码,通过软件让CPU对视频文件进行解码操作。

    硬解:即硬件解码,为了减轻CPU的压力,采用GPU来处理原来全部让CPU处理的部分视频数据。

    软解需要对大量的视频信息进行处理,所以软解非常吃CPU,一条FFmpeg的命令都有可能把CPU干趴下了。

    相比而言,硬解的效率非常高,但是硬解的缺点也显而易见,它不能像软解那样,对字幕、画质等的处理效果都不是很好。如果我没记错的话,七牛云平台(一个相对专业的音视频平台)现在还不支持硬解。

    ffmpeg是最常见的软解码开源库,它实际是通过比如 H264、H265、MPEG-4等编解码算法进行软解。

    在现如今的音视频领域,ffmpeg 几乎支持所有音视频的编解码,非常强大。

    转码:即编码转换,是将视频从一种格式转换为另一种格式。比如将一个flv文件转换为mp4文件。

    ffmpeg -i input.flv output.mp4

    比特率

    比特率又称码率,表示编码器每秒输出的字节数,单位是 Kbps,b 为 比特(bit) 这个就是电脑文件大小的计量单位,1KB=8Kb,区分大小写,s 为 秒(second) p 为 每(per) 。

    比如

    在相同的压缩算法下(后面我们会介绍若干不同的压缩算法),码率越高,视频的质量也就越高。

    对于压缩文件,按照上面的理解,码率的粗略计算方式=文件大小/时长。

    比如 r1ori.mp4 的大小是 13.7兆,时长约59秒,那么它的码率大约等于 (13.7 x 1024 x 8) / 59 = 1900 kb/s

    公式:1MB=8Mb=1024KB=8192Kb

    因为还有一些参数的影响,所以这个码率我们也只能得到一个大约的数值。

    固定码率和可变码率

    早些年的时候,音频编码的时候选择的都是固定码率(Constant Bitrate, CBR),后面出现了可变码率(Variable Bitrate, VBR),固定码率指的是编码器输出的码率固定,这样就很难均衡“平静的画面”和“剧烈的画面”,相对而言,可变码率就可以很好的控制编码器,在细节比较多,画面相对剧烈的时候使用更多的比特位,对于相对平静的画面,使用更低的比特位。如此一来,在输出质量一定的情况下,VBR更具优势,存储的话我们也会优先选择可变码率。

    帧和帧率

    帧指的是一个画面。

    帧率(frames per second, fps),即每秒输出多少帧,你也可以理解画面每秒输出多少次。

    大家在玩游戏的时候一定深有体验,游戏卡顿的时候,画面都是帧与帧之间跳动的,非常的不顺畅。

    帧率影响画面的流畅度,帧率越高,画面也就越流畅。

    由于视觉暂留现象(即当物体在快速运动时, 人眼所看到的影像消失后,人眼仍能继续保留其影像1/24秒左右的图像)的存在,所以对于一般的电影视频,要求最低帧率是24,也就是每帧曝光1/24 = 0.042秒。

    分辨率

    分辨率大家应该都不陌生,比如某视频网站常见的蓝光1080P,超清720P,高清540P。

    分辨率可以理解为视频画面的大小,即视频的宽度和高度。720P指的就是高度是720像素。

    了解过码率和帧率我们发现,不能绝对的说分辨率越高视频越清晰,更重要的是如何平衡好码率、帧率以及分辨率三者的关系。

    总的来说,我们更愿意接受视频体积越小,清晰度越高的视频,一来是存储方便,二来是看起来爽。

    有损和无损

    首先我们说一下什么是音视频的原始数据?原始数据指的是通过音视频设备采集的、没有经过任何加工的数据。音频的原始数据是pcm格式,视频的原始数据是yuv格式。

    有损和无损,即有没有损失,这里针对的是多媒体数据压缩的一种说法。有损压缩又称之为破坏性压缩,当然并不是说压缩之后无法解压的那种破坏。比如我们常见的mp3、mp4文件都是有损压缩。

    以音频编码为例,音频里面的声音来源于自然界,我们通过技术方案捕获到声音,然后根据一定的算法进行存储。

    在现阶段,我们存储下来的声音不能完全还原为自然界的声音,任何音频编码都是有损的。

    有同学可能要提出疑问了,我看有文章介绍,音频的原始数据不是pcm格式的吗?

    其实pcm编码也只是无限接近于无损,它能够达到信号的最高保真,因此,pcm编码才被约定为无损压缩。

    好好的音频,我想听最真实的从自然界采集的声音,为什么要压缩呢?

    原始数据太大,不方便存储

    即使存储下来了,也不方便传输,需要极大的带宽

    现在视频的压缩比很高,比如现如今大家耳熟能详的4k 8k,看起来完全能满足需要

    复用器和解复用器

    对于容器而言,注意这里针对的是容器,我们经常会有两种频繁的操作。

    取出容器内的音视频数据,我们称之为解封装,由demuxer解封装器(又称之为解复用器)完成。

    把处理好的音视频数据装进容器内称之为封装,由muxer封装器(又称之为复用器)完成。

    我们会在这边文章下面持续更新音视频相关的概念,如果你觉得有什么概念不好理解,可以给我留言,我会再收集并作补充。

  • 相关阅读:
    Median Value
    237. Delete Node in a Linked List
    206. Reverse Linked List
    160. Intersection of Two Linked Lists
    83. Remove Duplicates from Sorted List
    21. Merge Two Sorted Lists
    477. Total Hamming Distance
    421. Maximum XOR of Two Numbers in an Array
    397. Integer Replacement
    318. Maximum Product of Word Lengths
  • 原文地址:https://www.cnblogs.com/wwolf/p/14918005.html
Copyright © 2011-2022 走看看