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 enter image description here

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 teniendo

    Respondida 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.8from 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 utiliza process.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.8from 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