FileNotFoundError: [WinError 2] 系统找不到指定的文件 - FFMPEG

0 投票
1 回答
84 浏览
提问于 2025-04-14 15:37

我在Windows上使用conda环境运行一个脚本,结果遇到了一个错误(下面有详细信息),看起来是因为Python找不到ffmpeg.exe这个程序。网上有很多关于这个问题的讨论,但遗憾的是,没有一个解决方案对我有效,所以我希望有人能提供新的思路。

我尝试过的办法:

  • conda install -c conda-forge ffmpeg(执行这个命令后,我可以在命令行中运行ffmpeg,但还是出现了错误)
  • pip install ffmpeg-python
  • 把ffmpeg.exe所在的文件夹添加到Windows的路径中,并且也加到了Python的sys.path里。
  • 把同一个ffmpeg.exe文件:a) 复制到conda环境中python.exe的文件夹,b) 复制到我正在运行的脚本的文件夹,c) 复制到subprocess.py的文件夹。
  • 下载了ffmpeg的Windows版本,并用那个文件重复了最后两步。

还有什么其他的方法可以尝试让它正常工作吗?

---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In[10], line 22
     19 truncate_second = 8.2         # Video end = start_second + truncate_second
     21 # Extract Video CAVP Features & New Video Path:
---> 22 cavp_feats, new_video_path = extract_cavp(video_path, start_second, truncate_second, tmp_path=tmp_path)

File D:\Software\Anaconda\envs\diff_foley\Lib\site-packages\torch\nn\modules\module.py:1518, in Module._wrapped_call_impl(self, *args, **kwargs)
   1516     return self._compiled_call_impl(*args, **kwargs)  # type: ignore[misc]
   1517 else:
-> 1518     return self._call_impl(*args, **kwargs)

File D:\Software\Anaconda\envs\diff_foley\Lib\site-packages\torch\nn\modules\module.py:1527, in Module._call_impl(self, *args, **kwargs)
   1522 # If we don't have any hooks, we want to skip the rest of the logic in
   1523 # this function, and just call forward.
   1524 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
   1525         or _global_backward_pre_hooks or _global_backward_hooks
   1526         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1527     return forward_call(*args, **kwargs)
   1529 try:
   1530     result = None

File D:\Software\Anaconda\envs\diff_foley\Lib\site-packages\torch\utils\_contextlib.py:115, in context_decorator.<locals>.decorate_context(*args, **kwargs)
    112 @functools.wraps(func)
    113 def decorate_context(*args, **kwargs):
    114     with ctx_factory():
--> 115         return func(*args, **kwargs)

File D:\Work\DIff-Foley\Diff-Foley\inference\demo_util.py:131, in Extract_CAVP_Features.forward(self, video_path, start_second, truncate_second, tmp_path)
    129 print("truncate second: ", truncate_second)
    130 # Load the video, change fps:
--> 131 video_path_low_fps = reencode_video_with_diff_fps(video_path, self.tmp_path, self.fps, start_second, truncate_second)
    132 video_path_high_fps = reencode_video_with_diff_fps(video_path, self.tmp_path, 21.5, start_second, truncate_second)
    134 # read the video:

File D:\Work\DIff-Foley\Diff-Foley\inference\demo_util.py:42, in reencode_video_with_diff_fps(video_path, tmp_path, extraction_fps, start_second, truncate_second)
     31 def reencode_video_with_diff_fps(video_path: str, tmp_path: str, extraction_fps: int, start_second, truncate_second) -> str:
     32     '''Reencodes the video given the path and saves it to the tmp_path folder.
     33 
     34     Args:
   (...)
     40         str: The path where the tmp file is stored. To be used to load the video from
     41     '''
---> 42     assert which_ffmpeg() != '', 'Is ffmpeg installed? Check if the conda environment is activated.'
     43     # assert video_path.endswith('.mp4'), 'The file does not end with .mp4. Comment this if expected'
     44     # create tmp dir if doesn't exist
     45     os.makedirs(tmp_path, exist_ok=True)

File D:\Work\DIff-Foley\Diff-Foley\inference\demo_util.py:26, in which_ffmpeg()
     20 def which_ffmpeg() -> str:
     21     '''Determines the path to ffmpeg library
     22 
     23     Returns:
     24         str -- path to the library
     25     '''
---> 26     result = subprocess.run(['which', 'ffmpeg'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
     27     ffmpeg_path = result.stdout.decode('utf-8').replace('\n', '')
     28     return ffmpeg_path

File D:\Software\Anaconda\envs\diff_foley\Lib\subprocess.py:548, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
    545     kwargs['stdout'] = PIPE
    546     kwargs['stderr'] = PIPE
--> 548 with Popen(*popenargs, **kwargs) as process:
    549     try:
    550         stdout, stderr = process.communicate(input, timeout=timeout)

File D:\Software\Anaconda\envs\diff_foley\Lib\subprocess.py:1026, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
   1022         if self.text_mode:
   1023             self.stderr = io.TextIOWrapper(self.stderr,
   1024                     encoding=encoding, errors=errors)
-> 1026     self._execute_child(args, executable, preexec_fn, close_fds,
   1027                         pass_fds, cwd, env,
   1028                         startupinfo, creationflags, shell,
   1029                         p2cread, p2cwrite,
   1030                         c2pread, c2pwrite,
   1031                         errread, errwrite,
   1032                         restore_signals,
   1033                         gid, gids, uid, umask,
   1034                         start_new_session, process_group)
   1035 except:
   1036     # Cleanup if the child failed starting.
   1037     for f in filter(None, (self.stdin, self.stdout, self.stderr)):

File D:\Software\Anaconda\envs\diff_foley\Lib\subprocess.py:1538, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, unused_restore_signals, unused_gid, unused_gids, unused_uid, unused_umask, unused_start_new_session, unused_process_group)
   1536 # Start the process
   1537 try:
-> 1538     hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
   1539                              # no special security
   1540                              None, None,
   1541                              int(not close_fds),
   1542                              creationflags,
   1543                              env,
   1544                              cwd,
   1545                              startupinfo)
   1546 finally:
   1547     # Child is launched. Close the parent's copy of those pipe
   1548     # handles that only the child should have open.  You need
   (...)
   1551     # pipe will not close when the child process exits and the
   1552     # ReadFile will hang.
   1553     self._close_pipe_fds(p2cread, p2cwrite,
   1554                          c2pread, c2pwrite,
   1555                          errread, errwrite)

FileNotFoundError: [WinError 2] The system cannot find the file specified

1 个回答

0

你需要把ffmpeg.exe放到一个路径里,可以通过环境变量或者在Python运行时修改sys.path来实现。

我知道有几个比较方便的替代方案。

  1. ffmpeg-downloader(我是开发者。)

这个包提供了一个类似pip的命令,可以下载最新版本的ffmpeg(还有其他版本)。它会把ffmpeg安装到用户的AppData目录,这样在多个Python虚拟环境(venv)中都能使用(或者其他一般用途)。

简单用法:

pip install ffmpeg-downloader
ffdl install --add-path

更多用法请查看这个库的readme。

  1. static-ffmpeg

这个则是把ffmpeg下载到当前的虚拟环境中。

如果你不使用虚拟环境,任意一个都可以用。如果你在多个项目中使用ffmpeg并且使用虚拟环境,我建议你使用第一个。

撰写回答