Advertisement
Guest User

Untitled

a guest
Nov 18th, 2023
608
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.58 KB | None | 1 0
  1. from pydub import AudioSegment, effects
  2. from yt_dlp import YoutubeDL
  3. import glob
  4. import os
  5. import random
  6.  
  7. BATCH_SIZE = 320
  8. MAX_SEARCH_RESULTS = 10
  9. DOWNLOAD_DIR = 'wavs/raw'
  10. LOOP_OUTPUT_DIR = 'wavs/processed/loop'
  11. ONESHOT_OUTPUT_DIR = 'wavs/processed/oneshot'
  12. WORD_LIST = 'birdwater.txt'
  13.  
  14. def read_lines(file):
  15. return open(file).read().splitlines()
  16.  
  17. class download_range_func:
  18. def __init__(self):
  19. pass
  20. def __call__(self, info_dict, ydl):
  21. timestamp = self.make_timestamp(info_dict)
  22. yield {
  23. 'start_time': timestamp,
  24. 'end_time': timestamp,
  25. }
  26. @staticmethod
  27. def make_timestamp(info):
  28. duration = info['duration']
  29. if duration is None:
  30. return 0
  31. return duration/2
  32.  
  33. def make_random_search_phrase(word_list):
  34. words = random.sample(word_list, 2)
  35. phrase = ' '.join(words)
  36. print('Search phrase: "{}"'.format(phrase))
  37. return phrase
  38.  
  39. def make_download_options(phrase):
  40. safe_phrase = ''.join(x for x in phrase if x.isalnum() or x in "._- ")
  41. return {
  42. 'format': 'bestaudio/best',
  43. 'paths': {'home': DOWNLOAD_DIR},
  44. 'outtmpl': {'default': f'{safe_phrase}-%(id)s.%(ext)s'},
  45. 'download_ranges': download_range_func(),
  46. 'postprocessors': [{
  47. 'key': 'FFmpegExtractAudio',
  48. 'preferredcodec': 'wav',
  49. }]
  50. }
  51.  
  52. def make_oneshot(sound, phrase, output_filepath):
  53. final_length = min(2000, len(sound))
  54. quarter = int(final_length/4)
  55. sound = sound[:final_length]
  56. sound = sound.fade_out(duration=quarter)
  57. sound = effects.normalize(sound)
  58. sound.export(output_filepath, format="wav")
  59.  
  60. def make_loop(sound, phrase, output_filepath):
  61. final_length = min(2000, len(sound))
  62. half = int(final_length/2)
  63. fade_length = int(final_length/4)
  64. beg = sound[:half]
  65. end = sound[half:]
  66. end = end[:fade_length]
  67. beg = beg.fade_in(duration=fade_length)
  68. end = end.fade_out(duration=fade_length)
  69. sound = beg.overlay(end)
  70. sound = effects.normalize(sound)
  71. sound.export(output_filepath, format="wav")
  72.  
  73. def process_file(filepath, phrase):
  74. try:
  75. safe_phrase = ''.join(x for x in phrase if x.isalnum() or x in "._- ")
  76. filename = os.path.basename(filepath)
  77. output_filepath_oneshot = os.path.join(ONESHOT_OUTPUT_DIR, f'oneshot_{safe_phrase}-{filename}')
  78. output_filepath_loop = os.path.join(LOOP_OUTPUT_DIR, f'loop_{safe_phrase}-{filename}')
  79.  
  80. sound = AudioSegment.from_file(filepath, "wav")
  81. if (len(sound) > 500):
  82. if not os.path.exists(output_filepath_oneshot):
  83. make_oneshot(sound, phrase, output_filepath_oneshot)
  84. if not os.path.exists(output_filepath_loop):
  85. make_loop(sound, phrase, output_filepath_loop)
  86. os.remove(filepath)
  87. except Exception as err:
  88. print("Failed to process '{}' ({})".format(filepath, err))
  89.  
  90. def setup():
  91. if not os.path.exists(LOOP_OUTPUT_DIR):
  92. os.makedirs(LOOP_OUTPUT_DIR)
  93. if not os.path.exists(ONESHOT_OUTPUT_DIR):
  94. os.makedirs(ONESHOT_OUTPUT_DIR)
  95.  
  96. def main():
  97. try:
  98. setup()
  99. word_list = read_lines(WORD_LIST)
  100. for _ in range(BATCH_SIZE):
  101. phrase = make_random_search_phrase(word_list)
  102. video_url = f'ytsearch1:"{phrase}"'
  103. options = make_download_options(phrase)
  104. YoutubeDL(options).download([video_url])
  105. for filepath in glob.glob(os.path.join(DOWNLOAD_DIR, f'{phrase}-*.wav')):
  106. process_file(filepath, phrase)
  107. except Exception as err:
  108. print('FATAL ERROR: {}'.format(err))
  109.  
  110. if __name__ == '__main__':
  111. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement