In my application I want to modify various mp3 and then mix them together. I know I could do it with a single command line in FFmpeg but It can end up very messy since I need to use various filter on each sample and I have five of them. My idea is to edit each sample individually, save them into a variable and finally mix them. This is my code:
import subprocess
def create_samp():
sample= subprocess.run(["ffmpeg", "-y", "-i", "https://freesound.org/data/previews/186/186942_2594536-hq.mp3", \
"-filter_complex", "adelay=15000|15000", "-codec:v", "copy", "-f", "mp3","-"], stdout=subprocess.PIPE)
return(sample)
def record(samp):
subprocess.run(["ffmpeg", "-y", "-i", "https://cdns-preview-b.dzcdn.net/stream/c-b0b684fe962f93dc43f1f7ea493683a1-3.mp3", \
"-i", samp.stdout, "-f", "-mp3", "copy", "output.mp3"])
samp = create_samp()
record(samp)
My issue is that I have to encode the stdout
. I've tried 'utf-8'
but got this error:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 45: invalid start byte
With `'utf-16':
UnicodeDecodeError: 'utf-16-le' codec can't decode bytes in position 239454-239455: illegal encoding
Why is the way to fix this issue? Is my approach the right one?
Thanks to @Rotem I succeed to do what I wanted to. But now I am facing an other issue, since I want to mix up to 5 sounds, I tried to implement it the lazy/easy way:
import subprocess
def create_samp_2():
sample= subprocess.run(["ffmpeg", "-i", "https://freesound.org/data/previews/186/186942_2594536-hq.mp3", \
"-af", "adelay=15000|15000", "-f", "mp3", "pipe:"], stdout=subprocess.PIPE).stdout
return(sample)
def create_samp():
sample= subprocess.run(["ffmpeg", "-i", "https://freesound.org/data/previews/370/370934_6399962-lq.ogg", \
"-af", "adelay=1000|1000", "-f", "mp3", "pipe:"], stdout=subprocess.PIPE).stdout
return(sample)
def record(samp, samp_2):
process = subprocess.Popen(["ffmpeg", "-y", '-f', 'mp3', \
"-i", "https://cdns-preview-b.dzcdn.net/stream/c-b0b684fe962f93dc43f1f7ea493683a1-3.mp3", \
"-i", "pipe:", \
"-i", "pipe:", \
"-filter_complex", "amix=inputs=3:duration=longest", "output.mp3"], stdin=subprocess.PIPE)
process.stdin.write(samp)
process.stdin.write(samp_2)
process.stdin.close()
process.wait()
samp = create_samp()
samp_2 = create_samp_2()
record(samp, samp_2)
Surprisingly it works, my two sounds start at the right time, but the second sound is messed up. So it's not the right way to do it.
Then I tried named pipes as suggested this way:
"pipe1:"
But I get this error:
pipe1:: Protocol not found
Did you mean file:pipe1:?
Reading named pipe wiki it is stated that I have to create them with mkfifo()
.
So I tried:
import os
pipe1 = "pipe1"
def create_pipe1():
os.mkfifo(pipe1)
But now I have this error: pipe1:: Protocol not found
Did you mean file:pipe1:?