initial commit
This commit is contained in:
commit
6eff688132
2 changed files with 96 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
rec/*
|
95
spotigrab.py
Normal file
95
spotigrab.py
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
# python spotify grabber
|
||||||
|
# requirements: pygetwindow from pip and fmedia in $path
|
||||||
|
import pygetwindow
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
import threading
|
||||||
|
import logging
|
||||||
|
import string
|
||||||
|
import unicodedata
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# configuration
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format='%(asctime)s %(levelname)-8s %(message)s'
|
||||||
|
)
|
||||||
|
rec_path=".\\rec\\"
|
||||||
|
loopback_dev="3"
|
||||||
|
monitor_interval=.2
|
||||||
|
# end configuration
|
||||||
|
|
||||||
|
valid_filename_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)
|
||||||
|
counter=0
|
||||||
|
|
||||||
|
def clean_filename(filename, whitelist=valid_filename_chars):
|
||||||
|
# keep only valid ascii chars
|
||||||
|
cleaned_filename = unicodedata.normalize('NFKD', filename).encode('ASCII', 'ignore').decode()
|
||||||
|
|
||||||
|
# keep only whitelisted chars
|
||||||
|
cleaned_filename = ''.join(c for c in cleaned_filename if c in whitelist)
|
||||||
|
return cleaned_filename
|
||||||
|
|
||||||
|
def start_rec(artist, title):
|
||||||
|
def rec_subprocess():
|
||||||
|
filename = '{rec_path}{nn:03d}. {artist} - {title}.mp3'.format(
|
||||||
|
nn=counter,
|
||||||
|
rec_path=rec_path,
|
||||||
|
artist=clean_filename(artist),
|
||||||
|
title=clean_filename(title)
|
||||||
|
)
|
||||||
|
logging.debug('recording to {filename}'.format(filename=filename))
|
||||||
|
command = 'fmedia --record --dev-loopback={device} -o "{filename}" --mpeg-quality=2 --globcmd=listen'.format(device=loopback_dev, filename=filename)
|
||||||
|
logging.debug('starting recording subprocess: {command}'.format(command=command))
|
||||||
|
subprocess.run(command, shell=True, capture_output=True, check=True)
|
||||||
|
|
||||||
|
logging.debug('starting subprocess')
|
||||||
|
global counter
|
||||||
|
counter += 1
|
||||||
|
thread = threading.Thread(target=rec_subprocess)
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
def stop_rec():
|
||||||
|
subprocess.run('fmedia --globcmd=stop', shell=True)
|
||||||
|
logging.debug('stopped recording')
|
||||||
|
|
||||||
|
def parse_win_title(win_title):
|
||||||
|
metadata = win_title.split('Spotify - ')[1].split(' · ')
|
||||||
|
title = metadata[0]
|
||||||
|
artist = metadata[1]
|
||||||
|
logging.debug('got metadata {title} by {artist}'.format(title=title, artist=artist))
|
||||||
|
return title, artist
|
||||||
|
|
||||||
|
def watch_window():
|
||||||
|
old_title = ''
|
||||||
|
logging.debug('started window watcher')
|
||||||
|
|
||||||
|
while True:
|
||||||
|
win_titles = pygetwindow.getAllTitles()
|
||||||
|
for win_title in win_titles:
|
||||||
|
if re.search('^Spotify - .+', win_title):
|
||||||
|
if win_title != old_title:
|
||||||
|
logging.debug('window title changed to {wintitle}'.format(wintitle=win_title))
|
||||||
|
|
||||||
|
# read metadata from window title
|
||||||
|
title, artist = parse_win_title(win_title)
|
||||||
|
|
||||||
|
if old_title != '':
|
||||||
|
logging.debug('stop recording')
|
||||||
|
stop_rec()
|
||||||
|
|
||||||
|
logging.debug('start recording now')
|
||||||
|
start_rec(title, artist)
|
||||||
|
|
||||||
|
old_title = win_title
|
||||||
|
time.sleep(.5)
|
||||||
|
|
||||||
|
input('press enter to arm')
|
||||||
|
try:
|
||||||
|
watch_window()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
logging.info('got CTRL+C - trying to clean up my mess')
|
||||||
|
stop_rec()
|
||||||
|
logging.info('Bye Bye')
|
||||||
|
sys.exit(0)
|
Loading…
Reference in a new issue