media-sucker/src/cd.py

131 lines
3.6 KiB
Python

#! /usr/bin/python3
import subprocess
import time
import logging
import re
import os
import socket
import io
import gnudb
SECOND = 1
MINUTE = 60 * SECOND
HOUR = 60 * MINUTE
def read(device, status):
# Get disc ID
p = subprocess.run(
[
"cd-discid",
device,
],
encoding="utf-8",
capture_output=True,
)
discid = p.stdout
status["discid"] = discid
# Look it up in cddb
email = os.environ.get("EMAIL") # You should really set this variable, tho
if not email:
user = "user"
try:
user = os.getlogin()
except OSError:
pass
email = "%s@%s" % (user, socket.gethostname())
db_server = gnudb.Server(email)
disc = db_server.bestguess(discid)
if disc:
# There was a hit! Hooray!
# We're expected to be automatic here,
# so just use the first one.
for k in ("title", "artist", "genre", "year", "tracks"):
status[k] = disc[k]
else:
now = time.strftime("%Y-%m-%dT%H%M%S")
num_tracks = int(discid.split()[1])
status["title"] = "Unknown CD - %s" % now
status["tracks"] = [""] * num_tracks
def rip(device, status, directory):
# cdparanoia reports completion in samples
# use discid duration to figure out total number of samples
duration = int(status["discid"].split()[-1]) * SECOND # disc duration in seconds
total_samples = duration * (75 / SECOND) * 1176 # 75 sectors per second, 1176 samples per sector
track_num = 1
for track_name in status["tracks"]:
logging.debug("Ripping track %d of %d", track_num, len(status["tracks"]))
p = subprocess.Popen(
[
"cdparanoia",
"--stderr-progress",
"--force-cdrom-device", device,
"--batch",
str(track_num),
],
cwd = directory,
stderr = subprocess.PIPE,
encoding = "utf-8",
)
for line in p.stderr:
line = line.strip()
if line.startswith("##: -2"):
samples = int(line.split()[-1])
status["complete"] = samples / total_samples
track_num += 1
def encode(status, directory):
# Encode the tracks
track_num = 1
for track_name in status["tracks"]:
argv = [
"lame",
"--preset", "standard",
"-tl", status["title"],
"--tn", "%d/%d" % (track_num, len(status["tracks"])),
]
if status["artist"]:
argv.extend(["-ta", status["artist"]])
if status["genre"]:
argv.extend(["-tg", status["genre"]])
if status["year"]:
argv.extend(["-ty", status["year"]])
if track_name:
argv.extend(["-tt", track_name])
outfn = "%d - %s.mp3" % (track_num, track_name)
else:
outfn = "%d.mp3" % track_num
argv.append("track%02d.cdda.wav" % track_num)
argv.append(outfn)
p = subprocess.Popen(
argv,
cwd = directory,
stdin = subprocess.PIPE,
encoding = "utf-8",
)
p.communicate(input=track_name)
track_num += 1
if __name__ == "__main__":
import pprint
logging.basicConfig(level=logging.DEBUG)
status = {}
read("/dev/sr0", status)
pprint.pprint(status)
directory = os.path.join(".", status["title"])
os.makedirs(directory, exist_ok=True)
rip("/dev/sr0", status, directory)
pprint.pprint(status)
encode(status, directory)
pprint.pprint(status)
# vi: sw=4 ts=4 et ai