我正在使用a previously asked question a few years ago的代码,但是,我相信这已经过时了。试图运行代码,我收到上面的错误。我仍然是Python的新手,所以我无法从类似的问题中得到很多澄清。有谁知道为什么会这样?
import subprocess
def getLength(filename):
result = subprocess.Popen(["ffprobe", filename],
stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
return [x for x in result.stdout.readlines() if "Duration" in x]
print(getLength('bell.mp4'))
追溯
Traceback (most recent call last):
File "B:\Program Files\ffmpeg\bin\test3.py", line 7, in <module>
print(getLength('bell.mp4'))
File "B:\Program Files\ffmpeg\bin\test3.py", line 6, in getLength
return [x for x in result.stdout.readlines() if "Duration" in x]
File "B:\Program Files\ffmpeg\bin\test3.py", line 6, in <listcomp>
return [x for x in result.stdout.readlines() if "Duration" in x]
TypeError: a bytes-like object is required, not 'str'
subprocess
默认返回stdout或stderr流的bytes
对象。这意味着您还需要在针对这些对象的操作中使用bytes
对象。 "Duration" in x
使用str
对象。使用字节文字(注意b
前缀):
return [x for x in result.stdout.readlines() if b"Duration" in x]
或者首先解码您的数据,如果您知道使用的编码(通常,语言环境默认,但您可以为子进程使用set LC_ALL
or more specific locale environment variables):
return [x for x in result.stdout.read().decode(encoding).splitlines(True)
if "Duration" in x]
另一种方法是通过将subprocess.Popen()
参数设置为合适的编解码器,告诉encoding
将数据解码为Unicode字符串:
result = subprocess.Popen(
["ffprobe", filename],
stdout=subprocess.PIPE, stderr = subprocess.STDOUT,
encoding='utf8'
)
如果设置text=True
(Python 3.7及更高版本,在此版本中称为universal_newlines
),您还可以使用system default codec启用与open()
调用相同的解码。在此模式下,管道默认为行缓冲。
就像错误说的那样,“持续时间”是一个字符串。然而,X是像对象一样的字节,因为qazxsw poi将输出中的行读取为字节码而不是字符串。
因此,将“Duration”存储在变量中,比如str_var,并使用results.stdout.readlines()
将其编码为字节数组对象。
请参阅[this] [1]。
[1]:str_var.encode('utf-8')