【问题标题】:"TypeError: byte indices must be integers or slices, not str" Converting bytes to ints“TypeError:字节索引必须是整数或切片,而不是 str”将字节转换为整数
【发布时间】:2016-02-19 19:40:18
【问题描述】:

我正在使用不同的程序 (ffmpeg) 来获取已下载的 youtube 视频的长度,以便随机化视频中的特定点。但是,当我尝试执行此代码时出现此错误:

def grabTimeOfDownloadedYoutubeVideo(youtubeVideo):
    process = subprocess.Popen(['/usr/local/bin/ffmpeg', '-i', youtubeVideo], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    stdout, stderr = process.communicate()
    matches = str(re.search(b"Duration:\s{1}(?P<hours>\d+?):(?P<minutes>\d+?):(?P<seconds>\d+\.\d+?),", stdout, re.DOTALL).groupdict()).encode()
    print(matches)
    hours = int(matches['hours'])
    minutes = int(matches['minutes'])
    seconds = int(matches['seconds'])
    total = 0
    total += 60 * 60 * hours
    total += 60 * minutes
    total += seconds
    print(total)

matches 变量打印出来:

b"{'minutes': b'04', 'hours': b'00', 'seconds': b'24.94'}"

所以所有的输出都以'b'开头。如何删除“b”并获取数字?

这里有完整的错误信息:

Traceback (most recent call last):
  File "bot.py", line 87, in <module>
    grabTimeOfDownloadedYoutubeVideo("videos/1.mp4")
  File "bot.py", line 77, in grabTimeOfDownloadedYoutubeVideo
    hours = int(matches['hours'])
TypeError: byte indices must be integers or slices, not str

【问题讨论】:

标签: python ffmpeg


【解决方案1】:
matches = str(re.search(b"Duration:\s{1}(?P<hours>\d+?):(?P<minutes>\d+?):(?P<seconds>\d+\.\d+?),", stdout, re.DOTALL).groupdict()).encode()

很奇怪。通过将正则表达式匹配的结果转换为字符串,您会导致错误(因为现在matches['hours'] 将失败)。

通过将该字符串编码为bytes 对象(为什么?),您会使事情变得更加复杂。

matches = re.search(r"Duration:\s(?P<hours>\d+?):(?P<minutes>\d+?):(?P<seconds>\d+\.\d+?),", stdout).groupdict()

应该这样做(虽然我不确定是否使用stdout 作为输入...)

【讨论】:

  • 感谢您的回复!我实际上将它转换为读取此答案的字节对象stackoverflow.com/questions/5184483/python-typeerror-on-regex 这是以某种方式让我克服该错误的答案,并认为这可能是我所要求的更简单的解决方案
  • 每当我使用你使用的东西时,我都会得到另一个 TypeError TypeError: cannot use a string pattern on a bytes-like object
  • 这可能是因为您正在访问stdout。您需要.decode() 使用正确的编码(这取决于您的平台)。如果幸运的话,使用 str(stdout) 代替 stdout 已经可以了。
  • 更好的是,使用universal_newlines=True 选项调用Popen。这样,您将获得字符串而不是 bytes 对象,这些对象已经使用系统编码进行了转换。
  • 感谢蒂姆的帮助。
【解决方案2】:

您那里似乎有一个byte 对象。为了使用它,您可以执行以下操作**:

解码:

matches = matches.decode("utf-8")

然后,通过使用 ast.literal_eval,将 str 转换为真正的 dict

matches = ast.literal_eval(matches)

然后你可以像往常一样访问匹配的内容:

int(matches['hours']) # returns 0

**当然,这只是修复了一个错误,正如@Tim 指出的那样,一开始就不应该出现在这里。

【讨论】:

  • 这不是完全倒退吗?他自己创建了 bytes 对象,原因不明。
  • 当然,我只是填写此内容,因为标题表明错误始终可以按照我建议的步骤进行修复。
猜你喜欢
  • 2019-02-05
  • 1970-01-01
  • 1970-01-01
  • 2017-11-06
  • 2021-06-29
  • 1970-01-01
  • 2015-12-09
  • 2021-11-28
  • 2017-03-11
相关资源
最近更新 更多