这篇文章上次修改于 287 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

关于 FFmpeg

一个强大的用于处理视频音频图片等文件的命令行程序

官网: https://ffmpeg.org/

常见参数

  • -c:[v,a,s]: video,audio,subtitle. c 是 codec 简写 (也可以用 -codec).
  • -b:[v,a]: bitrate, 如 -b:v:0 3000k -b:a:0 128k 分别指定了第一个视频流和音频流的比特率.
  • -y: 输出文件强制覆盖模式
  • -r: 帧率控制
  • -f: format, 手动指定输出文件格式(忽略输出文件拓展名)
  • -metadata: 以 key=value 形式存在的元信息, 音频文件见的比较多, 常常会写上对应专辑和曲名的信息.
  • -threads 1: 限制线程, 默认 auto. 如果在服务器上跑那这很有必要, 否则会影响其他服务.
  • -qscale 0: 质量控制.
  • -hide_banner: 顾名思义

命令格式: ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...

视频处理

我主要拿来处理视频, 所以其他方面写的比较简单.

-filter:v scale=1280:720
-s 1280x720

转码

CUDA 加速 H264 / H265
ffmpeg -hwaccel cuda -i [输入视频地址] -c:v [h264_nvenc, hevc_nvenc] -preset medium -crf [0 ~ 51] -c:a aac -b:a 128k -strict experimental out.mp4

CPU 硬解
ffmpeg -i [输入视频地址] -c:v [libx264, libx265] -c:a copy out.mp4

压缩

保证码率压缩 4K 同时抹去多余元信息

ffmpeg -hide_banner -hwaccel cuda -hwaccel_device 0 -i $file.FullName -map_metadata -1 -c:v hevc_nvenc -preset fast -crf 51 -b:v 6M -minrate 4M -maxrate 12M -bufsize 128M -c:a copy -y $outputFile

替换视频缩略图

对 mkv 无效
ffmpeg -i 视频.mp4 -i thumbnail.jpg -map 0 -map 1 -c copy -disposition:v:1 attached_pic 输出视频.mp4

拼接

ffmpeg -f concat -safe 0 -i input.txt -c copy output.mp4

文件内容格式:

file '1.mp4'
file '2.mp4'
file '3.mp4'

或者
ffmpeg -hwaccel cuda -i "1.mp4" -i "2.mp4" -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" -y output.mp4

ffmpeg -i "concat:audio1.mp3|audio2.mp3|audio3.mp3" -c copy output.mp3

画面翻转

这个有点绕, 而且 FFmpeg 的特色就是不同写法的参数具有相同作用....

https://ostechnix.com/how-to-rotate-videos-using-ffmpeg-from-commandline/

-vf "transpose=1"

水平翻转: -vf "hflip"

水平 + 垂直翻转: -vf "hflip,vflip"

音频处理

转码

避免失真
ffmpeg -i in.dsf -c:a flac -af "lowpass=24000, volume=6dB" -sample_fmt s16 -ar 48000 out.flac

仅转换格式
ffmpeg -i in.dsf -c:a flac -compression_level 0 out.flac

图片处理

顺时针旋转
ffmpeg -i input.jpg -vf "transpose=1" -y input.jpg

不压缩仅转码 (根据输出文件拓展名自动判断类型)
ffmpeg -i input.tif -q:v 1 output.jpg

批处理

Windows

PowerShell 环境, 需要先手动创建一个输出文件夹. 下面只给出一个最简单的转码压缩视频命令, 因为 Windows 其实不太好用.
Get-ChildItem -Path . -Filter *.mp4 | ForEach-Object {ffmpeg -i $_.FullName -c:v libx265 -preset medium -crf 23 ./output/$($_.Name)}

Linux

#!/bin/bash
num=1
for file in $(ls -v *.mp4); do
    filename=$(basename "$file" .mp4)
    ffmpeg -hide_banner -i "$file" -vf "select=eq(n\,0)" -vframes 1 "$(printf "%02d" $num) - $filename.jpg"
    num=$((num+1))
done

$filename 是不包含 .mp4 的文件名部分, $(printf "%02d" $num) 是包含一个前导零的两位数, 根据自己需要调整. (核心部分还是获取文件列表如何丢到循环执行, 例如外挂字幕文件的重命名也很方便.

流媒体

查找设备: ffmpeg -list_devices true -f dshow -i dummy

直播(但是祖传代码): ffmpeg -re -i "luck star.mp4" -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 rtmp://10.0.0.1:1935/hls/debug

摄像头采集: ffmpeg -re -f dshow -i video="ACER HD User Facing" -c:v libx264 -an -f flv rtmp://10.0.0.1:1935/hls/ffmpeg