I'm looking to combine a range of different audio files (mp3) in Python. One of the requirements is that I need to be able to specify a delay at the end of each file. To illustrate, something like:
[file1.mp3--------3 seconds----------][delay---------2 seconds--------][file2.mp3]-------------4 seconds][delay---------2 seconds][file3.mp3----------3 seconds---------]
Does anyone here know of any mp3 libraries that can accomplish this? Python isn't really a necessity here. If it'll be easier in another language, that'll be fine.
I think FFmpeg can do this, given the right arguments. No real need to use a library.
To combine wav or aiff files, you can do something like this: (inspiration from here)
import aifc
def concatenate(*items):
data = []
for item in items:
f = aifc.open(item, 'rb')
data.append([f.getparams(), f.readframes(f.getnframes())])
f.close()
output = aifc.open('output.aif', 'wb')
output.setparams(data[0][0])
for item in data:
output.writeframes(item[1])
output.close()
See the link for the wav format (it's pretty much the same, but with the wave library)
To add silence, I would just make a one second silent file using your favorite audio editor and then concatenate in the proper amount of silence.
Related
I have a python script that pulls random audio clips from a hard drive. It finds wav and mp3 files and moviepy deals with them fine. When I added the aiff extensions to the search query I get this from moviepy...
codec = extensions_dict[ext[1:]]['codec'][0] KeyError: "'aiff'"
Does anyone know if moviepy specifically does not handle aiff audio?
Could there be a simple way to add aiff handling to moviepy?
Thanks for the head's up Tom. In case this can help someone else, here's what is working for me now.
for clip, title in audioClips.items(): #Iterate by key & value through the dictionary
#print(f"The title is {title}.")
if title.endswith('.aif') or title.endswith('aiff'):
clip.write_audiofile(dirpath+str(title),codec='pcm_s16le')
else:
clip.write_audiofile(dirpath+str(title))
clip.close()
Hi I have a question for Matlab programming, I want to ask if I am using Mac OS and I have placed all my audio files in the same folder as Matlab, how do I read all the .wav audio files? I want to automate the process.
Example:
Firstly, I have an excel sheet with the audio file name and information.
Secondly, I want to extract the audio file names from the excel sheet (first column) and put it into the audioread function in MatLab.
I need to use the following audioread function.
[y,Fs]=audioread('audio1.wav');
I want to read audio1.wav and do some calculations on it. After finishing the calculation, I will proceed to read audio2.wav and do the same calculation for it. Can you teach me how to do this and show me the code for this?
Thank you.
In Matlab you can read xls files with readmatrix. You are maybe best to export your spreadsheet of audio files to a csv file first.
With regard to organising the data, it would be easiest for the spreadsheet to contain the full pathname to the file (i.e. /path/from/root/to/file.wav)
So, say you had a audio_files.csv of file paths like
/path/to/file1.wav, file1data
/path/to/file2.wav, file2data
/path/to/file3.wav, file3data
You could read each file with something like
filename = 'audio_files.csv';
audio_file_list = readmatrix(filename);
for audio_file = audio_file_list(:,1) % so long as the first column is the file paths
[y,Fs]=audioread(audio_file);
% do something to y
end
Of course, the % do something to y will depend entirely on what you want to achieve.
I am able to use the moviepy library to add a watermark to a section of video. However when I do this it is taking the watermarked segment, and creating a new file with it. I am trying to figure out if it is possible to simply splice in the edited part back into the original video, as moviepy is EXTREMELY slow writing to the disk, so the smaller the segment the better.
I was thinking maybe using shutil?
video = mp.VideoFileClip("C:\\Users\\admin\\Desktop\\Test\\demovideo.mp4").subclip(10,20)
logo = (mp.ImageClip("C:\\Users\\admin\\Desktop\\Watermark\\watermarkpic.png")
.set_duration(20)
.resize(height=20) # if you need to resize...
.margin(right=8, bottom=8, opacity=0) # (optional) logo-border padding
.set_pos(("right","bottom")))
final = mp.CompositeVideoClip([video, logo])
final.write_videofile("C:\\Users\\admin\\Desktop\\output\\demovideo(watermarked).mp4", audio = True, progress_bar = False)
Is there a way to copy the 10 second watermarked snippet back into the original video file? Or is there another library that allows me to do this?
What is slow in your use case is the fact that Moviepy needs to decode and reencode each frame of the movie. If you want speed, I believe there are ways to ask FFMPEG to copy video segments without rencoding.
So you could use ffmpeg to cut the video into 3 subclips (before.mp4/fragment.mp4/after.mp4), only process fragment.mp4, then reconcatenate all clips together with ffmpeg.
The cutting into 3 clips using ffmpeg can be done from moviepy:
https://github.com/Zulko/moviepy/blob/master/moviepy/video/io/ffmpeg_tools.py#L27
However for concatenating everything together you may need to call ffmpeg directly.
is there any possibility of unmixing a file? I have use overlay to mix 2 audios, but I want to get back the original first audio. Is there something in pydub that I can use?
sound1 = AudioSegment.from_mp3("/path/to/file1.mp3")
sound2 = AudioSegment.from_mp3("/path/to/file2.mp3")
output = sound1.overlay(sound2, position=5000)
output.export("mixed_sounds.mp3", format="mp3")
The original audio in the sound1 variable has not been modified, so you can use it right away if you like.
If you mean recovering just the audio from sound1 from the exported “mixed_sounds.mp3” file, without acccess to the original data, that is not possible unless you know very specific things (for example if sound2 is silent and you know when sound1 starts and ends)
I have 2 functions as below:
def select_audio():
os.chdir("/home/norman/songbook")
top1.lower(root)
name=tkFileDialog.askopenfilename()
doit="play " + name
top1.lift(root)
os.system(doit)
def select_video():
os.chdir("/home/norman/Videos")
top2.lower(root)
name=tkFileDialog.askopenfilename()
doit="mpv --fs " + name
top2.lift(root)
os.system(doit)
They are selected from buttons to allow choosing and playing audio files or video files.
They work to some extent.
Videos are in a different directory and at the same level as the audio files.
It doesn't matter which I choose first I see the correct directory so I can play say a video, if after it's finished I choose audio it still shows the video directory.
Similarly if I first choose audio it still shows the audio directory if I select videos.
I have no idea why it does this. I am not an experienced programmer as you can probably tell from the code.
Some suggestions:
Use a raw string to make sure that Python doesn't try to interpret anything following a \ as an escape sequence:
Change os.chdir("/home/norman/whatever") to os.chdir(r"/home/norman/whatever")
It won't solve this problem, but it will avoid you future problems.
For tkFileDialog use the initialdir option:
Change name=tkFileDialog.askopenfilename() to
name=tkFileDialog.askopenfilename(initialdir=r"home/norman/whatever", parent=root)