Counters updating; store full path; round milliseconds

This commit is contained in:
Keith Edmunds 2021-03-26 23:55:53 +00:00
parent 31cf7ca3e6
commit 28143ced6c
3 changed files with 46 additions and 67 deletions

View File

@ -3,6 +3,9 @@ import os
class Config(object): class Config(object):
AUDIO_SEGMENT_CHUNK_SIZE = 10
DBFS_FADE = -12
DBFS_SILENCE = -50
DISPLAY_SQL = False DISPLAY_SQL = False
ERRORS_TO = ['kae@midnighthax.com'] ERRORS_TO = ['kae@midnighthax.com']
LOG_LEVEL_STDERR = logging.INFO LOG_LEVEL_STDERR = logging.INFO
@ -12,9 +15,10 @@ class Config(object):
MAIL_SERVER = os.environ.get('MAIL_SERVER') or "woodlands.midnighthax.com" MAIL_SERVER = os.environ.get('MAIL_SERVER') or "woodlands.midnighthax.com"
MAIL_USERNAME = os.environ.get('MAIL_USERNAME') MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None
MILLISECOND_SIGFIGS = 1
MYSQL_CONNECT = "mysql+mysqldb://songdb:songdb@localhost/songdb" MYSQL_CONNECT = "mysql+mysqldb://songdb:songdb@localhost/songdb"
ROOT = "/home/kae/music" ROOT = "/home/kae/music"
TIMER_MS = 500 TIMER_MS = 1000
config = Config config = Config

View File

@ -10,7 +10,6 @@ from log import DEBUG, ERROR
from PyQt5.QtCore import Qt, QTimer from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QApplication, QDialog, QMainWindow from PyQt5.QtWidgets import QApplication, QDialog, QMainWindow
from PyQt5.QtWidgets import QTableWidgetItem, QFileDialog, QListWidgetItem from PyQt5.QtWidgets import QTableWidgetItem, QFileDialog, QListWidgetItem
from threading import Timer
from ui.main_window_ui import Ui_MainWindow from ui.main_window_ui import Ui_MainWindow
from ui.dlg_search_database_ui import Ui_Dialog from ui.dlg_search_database_ui import Ui_Dialog
@ -19,34 +18,9 @@ from config import Config
from model import Settings, Tracks from model import Settings, Tracks
class RepeatedTimer:
def __init__(self, interval, function, *args, **kwargs):
self._timer = None
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.is_running = False
self.start()
def _run(self):
self.is_running = False
self.start()
self.function(*self.args, **self.kwargs)
def start(self):
if not self.is_running:
self._timer = Timer(self.interval, self._run)
self._timer.start()
self.is_running = True
def stop(self):
self._timer.cancel()
self.is_running = False
class Music: class Music:
def __init__(self): def __init__(self):
self.current_track = { self.current_track = {
"player": None, "player": None,
"meta": None "meta": None
@ -106,6 +80,12 @@ class Music:
self.current_track['player'].play() self.current_track['player'].play()
def playing(self):
if self.current_track['player']:
return self.current_track['player'].is_playing()
else:
return False
def resume_last(self): def resume_last(self):
pass pass
@ -220,9 +200,17 @@ class Window(QMainWindow, Ui_MainWindow):
ERROR("Can't set next track") ERROR("Can't set next track")
def tick(self): def tick(self):
self.current_time.setText( now = datetime.now()
datetime.strftime(datetime.now(), "%H:%M:%S") self.current_time.setText(now.strftime("%H:%M:%S"))
) if self.music.playing():
playtime = self.music.get_current_playtime()
self.label_elapsed_timer.setText(ms_to_mmss(playtime))
self.label_fade_timer.setText(
ms_to_mmss(self.music.get_current_fade_at() - playtime))
self.label_silent_timer.setText(
ms_to_mmss(self.music.get_current_silence_at() - playtime))
self.label_end_timer.setText(
ms_to_mmss(self.music.get_current_duration() - playtime))
def add_to_playlist(self, track): def add_to_playlist(self, track):
""" """
@ -292,13 +280,15 @@ class DbDialog(QDialog):
self.parent().add_to_playlist(track) self.parent().add_to_playlist(track)
def ms_to_mmss(ms, decimals=0): def ms_to_mmss(ms, decimals=0, negative=False):
if not ms: if not ms:
return "-" return "-"
sign = ""
if ms < 0: if ms < 0:
sign = "-" if negative:
else: sign = "-"
sign = "" else:
ms = 0
minutes, remainder = divmod(ms, 60 * 1000) minutes, remainder = divmod(ms, 60 * 1000)
seconds = remainder / 1000 seconds = remainder / 1000

View File

@ -5,20 +5,13 @@ import hashlib
import logging import logging
import os import os
import pytiger.logging.config from config import Config
from log import INFO
from tinytag import TinyTag
from pydub import AudioSegment
from model import Tracks, session from model import Tracks, session
from pydub import AudioSegment
from tinytag import TinyTag
INFO("Starting")
# "Constants"
ROOT = "/home/kae/music"
# Instantiate logging
pytiger.logging.config.basic_config(stderr=False, level=logging.INFO)
log = logging.getLogger(__name__)
log.info("Starting")
def main(): def main():
@ -49,8 +42,8 @@ def get_audio_segment(path):
return None return None
def leading_silence(audio_segment, silence_threshold=-50.0, def leading_silence(audio_segment, silence_threshold=Config.DBFS_SILENCE,
chunk_size=10): chunk_size=Config.AUDIO_SEGMENT_CHUNK_SIZE):
""" """
Returns the millisecond/index that the leading silence ends. Returns the millisecond/index that the leading silence ends.
audio_segment - the segment to find silence in audio_segment - the segment to find silence in
@ -71,7 +64,7 @@ def leading_silence(audio_segment, silence_threshold=-50.0,
return min(trim_ms, len(audio_segment)) return min(trim_ms, len(audio_segment))
def fade_point(audio_segment, fade_threshold=-20.0, chunk_size=10): def fade_point(audio_segment, fade_threshold=Config.DBFS_FADE, chunk_size=Config.AUDIO_SEGMENT_CHUNK_SIZE):
""" """
Returns the millisecond/index of the point where the fade is down to Returns the millisecond/index of the point where the fade is down to
fade_threshold and doesn't get louder again. fade_threshold and doesn't get louder again.
@ -95,7 +88,7 @@ def fade_point(audio_segment, fade_threshold=-20.0, chunk_size=10):
def trailing_silence(audio_segment, silence_threshold=-50.0, def trailing_silence(audio_segment, silence_threshold=-50.0,
chunk_size=10): chunk_size=Config.AUDIO_SEGMENT_CHUNK_SIZE):
return fade_point(audio_segment, silence_threshold, chunk_size) return fade_point(audio_segment, silence_threshold, chunk_size)
@ -107,22 +100,25 @@ def update_db():
""" """
count = 0 count = 0
for root, dirs, files in os.walk(ROOT): for root, dirs, files in os.walk(Config.ROOT):
for f in files: for f in files:
count += 1 count += 1
path = os.path.join(root, f) path = os.path.join(root, f)
ext = os.path.splitext(f)[1] ext = os.path.splitext(f)[1]
if ext in [".flac", ".mp3"]: if ext in [".flac", ".mp3"]:
track = Tracks.get_or_create(os.path.relpath(path, ROOT)) track = Tracks.get_or_create(path)
tag = TinyTag.get(path) tag = TinyTag.get(path)
audio = get_audio_segment(path) audio = get_audio_segment(path)
track.title = tag.title track.title = tag.title
track.artist = tag.artist track.artist = tag.artist
track.duration = int(tag.duration * 1000) track.duration = int(round(
tag.duration, Config.MILLISECOND_SIGFIGS) * 1000)
track.start_gap = leading_silence(audio) track.start_gap = leading_silence(audio)
track.fade_at = fade_point(audio) track.fade_at = round(
track.silence_at = trailing_silence(audio) fade_point(audio), Config.MILLISECOND_SIGFIGS) * 1000
track.silence_at = round(
trailing_silence(audio), Config.MILLISECOND_SIGFIGS) * 1000
track.mtime = os.path.getmtime(path) track.mtime = os.path.getmtime(path)
session.commit() session.commit()
@ -132,16 +128,5 @@ def update_db():
print(f"{count} files processed") print(f"{count} files processed")
def md5(path):
"https://stackoverflow.nl9om/questions/3431825/"
"generating-an-md5-checksum-of-a-file"
hash_md5 = hashlib.md5()
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
if __name__ == '__main__': if __name__ == '__main__':
main() main()