subproceso “TypeError: se requiere un objeto de tipo bytes, no ‘str'”

Estoy usando este código de una pregunta previa hace unos años , sin embargo, creo que esto no está actualizado. Tratando de ejecutar el código, recibo el error anterior. Todavía soy un principiante en Python, así que no pude obtener mucha aclaración de preguntas similares. ¿Alguien sabe por qué ocurre esto?

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')) 

Rastrear

 Traceback (most recent call last): File "B:\Program Files\ffmpeg\bin\test3.py", line 7, in  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  return [x for x in result.stdout.readlines() if "Duration" in x] TypeError: a bytes-like object is required, not 'str' 

subprocess devuelve objetos de bytes para stdout o stderr streams de forma predeterminada. Eso significa que también necesita usar objetos de bytes en operaciones contra estos objetos. "Duration" in x usa el objeto str . Use un literal de bytes (note el prefijo b ):

 return [x for x in result.stdout.readlines() if b"Duration" in x] 

o decodifique sus datos primero, si conoce la encoding utilizada (por lo general, la configuración regional predeterminada, pero podría establecer LC_ALL o variables de entorno de configuración regional más específicas para el subproceso):

 return [x for x in result.stdout.read().decode(encoding).splitlines(True) if "Duration" in x] 

La alternativa es decirle a subprocess.Popen() que decodifique los datos a cadenas Unicode configurando el argumento de encoding a un códec adecuado:

 result = subprocess.Popen( ["ffprobe", filename], stdout=subprocess.PIPE, stderr = subprocess.STDOUT, encoding='utf8' ) 

Si establece text=True (Python 3.7 y superior, en versiones anteriores esta versión se llama universal_newlines ) también habilita la deencoding, utilizando el códec predeterminado del sistema , el mismo que se usa para open() llamadas open() . En este modo, las tuberías están en línea con búfer de forma predeterminada.

Como dice el error, “Duración” es una cadena. Mientras que, la X es un objeto similar a un byte como results.stdout.readlines() lee las líneas en la salida como bytecode y no como cadena.

Por lo tanto, almacene “Duración” en una variable, diga str_var y codifíquelo en un objeto de matriz de bytes usando str_var.encode('utf-8') .

Consulte [este] [1].

[1]: ¿La mejor forma de convertir cadenas a bytes en Python 3?