question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

console breaks when running in parallel

See original GitHub issue

I am calling the following code inside the job of an pool.imap_unordered:

    data, _ = (ffmpeg
               .input(filename)
               .output('pipe:', format=format, acodec=acodec, ac=ac, ar=sr)
               .run(capture_stdout=True, capture_stderr=True))

in order to load a lot of audio in parallel. It seems to work correctly, but when it’s done running I can’t type in the console anymore. Or rather, the text I type does not appear, but when I hit return the commands are still executed.

If I run the script inside screen and then exit the screen, the original console works.

Is there another way that I should be running ffmpeg-python when using multiprocessing?

Looking at this issue https://askubuntu.com/questions/171449/shell-does-not-show-typed-in-commands-reset-works-but-what-happened my situation matches it very closely. Before I run the script the result of stty --all is:

speed 9600 baud; rows 33; columns 197; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O;
min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

and after it is:

speed 9600 baud; rows 33; columns 197; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O;
min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig -icanon -iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

echo is one of the options that switches from true to false. But I can’t find what in the ffmpeg-python library causes this.

Previously I had written my own wrapper to ffmpeg https://github.com/kylemcdonald/python-utils/blob/master/ffmpeg_load_audio.py I didn’t notice this problem before. But I just did some more testing and it has the same bug. Which means it’s something pretty basic about running Popen in threads.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

10reactions
vguzovcommented, May 4, 2020

Hi, Just wanted to say that adding '-nostdin' to .global_args() in reader processes fixed the issue with terminal for me.

3reactions
kylemcdonaldcommented, Aug 3, 2019

Hi 👋I’m back again.

I found an example that doesn’t use any threads outside the library, just run_async. I think this could give a clue of what’s going on:

import ffmpeg
import numpy as np

in1_filename = 'ch03.mp4'
in2_filename = 'ch04.mp4'
out_filename = 'ch03+04.mp4'
width = 3072
height = 3072

process1 = (
    ffmpeg
    .input(in1_filename)
    .output('pipe:', format='rawvideo', pix_fmt='rgb24', vframes=8)
    .global_args('-hide_banner', '-nostats', '-loglevel', 'panic')
    .run_async(pipe_stdout=True)
)

process2 = (
    ffmpeg
    .input(in2_filename)
    .output('pipe:', format='rawvideo', pix_fmt='rgb24', vframes=8)
    .global_args('-hide_banner', '-nostats', '-loglevel', 'panic')
    .run_async(pipe_stdout=True)
)

process3 = (
    ffmpeg
    .input('pipe:', format='rawvideo', pix_fmt='rgb24', s='{}x{}'.format(width*2, height))
    .output(out_filename, pix_fmt='yuv420p')
    .global_args('-hide_banner', '-nostats', '-loglevel', 'panic')
    .overwrite_output()
    .run_async(pipe_stdin=True)
)

print('Running')

while True:
    in1_bytes = process1.stdout.read(width * height * 3)
    in2_bytes = process2.stdout.read(width * height * 3)

    if not in1_bytes:
        break
    in1_frame = (
        np
        .frombuffer(in1_bytes, np.uint8)
        .reshape([height, width, 3])
    )

    if not in2_bytes:
        break
    in2_frame = (
        np
        .frombuffer(in2_bytes, np.uint8)
        .reshape([height, width, 3])
    )

    out_frame = np.hstack((in1_frame, in2_frame))

    process3.stdin.write(
        out_frame
        .astype(np.uint8)
        .tobytes()
    )

process1.wait()
process2.wait()
process3.stdin.close()
process3.wait()

This code stacks two videos side by side (you wouldn’t want to do it this way of course, it’s just an example). The snippet above works. But if you move this line down:

    in2_bytes = process2.stdout.read(width * height * 3)

So it appear after the break from not in2_bytes, then the terminal gets messed up. Even though we know process2.stdout.read is going to return None, we need to call it for it to properly make the terminal go back to normal.

If you have some script that is too complicated to figure out where this is happening, you can also add this to the end of your script:

import subprocess
subprocess.run(['stty', 'echo'])

And it will return the terminal to normal even if there’s some async code that has messed it up somehow.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Not sure if code runs in parallel. Tasks in console application
As far as I know when you start a task it runs in parallel so all the tasks should run in parallel. A...
Read more >
Debug a parallel application - Visual Studio (Windows)
This walkthrough provides sample code that has built-in breakpoints. After the code breaks, the walkthrough shows how to use the Parallel Tasks ...
Read more >
Debugging in Visual Studio Code
To run or debug a simple app in VS Code, select Run and Debug on the Debug ... does not "break" into the...
Read more >
Promise.all() - JavaScript - MDN Web Docs
console.log(values); ... We can use Promise.all to run them in parallel, so that the user doesn't have to wait for the prices to...
Read more >
JetBrains Rider - Debug multithreaded applications
Run, debug, test, deploy ... Parallel Stacks pane simplifies threads analysis by showing threads and ... JetBrains Rider: Parallel stacks.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found