commit 6eff68813241e0927efc0851ff19542c6cacbdfc Author: Christoph bsod@zom.bi Date: Thu Jan 27 21:57:08 2022 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..971519e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +rec/* diff --git a/spotigrab.py b/spotigrab.py new file mode 100644 index 0000000..12b7ab1 --- /dev/null +++ b/spotigrab.py @@ -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)