-
Notifications
You must be signed in to change notification settings - Fork 2
/
pyporwave.py
107 lines (77 loc) · 2.89 KB
/
pyporwave.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# DONE: Allow users to search songs, rather than paste URLs.
# DONE: Add mp3 conversion.
# TODO: Add bpm analysis for song 'chopping'.
import hashlib
import os
import sys
import uuid
import yt_dlp as youtube_dl
from pysndfx import AudioEffectsChain
from pydub import AudioSegment
vw_fx_chain = (
AudioEffectsChain()
.speed(0.75)
.chorus(0.4, 0.6, [[55, 0.4, 0.55, .5, 't']])
.reverb(
reverberance=30,
hf_damping=50,
room_scale=100,
stereo_depth=100,
pre_delay=20,
wet_gain=0,
wet_only=False
)
)
output_dir = 'output'
ydl_config = {
'quiet': True,
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'wav',
'preferredquality': '192', # Originally 192
}],
}
def download(query):
print(f' ...searching for "{query}" ...')
wav_path = f'{output_dir}/{random_filename()}.wav'
outtmpl = wav_path.replace('.wav', '.%(ext)s')
ydl_config['outtmpl'] = outtmpl
with youtube_dl.YoutubeDL(ydl_config) as ydl:
info = ydl.extract_info(f'ytsearch:{query}')
title = info["entries"][0]["title"]
print(f' ...found "{title}", downloaded to ./{wav_path} ...')
return title, wav_path
def random_filename():
return hashlib.md5(uuid.uuid4().bytes).hexdigest()[:12]
def apply_fx(in_wav_path):
print(f' ...applying vaporwave effects to ./{in_wav_path} ...')
out_wav_path = in_wav_path.replace('.wav', '.vw.wav')
vw_fx_chain(in_wav_path, out_wav_path)
print(f' ...vw result stored in ./{out_wav_path} ...')
return out_wav_path
def wav_to_mp3(wav_path):
print(f' ... converting ./{wav_path} into mp3 ...')
mp3_path = wav_path.replace('.wav', '.mp3')
with open(wav_path, 'rb') as wav_file:
wav = AudioSegment.from_file(wav_file, format='wav')
wav.export(mp3_path, format='mp3')
return mp3_path
def remove_all(*paths):
print(' ...tidying up ...')
for path in paths:
print(f' ... removing {path} ...')
os.remove(path)
def main(query):
print('Starting process ...')
title, in_wav_path = download(query)
out_wav_path = apply_fx(in_wav_path)
in_mp3_path = wav_to_mp3(in_wav_path)
out_mp3_path = wav_to_mp3(out_wav_path)
os.rename(in_mp3_path, f'{output_dir}/{title}.mp3')
os.rename(out_mp3_path, f'{output_dir}/{title} - vaporwave.mp3')
remove_all(in_wav_path, out_wav_path)
print('... finished.')
if __name__ == '__main__':
query = sys.argv[1]
main(query)