在 Linux 系统中使用 FFmpegFreeUI 的一般方法

August 29, 2025 · View on GitHub

本篇内容主要由 Uyanide 提供

前置条件

  • 正常工作的Wine:由于 FFmpegFreeUI 使用了非跨平台的 UI 框架 WinForms,因此在 Linux 系统中需要通过兼容层运行,这意味着您需要在系统中配置 Wine 或基于此的其他兼容环境如 Proton。此类软件的配置方法因发行版而异,此处不再赘述,可参阅:

Tip

如果您计划原生调用 linux 版本的 ffmpeg 而非转译后的 ffmpeg.exe,推荐使用原版 Wine 以获得最好的支持,Proton 或 Wine Staging 等其他兼容层可能会遇到各种问题。另外我们强烈推荐您在继续阅读前了解 Wine 的基础知识,例如 WINEPREFIX 的作用。

Tip

我们提供了 一键脚本 以供您方便地配置调用原生 ffmpeg 的转译环境,这将会自动处理诸如 字体 / 脚本 / WINEPREFIX 等一系列问题而无需您过多操心。

  • 耐心与包容心:使用兼容层通常意味着您可能会在各种场景下遇到各种问题,有些是操作失误,有些是系统 Bug。本文档无法覆盖所有可能遇到的问题,因此充分的耐心和强大的包容心同样是重要的前置条件之一 :)

简单使用方法

如果没有特殊需求,您大可以在兼容层中同时运行 FFmpegFreeUI 和 Windows 版的 ffmpeg.exe。这虽然略显丑陋,但确实是最省心的解决方案。

具体操作步骤十分简单,您只需要:

  1. 下载 Windows 版本的 ffmpeg 发行版
  2. ffmpeg.exeffprobe.exe 放置于 FFmpegFreeUI.exe 的同级目录;
  3. 使用兼容层启动 FFmpegFreeUI.exe

或者,如果您希望将 Windows 版本的 ffmpeg 保存在其他特定目录,可以在 FFmpegFreeUI 的 设置 -> 替代 Process 的 FileName 设置项中填入 ffmpeg.exe 的完整 DOS 路径(如:Z:\home\username\Downloads\ffmpeg-win\ffmpeg.exe)或相对路径。

关于如何获取 Unix 文件系统下某个文件在 Wine 中对应的 DOS 路径,可参阅 Wine 下的路径转换

调用原生 FFmpeg

完整方案

Warning

本节剩余内容仅在 Wine 环境经过测试,在其他兼容层如 Steam 的 Proton Experimental / Proton Hotfix 或 Wine Staging 中不保证可用性。

  1. 首先,需要准备三个脚本:

    • wait-exit.bat:暴露给 FFmpegFreeUI 的最外层脚本,用于调用 run-ffmpeg.py,等待 ffmpeg 进程结束,并转发其日志:

      @echo off
      setlocal enabledelayedexpansion
      
      set "log_file=Z:\tmp\3fui_ffmpeg.log"
      set "ret_file=Z:\tmp\3fui_ffmpeg.ret"
      set "finish_sign=Z:\tmp\3fui_ffmpeg_finish"
      set "log_file_tail=Z:\tmp\3fui_ffmpeg.log.tail"
      
      del "%log_file%"
      del "%ret_file%"
      del "%finish_sign%"
      del "%log_file_tail%"
      
      set "delay_script=%1"
      shift
      set "run-ffmpeg=%1"
      
      set "args="
      :loop
      shift
      if "%~1"=="" goto after_args
      set args=!args! "%~1"
      goto loop
      :after_args
      REM
      
      start "" %run-ffmpeg% %args%
      
      :check
      if exist "%finish_sign%" (
          set /p ret=<"%ret_file%"
          if not defined ret (
              set ret=1
          )
          type "%log_file%" 1>&2
          exit /b !ret!
      ) else (
          if exist "%log_file_tail%" (
              type "%log_file_tail%" 1>&2
          )
          cscript %delay_script% 2>nul
          goto check
      )
      
      endlocal
      
    • run-ffmpeg.py:实际调用 ffmpeg 的脚本,将其日志重定向至文件:

      #!/bin/env python3
      
      import sys
      import subprocess
      
      LOG_FILE = "/tmp/3fui_ffmpeg.log"
      LOG_TAIL_FILE = "/tmp/3fui_ffmpeg.log.tail"
      RET_FILE = "/tmp/3fui_ffmpeg.ret"
      FINISH_SIGN = "/tmp/3fui_ffmpeg_finish"
      
      
      def main():
          try:
              ffmpeg_cmd = ['ffmpeg'] + sys.argv[1:]
      
              with open(LOG_FILE, 'w') as log_file, open(LOG_TAIL_FILE, 'w') as tail_file:
                  process = subprocess.Popen(
                      ffmpeg_cmd,
                      stderr=subprocess.PIPE,
                      stdout=subprocess.DEVNULL,
                      text=True,
                      bufsize=1
                  )
                  if not process or not process.stderr:
                      return
      
                  for line in process.stderr:
                      tail_file.seek(0)
                      tail_file.write(line)
                      tail_file.truncate()
                      tail_file.flush()
      
                      log_file.write(line)
                      log_file.flush()
      
                  return_code = process.wait()
      
                  with open(RET_FILE, 'w') as ret_file:
                      ret_file.write(str(return_code) + '\n')
      
          except Exception as e:
              with open(RET_FILE, 'w') as ret_file:
                  ret_file.write("1\n")
      
          finally:
              with open(FINISH_SIGN, 'w') as f:
                  f.write("")
      
      
      if __name__ == "__main__":
          main()
      
    • delay.vbs:在 wait-exit.bat 中实现延时的工具脚本:

      WScript.Sleep 1000
      
  2. 然后,在 设置 -> 替代 Process 的 FileName 设置项中填入 wait-exit.bat 的完整 DOS 路径 或相对路径(引号可选)。如:

    "Z:\path\to\wait-exit.bat"

  3. 设置 -> 覆盖 Process 的参数传递 设置项中依次填入 delay.vbsrun-ffmpeg.py 的完整 DOS 路径 或相对路径(引号可选)与 <args>,以空格分隔。如:

    "Z:\path\to\delay.vbs" "Z:\path\to\run-ffmpeg.py" <args>

  4. 最后,勾选 设置 -> 转译模式,就可以正常添加文件进行编码了。

Tip

上述脚本与设置已经集成在 一键脚本 中,可一键配置,一键启动。

替代方案

以上三个脚本实现了基本的进度更新与报错显示。如果您不关心这些功能,而只是把 FFmpegFreeUI 当作参数生成器,可以仅勾选 设置 -> 转译模式 选项,并在开始任务后忽略软件的报错信息,在 编码队列 界面点击 复制命令行,自行在终端中运行。

或者,如果您不关心进度或报错信息,而只是想让 FFmpegFreeUI 启动原生 ffmpeg,可以进行如下操作:

Warning

本节剩余内容仅在 Wine 环境经过测试,在其他兼容层如 Steam 的 Proton Experimental / Proton Hotfix 或 Wine Staging 中不保证可用性。

  1. 设置 -> 替代 Process 的 FileName 设置项中填入 start
  2. 设置 -> 覆盖 Process 的参数传递 设置项中填入 /unix /path/to/ffmpeg <args>,将其中的 /path/to/ffmpeg 替换为您想使用的 ffmpeg 可执行文件的完整 Unix 路径,如 /usr/bin/ffmpeg
  3. 勾选 设置 -> 转译模式

此时,如果开始编码任务,对应任务会显示“错误”,ffmpeg 将会在后台持续运行直至任务完成。ffmpeg 的 stderr 输出将在启动 wine 的终端中可见。

为什么不用 start /wait 参数?因为这对于启动的 ffmpeg 进程没有作用 :)

一键脚本

3fui-linux-scripts 项目提供了一键运行脚本。

此项目包含了调用原生 ffmpeg 所需的脚本与设置,同时可以一键安装中文字体解决口口口乱码问题。

其他问题

界面口口口乱码

FFmpegFreeUI 提供了字体设置选项,目前该设置项位于 设置 -> 全局字体,选择支持中文显示的字体并确认后可解决此问题。

或者,如果您找不到这个设置项或希望在首次启动前配置正确的字体,可在 FFmpegFreeUI.exe 同级目录中新建 Settings.json 文件,并写入以下内容:

{
  "字体": "some font"
}

some font 替换为您系统上安装的中文字体。

Tip

如果您不知道系统上有什么字体,可以用 fc-list : family 查看。

在 FFmpegFreeUI 中设置字体后您仍然可能会在各种预料的位置发现中文乱码,可尝试以下解决方案(任选其一):

  • 通过 winetricks 安装 fakechinese;
  • 将微软雅黑字体 msyh.ttc 放入 FFmpegFreeUI 运行时相同的 WINEPREFIX 中的 C:\windows\Fonts\ 文件夹中。
  • 将你喜欢的中文字体文件放在 FFmpegFreeUI 运行时相同的 WINEPREFIX 中的 C:\windows\Fonts\ 文件夹中,并手动修改注册表伪装中文字体(可参照 这个脚本 中的做法);

高分辨率屏幕 界面过小

  1. 将环境变量 $WINEPREFIX 设为 FFmpegFreeUI 运行时相同的 WINEPREFIX,通过 winecfg 打开 Wine 的配置界面

  2. 在弹出的界面中选择 "显示" 并在 "屏幕分辨率" 中调整 DPI,高分辨率情况下推荐 144。

Wine 下的路径转换

Important

以下操作均需保持与 FFmpegFreeUI 运行时相同的 $WINEPREFIX,如果不懂这是什么就不用管,默认是 $HOME/.wine

  • 一般情况下,您可使用 winepath -w /unix/path 将 Unix 路径转换为 DOS 路径,使用 winepath -u Z:\dos\path 将 DOS 路径转换为 Unix 路径;

  • 或者,您可以在 winecfgDrivers 选项卡下看到所有的盘符映射位置;

  • 或者,您可以查看 $WINEPREFIX/dosdevices 下的符号链接以确认盘符映射位置。例如,ls -l $WINEPREFIX/dosdevices 的结果可能如下:

    lrwxrwxrwx 1 username username 10 Jan 01 00:00 c: -> ../drive_c
    lrwxrwxrwx 1 username username  1 Jan 01 00:00 z: -> /
    ...
    

    这表示 C:\ 映射 $WINEPREFIX/drive_c/Z:\ 映射 /

Tip

一般情况下,Wine 会将 Z:\ 映射为系统根目录 /,此外 Proton 通常还会将 X:\ 映射为用户家目录 /home/username/。但这只是经验规律,建议在实际应用场景中根据上述方法自行确认。

为什么 XXX 不工作 / 为什么有 XXX 报错 / 为什么 ...

正如开头所说:

使用兼容层通常意味着您可能会在各种场景下遇到各种问题,有些是操作失误,有些是系统 Bug。本文档无法覆盖所有可能遇到的问题,因此充分的耐心和强大的包容心同样是重要的前置条件之一 :)

持续不断的 Troubleshooting 是使用 GNU/Linux 系统不得不品的一环,尤其是对于本文所述强行兼容运行 WinForms 应用并调用外部二进制的场景。当然无论遇到任何问题或有任何改进建议都欢迎提出,也欢迎进群一起讨论。