compare a audio file (edited) to a video file (not edited) and remove the difference in python - audio

I am very new to python programming
I am suck at this problem kindly help
I have so much data from recorded audios and videos
audios and videos are recorded in the same environment at the same time.
someone only edited the audio files and removed all the mistakes from them. but video files are not edited I want this this code to remove the difference (mistakes present in video file) between them and its not working.
code:
import numpy as np
import soundfile as sf
import moviepy.editor as mp
def remove_difference(audio_file, video_file):
# read audio file
data1, rate1 = sf.read(audio_file, dtype='int16')
# get audio data from video file
video = mp.VideoFileClip(video_file)
audio = video.audio
data2, rate2 = sf.read(audio.fps==rate1)
# ensure audio files have same sample rate and same length
if rate1 != rate2:
raise ValueError("Sample rates of audio files do not match")
if data1.shape[0] != data2.shape[0]:
min_length = min(data1.shape[0], data2.shape[0])
data1 = data1[:min_length]
data2 = data2[:min_length]
# calculate difference between audio files
difference = data1 - data2
# remove difference from audio1
data1 = data1 - difference
# create a new video clip with the modified audio
new_audio = mp.AudioClip(data1, fps=rate1)
final_video = mp.VideoClip(lambda t: video.get_frame(t), audio=new_audio)
# save new video file
final_video.write_videofile("output.mp4", fps=video.fps)
# example usage
remove_difference("audio1.wav", "video2.mp4")

Related

Need to use python to convert media files to mp3 files

import moviepy.editor as m
import os
for i in os.listdir():
if i == ".mpeg": #How do I make that work(I know it can't, I just have it there to explain what I need)
video = m.VideoFileClip(i)
video.audio.write_audiofile(i)
Need it to sort through files, find the media ones, and change them to .mp3
Here's how I would change your code. Extract the filename and extension, use the extension to filter files and use the filename to create a new filename with the .mp3 extension. This makes sure you don't overwrite your source video file with audio.
import moviepy.editor as m
import os
for file_path in os.listdir():
filename, file_extension = os.path.splitext(file_path)
if file_extension == ".mpeg":
video = m.VideoFileClip(file_path)
audio_file_path = filename + ".mp3"
video.audio.write_audiofile(audio_file_path)

Convert multiple MP3 files to WAV in python

I want to convert multiple MP3 audio files in a folder to WAV format (with mono type) using python code.
I tried the below code using pydub:
import os
from pydub import AudioSegment
audio_files = os.listdir('path')
# Folder is having audio files of both MP3 and WAV formats
len_audio=len(audio_files)
for i in range (len_audio):
if os.path.splitext(audio_files[i])[1] == ".mp3":
mp3_sound = AudioSegment.from_mp3(audio_files[i])
mp3_sound.export("<path>\\converted.wav", format="wav")
I am getting how will i export the converted wav file with different file names.
please suggest
I would do something like:
import os
from pydub import AudioSegment
path = "the path to the audio files"
#Change working directory
os.chdir(path)
audio_files = os.listdir()
# You dont need the number of files in the folder, just iterate over them directly using:
for file in audio_files:
#spliting the file into the name and the extension
name, ext = os.path.splitext(file)
if ext == ".mp3":
mp3_sound = AudioSegment.from_mp3(file)
#rename them using the old name + ".wav"
mp3_sound.export("{0}.wav".format(name), format="wav")
You can find more about the format mini language here.
This is simply just changing the extension name of multiple files
import os
from pathlib import Path
path = "the path to the audio files"
#Change working directory
os.chdir(path)
audio_files = os.listdir()
for file in audio_files:
p = Path(file)
p.rename(p.with_suffix('.wav'))

Retrieve exif data from thousands of images fast - optimising function

I've written script that retrieves specific fields of exif data from thousands of images in a directory (including subdirectories) and saves the info to a csv file:
import os
from PIL import Image
from PIL.ExifTags import TAGS
import csv
from os.path import join
####SET THESE!###
imgpath = 'C:/x/y' #Path to folder of images
csvname = 'EXIF_data.csv' #Name of saved csv
###
def get_exif(fn):
ret = {}
i = Image.open(fn)
info = i._getexif()
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
ret[decoded] = value
return ret
exif_list = []
path_list = []
filename_list = []
DTO_list = []
MN_list = []
for root, dirs, files in os.walk(imgpath, topdown=True):
for name in files:
if name.endswith('.JPG'):
pat = join(root, name)
pat.replace(os.sep,"/")
exif = get_exif(pat)
path_list.append(pat)
filename_list.append(name)
DTO_list.append(exif['DateTimeOriginal'])
MN_list.append(exif['MakerNote'])
zipped = zip(path_list, filename_list, DTO_list, MN_list)
with open(csvname, "w", newline='') as f:
writer = csv.writer(f)
writer.writerow(('Paths','Filenames','DateAndTime','MakerNotes'))
for row in zipped:
writer.writerow(row)
However, it is quite slow. I've attempted to optimise the script for performance + readabilty by using list and dictionary comprehensions.
import os
from os import walk #Necessary for recursive mode
from PIL import Image #Opens images and retrieves exif
from PIL.ExifTags import TAGS #Convert exif tags from digits to names
import csv #Write to csv
from os.path import join #Join directory and filename for path
####SET THESE!###
imgpath = 'C:/Users/au309263/Documents/imagesorting_testphotos/Finse/FINSE01' #Path to folder of images. The script searches subdirectories as well
csvname = 'PLC_Speedtest2.csv' #Name of saved csv
###
def get_exif(fn): #Defining a function that opens an image, retrieves the exif data, corrects the exif tags from digits to names and puts the data into a dictionary
i = Image.open(fn)
info = i._getexif()
ret = {TAGS.get(tag, tag): value for tag, value in info.items()}
return ret
Paths = [join(root, f).replace(os.sep,"/") for root, dirs, files in walk(imgpath, topdown=True) for f in files if f.endswith('.JPG' or '.jpg')] #Creates list of paths for images
Filenames = [f for root, dirs, files in walk(imgpath, topdown=True) for f in files if f.endswith('.JPG' or '.jpg')] #Creates list of filenames for images
ExifData = list(map(get_exif, Paths)) #Runs the get_exif function on each of the images specified in the Paths list. List converts the map-object to a list.
MakerNotes = [i['MakerNote'] for i in ExifData] #Creates list of MakerNotes from exif data for images
DateAndTime = [i['DateTimeOriginal'] for i in ExifData] #Creates list of Date and Time from exif data for images
zipped = zip(Paths, Filenames, DateAndTime, MakerNotes) #Combines the four lists to be written into a csv.
with open(csvname, "w", newline='') as f: #Writes a csv-file with the exif data
writer = csv.writer(f)
writer.writerow(('Paths','Filenames','DateAndTime','MakerNotes'))
for row in zipped:
writer.writerow(row)
However, this has not changed the performance.
I've timed the specific regions of the code and found that specifically opening each image and getting the exif data from each image in the get_exif function is what takes time.
To make the script faster,I'm wondering if:
1) It is possible to optimise on the performance of the function?, 2) It is possible to retrive exif data without opening the image?, 3) list(map(fn,x)) is the fastest way of applying the funtion?
If read the docs in the right way PIL.Image.open() does not only extracts the EXIF data from the file but also reads and decodes the entire image, which probably is the bottleneck here. The first thing I would do would be to change to a library or routine that only works on the EXIF data and does not care for the image content. ExifRead or piexif might be worth a try.

Python adding files from URL to file on local file

I am trying to combine two files from the internet, and save the output on my computer. I have the below code,but no made what I try I always get the same result. I get the first URL, and nothing more.
To be exact, I am trying to comebine VideoURL and videoURL1, together into one file called output.mp4...
videoURL= 'http://file-examples.com/wp-content/uploads/2017/04/file_example_MP4_480_1_5MG.mp4'
videoURL1 = 'http://techslides.com/demos/sample-videos/small.mp4'
# print(str(embeddHTMLString).find('sources: ['))
local_filename = videoURL.split('/')[-1]
# NOTE the stream=True parameter
response = urlopen(videoURL)
response1 = urlopen(videoURL1)
with open(local_filename, 'wb') as f:
while True:
chunk = response.read(1024)
if not chunk:
break
f.write(chunk)
with open(local_filename, 'ab+') as d:
while True:
chunk1 = response1.read(1024)
if not chunk1:
break
d.write(chunk1)
You're doing it wrong. The gist of this answer has already been given by #Tempo810, you need to download the files separately and concatenate them into a single file later.
I am assuming you have both video1.mp4 and video2.mp4 downloaded from your urls separately. Now to combine them, you simply cannot use append to concat the files, since video files contains format header and metadata, and combining two media files into one means you need to rewrite new metadata and format header, and remove the old ones.
Instead you can use the the library moviepy to save yourself. Here is a small sample of code how to utilise moviepy's concatenate_videoclips() to concat the files:
from moviepy.editor import VideoFileClip, concatenate_videoclips
# opening the clips
clip1 = VideoFileClip("video1.mp4")
clip3 = VideoFileClip("video2.mp4")
# lets concat them up
final_clip = concatenate_videoclips([clip1,clip2])
final_clip.write_videofile("output.mp4")
Your resulting combined file is output.mp4. Thats it!

How do I convert a 4 channel stereo file to mono in Python

How do I convert a 4 channel stereo file to mono in Python, preferably using pydub? Thanks in advance
From the pydub documentation, I suppose you can try something like that:
from pydub import AudioSegment
song = AudioSegment.from_wav("example.wav") #read wav
song.export("out.wav", parameters=["-ac", "1"]) # export wav (1 channel)
As I understand the documentation, the values of "parameters" is based on the ffmpeg documentation (audio options). So you can use all parameters from ffmpeg. Here, I just set the number of audio channels to 1.
In addition to #Patrice answer, as per this discussion on github pydub repo, export returns without executing ffmpeg with parameters if format is wav.
You may need to modify pydub.AudioSegment as below in order for ffmpeg to actually execute with optional parameters provided in export.
Changing line 600
if format == "wav":
data = out_f
else:
data = NamedTemporaryFile(mode="wb", delete=False)
to:
if format == "wav" and parameters is None:
data = out_f
else:
data = NamedTemporaryFile(mode="wb", delete=False)
And line 616:
if format == 'wav':
return out_f
to:
if format == 'wav' and parameters is None:
return out_f
Then ffmpeg accepts parameters and processes accordingly .
I don't have a "quadrophonic" audio sample to test this "theory", if you can upload to your github issue tracker , above can be tested.
Let me know.

Resources