Streaming Media相关技术点(二)- FFmpeg安装+使用

FFmpeg是最好的多媒体框架之一,可用于编码,解码,转码,复用,解复用,记录,流式传输,过滤和播放任何类型的媒体文件。(encode, decode, transcode, mux, demux, record, stream, filter, and play any type of media files)

1. 安装

基于Yum安装、Mac基于Brew、亦或是基于自行编译安装都OK(官方下载对应的包)

// 1. 安装EPEL仓库
$ sudo yum install epel-release

// 2. Add RPMFusion repository 
RHEL 6.x, CentOS 6.x:
$ sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-6.noarch.rpm https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-6.noarch.rpm
RHEL 7.x, CentOS 7.x:
$ sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-7.noarch.rpm

// 3. 安装ffmpeg
$ sudo yum install ffmpeg ffmpeg-devel

2. FFmpeg各种流处理过程

  # ffmpeg 转码过程(input=>demuex=>decode=>encode=>mutex=>output)
 _______              ______________
|       |            |              |
| input |  demuxer   | encoded data |   decoder
| file  | ---------> | packets      | -----+
|_______|            |______________|      |
                                           v
                                       _________
                                      |         |
                                      | decoded |
                                      | frames  |
                                      |_________|
 ________             ______________       |
|        |           |              |      |
| output | <-------- | encoded data | <----+
| file   |   muxer   | packets      |   encoder
|________|           |______________|

  # Filtering(滤镜,支持简单和复杂)
在编码之前,ffmpeg可以使用libavfilter库中的过滤器处理原始音频和视频帧。

  # 简单滤镜(一进一出,解码=>过滤帧=>编码)
 _________                        ______________
|         |                      |              |
| decoded |                      | encoded data |
| frames  |\                   _ | packets      |
|_________| \                  /||______________|
             \   __________   /
  simple     _\||          | /  encoder
  filtergraph   | filtered |/
                | frames   |
                |__________|

  # 视频和音频使用-vf和-af别名
 _______        _____________        _______        ________
|       |      |             |      |       |      |        |
| input | ---> | deinterlace | ---> | scale | ---> | output |
|_______|      |_____________|      |_______|      |________|

  # 复杂滤镜(多个输入和输出)
 _________
|         |
| input 0 |\                    __________
|_________| \                  |          |
             \   _________    /| output 0 |
              \ |         |  / |__________|
 _________     \| complex | /
|         |     |         |/
| input 1 |---->| filter  |\
|_________|     |         | \   __________
               /| graph   |  \ |          |
              / |         |   \| output 1 |
 _________   /  |_________|    |__________|
|         | /
| input 2 |/
|_________|

  # 流拷贝(-codec copy)
_______              ______________            ________
|       |            |              |          |        |
| input |  demuxer   | encoded data |  muxer   | output |
| file  | ---------> | packets      | -------> | file   |
|_______|            |______________|          |________|

  # 流选择
    -vn / -an / -sn / -dn 分别代表(video, audio, subtitle and data)

  # 将mp4视频格式,转成mp3音频格式
    -ar : 设置输出文件的音频。使用的常用值是22050,44100,48000 Hz
    -ac : 设置音频通道的数量。
    -ab : 设置音频比特率。
    -f  : 设置输出文件格式。

3. FFmpeg基本命令

// 1. 显示视频信息、支持格式
$ ffmpeg -i video.mp4
$ ffmpeg -i video.mp4 -hide_banner
$ ffmpeg -formats

// 2. 转换视频格式、转换保留视频质量(-qscale 0)
$ ffmpeg -i video.mp4 video.avi
$ ffmpeg -i video.flv video.mpeg
$ ffmpeg -i input.webm -qscale 0 output.mp4

// 3. 将mp4视频格式,转成mp3音频格式
    -vn : 禁用视频输出
    -an : 禁用音频输出
    -ar : 设置输出文件的音频。使用的常用值是22050,44100,48000 Hz
    -ac : 设置音频通道的数量。
    -ab : 设置音频比特率。
    -f  : 设置输出文件格式。在我们的例子中,它是mp3格式
$ ffmpeg -i input.mp4 -vn -ab 320 output.mp3
$ ffmpeg -i input.mp4 -vn -ar 44100 -ac 2 -ab 320 -f mp3 output.mp3

// 4. 如果要为视频文件设置特定分辨率,可以使用以下命令:
$ ffmpeg -i input.mp4 -filter:v scale=1280:720 -c:a copy output.mp4
$ ffmpeg -i input.mp4 -s 1280x720 -c:a copy output.mp4
$ ffmpeg -i input.mp4 -filter:v scale=640:480 -c:a copy output.mp4
$ ffmpeg -i input.mp4 -s 640x480 -c:a copy output.mp4

// 5. 视频压缩(24过于激进,您可以将该crf值降低到23或更低)
$ ffmpeg -i input.mp4 -vf scale=1280:-1 -c:v libx264 -preset veryslow -crf 24 output.mp4
(-ac 2 -c:a aac -strict -2 -b:a 128k #还可以将音频转码一点,并通过包含以下选项使立体声减小尺寸。)

// 6. 音频压缩
$ ffmpeg -i input.mp3 -ab 128 output.mp3
【支持的音频比特率】
96kbps
112kbps
128kbps
160kbps
192kbps
256kbps
320kbps

// 7. 移除音频
$ ffmpeg -i input.mp4 -an output.mp4

// 8. 移除视频
$ ffmpeg -i input.mp4 -vn output.mp3
$ ffmpeg -i input.mp4 -vn -ab 320 output.mp3

// 9. 从视频中提取图片,方便为视频文件创建相册
    -r : 设置帧速率。即每秒要提取到图像中的帧数。默认值为25。
    -f : 设置输出格式,即图像格式。
    image-%2d.png : 设置如何命名提取的图像(image-01.png、image-02.png..)
$ ffmpeg -i input.mp4 -r 1 -f image2 image-%2d.png

// 10. 视频裁剪(尺寸为300×300的视频)
    -croptop :
    -cropbottom :
    -cropleft :
    -cropright : 
$ ffmpeg -i input.mp4 -croptop 100 -cropbottom 100 -cropleft 300 -cropright 300 output.mp4

// 11. 转换视频的特定部分,支持(将给定video.mp4文件的前50秒转换为video.avi格式)
$ ffmpeg -i input.mp4  -t 50 output.avi
(同样支持hh.mm.ss格式)

// 12. 设置视频的宽高比率
$ ffmpeg -i input.mp4 -aspect 16:9 output.mp4
【常见比率】:
16:9
4:3
16:10
5:4
2:21:1
2:35:1
2:39:1

// 13. 为音频添加海报
$ ffmpeg -loop 1 -i inputimage.jpg -i inputaudio.mp3 -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest output.mp4

// 14. 使用开始和停止时间将视频或音频剪裁
    -ss : 表示视频剪辑的开始时间
    -t : 表示总持续时间
$ ffmpeg -i input.mp4 -ss 00:00:50 -codec copy -t 50 output.mp4
$ ffmpeg -i audio.mp3 -ss 00:01:54 -to 00:06:53 -c copy output.mp3

// 15. 将大视频文件拆分为多个较小的部分
    -t : 从开始到第30s,复制到part1
    -ss: 从第30s到结束,复制到part2
$ ffmpeg -i input.mp4 -t 00:00:30 -c copy part1.mp4 -ss 00:00:30 -codec copy part2.mp4

// 16. 将多个视频部分合二为一
cat join.txt
/home/sk/myvideos/part1.mp4
/home/sk/myvideos/part2.mp4
/home/sk/myvideos/part3.mp4
/home/sk/myvideos/part4.mp4
$ ffmpeg -f concat -i join.txt -c copy output.mp4

// 17. 为视频文件添加字幕
$ fmpeg -i input.mp4 -i subtitle.srt -map 0 -map 1 -c copy -c:v libx264 -crf 23 -preset veryfast output.mp4

// 18. 使用命令从终端播放
$ ffplay video.mp4
$ ffplay audio.mp3

// 19. 增加/减少视频播放速度
$ ffmpeg -i inputvideo.mp4 -vf "setpts=0.5*PTS” outputvideo.mp4
$ ffmpeg -i inputvideo.mp4 -vf "setpts=4.0*PTS” outputvideo.mp4

// 20. 获取帮助
$ man ffmpeg

4. 示例

// 将一个mp4视频生成vod点播文件
ffmpeg -i ghq.mp4 \
    -hls_time 5 -hls_playlist_type vod -hls_segment_filename 720p_%03d.ts \
    720p.m3u8
    
// 基于一个视频输入流,输出到直播输入流
ffmpeg -loglevel verbose -re -i movie.avi  -vcodec libx264
        -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1
        -f flv rtmp://localhost:1935/hls/movie

5. Nginx-Rtmp-Module

支持RTMP协议的NGINX扩展模块,更多细节可以基于参考链接查看

6. 参考