Subproceso de pitón. Popen + ffmpeg rompe la entrada terminal
Estaba escribiendo un módulo para crear capturas de pantalla aleatorias de un vídeo y utilizado subprocess.Popen
ejecutar múltiples comandos en paralelo, pero esto conduce a terminal negándose a mostrar cualquier entrada una vez que el programa de pitón se termine de ejecutar. Pero todavía acepta la mayoría de las entradas dadas desde el teclado simplemente no lo muestra.
Sólo si escribo el reset
terminal de comando comienza a funcionar bien
Esto sucedió en ssh con putty y otros clientes ssh incluso ssh con powershell en ventanas y corriendo directamente en terminal con VNC
Pero sin ssh ejecutar directamente el mismo comando en ventanas ssh funciona bien y las entradas son visibles
aquí hay un ejemplo para lo que está pasando
y código para replicarlo
#!/usr/bin/env python3.8
from subprocess import Popen
def create_screenshots():
commands = ['ffmpeg -hide_banner -loglevel panic -ss 329 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.329.frame.png"',
'ffmpeg -hide_banner -loglevel panic -ss 312 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.312.frame.png"',
'ffmpeg -hide_banner -loglevel panic -ss 533 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.533.frame.png"',
'ffmpeg -hide_banner -loglevel panic -ss 444 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.444.frame.png"',
'ffmpeg -hide_banner -loglevel panic -ss 411 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.411.frame.png"',
'ffmpeg -hide_banner -loglevel panic -ss 413 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.413.frame.png"']
screenshot_files = []
processes = [Popen(command, shell=True) for command in commands]
for process in processes:
process.wait()
return screenshot_files
create_screenshots()
Pregunta hecha hace 3 años, 5 meses, 1 días - Por quantumquasar
3 Respuestas:
-
Después de semanas de búsqueda finalmente encontró la respuesta a este derecho después de publicar la pregunta
esta respuesta es lo que estaba buscando https://stackoverflow.com/a/59148094
no seguro si hay una mejor manera de manejar esto con Popen pero añadir
-nostdin
bandera al mando de ffmpeg arregló el tema que estaba teniendoRespondida el Dec 16, 2020 a las 19:05 - por codesculptor3f6e
Votos positivos: 0 | Votos negativos: 0 -
El problema que estás experimentando parece estar relacionado con la forma en que se están ejecutando los comandos ffmpeg con subprocess.Popen y cómo interactúa con la terminal. Al utilizar
shell=True
, estás pasando una cadena de comandos al shell para su ejecución, lo cual puede estar causando que la terminal se comporte de forma inesperada al finalizar la ejecución de los comandos.Una posible solución es modificar ligeramente tu código para evitar este problema. En lugar de ejecutar los comandos ffmpeg de esa manera, puedes usar directamente el módulo subprocess y pasar los argumentos como una lista de cadenas, en lugar de una cadena completa que se pasa al shell.
Aquí te muestro un ejemplo de cómo podrías modificar tu código:
python
!/usr/bin/env python3.8 from subprocess import Popen, PIPE def create_screenshots(): commands = [['ffmpeg', '-hide_banner', '-loglevel', 'panic', '-ss', '329', '-i', '/home/user/file.mkv', '-y', '-vframes', '1', '/home/user/file.329.frame.png'], ['ffmpeg', '-hide_banner', '-loglevel', 'panic', '-ss', '312', '-i', '/home/user/file.mkv', '-y', '-vframes', '1', '/home/user/file.312.frame.png'], ['ffmpeg', '-hide_banner', '-loglevel', 'panic', '-ss', '533', '-i', '/home/user/file.mkv', '-y', '-vframes', '1', '/home/user/file.533.frame.png'], ['ffmpeg', '-hide_banner', '-loglevel', 'panic', '-ss', '444', '-i', '/home/user/file.mkv', '-y', '-vframes', '1', '/home/user/file.444.frame.png'], ['ffmpeg', '-hide_banner', '-loglevel', 'panic', '-ss', '411', '-i', '/home/user/file.mkv', '-y', '-vframes', '1', '/home/user/file.411.frame.png'], ['ffmpeg', '-hide_banner', '-loglevel', 'panic', '-ss', '413', '-i', '/home/user/file.mkv', '-y', '-vframes', '1', '/home/user/file.413.frame.png']] screenshot_files = [] processes = [Popen(command, stdout=PIPE, stderr=PIPE) for command in commands] for process in processes: out, err = process.communicate() if process.returncode == 0: screenshot_files.append(out) return screenshot_files create_screenshots()En este código, cada comando ffmpeg se pasa como una lista de argumentos, lo que evita la necesidad de usar
shell=True
. Además, se utilizaprocess.communicate()
para capturar la salida estándar y el error de cada proceso. Finalmente, se verifica el código de retorno del proceso y se maneja la salida según sea necesario.Espero que esta modificación te ayude a resolver el problema que estás experimentando con la terminal. ¡Házmelo saber si tienes alguna otra pregunta!
Respondida el Dec 17, 2020 a las 19:02 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El problema que estás experimentando se debe a que los subprocesos creados por
subprocess.Popen
no están heredando correctamente el descriptor de archivo de entrada del proceso principal. Como resultado, cuando los subprocesos intentan leer la entrada, se bloquean, lo que impide que la terminal muestre las pulsaciones de teclas.Para solucionar este problema, puedes utilizar el argumento
stdin=subprocess.PIPE
al crear los subprocesos. Esto creará una tubería entre el proceso principal y los subprocesos, lo que permitirá a los subprocesos leer la entrada del proceso principal.Aquí tienes el código actualizado:
python
!/usr/bin/env python3.8 from subprocess import Popen def create_screenshots(): commands = ['ffmpeg -hide_banner -loglevel panic -ss 329 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.329.frame.png"', 'ffmpeg -hide_banner -loglevel panic -ss 312 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.312.frame.png"', 'ffmpeg -hide_banner -loglevel panic -ss 533 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.533.frame.png"', 'ffmpeg -hide_banner -loglevel panic -ss 444 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.444.frame.png"', 'ffmpeg -hide_banner -loglevel panic -ss 411 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.411.frame.png"', 'ffmpeg -hide_banner -loglevel panic -ss 413 -i "/home/user/file.mkv" -y -vframes 1 "/home/user/file.413.frame.png"'] screenshot_files = [] processes = [Popen(command, shell=True, stdin=subprocess.PIPE) for command in commands] for process in processes: process.wait() return screenshot_files create_screenshots()Respondida el Dec 17, 2020 a las 19:11 - por Gemini
Votos positivos: 0 | Votos negativos: 0