Lambholl 发表于 2022-7-30 23:59:45

[科普向] ffmpeg的安装与基本使用方法

本帖最后由 Lambholl 于 2024-1-18 22:03 编辑

一时兴起而写,如有错误请指出
最开始是用Word排版的,建议下载下面的附件看;转html后没怎么修改排版了
果然中西文之间的空格还是Word做的好

在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程
在阅读此文之前,请先阅读 VCB-S 的科普教程

Windows下的安装
下载 ffmpeg,将其解压到一个不会去移动/删除的文件夹,并记住其子文件夹「bin」的路径


首先,右键「此电脑」,点击「属性」,找到「高级系统设置」,打开「环境变量」


选中「Path」,点击「编辑」


点击「新建」,再点击「浏览」,将刚才解压的路径添加进去



Linux下的安装
使用apt / yum即可
sudo apt install ffmpegsudo yum -y install ffmpeg
使用
首先我们需要理解「命令行工具」,就是只能用命令行调用的工具;在 Windows 下通过 cmd 或者 PowerShell 调用,在 Linux / macOS 下通过终端调用
附:Windows下快速在一个文件夹打开cmd窗口的方法



ffmpeg 就是一个命令行工具,其基本语法为:
ffmpeg [ -i infile]... { outfile}...
常用参数有:
       -c[:a|:v|:s]   指定编/解码器
       -b[:a|:v]       制定音频/视频码率
       -vf                指定滤镜
       -an -vn         使输出文件不带音轨/视频轨
       -ar                指定定音频采样率
       -map            制定输入文件中的流
      etc. (详见帮助文档或者使用必应/谷歌等搜索引擎搜索)

例如,想要将一个包含 flac 音轨的 114514.mkv 视频文件的音轨压缩至 AAC 256Kbps,视频轨保持不变,输出至1919810.mp4,可以使用指令:
ffmpeg -i 114514.mkv -c:a aac -b:a 256k -c:v copy 1919810.mp4(需要注意的是,mp4 不能封装 flac 音轨;虽然 ffmepg 的实验性功能提供将其封装进去的选项,但是很有可能出现兼容性问题;如需封装无损音轨,请使用 alac)

如果想要将一个包含两个音频轨的 114514.mkv 的第二条音频轨拆出来,应先使用
ffprobe 114514.mkv查询该音频轨的编码和流序号;假设查询得知此音频为 aac 编码,编号为 #0:2,那么可以使用指令:
ffmpeg -i 114514.mkv -map 0:2 -c copy 114514.aacffmpeg -i 114514.mkv -map 0:2 -c:a copy -vn 114514.m4affmpeg -i 114514.mkv -map 0:2 -c:a copy -vn 114514.mka既可以将其封装进aac文件,也可以封装进 m4a 和 mka
如果需要拆的流为默认轨道,或者文件中只有一个视频轨/音频轨,那么可以将-map去掉;抽取字幕流/视频流同理

如果需要将音频 1.flac 从 0:1:1.400 到 0:4:05.14 截取出来,并保存为 2.flac,可以使用指令:
ffmpeg -i 1.flac -ss 0:1:1.4 -to 0:4:05.14 2.flac也可以使用 -t 取代 -to,其参数变为持续时间
将-ss,-to,-t 放在 -i 前后的区别是,如果放在前面,ffmpeg 将直接从那个时间点开始解码编码,直至结束的时间点;如果放在后面,ffmpeg 将从头开始解码,从指定的开始时间点开始编码,直至结束的时间点

需要注意的是,当使用-c:v copy剪切视频时,由于 H264 (AVC) 与 H265 (HEVC) 存在「关键帧」的概念,因此必须精确地从关键帧开始切割,否则:
如果将-ss参数放在-i后面,从视频开始直至指定的时间点之后的第一个关键帧,画面都会是静止;
如果将-ss参数放在-i前面,剪切出来的视频将会提前一段时间开始,并且如果指定了音频重编码,直至指定的时间点为止都是静音
如果剪切视频时使用了-c:a copy,由于 AAC 等格式也存在「关键帧」的概念,ffmpeg会在封装时自动加上一个延时的参数,使音视频同步;但是部分播放器或者解码器并不支持这一参数,因此会造成音视频不同步(典型的例子是将这样剪切出来的视频直接往B站投稿,可能会导致音视频不同步)

然而在实际操作过程中,即使使用 Aegisub 等工具找准了时间点,往往也会发生上述现象。因此,我个人认为比较合适的剪切视频比较好的方法是:使用 ffmpeg 的 hls 生成 m3u8 切片,将 -ss 设置在开始前一段时间,并且设置好合适的 -hls_time

以下操作可能有些大佬看来是很奇怪的操作,这里得说明一下,是为了规避 ffmpeg 的无损切割 bug 而想出来的歪门邪道;如果觉得麻烦,完全可以用 MKVToolNix 以帧切割(当然也得找准关键帧)

如果这么操作,那么需要首先找到需要开始切割的关键帧的前一个关键帧,可以使用 Aegisub 得知(如图,默认设置的情况下,进度条会显示关键帧位置,播放到那一帧时表示时间的方框会变色)

假如我们要从这一帧开始切割,查询得知上一个关键帧的时间点为0:14:07.888,假设我们要切割至0:15:30.0,那么我们首先插件一个叫「a」的文件夹,然后使用指令:ffmpeg -ss 0:14:07.8 -to 0:15:30 -i 1.mkv -hls_time 10 -hls_list_size 0 -vbsf h264_mp4toannexb -c copy a/1.m3u8这时我们打开文件夹「a」,可以看到这些文件

打开视频查看可知,10.ts 为指定的开始时间至我们所需切割的开始时间的文件,因此我们不需要这个文件;而11.ts直至19.ts都是我们需要的文件因此这时我们需要用文本编辑器打开那个 m3u8 文件,将 10.ts 的信息删掉,保存
然后使用指令
ffmpeg -i a/1.m3u8 -c copy 1_clip.mkv就得到了切割完成的文件(此方法有小几率失败,可能是由于时间码有关的玄学问题)

如果需要指定解码器/编码器,可以使用 -c
例如,假如要用NVDEC硬解视频流为HEVC的114514.mkv,并使用x264的medium预设以crf 18重编码成1919810.mkv,同时复制音频,那么可以使用:
ffmpeg -c:v hevc_cuvid -i 114514.mkv -preset medium -crf 18 -c:a copy 1919810.mkv假如要编码成 10bit,那么可以使用:
ffmpeg -c:v hevc_cuvid -i 114514.mkv -preset medium -crf 18 -c:a copy -pix_fmt yuv420p10 1919810.mkv假如同时要设置线程数为 12,那么就变为:
ffmpeg -c:v hevc_cuvid -i 114514.mkv -preset medium -crf 18 -c:a copy -pix_fmt yuv420p10 -threads 12 1919810.mkv假如要使用 x265 的 slow 预设并且以 crf 19 编码成 10bit,可以使用:
ffmpeg -c:v hevc_cuvid -i 114514.mkv -preset slow -crf 19 -c:v libx265 -c:a copy -pix_fmt yuv420p10 1919810.mkv假如要使用 NVENC 硬编 Ma10p (非常不推荐使用硬编),并且指定固定码率 20Mbps,那么可以用:
ffmpeg -c:v hevc_cuvid -i 114514.mkv -preset slow -crf 19 -c:v hevc_cuvid -b:v 20M -c:a copy -pix_fmt yuv420p10 1919810.mkv在使用硬编/硬解之前,请先确认自己的显卡是否支持这个格式!
同时请注意,默认的YUV采样模式和位深为输入视频的参数;例如输入视频为Hi10p或者Ma10p,那么输出默认也是10bit;如果需要输出8bit,需要手动指定-pix_fmt yuv420p(我想用ffmpeg也不至于去编码yuv444吧);这点在硬编/解的兼容性上面会体现出来,因为较老的显卡不支持Hi10p,更老的显卡不支持Ma10p;而对于YUV444来说,各家显卡的兼容性就更差了。

如果需要将 1920*1080 的 Hi10p 视频用 lanczos 缩小到 720p,并且使用 x264 8bit crf 18,预设 veryslow,那么可以使用:
ffmpeg -i 114514.mp4 -c:a copy -crf 18 -preset veryslow -s 1280x720 -sws_flags lanczos -pix_fmt yuv420p 1919810.mp4也可以使用:
ffmpeg -i 114514.mp4 -c:a copy -crf 18 -preset veryslow -vf scale=1280:-1 -sws_flags lanczos 1919810.mp4
-vf 还有别的各种用处,例如加字幕、旋转视频和倒放音频等(不如试试把寒蝉第二季的OP TV ver倒放听一听)
例如,如果需要将生肉 1.mkv 以 x264 8bit crf 20 preset slow 来压制,同时内嵌 1.ass,同时将音频复制,那么可以使用:ffmpeg -i 1.mkv -c:a copy -crf 20 -preset slow -vf subtitles=1.ass 1919810.mp4假如文件名带有空格(如:1 1.mkv 1 1.ass),那么修改成:
ffmpeg -i "1 1.mkv" -c:a copy -crf 20 -preset slow -vf "subtitles='1 1.ass'" "1919810.mp4"需要特别注意的是,ffmpeg自带的libass对华康的字形无法正确选择(可能是因为版本原因)。例如:指定字体为DFPSNGyoSho-W5,实际压制时会选择成DFSNGyoSho-W5
这一点在基于ffmpeg的GUI压制工具ShanaEncoder中得到修复,原因未知。
另外,由于ffmpeg的字幕滤镜为libass,因此不支持VsFilterMod的标签;如需使用vsfm,请使用AviSynth或VapourSynth。

ffmpeg 也可以处理其他格式。例如,如果需要将 1.jpg 转换成 1.png,可以使用指令:
ffmpeg -i 1.jpg 1.png有人会问,png,bmp 和 jpg 的区别在哪里呢?这三个格式都支持无损,区别在于,png 是 RGB 格式,jpg 是 YUV 格式;而 bmp 则是未压缩的格式。

ffmpeg作为一个万能的格式转换软件,并不是专业的视频/音频处理工具,其封装或处理可能存在不合标准之处,对输入文件也有较高的标准要求;有的时候ffmepg并不能正确处理视频文件,可能会有各种各样的bug;这时请使用别的工具替代,如MeGUI和MKVToolNix等
以上所述的功能仅为方便日常调用而介绍;如需进行专业的处理,请务必使用对应的专业工具,如AVS/VS,QAAC,MKVToolNix等

更多的使用方法请善用搜索引擎






高司舞 发表于 2022-7-31 00:34:47

楼主知道这是为什么吗





高司舞 发表于 2022-7-31 00:43:58

害 变量也设置了就是运行不了这bat

dtlnor 发表于 2022-7-31 00:55:19

本帖最后由 dtlnor 于 2022-7-31 01:14 编辑

高司舞 发表于 2022-7-31 00:43
害 变量也设置了就是运行不了这bat
你這個bat前幾行可以正常運行,是不是編碼的問題?(建議用無BOM的utf-8,也就是ascii,或者是ANSI。因為有bom的話文件頭好像會被當成字符)

編輯:剛才試了試,你是用的utf16-LE有BOM的編碼吧。換成utf8無bom吧

高司舞 发表于 2022-7-31 01:23:02

dtlnor 发表于 2022-7-31 00:55
你這個bat前幾行可以正常運行,是不是編碼的問題?(建議用無BOM的utf-8,也就是ascii,或者是ANSI。因為 ...

解决了 非常感谢大佬 想了这么久居然没想到会是编码问题{:4_675:}

Lambholl 发表于 2022-7-31 02:56:32

本帖最后由 Lambholl 于 2022-7-31 03:00 编辑

dtlnor 发表于 2022-7-31 00:55
你這個bat前幾行可以正常運行,是不是編碼的問題?(建議用無BOM的utf-8,也就是ascii,或者是ANSI。因為 ...
草 我本来也觉得可能是编码问题,但是想了想都是西文字符,觉得不太可能是这个问题https://p.sda1.dev/6/e82fd3aeaab1e47de443a8e1f4a2ec6f/em198.gif

没想到有人去用 UTF-16 这种编码https://p.sda1.dev/6/e82fd3aeaab1e47de443a8e1f4a2ec6f/em198.gif

joker2000 发表于 2022-7-31 10:35:00

视频剪切那块纯粹胡扯,请用mmg。另外,这里提到的大部分操作都不推荐使用ffmpeg,除非你想体验各种奇妙的出错以及折磨自己(

Lambholl 发表于 2022-7-31 13:05:45

本帖最后由 Lambholl 于 2022-7-31 13:27 编辑

joker2000 发表于 2022-7-31 10:35
视频剪切那块纯粹胡扯,请用mmg。另外,这里提到的大部分操作都不推荐使用ffmpeg,除非你想体验各种奇妙的 ...
你这么说有什么根据吗

我说了是「方便日常使用」而介绍;而且这些操作的可用性都是我实验过的,如果你说「胡扯」,那么请你用实验证明不可行
(另外,视频剪切还是建议重编码)

其次,这里的「大部分操作」都是有关视频的抽流、重新封装和重编码(特别是针对特定轨道的重编码),不用 ffmpeg 那无非也是用 ShanaEncoder,本质上还是基于ffmpeg(当然如果要用小丸 MeGUI那也行);抽流更是离不开ffmpeg
还有一块讲的比较多的内容是视频重编码,而对于绝大多数人的日常使用来说,要实现这些功能,ffmpeg 完全是足够的。你总不能要求每个人为了把视频缩到 720p 专门去写一个 vs 脚本

你说「奇妙的出错」的话,请给出依据,我写的所有内容里面,有哪些会造成「奇妙的出错」,容易造成报错的操作我都是写了操作警告的;
另外,又有哪些是在「折磨自己」,这个我实在是想不明白(我想,为了调整视频分辨率专门去写一个vs脚本来跑,那更是在「折磨自己」吧)


菜姬 发表于 2022-7-31 19:34:03

视频剪切那部分问题确实有点大,其他的部分倒也没必要那么苛刻吧
不过确实是稍微复杂一点的操作都不推荐用ffmpeg去做 比如 resample 加字幕这种

菜姬 发表于 2022-7-31 21:47:10

精准的切就重编码,无损的切就基于GOP区间
我看你这中间转一次m3u8是打算规避ffmpeg的某些奇怪的特性?
你既然都知道关键帧在哪了,要么就切长一点,要么就切短一点
先切长再手动改m3u8切短这种操作真的是怎么看怎么诡异
页: [1] 2
查看完整版本: [科普向] ffmpeg的安装与基本使用方法