Store all track metadata in db
This commit is contained in:
parent
a91d833da5
commit
086a4a2933
6
model.py
6
model.py
@ -42,8 +42,12 @@ class Tracks(Base):
|
|||||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||||
title = Column(String(256), index=True)
|
title = Column(String(256), index=True)
|
||||||
artist = Column(String(256), index=True)
|
artist = Column(String(256), index=True)
|
||||||
length = Column(Integer, index=True)
|
duration = Column(Integer, index=True)
|
||||||
|
start_gap = Column(Integer, index=False)
|
||||||
|
fade_at = Column(Integer, index=False)
|
||||||
|
silence_at = Column(Integer, index=False)
|
||||||
path = Column(String(2048), index=False, nullable=False)
|
path = Column(String(2048), index=False, nullable=False)
|
||||||
|
|
||||||
mtime = Column(Float, index=True)
|
mtime = Column(Float, index=True)
|
||||||
lastplayed = Column(DateTime, index=True, default=None)
|
lastplayed = Column(DateTime, index=True, default=None)
|
||||||
|
|
||||||
|
|||||||
72
songdb.py
72
songdb.py
@ -8,6 +8,7 @@ import os
|
|||||||
import pytiger.logging.config
|
import pytiger.logging.config
|
||||||
|
|
||||||
from tinytag import TinyTag
|
from tinytag import TinyTag
|
||||||
|
from pydub import AudioSegment
|
||||||
|
|
||||||
from model import Tracks, session
|
from model import Tracks, session
|
||||||
|
|
||||||
@ -38,6 +39,66 @@ def main():
|
|||||||
log.info("Finished")
|
log.info("Finished")
|
||||||
|
|
||||||
|
|
||||||
|
def get_audio_segment(path):
|
||||||
|
try:
|
||||||
|
if path.endswith('.mp3'):
|
||||||
|
return AudioSegment.from_mp3(path)
|
||||||
|
elif path.endswith('.flac'):
|
||||||
|
return AudioSegment.from_file(path, "flac")
|
||||||
|
except AttributeError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def leading_silence(audio_segment, silence_threshold=-50.0,
|
||||||
|
chunk_size=10):
|
||||||
|
"""
|
||||||
|
Returns the millisecond/index that the leading silence ends.
|
||||||
|
audio_segment - the segment to find silence in
|
||||||
|
silence_threshold - the upper bound for how quiet is silent in dFBS
|
||||||
|
chunk_size - chunk size for interating over the segment in ms
|
||||||
|
|
||||||
|
https://github.com/jiaaro/pydub/blob/master/pydub/silence.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
trim_ms = 0 # ms
|
||||||
|
assert chunk_size > 0 # to avoid infinite loop
|
||||||
|
while (
|
||||||
|
audio_segment[trim_ms:trim_ms + chunk_size].dBFS <
|
||||||
|
silence_threshold and trim_ms < len(audio_segment)):
|
||||||
|
trim_ms += chunk_size
|
||||||
|
|
||||||
|
# if there is no end it should return the length of the segment
|
||||||
|
return min(trim_ms, len(audio_segment))
|
||||||
|
|
||||||
|
|
||||||
|
def fade_point(audio_segment, fade_threshold=-20.0, chunk_size=10):
|
||||||
|
"""
|
||||||
|
Returns the millisecond/index of the point where the fade is down to
|
||||||
|
fade_threshold and doesn't get louder again.
|
||||||
|
audio_segment - the sdlg_search_database_uiegment to find silence in
|
||||||
|
fade_threshold - the upper bound for how quiet is silent in dFBS
|
||||||
|
chunk_size - chunk size for interating over the segment in ms
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert chunk_size > 0 # to avoid infinite loop
|
||||||
|
|
||||||
|
segment_length = audio_segment.duration_seconds * 1000 # ms
|
||||||
|
trim_ms = segment_length - chunk_size
|
||||||
|
while (
|
||||||
|
audio_segment[trim_ms:trim_ms + chunk_size].dBFS < fade_threshold
|
||||||
|
and trim_ms > 0):
|
||||||
|
trim_ms -= chunk_size
|
||||||
|
|
||||||
|
# if there is no trailing silence, return lenght of track (it's less
|
||||||
|
# the chunk_size, but for chunk_size = 10ms, this may be ignored)
|
||||||
|
return int(trim_ms)
|
||||||
|
|
||||||
|
|
||||||
|
def trailing_silence(audio_segment, silence_threshold=-50.0,
|
||||||
|
chunk_size=10):
|
||||||
|
return fade_point(audio_segment, silence_threshold, chunk_size)
|
||||||
|
|
||||||
|
|
||||||
def update_db():
|
def update_db():
|
||||||
"""
|
"""
|
||||||
Repopulate database
|
Repopulate database
|
||||||
@ -54,15 +115,20 @@ def update_db():
|
|||||||
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(os.path.relpath(path, ROOT))
|
||||||
tag = TinyTag.get(path)
|
tag = TinyTag.get(path)
|
||||||
|
audio = get_audio_segment(path)
|
||||||
|
|
||||||
track.title = tag.title
|
track.title = tag.title
|
||||||
track.artist = tag.artist
|
track.artist = tag.artist
|
||||||
track.length = int(tag.duration * 1000)
|
track.duration = int(tag.duration * 1000)
|
||||||
|
track.start_gap = leading_silence(audio)
|
||||||
|
track.fade_at = fade_point(audio)
|
||||||
|
track.silence_at = trailing_silence(audio)
|
||||||
track.mtime = os.path.getmtime(path)
|
track.mtime = os.path.getmtime(path)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
elif ext not in [".jpg"]:
|
elif ext not in [".jpg"]:
|
||||||
print(f"Unrecognised file type: {path}")
|
print(f"Unrecognised file type: {path}")
|
||||||
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
print(f"{count} files processed")
|
print(f"{count} files processed")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user