I have a list of WAV files in a folder of data showing in the format of hours, minutes and second.
For example,
C:\Users\Desktop\Data
01h02m02s.wav
01h02m13s.wav
01h02m24s.wav
I need the filename to be modified, programmatically such that it needs to be converted into seconds. How do I do it?
3722s.wav
3733s.wav
3744s.wav
Would appreciate all feedback and help.
Thank you
Use glob.glob() to get your file list and then an regular expression to try and extract the hours, minutes and seconds from the filename. os.rename() is used to actually rename the file:
import glob
import re
import os
path = r'C:\Users\Desktop\Data'
for wav in glob.glob(os.path.join(path, '*.wav')):
re_hms = re.findall(r'(\d+)h(\d+)m(\d+)s\.wav', wav)
if re_hms:
hours, minutes, seconds = map(int, re_hms[0])
total_seconds = hours * 3600 + minutes * 60 + seconds
new_wav = os.path.join(path, '{}s.wav'.format(total_seconds))
print "{} -> {}".format(wav, new_wav)
os.rename(wav, new_wav)
os.path.join() is used to safely join file paths together without having to worry about adding path separators.
You could use this if all the files in the path are WAV and their names have the pattern as shown by you.
import os
path = r'C:\Users\Desktop\Data'
waves = os.listdir(path)
for wave in waves:
hours, minutes, seconds = map(int, [wave[:2], wave[3:5], wave[6:8]])
total_seconds = hours * 3600 + minutes * 60 + seconds
new_name = os.path.join(path, "{}s.wav".format(total_seconds))
os.rename(os.path.join(path, wave), new_name)
Related
i have a script to play a random wav file from a folder works good but Il like it to only play between 9am and 5pm not sure how to do that
Thanks
from os.path import isfile, join
import random
#path you want to get wav files from
path = "C:\Windows\Media"
onlyfiles = [ f for f in listdir(path) if isfile(join(path,f)) ]
onlywavfiles = []
for f in onlyfiles:
if f[-3:] == "wav":
onlywavfiles.append(f)
#generate random number based on number of available files
randomnum = random.randint(0,len(onlywavfiles)-1)
eg.plugins.System.PlaySound(path + "/" + onlywavfiles[randomnum], 1, False)
Because you did not say what triggers that script, I' ll have to guess.
I guess: The script is triggered by an event from your home automation. Perhaps someone rings the bell, or Balto requests his meal, or a fish jumps out of the aquarium.
That triggers an event and starts the script. The script plays a random wav file from the Media folder.
But you don't want the music to be played outside the interval you specified.
It doesn't matter, if the script is still executed/triggered, only the sound must not be played.
You could simply read the time, extract the hour and test 9 < hour or hour > 16
and return from the script before the sound is played if the test is true.
(I'm from Germany so we have 24 hour time. I dont know how python returns hours for 12 hr systems.)
from os.path import isfile, join
import random
import datetime
hr = datetime.datetime.now().hour
if hr < 9 or hr > 16:
exit()
#path you want to get wav files from
path = "C:\Windows\Media"
onlyfiles = [ f for f in listdir(path) if isfile(join(path,f)) ]
onlywavfiles = []
for f in onlyfiles:
if f[-3:] == "wav":
onlywavfiles.append(f)
#generate random number based on number of available files
randomnum = random.randint(0,len(onlywavfiles)-1)
eg.plugins.System.PlaySound(path + "/" + onlywavfiles[randomnum], 1, False)
import os
src = "/home/user/Desktop/images/"
ext = ".jpg"
for i,filename in enumerate(os.listdir(src)):
# print(i,filename)
if filename.endswith(ext):
os.rename(src + filename, src + str(i) + ext)
print(filename, src + str(i) + ext)
else :
os.remove(src + filename)
this code will rename all the images in a folder starting with 0.jpg,1.jpg etc... and remove none jpg but what if i already had some images in that folder, let's say i had images 0.jpg, 1.jpg, 2.jpg, then i added a few others called im5.jpg and someImage.jpg.
What i want to do is adjust the code to read the value of the last image number, in this case 2 and start counting from 3 .
In other words i'll ignore the already labeled images and proceed with the new ones counting from 3.
Terse and semi-tested version:
import os
import glob
offset = sorted(int(os.path.splitext(os.path.basename(filename))[0])
for filename in glob.glob(os.path.join(src, '*' + ext)))[-1] + 1
for i, filename in enumerate(os.listdir(src), start=offset):
...
Provided all *.jpg files consist of a only a number before their extension. Otherwise you will get a ValueError.
And if there happens to be a gap in the numbering, that gap will not be filled with new files. E.g., 1.jpg, 2.jpg, 3.jpg, 123.jpg will continue with 124.jpg (which is safer anyway).
If you need to filter out filenames such as im5.jpg or someImage.jpg, you could add an if-clause to the list comprehension, with a regular expression:
import os
import glob
import re
offset = sorted(int(os.path.splitext(os.path.basename(filename))[0])
for filename in glob.glob(os.path.join(src, '*' + ext))
if re.search('\d+' + ext, filename))[-1] + 1
Of course, by now the three lines are pretty unreadable, and may not win the code beauty contest.
Im trying to write a basic program that picks 2 audio files at random, layers them, and writes it out as a new file. I'm using pydub and it all works, however the results are distorted. I suspect it's because from what I've learnt, pydub cannot handle 24 bit wavs, which happen to be the norm in sample packs.
So needing some small blip of code that converts the wav to 16 bit before it enters pydub. Hopefully not one that requires writing it to disc first.
from pydub import AudioSegment
import os
import random
import shutil
def process(user_folder):
new_library_folder = user_folder + " Generated Combo Samples"
files_list = []
for root, directory, files in os.walk(user_folder):
for file in files:
if file_is_valid_ext(file):
filepath = str(root) + "/" + str(file)
# print filepath
files_list.append(filepath)
# removes previously created folder
shutil.rmtree(new_library_folder)
os.makedirs(new_library_folder)
i = 0
for number in range(gen_count): # global at 100
i = i + 1
file1 = random.choice(files_list)
file2 = random.choice(files_list)
sound1 = AudioSegment.from_file(file1)
sound2 = AudioSegment.from_file(file2)
sound1 = match_target_amplitude(sound1, -20)
sound2 = match_target_amplitude(sound2, -20)
combinedsound = sound1.overlay(sound2)
combinedsoundnormalised = match_target_amplitude(combinedsound, -6)
combinedsound_path = new_library_folder + "/" + "Sample " + str(i) + ".wav"
combinedsoundnormalised.export(combinedsound_path, format='wav')
It has been some months since you posted this question but I will answer it for others who may need a solution to this. As far as I have found, PySoundFile is the only python package that can deal with 24 bit audio (I am sure there are others but I haven't found them). My suggestion would be to initially read in the audio using PySoundFile and then create a pydub.AudioSegment using that data.
I'd like to create python command line code that is able to print directory tree with sizes of all subdirectories (from certain directory) and most frequent extensions... I will show the example output.
root_dir (5 GB, jpg (65 %): avi ( 30 %) : pdf (5 %))
-- aa (3 GB, jpg (100 %) )
-- bb (2 GB, avi (20 %) : pdf (2 %) )
--- bbb (1 GB, ...)
--- bb2 (1 GB, ...)
-- cc (1 GB, pdf (100 %) )
The format is :
nesting level, directory name (size of the directory with all files and subdirectories, most frequent extensions with size percentages in this directory.
I have this code snippet so far. The problem is that it counts only file sizes in directory, so the resulting size is smaller than real size of the directory. Other problem is how to put it all together to print the tree I defined above without redundant computations.
Calculating directory sizes really isn't python's strong suit, as explained in this post: very quickly getting total size of folder. If you have access to du and find, by all means use that. You can easily display the size of each directory with the following line:
find . -type d -exec du -hs "{}" \;
If you insist in doing this in python, you may prefer post-order traversal over os.walk, as suggested by PableG. But using os.walk can be visually cleaner, if efficiency is not the utmost factor for you:
import os, sys
from collections import defaultdict
def walkIt(folder):
for (path, dirs, files) in os.walk(folder):
size = getDirSize(path)
stats = getExtensionStats(files)
# only get the top 3 extensions
print '%s (%s, %s)'%(path, size, stats[:3])
def getExtensionStats(files):
# get all file extensions
extensions = [f.rsplit(os.extsep, 1)[-1]
for f in files if len(f.rsplit(os.extsep, 1)) > 1]
# count the extensions
exCounter = defaultdict(int)
for e in extensions:
exCounter[e] += 1
# convert count to percentage
percentPairs = [(e, 100*ct/len(extensions)) for e, ct in exCounter.items()]
# sort them
percentPairs.sort(key=lambda i: i[1])
return percentPairs
def getDirSize(root):
size = 0
for path, dirs, files in os.walk(root):
for f in files:
size += os.path.getsize( os.path.join( path, f ) )
return size
if __name__ == '__main__':
path = sys.argv[1] if len(sys.argv) > 1 else '.'
walkIt(path)
I personally find os.listdir + a_recursive_function best suited for this task than os.walk:
import os, copy
from os.path import join, getsize, isdir, splitext
frequent_ext = { ".jpg": 0, ".pdf": 0 } # Frequent extensions
def list_dir(base_dir):
dir_sz = 0 # directory size
files = os.listdir(base_dir)
ext_size = copy.copy(frequent_ext)
for file_ in files:
file_ = join(base_dir, file_)
if isdir(file_):
ret = list_dir(file_)
dir_sz += ret[0]
for k, v in frequent_ext.items(): # Add to freq.ext.sizes
ext_size[k] += ret[1][k]
else:
file_sz = getsize(file_)
dir_sz += file_sz
ext = os.path.splitext(file_)[1].lower() # Frequent extension?
if ext in frequent_ext.keys():
ext_size[ext] += file_sz
print base_dir, dir_sz,
for k, v in ext_size.items():
print "%s: %5.2f%%" % (k, float(v) / max(1, dir_sz) * 100.),
print
return (dir_sz, ext_size)
base_dir = "e:/test_dir/"
base_dir = os.path.abspath(base_dir)
list_dir(base_dir)
#Cldy Is right use os.path
for example os.path.walk will walk depth first through every directory below the argument, and return the files and folders in each directory
Use os.path.getsize to get the sizes and split to get the extensions. Store extensions in a list or dict and count them after going through each
If your are on Linux, I would suggest looking at du instead.
That's the module you need. And also this.
In Python v2, is there a way to get a date/time stamp and put it into creating a new text file?
IE: When I want to create a new text file and write the contents of my program to it, it will create a new text file with the time/date in it.
Thanks for any help.
import datetime
def timeStamped(fname, fmt='%Y-%m-%d-%H-%M-%S_{fname}'):
return datetime.datetime.now().strftime(fmt).format(fname=fname)
with open(timeStamped('myfile.txt'),'w') as outf:
outf.write('data!')
This will prepend a timestamp to the front of the filename:
from datetime import datetime
# define a timestamp format you like
FORMAT = '%Y%m%d%H%M%S'
path = 'foo.txt'
data = 'data to be written to the file\n'
new_path = '%s_%s' % (datetime.now().strftime(FORMAT), path)
open(new_path, 'w').write(data)
import datetime
f=open("/home/rohitsai/Documents/acs.txt",'a')
f.write ("heloo"+'\t')
f.write(datetime.datetime.now().ctime())
print datetime.datetime.now()
this code will add helo as well as current date on same file. 'a' is for append mode, \t for tab space.
import datetime
open("file", "w").write(datetime.datetime.now().ctime())
open(datetime.datetime.now().ctime(), "w").write("foo")
I like just having the date in my file handles:
from datetime import date
def timeIzNow():
'''
returns current date as a string
'''
now = date.today()
full = "-" + str(now.month) + "-" + str(now.day) + "-" + str(now.year)
return full
fileN = "findGenes"
with open(fileN + timeIzNow() + ".txt", 'w') as f:
#DO STUFF
Your new file name will look like
findGenes-6-5-2013.txt
A lot of these answers are unnecessarily complicated if you just want to spit out a timestamp to a file and don't care about tweaking the format of said stamp
You can literally do it in one line:
f.write(datetime.now().__str__() + "\n")
Here I assume f is a file - so we print the string representation of datetime.now() and add a new line, because write() doesn't do that for you. (You probably already knew that though.)
Note: checked working with Python 3, I didn't test with Python 2, I'm not sure which version of the language spec you are using.