跳到主要内容

FFmpeg 入门指南

FFmpeg 是一种强大而应用广泛的视频、音频处理工具集。它包含了跨平台的视频、音频导入和导出功能,以及格式转换和媒体播放能力。这篇文章将大致认识 FFmpeg的基础信息,并提供实际示例。

FFmpeg 是什么?

FFmpeg 是一种开源的媒体处理框架,可用于播放、跨格式转换和处理视音媒体。它包含以下主要组件:

  • ffmpeg: 命令行工具,用于视音媒体操作,如格式转换和视音处理。
  • ffplay: 简单的媒体播放器,用于快速测试视频和音频文件。
  • ffprobe: 用于分析媒体文件的详细信息,如视频分识率和类型。

FFmpeg 的主要特性

  1. 格式支持广泛: FFmpeg 支持三百余种格式,包括旧版的 AVI、MP3 ,以及最新的格式。
  2. 过滤器和调整功能: 持有丰富的过滤器,可用于音频和视频处理,如进行色调和声音加工。
  3. 操作方便: 通过命令行可以完成很多处理任务,例如优化视频大小和分识率。
  4. 充分定制: 支持应用程序绑定,通过操作库实现更复杂的媒体操作。

如何在 Windows 上安装和使用 FFmpeg

安装步骤:

  1. 下载 FFmpeg
    • 前往 FFmpeg 官网
    • 选择 Windows 的预编译版本(通常会跳转到第三方编译站点,如 gyan.dev)。
    • 下载静态版本(Static Builds)。
  2. 解压文件
    • 下载完成后,将压缩包解压到一个文件夹,比如 C:\ffmpeg
  3. 配置环境变量
    • 打开系统设置,进入 高级系统设置 > 环境变量
    • 系统变量 中找到 Path,点击 编辑
    • 添加 FFmpeg 的 bin 路径,例如:C:\ffmpeg\bin
    • 保存设置。
  4. 验证安装
    • 打开命令提示符(Win + R,输入 cmd)。
    • 输入 ffmpeg -version,如果显示版本信息,则安装成功。

FFmpeg 的实际示例

格式转换

将 MP4 视频转换为 AVI 格式:

ffmpeg -i input.mp4 output.avi

压缩视频

使用 H.264 编码器将视频压缩:

ffmpeg -i input.mp4 -vcodec libx264 -crf 23 output.mp4

查看媒体信息

分析视频文件的详细信息:

ffprobe input.mp4

取出图片

从视频中抽取图片:

ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 output.png

FFmpeg 的实际应用

  1. 视频上传和下载: 通过压缩和格式转换优化视频大小,提高上传和播放性能。
  2. 视频编辑: 添加特效和调整色调。
  3. 媒体播放: 实现流媒体播放,如直播和视频播放服务。

音频

不修改音乐质量,截取前30秒

ffmpeg -i input.mp3 -t 00:00:30 -acodec copy output.mp3
  • -i input.mp3:指定输入文件是 input.mp3
  • -t 00:00:30-t 参数后面跟的是时间,这里指定了截取的时长为 30 秒。
  • -acodec copy:表示复制音频流,不进行重新编码。这可以确保音频质量和编码参数保持不变。
  • output.mp3:指定输出文件名。

不修改音乐质量,截取第15秒到第30秒

ffmpeg -i input.mp3 -ss 00:00:15 -t 00:00:15 -acodec copy output.mp3
  • -i input.mp3:指定输入文件是 input.mp3
  • -ss 00:00:15-ss 参数后面跟的是开始时间,这里指定了从第 15 秒开始截取。
  • -t 00:00:15-t 参数后面跟的是截取的时长,这里指定了截取 15 秒的长度,即从第 15 秒到第 30 秒。
  • -acodec copy:表示复制音频流,不进行重新编码。这可以确保音频质量和编码参数保持不变。
  • output.mp3:指定输出文件名。

转换FLAC到MP3

ffmpeg -i input.flac -codec:a libmp3lame -qscale:a 2 output.mp3
  • 参数解释

  • -i input.flac:指定输入文件为 input.flac

  • -codec:a libmp3lame:指定音频编码器为 libmp3lame,这是 FFmpeg 中用于生成 MP3 文件的编码器。

  • -qscale:a 2:设置 MP3 的质量。qscale 的值范围是 0(最高质量,文件较大)到 9(最低质量,文件较小)。2 是一个常用的平衡点,既保证了较好的音质,又不会使文件过大。

  • output.mp3:指定输出文件的名称。

  • 如果需要更高的音质,可以将 -qscale:a 的值设置得更低(如 0 或 1),但文件会更大。

  • 如果需要更小的文件,可以将 -qscale:a 的值设置得更高(如 5 或 6),但音质会稍差。

  • 指定比特率: 如果你希望指定 MP3 的比特率,可以使用 -b:a 参数。例如,将比特率设置为 192kbps:

ffmpeg -i input.flac -codec:a libmp3lame -b:a 192k output.mp3

批量转换ncm及flac

  • 递归处理当前文件夹及所有子文件夹
@echo off
setlocal enabledelayedexpansion

REM === 1) 将当前文件夹及子文件夹所有 .ncm 转为 .flac ===
echo [INFO] Converting all .ncm files (recursive) to .flac ...

ncmdump-go --dir . --recursive

echo [INFO] Done converting .ncm to .flac.

REM === 2) 将当前文件夹及子文件夹所有 .flac 转为 .mp3 ===
echo [INFO] Converting all .flac files (recursive) to .mp3 ...

REM 使用 for /R 递归
for /R %%f in (*.flac) do (
echo [INFO] Processing %%f ...
ffmpeg -i "%%f" -codec:a libmp3lame -qscale:a 2 "%%~dpnf.mp3"
)

echo [INFO] Done converting .flac to .mp3.

pause

视频

压缩网课视频

下载或录制的视频,特别大,1个小时上G了。实际上没有必要保存那么清晰

import os
import subprocess
import argparse
import time

# 设置支持的视频格式
formats = ['mp4', 'mkv', 'avi', 'mov', 'ts', 'mp3']

# 压缩视频文件的函数
def compress_video(file_path, log_file):
# 获取文件目录、文件名和扩展名
dir_name, file_name = os.path.split(file_path)
base_name, ext = os.path.splitext(file_name)

# 生成目标输出文件路径(加上 _output 后缀)
output_file = os.path.join(dir_name, f"{base_name}_output{ext}")

# 如果目标文件已存在或原文件包含 "_output",则跳过
if "_output" in file_path or os.path.exists(output_file):
log_file.write(f"Skipping already compressed file: {file_path}\n")
log_file.flush() # 立即将日志写入硬盘
return

# 记录当前处理的文件
log_file.write(f"Processing file: {file_path}\n")
log_file.flush() # 立即将日志写入硬盘
start_time = time.time() # 记录开始时间

# 使用 FFmpeg 压缩视频
command = [
'ffmpeg',
'-i', file_path, # 指定输入文件路径
'-vf', "scale='min(1280,iw)':'-2'", # 视频过滤器,限制视频宽度为 1280,保持原始宽高比
'-c:v', 'libx264', # 视频编码器使用 libx264(H.264 格式)
'-crf', '32', # 压缩质量设置为 32(数值越高压缩越多,质量越低)
'-preset', 'slow', # 压缩预设,慢速模式提供更高的压缩效率
'-c:a', 'aac', # 音频编码器使用 AAC
'-b:a', '96k', # 音频比特率设置为 96 kbps
'-threads', '12', # 使用 12 个线程加速处理
output_file # 输出文件路径
]

subprocess.run(command)

# 记录结束时间并计算耗时
end_time = time.time()
elapsed_time = end_time - start_time
log_file.write(f"Finished processing {file_path}. Time taken: {elapsed_time:.2f} seconds.\n\n")
log_file.flush() # 立即将日志写入硬盘

# 遍历目录并压缩文件
def traverse_directory(root_dir):
# 打开日志文件
with open("result.log", "w", encoding="utf-8") as log_file:
log_file.write(f"Compression started...\n")
log_file.flush() # 立即将日志写入硬盘

for dirpath, dirnames, filenames in os.walk(root_dir):
for file in filenames:
# 检查文件格式
if any(file.lower().endswith(f".{ext}") for ext in formats):
file_path = os.path.join(dirpath, file)
compress_video(file_path, log_file)

log_file.write(f"Compression finished.\n")
log_file.flush() # 立即将日志写入硬盘

# 程序入口
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Compress videos in a directory.")
parser.add_argument("root_dir", help="Root directory to process")
args = parser.parse_args()

traverse_directory(args.root_dir)

Python脚本

递归遍历指定目录及其子目录中的视频文件,自动压缩符合格式的视频文件并记录日志

具体来说:

  1. 支持的视频格式

    • 脚本支持多种视频和音频格式,包括 mp4, mkv, avi, mov, ts, mp3

    • 可以在脚本中自行添加或修改支持的格式。

  2. 自动压缩

    • 对于符合格式的文件,脚本使用 FFmpeg 工具进行压缩,设置了一系列优化参数(如分辨率限制、压缩质量控制等),以减少文件大小。

    • 输出的压缩文件会保存到同目录下,文件名后添加 _output 后缀。例如:video.mp4 的压缩结果是 video_output.mp4

  3. 避免重复压缩

    • 如果文件名中包含 _output 后缀(表示该文件已被处理过),脚本会跳过此文件。

    • 如果目标文件已经存在(例如 video_output.mp4),脚本也会跳过。

  4. 记录日志

    • 脚本将处理的详细信息记录到

      result.log

      文件中,包括:

      • 跳过了哪些文件(已压缩或目标文件已存在)。

      • 哪些文件正在处理。

      • 每个文件的处理开始时间、结束时间,以及耗时。

  5. 多线程支持

    • 脚本通过 -threads 参数限制 FFmpeg 使用的线程数,可以更高效地利用多核 CPU 资源。

  6. 分辨率限制

    • 视频的宽度被限制为最大 1280 像素,同时保持宽高比不变。小于 1280 的视频分辨率不会被放大。

FFmpeg 参数详解

以下是脚本中使用的 FFmpeg 参数及其作用的详细解释:

1. -i
  • 作用:指定输入文件。
  • 示例-i input.mp4 表示将 input.mp4 作为输入文件进行处理。
2. -vf "scale='min(1280,iw)':'-2'"
  • 作用

    :设置视频过滤器。

    • scale:调整视频分辨率。
    • min(1280,iw):限制视频宽度不超过 1280 像素,如果视频宽度(iw)小于 1280,则保持原宽度。
    • '-2':高度根据宽高比自动计算(必须是偶数)。
  • 示例:如果原始视频是 1920×1080,则会调整为 1280×720;如果原始视频是 800×600,则保持不变。

3. -c:v libx264
  • 作用:指定视频编码器为 H.264(libx264)。
  • 特点:H.264 是一种高效的视频编码格式,兼容性好,广泛用于流媒体和存储。
4. -crf 32
  • 作用

    :设置 CRF(恒定速率因子)。

    • CRF 是一种衡量视频压缩质量的参数。
    • 数值范围为 0-51,数值越低质量越高,文件越大;数值越高压缩越多,质量越低。
  • 示例-crf 32 表示中等质量。如果希望提高质量,可降低到 23-28。

5. -preset slow
  • 作用

    :设置编码速度与压缩效率的平衡。

    • 可选值从 ultrafastveryslow
    • slow 模式提供较高的压缩效率,但编码速度较慢。
  • 示例:如果需要更快的处理速度,可改为 -preset medium-preset fast

6. -c:a aac
  • 作用:指定音频编码器为 AAC。
  • 特点:AAC 是一种常见的音频编码格式,具有高压缩率和良好的音质。
7. -b:a 96k
  • 作用:设置音频比特率为 96 kbps。
  • 特点:较低的音频比特率适合语音主导的视频(如网课),但对于音乐质量可能不足。
8. -threads 12
  • 作用:指定使用的线程数。
  • 特点:多线程可以加速视频处理,适合多核 CPU。如果未指定,FFmpeg 会自动选择线程数。

调整视频音量

import os
import subprocess
import argparse

def process_files(directory, volume_multiplier=10.0, file_extension='mkv'):
for root, dirs, files in os.walk(directory):
# Skip '.output' directories
if '.output' in dirs:
dirs.remove('.output')

output_dir = os.path.join(root, '.output')
os.makedirs(output_dir, exist_ok=True)

for file in files:
if file.lower().endswith(f'.{file_extension.lower()}'):
input_path = os.path.join(root, file)
output_path = os.path.join(output_dir, file)

command = [
'ffmpeg', '-i', input_path,
'-af', f'volume={volume_multiplier}',
'-c:v', 'copy',
output_path
]

print(f"Processing: {input_path}")
subprocess.run(command)

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Process video files to adjust volume.")
parser.add_argument('directory', type=str, help='Directory to process video files in.')
parser.add_argument('-v', '--volume', type=float, default=10.0, help='Volume multiplier (default: 10.0).')
parser.add_argument('-e', '--ext', type=str, default='mkv', help='File extension to process (default: mkv).')

args = parser.parse_args()
process_files(args.directory, args.volume, args.ext)

递归遍历指定目录,调整符合格式的视频文件音量

本脚本的主要功能是:

  1. 遍历目录及其子目录
    • 递归遍历指定的 directory 及其所有子目录,寻找符合格式的视频文件。
    • 默认仅处理 .mkv 文件,但用户可以通过参数指定其他扩展名。
  2. 调整音量
    • 使用 FFmpeg 命令行工具,修改音频音量。
    • 默认音量调整系数为 10.0 倍,可通过参数调整。
  3. 输出目录管理
    • 处理后的文件会保存在 .output 目录中,防止覆盖原文件。
    • 如果 .output 目录已存在,则不会重新创建。
    • 目录名包含 .output 的子目录会被跳过,避免不必要的重复处理。
  4. 避免重复处理
    • 原始视频文件不会被覆盖,所有处理后的文件都存放在 .output 目录中。
    • 如果 .output 目录中已经存在目标文件,则不会额外检查是否已处理。

脚本详细解析

1. 递归遍历目录
  • 使用 os.walk(directory) 遍历 directory 及其所有子目录。
  • 通过 dirs.remove('.output') 排除 .output 目录,避免处理已处理的视频。
for root, dirs, files in os.walk(directory):
if '.output' in dirs:
dirs.remove('.output')

2. 处理符合格式的视频文件
  • 默认仅处理 .mkv 格式文件。
  • 用户可以通过 -e 选项指定不同的扩展名,如 .mp4.avi 等。
  • file.lower().endswith(f'.{file_extension.lower()}') 确保匹配大小写不同的扩展名。
if file.lower().endswith(f'.{file_extension.lower()}'):
input_path = os.path.join(root, file)
output_path = os.path.join(output_dir, file)

3. FFmpeg 处理逻辑
  • 使用 FFmpeg 进行音量调整,命令如下:
ffmpeg -i input.mkv -af "volume=10.0" -c:v copy output.mkv
  • 其中:
    • -i input.mkv:指定输入文件。
    • -af "volume=10.0":设置音量调整系数(默认为 10.0)。
    • -c:v copy:直接复制视频流,避免重新编码,提高效率。
    • output.mkv:输出文件路径。
command = [
'ffmpeg', '-i', input_path,
'-af', f'volume={volume_multiplier}',
'-c:v', 'copy',
output_path
]

4. 运行 FFmpeg 命令
  • subprocess.run(command) 运行 FFmpeg 命令进行音量调整。
  • print(f"Processing: {input_path}") 便于用户查看当前正在处理的文件。
print(f"Processing: {input_path}")
subprocess.run(command)

脚本运行方式

基本用法
python script.py /path/to/videos
  • 处理 /path/to/videos 目录中的所有 .mkv 文件,并将调整后的文件存放在 .output 目录。
调整音量
python script.py /path/to/videos -v 5.0
  • 将音量调整为 5 倍,而不是默认的 10 倍。
更改文件格式
python script.py /path/to/videos -e mp4
  • 仅处理 .mp4 格式的文件。

FFmpeg 参数详解

参数作用
-i指定输入文件
-af "volume=10.0"设置音量增益为 10.0 倍
-c:v copy直接复制视频流,避免重新编码
-c:a aac指定音频编码器(默认不指定)

压缩高清视频

  • 从网络上下载的MTK视频,动辄数十G,在保证清晰度的前提下适当压缩便于保存
@echo off
setlocal enabledelayedexpansion

:: 遍历所有 .mkv 文件
for %%f in (*.mkv) do (
echo Processing: %%f

:: 提取不含扩展名的主文件名
set "filename=%%~nf"

:: 构造新文件名:加 .cov 后缀
set "newname=!filename!.cov.mkv"

:: 调用 ffmpeg 进行压缩转换
ffmpeg -hwaccel d3d11va -i "%%f" -map 0 -c:v hevc_amf -usage transcoding -quality balanced -b:v 3M -c:a copy -c:s copy "!newname!"

echo Done: !newname!
echo.
)

echo All files processed.
pause

结论

FFmpeg 是视音媒体处理领域中强大的工具,它能够解决从基础操作到复杂实现的多种需求。无论是视音媒体小工具进阶,还是视频编辑和播放,FFmpeg 都是一个优秀的选择。