Python Youtube MP3 Splitter

A Python program that splits mp3 files from YouTube albums into individual songs.

Dependencies

  • Python 2.7+
  • ffmpeg

Getting Started

You need to have Python 2.7+ and ffmpeg installed.

Useful links:

Usage

  1. Install Python and ffmpeg.

  2. Download the album from Youtube as mp3.
    (You could use YouTube-dl or any online service).

youtube-dl --extract-audio --audio-format mp3 --audio-quality 0 <Video-URL>
  1. Download application.py

  2. Copy the timestamps into a .txt file

  3. Run

    python application.py <music file.mp3> <tracklist file.txt>
  4. Enjoy!
import sys
import subprocess

inputfile = sys.argv[1]
codec = '-acodec'

#ffmpeg did not like having '?' in the file name, add any other problematic symbol here.
escape_list = ['?']

def RemoveSymbols(text):
    for symbol in escape_list:
        text = text.replace(symbol, '')
    return text

tracklist = []

class Track:
    def __init__(self, timestamp, name):
        self.timestamp = timestamp
        self.name = name

class ExtractTracks:
    def __init__(self):
        with open(sys.argv[2], "r") as values:
            for value in values:
                name = ""
                timestamp = ""
                #split all by spaces.
                keyVal = value.split(' ')
                #find timestamp
                for word in keyVal:
                    if ':' in word:
                        timestamp = word
                    else:
                        name += word + ' '
                tracklist.append(Track(timestamp, name))

#Initialize
ExtractTracks()


def GenerateSplitCommand(start, end, filename):
    return ['ffmpeg', '-i', inputfile, '-ss', start, '-to', end, '-c', 'copy', filename+'.mp3', '-v', 'error']

def GetVideoEnd():
    ffprobeCommand = [
        'ffprobe',
        '-v',
        'error',
        '-show_entries',
        'format=duration',
        '-of',
        'default=noprint_wrappers=1:nokey=1',
        '-sexagesimal',
        inputfile
    ]
    return subprocess.check_output(ffprobeCommand).strip()

for i in range(0, len(tracklist)):
    name = tracklist[i].name.strip()
    name = RemoveSymbols(name)
    startTime = tracklist[i].timestamp.strip()
    if i != (len(tracklist) - 1):
        endTime = tracklist[i+1].timestamp.strip() #- startTime
    else:
        endTime = GetVideoEnd() #- startTime
    print('---')
    print('Generating ' + name + ' from ' + startTime + ' to ' + endTime)
    print('---')
    command = GenerateSplitCommand(str(startTime), str(endTime), name)
    output = subprocess.check_call(command)