FFMPEG mp3 to mu-law output delayed – Python subprocess w/ pipes
I am using a python subprocess and pipes to convert mp3 audio into mulaw. The basic problem is that i get about a 0.5second delay in the first output. The input is being piped in as one 45-byte ID3 header and 480-byte mp3 frames (each a “chunk” in the code). It seems to wait about 40+ frames/chunks before generating any mulaw output. After that it generates mulaw output pretty much with each input frame/chunk.
# This spins up a single ffmpeg process and uses pipes to write and read from the process.
# Current issue is that it wants a bunch of mp3 frames before it gives an audio back.
def convert_chunks(self, chunks: Iterable[bytes]) -> Iterable[bytes]:
# Start the persistent ffmpeg subprocess
ffmpeg_process = subprocess.Popen(
[
'ffmpeg',
# None of these options seem to help with the delay. One of them causes the first few seconds to be cut off.
# '-fflags', '+nobuffer', # Disable internal buffering
# '-flags', 'low_delay', # Enable low-latency processing
# '-flush_packets', '1', # Flush packets immediately
# '-max_delay', '0', # Eliminate additional delay
'-f',
'mp3', # Input format is MP3
'-i',
'pipe:0', # Read input from stdin
'-f',
'mulaw', # Output format is mu-law
'-ar',
'8000', # Set sample rate to 8000 Hz
'-ac',
'1', # Set audio channels to mono
'pipe:1',
], # Write output to stdout,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
# stderr=subprocess.DEVNULL # Suppress ffmpeg output for simplicity
)
# this is important to avoid blocking the read from ffmpeg stdout
os.set_blocking(ffmpeg_process.stdout.fileno(), False)
# input('Press Enter to continue...')
closed = False
try:
for chunk in chunks:
ffmpeg_process.stdin.write(chunk)
ffmpeg_process.stdin.flush()
audio = ffmpeg_process.stdout.read()
if audio:
yield audio
# we do want to block on the final read
os.set_blocking(ffmpeg_process.stdout.fileno(), True)
ffmpeg_process.stdin.close()
closed = True
audio = ffmpeg_process.stdout.read()
if audio:
yield audio
except Exception as ex:
print(f'convert_chunks exception: {ex}')
finally:
if not closed:
ffmpeg_process.stdin.close()
ffmpeg_process.wait()
There are obviously some other things i can look at (including the python code, and maybe run some trace-s on the process) but maybe somebody knows if this is a fundamental limit to how quickly i can get the mulaw out?
Read more here: Source link
