Last active
March 3, 2025 10:47
-
-
Save marjanmo/36f9f2328f5c4fa956b594375fd59b46 to your computer and use it in GitHub Desktop.
Download Youtube music compilation into separate .mp3 files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import subprocess | |
import sys, os | |
""" | |
##################################### | |
##### YOUTUBE TO MP3 SPLITTER ###### | |
##################################### | |
ABOUT: | |
Have you ever found a good music compilation on youtube and wanted to download a playlist but you | |
didn't have time to mess around with splitting music into separate songs and do the boring ID3 editing in Audacity? | |
This script might help you. You just need a youtube link and a tracklist of the songs with their timestamps | |
(usually already in description or in top comments). Read the comments below for detailed instructions! | |
PYTHON REQUIREMENTS: | |
Python 3, pydub and youtube_dl | |
The script wil try to autoinstall missing dependecies, so if using in virtualenv, remove autoinstalling part or make sure | |
you already have pydub and youtube_dl installed! | |
USAGE: | |
The script itself is already a working example for downloading and splitting a Proleter video, so just modify it | |
according to your favourite Youtube music compilation. Just edit a SAVE_FOLDER to match your PC and create a textfile called | |
Proleter.txt next to this script with the following content (found under the Youtube video) | |
Proleter.txt | |
0:00:00 - My Melancholy Baby | |
0:03:58 - Can't Stop Me | |
0:07:42 - Fat Morris | |
0:11:32 - Sometimes | |
0:13:07 - Red Soap | |
0:16:23 - April Showers | |
0:20:52 - By The Rivers | |
0:24:33 - It Don't Mean A Thing | |
0:28:12 - Queen of Hearts | |
0:32:09 - U Can Get It | |
0:36:30 - Not Afraid | |
0:39:47 - Throw It Back (Instrumental) | |
0:42:48 - Downtown Irony | |
0:47:21 - Faidherbe Square | |
0:50:50 - Muhammad Ali | |
DISCLAIMER: | |
This is just a proof of concept. Use at your own risk! Songs might be cut unproperly if provided timestamps don't match | |
the actual songs in the video! Tested on Linux only. | |
Year: 2020 | |
Author: Marjan Moderc | |
github: https://github.com/marjanmo | |
""" | |
#YOUR INPUTS GO BELOW!: | |
# Link of the youtube music video that you want split. | |
YOUTUBE_LINK = 'https://www.youtube.com/watch?v=SYviQ0EztuQ' | |
# Info about songs | |
# Can usually be found in description of in the topmost comments. | |
# Copy/paste playlist with timestamps in a text file that will reside next to this script. | |
# You have to change the separator and the order of INFO list to match the original list. Be consistent! | |
# You might need some text file editing to match given criteria! | |
# INFO variable must have 2 or 3 elements. Adjust ordering of elements to match the file contents. | |
# TIME and TITLE are neccessary, ARTIST is optional, if downloading compilation! If not in the file, specifiy artist | |
# separately | |
TRACKLIST_FILE = "Proleter.txt" #Text file to be put next to the script! | |
INFO = ["TIME","TITLE"] #what info does the textfile contain and what is the order | |
SEPARATOR = " - " | |
# Constants for ID3 mp3 TAGGING | |
ARTIST = "Proleter" #Will be obtained from the tracklist if specified. | |
ALBUM = "The best of" | |
YEAR = 2000 | |
#DEMO FOLDER -- Script root | |
SAVE_FOLDER = os.path.dirname(os.path.realpath(__file__)) #Will be crated if not exist | |
#DEMO TEXT FILE - will be created for demo purposes, you should create it yourself for your own video. | |
with open(TRACKLIST_FILE, "w") as f: | |
f.write("0:00:00 - My Melancholy Baby\n0:03:58 - Can't Stop Me\n 0:07:42 - Fat Morris\n 0:11:32 - Sometimes\n 0:13:07 - Red Soap\n 0:16:23 - April Showers\n 0:20:52 - By The Rivers\n 0:24:33 - It Don't Mean A Thing\n 0:28:12 - Queen of Hearts\n 0:32:09 - U Can Get It\n 0:36:30 - Not Afraid\n 0:39:47 - Throw It Back (Instrumental)\n 0:42:48 - Downtown Irony\n 0:47:21 - Faidherbe Square\n 0:50:50 - Muhammad Ali") | |
################################################## | |
### Dont (have to) touch anything below this! #### | |
################################################## | |
# Try to autoinstall missing modules... | |
try: | |
import youtube_dl | |
except ImportError: | |
subprocess.check_call([sys.executable, "-m", "pip", "install", 'youtube_dl']) | |
import youtube_dl | |
try: | |
import pydub | |
except ImportError: | |
subprocess.check_call([sys.executable, "-m", "pip", "install", 'pydub']) | |
import pydub | |
# Helper function | |
def time_to_seconds(time_str): | |
if len(time_str.split(":")) == 2: | |
m, s = time_str.split(':') | |
return int(m) * 60 + int(s) | |
else: | |
h, m, s = time_str.split(':') | |
return int(h) * 3600 + int(m) * 60 + int(s) | |
# 1. Download the video to temporary file (couldn't make youtube_dl to create mp3 that pydub would eat happily) | |
ydl_opts = { | |
'outtmpl': 'tmp.mp4', | |
'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]' | |
} | |
with youtube_dl.YoutubeDL(ydl_opts) as ydl: | |
a = ydl.download([YOUTUBE_LINK]) | |
# 2. Read the songs info | |
with open(TRACKLIST_FILE, "r") as f: | |
songs = f.readlines() | |
songs = [i.strip("\n").strip("").split(SEPARATOR) for i in songs] | |
# 3. Read mp4 as AudioSegment | |
print("Reading source mp3 file ...") | |
sound = pydub.AudioSegment.from_file("tmp.mp4","mp4") | |
print("Done.") | |
# 4. Create a destination folder if doesnt exist | |
if not os.path.exists(SAVE_FOLDER): | |
os.mkdir(SAVE_FOLDER) | |
INFO = [i.lower() for i in INFO] #idiot proofing | |
# 5. Extract songs separately. | |
for i,j in enumerate(songs): | |
print("Converting song no.",i,j) | |
artist = j[INFO.index("artist")] if "artist" in INFO else ARTIST | |
time_start = j[INFO.index("time")] | |
title = j[INFO.index("title")] | |
time_start = time_to_seconds(time_start)*1000 | |
# Last one have special treatment... | |
if i+1 == len(songs): | |
song = sound[time_start:-1] | |
else: | |
time_finish = time_to_seconds(songs[i+1][INFO.index("time")])*1000-200 #time to the next one! | |
song = sound[time_start:time_finish] | |
song.export(os.path.join(SAVE_FOLDER,"{} - {}.mp3".format(artist,title)), format="mp3", | |
tags={"artist":artist,"album":ALBUM,"title":title, "track": i+1}) | |
# 5. Clean temporary file. | |
os.remove("tmp.mp4") |
Worked well with yt-dlp, thank you very much!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I tried to write similar code in python, but all my attempts were unsuccessful. In addition, I found an excellent online service that will help you quickly and easily convert YouTube videos. The advantage of some online services like https://coconvert.com/youtube-aac-converter.html is that you do not need to download videos, but paste the link into the converter and get a ready-made audio format. It is more convenient than you think and it saves a lot of memory.