Linux Mint下Python调用FFmpeg合并图片帧与音频失败求助
解决Python调用ffmpeg生成视频失败的问题
嘿,我来帮你搞定这个问题!你手动执行ffmpeg命令没问题,但Python调用就出状况,核心原因大概率是工作目录不匹配或者命令执行的细节没处理好,咱们一步步来排查和解决:
最可能的原因:相对路径的坑
你在终端执行命令时,当前工作目录应该是tmp文件夹的上级目录,所以tmp/%d.png和tmp/output.mov这些相对路径能被正确识别。但Python脚本运行时,它的当前工作目录可能和你终端的不一样(比如脚本在别的文件夹,或者IDE默认的工作目录不同),导致os.system找不到tmp/output.mov,而subprocess.call虽然没报错,但其实可能因为路径问题悄悄失败了(只是你没看到报错信息)。
具体解决方案
1. 先确认Python的工作目录
先在脚本里加一行代码,看看当前脚本运行时的工作目录:
import os print("当前工作目录:", os.getcwd())
对比一下你手动执行ffmpeg命令时的终端工作目录(终端里执行pwd就能看到),如果不一样,那就是路径问题没错了。
2. 用绝对路径替代相对路径(推荐)
把所有涉及到文件的路径都改成绝对路径,这样不管脚本在哪里运行都能找到文件。比如:
import subprocess import os # 获取tmp文件夹的绝对路径 tmp_dir = os.path.abspath("tmp") # 第一步:生成无音频视频 cmd1 = [ "ffmpeg", "-i", f"{tmp_dir}/%d.png", "-vcodec", "png", f"{tmp_dir}/output.mov", "-y" ] # 用subprocess.run捕获输出,方便调试 result1 = subprocess.run(cmd1, capture_output=True, text=True) if result1.returncode != 0: print("生成无音频视频出错:") print("输出信息:", result1.stdout) print("错误信息:", result1.stderr) else: print("无音频视频生成成功!") # 第二步:合并音频 cmd2 = [ "ffmpeg", "-i", f"{tmp_dir}/output.mov", "-i", f"{tmp_dir}/audio.mp3", "-codec", "copy", "output.mov", # 如果想把最终视频放tmp里,就改成f"{tmp_dir}/final_output.mov" "-y" ] result2 = subprocess.run(cmd2, capture_output=True, text=True) if result2.returncode != 0: print("合并音频出错:") print("输出信息:", result2.stdout) print("错误信息:", result2.stderr) else: print("最终视频合成成功!")
3. 或者切换工作目录再执行命令
如果你不想改路径,也可以让Python先切换到终端的工作目录,再执行命令:
import os import subprocess # 切换到你手动执行命令的目录(比如替换成你的实际路径) os.chdir("/path/to/your/working/directory") # 然后执行命令,用subprocess.run更靠谱 subprocess.run("ffmpeg -i tmp/%d.png -vcodec png tmp/output.mov -y", shell=True, capture_output=True, text=True) subprocess.run("ffmpeg -i tmp/output.mov -i tmp/audio.mp3 -codec copy output.mov -y", shell=True, capture_output=True, text=True)
不过这种方法不如绝对路径灵活,因为换了运行环境可能还要改路径。
4. 额外排查点
- ffmpeg路径问题:有时候Python环境里的ffmpeg路径和终端不一样,你可以在终端执行
which ffmpeg得到绝对路径,然后在Python命令里用这个绝对路径(比如"/usr/bin/ffmpeg")代替"ffmpeg"。 - 权限问题:检查
tmp文件夹的权限,确保运行Python的用户有读写权限(终端执行ls -ld tmp就能看权限)。
为什么推荐用subprocess.run而不是os.system/call?
os.system已经是比较老旧的方法了,它无法捕获命令的输出,出错了你也看不到原因;subprocess.call虽然比os.system好,但subprocess.run是Python 3.5+推荐的方法,能更方便地捕获输出、检查返回码,调试起来轻松多了。
内容的提问来源于stack exchange,提问作者muh.widad
相关产品推荐
相关产品推荐

