如果你希望在使用subprocess.run调用FFmpeg转码视频时,能够看到FFmpeg的速度信息和进度更新,你需要采用不同的方法来运行FFmpeg命令,由于subprocess.run会等待命令执行完毕,只在最后提供输出和错误信息。
为了实时地看到FFmpeg的输出(包括速度信息),可以用subprocess.Popen取代subprocess.run,这个函数会创建一个新的进程,你可以与它的输出交互地方式来获取实时信息。
这里提供一个简单的例子,展示如何修改代码来实现以上的效果:
import subprocess
def transcode_video(input_file):
output_file = os.path.splitext(input_file)[0] + _hevc.mp4
ffmpeg_command = [
ffmpeg ,
# ...(其余参数)
output_file
]
# 使用Popen取代run,并设置stderr为STDOUT,以便可以获取FFmpeg的进度信息
process = subprocess.Popen(ffmpeg_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
# 实时读取输出信息
while True:
output = process.stdout.readline()
if not output and process.poll() is not None:
break
if output:
print(output.strip(), flush=True) # 打印实时信息
# 检查转码是否成功
if process.returncode != 0:
# 转码失败
print(f"转码失败:{input_file}")
else:
# 转码成功
print(f"转码完成:{output_file}")
# 使用这个修改过的函数,你将能够看到FFmpeg转码的实时速度信息
output = process.stdout.readline()
if not output and process.poll() is not None:
1. output = process.stdout.readline() 读取进程的标准输出,这一般包含了FFmpeg在工作时产生的输出信息。如果当前没有新的输出,也就是说output是空的,那么 if not output 这个条件会被满足。
2. process.poll() 会检查子进程(这里是FFmpeg进程)是否已经结束。如果进程已经结束,这个方法会返回子进程的退出码,否则返回 None。
因此,if not output and process.poll() is not None: 这一行的含义是:
• 如果当前没有新的输出信息(not output),并且
• FFmpeg进程已经结束(process.poll() 不是 None,表明进程已经有退出码)。
当这两个条件都满足的时候,循环将通过 break 结束。这意味着FFmpeg进程已完成其任务,没有更多的输出信息需要读取。这是一种在处理子进程的实时输出信息时常用的模式,它允许你的程序在子进程结束时停止读取输出。
解释这行代码
print(output.strip(), flush=True):
1. output.strip() 是对变量 output 调用 strip() 方法。这是Python字符串的一个方法,它会移除字符串开始和结束处的空白字符,包括空格、制表符、换行符等。这可以协助清理从进程中读出的每行输出,使其看起来更整洁。
2. print() 函数用来在控制台上打印出经过 strip 处理后的字符串。
3. flush=True 参数是对 print() 函数的一个额外配置,一般,print() 函数会把输出内容发送到缓冲区,直到缓冲区满或者流程结束时才会刷新(flush)缓冲区,将所有内容一次性输出到控制台。
○ 当 flush 设置为 True 时,它会指示 print() 函数在每次调用后立即刷新(清空)输出缓冲区,确保每一行输出立即出目前控制台上。这对于实时监控长时间运行的进程的输出超级有用,由于你可以立即看到每条新的输出信息,而不用等到程序运行结束。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...


