Skip to content

Commit 7d55571

Browse files
committed
v 1.0
0 parents  commit 7d55571

File tree

4 files changed

+189
-0
lines changed

4 files changed

+189
-0
lines changed

.gitignore

Whitespace-only changes.

README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Cue sheet generator
2+
You like your songs organised, and when listening to sets, you want to just look at foobar2000 (you don't use anything else, be honest ;) and know, what song is playing. For that, there is certain type of file called _cuesheet_. This file contains info about track artist, title and its timestamp in the mix. I love these files, it's really convinient on PC and mobile. But manually creating these files, or using some online generators is major pain in the butt. And since you already have (presumably) tracklist with timestamps, why not create a tool that generates this file for you?
3+
4+
# Usage
5+
## Installation
6+
You don't need any special packages. Only two imports that I use are _os_ package for manipulating with files, and my custom [cue file generator](cuefilegenerator.py). So just clone the repo:
7+
```bash
8+
git clone https://github.com/ApplePie420/CueSheetGenerator.git
9+
```
10+
11+
and then run
12+
13+
```bash
14+
python generator.py
15+
```
16+
17+
and just follow instructions.
18+
19+
## Using the script
20+
First of all, insert __name of performer__, i.e. the person that mixed the set.
21+
22+
Then, it'll ask you for path where __your audio file and tracklist.txt is__. Enter full path, for example
23+
```
24+
D:\music\sets\myFavouriteProducer\myFavouriteMix\
25+
```
26+
or on linux
27+
```
28+
/home/yourName/music/myFavouriteProducer/myFavouriteMix/
29+
```
30+
You __do not need__ to insert the path between quotation marks, even if it contains spaces. It works somehow. If it doesn't, then try it with them :D
31+
32+
__Script automatically looks for audio files__ with these extensions:
33+
- mp3
34+
- m4a
35+
- ogg/opus
36+
- aac
37+
- flac
38+
- wav
39+
- wma
40+
- aiff
41+
- alac
42+
Although for now, it only works with __mp3, m4a, ogg/opus, flac and alac__.
43+
44+
Next, you need to specify your __tracklist__ file. By default, it will look for file named `tracklist.txt`. If your tracklist is named differently, for example `list.txt`, type that in. __!Be sure that tracklist is formatted as needed (example below)!__.
45+
46+
And if everything went well, a _.cue_ file should append in your directory.
47+
48+
# Tracklist format
49+
Obviously, this script is not magical and it cannot read your tracklist properly unless it is formatted properly. So your tracklist should look like this:
50+
```
51+
00:00:00 Artist - Title
52+
00:05:30 Artist - Title
53+
00:12:58 Artist - Title
54+
...
55+
01:03:34 Artist - Title
56+
```
57+
58+
You __HAVE__ to have a space between timestamp and song name, and a ` - ` (aka space dash space) between artist and title.
59+
Time is formatted in HH:MM:SS, where HH is hours, MM are minutes and SS seconds. Script automatically transforms hours into minutes, and adds CD frame (defaults to 00). And yes, there __HAS__ to be leading zeroes. 1. It makes it look pretty and 2. I've hardcoded timestamp length.. :D (I will change it later)
60+
61+
I may add different tracklist formats support later, but honestly why. This is very readable, compact and have all necessary information. And __YES, you can have `[label]` at the end__. If you have problem with this tracklist format, either get used to it, fork this script and modify it, or create other script to convert your format to mine.
62+
63+
# Todo list
64+
[] - Automatically detect codec for cue `FILE` parameter
65+
[] - Ignore missing leading zeroes
66+
[] - Add `REM GENRE` and `DATE`
67+
68+
If you have Issues, you know where to post them. Please, feel free to fork, upgrade and request merge. I made this in under an hour so it won't be perfect.

cuefilegenerator.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import os
2+
3+
def write_cue_file(performer, title, file, tracks, tracks_timestamp, savePath):
4+
f = open(savePath + title + ".cue", "w")
5+
# check if all of data is present
6+
if(performer == ""):
7+
print("Performer not specified!")
8+
return 1
9+
elif(title == ""):
10+
print("Title not specified!")
11+
return 1
12+
elif(file == ""):
13+
print("File path not specified!")
14+
return 1
15+
elif(len(tracks) != len(tracks_timestamp)):
16+
print("Tracks and timestamps count does not match")
17+
return 1
18+
else:
19+
# try to guess codec, this might not work always
20+
# TODO: make this somehow automated, maybe some packages?
21+
extension = file.split(".")[1]
22+
codec = ""
23+
if(extension == "mp3"):
24+
codec = "MP3"
25+
elif(extension == "m4a"):
26+
codec = "AAC"
27+
elif(extension == "ogg" or extension == "opus"):
28+
codec = "AIFF"
29+
elif(extension == "flac"):
30+
codec = "FLAC"
31+
elif(extension == "alac"):
32+
codec = "ALAC"
33+
# write info about cuesheet
34+
f.write("PERFORMER \"" + performer + "\"\n")
35+
f.write("TITLE \"" + title + "\"\n")
36+
f.write("FILE \"" + file + "\" " + str(codec) + "\n")
37+
38+
# write individual tracks
39+
for i in range(len(tracks)):
40+
# TRACK 0x AUDIO
41+
f.write("\tTRACK %02d AUDIO\n" % (i+1,))
42+
# PERFORMER "DJ_name"
43+
f.write("\t\tPERFORMER \"" + tracks[i].split(" - ")[0] + "\"\n")
44+
# TITLE "title"
45+
f.write("\t\tTITLE \"" + tracks[i].split(" - ")[1] + "\"\n")
46+
# INDEX 01 timestamp
47+
f.write("\t\tINDEX 01 " + tracks_timestamp[i] + ":00\n")
48+
f.close()
49+
return 0

generator.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import os
2+
from cuefilegenerator import write_cue_file
3+
4+
def get_audio_files(folder):
5+
audio_ext = [".mp3", ".m4a", ".ogg", ".opus", ".aac", ".flac", ".wav", ".wma", ".aiff", ".alac"]
6+
for file in os.listdir(folder):
7+
if file.endswith(tuple(audio_ext)):
8+
return file
9+
10+
def get_timestamps(tracklist):
11+
# open file
12+
f = open(tracklist, "r")
13+
# read lines and split by \n
14+
content = f.read()
15+
content = content.split("\n")
16+
17+
# array to return
18+
tStamps = []
19+
20+
# get all timestamps
21+
for song in content:
22+
timestamps = song.split(" ")[0]
23+
24+
#get individually hours, minutes and seconds
25+
hours = timestamps.split(":")[0]
26+
minutes = timestamps.split(":")[1]
27+
seconds = timestamps.split(":")[2]
28+
29+
# parse hours into minutes
30+
if(int(hours) > 0):
31+
minutes = int(minutes) + int(hours)*60
32+
33+
# create cuefile timestamp in format MM:SS where MM is minutes, SS seconds
34+
timestamp = str(minutes) + ":" + str(seconds)
35+
tStamps.append(timestamp)
36+
return tStamps
37+
38+
def get_songs(tracklist):
39+
# open file
40+
f = open(tracklist, "r")
41+
# read lines and split by \n
42+
content = f.read()
43+
content = content.split("\n")
44+
45+
# array to return
46+
songs = []
47+
48+
for song in content:
49+
track = song[9:]
50+
songs.append(track)
51+
52+
return songs
53+
54+
####################################### main program #####################################
55+
performer = input("Performer: ")
56+
path = input("Enter DIRECTORY path where audio file and tracklist is (default './'): ")
57+
if(path == ""):
58+
path = "./"
59+
file = get_audio_files(path)
60+
title = file.split(".")[0]
61+
62+
tracklist = input("Tracklist file (default 'tracklist.txt'): ")
63+
# make "tracklist.txt" default tracklist
64+
if(tracklist == ""):
65+
tracklist = path + "tracklist.txt"
66+
67+
# get timestamps and song names and artists
68+
timestamps = get_timestamps(tracklist)
69+
songs = get_songs(tracklist)
70+
71+
# write to a cuesheet
72+
write_cue_file(performer, title, file, songs, timestamps, path)

0 commit comments

Comments
 (0)