FileNotFoundError: [WinError 2] 系统找不到指定的文件 - FFMPEG
我在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
来实现。
我知道有几个比较方便的替代方案。
ffmpeg-downloader
(我是开发者。)
这个包提供了一个类似pip的命令,可以下载最新版本的ffmpeg(还有其他版本)。它会把ffmpeg安装到用户的AppData目录,这样在多个Python虚拟环境(venv)中都能使用(或者其他一般用途)。
简单用法:
pip install ffmpeg-downloader
ffdl install --add-path
更多用法请查看这个库的readme。
这个则是把ffmpeg下载到当前的虚拟环境中。
如果你不使用虚拟环境,任意一个都可以用。如果你在多个项目中使用ffmpeg并且使用虚拟环境,我建议你使用第一个。