auto
This commit is contained in:
parent
5c27645666
commit
d579a60917
@ -51,7 +51,6 @@ config.ini db/
|
|||||||
- ~~editable lyrics window~~
|
- ~~editable lyrics window~~
|
||||||
- ~~batch metadata changer (red highlight fields that have differing info)~~
|
- ~~batch metadata changer (red highlight fields that have differing info)~~
|
||||||
- ~~playlists~~
|
- ~~playlists~~
|
||||||
- playlist m3u files
|
|
||||||
- playlist autoexporting
|
- playlist autoexporting
|
||||||
- fix table headers being resized and going out window bounds
|
- fix table headers being resized and going out window bounds
|
||||||
- delete songs from library (del key || right-click delete)
|
- delete songs from library (del key || right-click delete)
|
||||||
|
|||||||
16
main.py
16
main.py
@ -188,7 +188,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
lambda: self.player.setPosition(self.playbackSlider.value())
|
lambda: self.player.setPosition(self.playbackSlider.value())
|
||||||
) # sliderReleased works better than sliderMoved
|
) # sliderReleased works better than sliderMoved
|
||||||
self.volumeSlider.sliderMoved[int].connect(lambda: self.volume_changed())
|
self.volumeSlider.sliderMoved[int].connect(lambda: self.volume_changed())
|
||||||
self.speedSlider.sliderReleased.connect(
|
self.speedSlider.sliderMoved.connect(
|
||||||
lambda: self.speed_changed(self.speedSlider.value())
|
lambda: self.speed_changed(self.speedSlider.value())
|
||||||
)
|
)
|
||||||
self.playButton.clicked.connect(self.on_play_clicked) # Click to play/pause
|
self.playButton.clicked.connect(self.on_play_clicked) # Click to play/pause
|
||||||
@ -448,7 +448,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.playButton.setText("⏸️")
|
self.playButton.setText("⏸️")
|
||||||
else:
|
else:
|
||||||
self.play_audio_file()
|
self.play_audio_file()
|
||||||
self.playButton.setText("⏸️")
|
self.playButton.setText("👽")
|
||||||
|
|
||||||
def on_previous_clicked(self) -> None:
|
def on_previous_clicked(self) -> None:
|
||||||
""""""
|
""""""
|
||||||
@ -490,7 +490,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
def create_playlist(self) -> None:
|
def create_playlist(self) -> None:
|
||||||
"""Creates a database record for a playlist, given a name"""
|
"""Creates a database record for a playlist, given a name"""
|
||||||
window = CreatePlaylistWindow(self.playlistCreatedSignal)
|
window = CreatePlaylistWindow(self.playlistCreatedSignal)
|
||||||
window.playlistCreatedSignal.connect(self.add_latest_playlist_to_tree) # type: ignore
|
window.playlistCreatedSignal.connect(self.add_latest_playlist_to_tree) # type: ignore
|
||||||
window.exec_()
|
window.exec_()
|
||||||
|
|
||||||
def import_playlist(self) -> None:
|
def import_playlist(self) -> None:
|
||||||
@ -562,17 +562,17 @@ if __name__ == "__main__":
|
|||||||
Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini"
|
Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini"
|
||||||
)
|
)
|
||||||
cfg_path = str(Path(user_config_dir(appname="musicpom", appauthor="billypom")))
|
cfg_path = str(Path(user_config_dir(appname="musicpom", appauthor="billypom")))
|
||||||
debug(f'config file: {cfg_file}')
|
debug(f"config file: {cfg_file}")
|
||||||
debug(f'config path: {cfg_path}')
|
debug(f"config path: {cfg_path}")
|
||||||
|
|
||||||
# If config path doesn't exist, create it
|
# If config path doesn't exist, create it
|
||||||
if not os.path.exists(cfg_path):
|
if not os.path.exists(cfg_path):
|
||||||
os.makedirs(cfg_path)
|
os.makedirs(cfg_path)
|
||||||
# If the config file doesn't exist, create it from the sample config
|
# If the config file doesn't exist, create it from the sample config
|
||||||
if not os.path.exists(cfg_file):
|
if not os.path.exists(cfg_file):
|
||||||
debug('copying sample config')
|
debug("copying sample config")
|
||||||
# Create config file from sample
|
# Create config file from sample
|
||||||
run(["cp", "sample_config.ini", cfg_file])
|
run(["cp", "./sample_config.ini", cfg_file])
|
||||||
config = ConfigParser()
|
config = ConfigParser()
|
||||||
config.read(cfg_file)
|
config.read(cfg_file)
|
||||||
db_filepath: str = config.get("db", "database")
|
db_filepath: str = config.get("db", "database")
|
||||||
@ -580,7 +580,7 @@ if __name__ == "__main__":
|
|||||||
# If the database location isnt set at the config location, move it
|
# If the database location isnt set at the config location, move it
|
||||||
if not db_filepath.startswith(cfg_path):
|
if not db_filepath.startswith(cfg_path):
|
||||||
new_path = f"{cfg_path}/{db_filepath}"
|
new_path = f"{cfg_path}/{db_filepath}"
|
||||||
debug(f'setting new db-database path: {new_path}')
|
debug(f"setting new db-database path: {new_path}")
|
||||||
config["db"]["database"] = new_path
|
config["db"]["database"] = new_path
|
||||||
# Save the config
|
# Save the config
|
||||||
with open(cfg_file, "w") as configfile:
|
with open(cfg_file, "w") as configfile:
|
||||||
|
|||||||
@ -1,38 +1,46 @@
|
|||||||
import DBA
|
import DBA
|
||||||
import logging
|
import os
|
||||||
|
from logging import debug
|
||||||
from utils import get_id3_tags, id3_timestamp_to_datetime
|
from utils import get_id3_tags, id3_timestamp_to_datetime
|
||||||
from PyQt5.QtCore import pyqtSignal
|
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from appdirs import user_config_dir
|
from appdirs import user_config_dir
|
||||||
|
import platform
|
||||||
config = ConfigParser()
|
|
||||||
cfg_file = (
|
|
||||||
Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini"
|
|
||||||
)
|
|
||||||
config.read(cfg_file)
|
|
||||||
|
|
||||||
|
|
||||||
def add_files_to_library(files, progress_callback=None):
|
def add_files_to_library(files, progress_callback=None):
|
||||||
"""Adds audio file(s) to the sqllite db
|
|
||||||
files = list() of fully qualified paths to audio file(s)
|
|
||||||
Returns a list of dictionaries of metadata
|
|
||||||
"""
|
"""
|
||||||
logging.info("started function")
|
Adds audio file(s) to the sqllite db
|
||||||
|
Args:
|
||||||
|
files: list() of fully qualified paths to audio file(s)
|
||||||
|
progress_callback: emit data for user feedback
|
||||||
|
Returns:
|
||||||
|
True on success, else False
|
||||||
|
"""
|
||||||
|
config = ConfigParser()
|
||||||
|
cfg_file = (
|
||||||
|
Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini"
|
||||||
|
)
|
||||||
|
config.read(cfg_file)
|
||||||
|
|
||||||
if not files:
|
if not files:
|
||||||
return []
|
return False
|
||||||
extensions = config.get("settings", "extensions").split(",")
|
extensions = config.get("settings", "extensions").split(",")
|
||||||
insert_data = [] # To store data for batch insert
|
insert_data = [] # To store data for batch insert
|
||||||
for filepath in files:
|
for filepath in files:
|
||||||
if any(filepath.lower().endswith(ext) for ext in extensions):
|
if any(filepath.lower().endswith(ext) for ext in extensions):
|
||||||
if progress_callback:
|
if progress_callback:
|
||||||
progress_callback.emit(filepath)
|
progress_callback.emit(filepath)
|
||||||
|
# if "microsoft-standard" in platform.uname().release:
|
||||||
|
# filename = filepath.split(r"\\")[-1]
|
||||||
|
# filepath = os.path.join(filepath)
|
||||||
|
# else:
|
||||||
filename = filepath.split("/")[-1]
|
filename = filepath.split("/")[-1]
|
||||||
audio = get_id3_tags(filepath)
|
audio = get_id3_tags(filepath)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
title = audio["TIT2"].text[0]
|
title = audio["TIT2"].text[0]
|
||||||
except KeyError as e:
|
except KeyError:
|
||||||
title = filename
|
title = filename
|
||||||
try:
|
try:
|
||||||
artist = audio["TPE1"].text[0]
|
artist = audio["TPE1"].text[0]
|
||||||
@ -75,7 +83,7 @@ def add_files_to_library(files, progress_callback=None):
|
|||||||
)
|
)
|
||||||
# Check if batch size is reached
|
# Check if batch size is reached
|
||||||
if len(insert_data) >= 1000:
|
if len(insert_data) >= 1000:
|
||||||
logging.info(f"inserting a LOT of songs: {len(insert_data)}")
|
debug(f"inserting a LOT of songs: {len(insert_data)}")
|
||||||
with DBA.DBAccess() as db:
|
with DBA.DBAccess() as db:
|
||||||
db.executemany(
|
db.executemany(
|
||||||
"INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
"INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
@ -86,9 +94,9 @@ def add_files_to_library(files, progress_callback=None):
|
|||||||
# continue adding files if we havent reached big length
|
# continue adding files if we havent reached big length
|
||||||
continue
|
continue
|
||||||
# Insert any remaining data
|
# Insert any remaining data
|
||||||
logging.info("i check for insert data")
|
debug("i check for insert data")
|
||||||
if insert_data:
|
if insert_data:
|
||||||
logging.info(f"inserting some songs: {len(insert_data)}")
|
debug(f"inserting some songs: {len(insert_data)}")
|
||||||
with DBA.DBAccess() as db:
|
with DBA.DBAccess() as db:
|
||||||
db.executemany(
|
db.executemany(
|
||||||
"INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
"INSERT OR IGNORE INTO song (filepath, title, album, artist, track_number, genre, codec, album_date, bitrate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
|||||||
@ -2,12 +2,11 @@
|
|||||||
# https://github.com/ravenkls/MilkPlayer/blob/master/audio/fft_analyser.py
|
# https://github.com/ravenkls/MilkPlayer/blob/master/audio/fft_analyser.py
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import os
|
|
||||||
from PyQt5 import QtCore
|
from PyQt5 import QtCore
|
||||||
from pydub import AudioSegment
|
from pydub import AudioSegment
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy.ndimage.filters import gaussian_filter1d
|
from scipy.ndimage.filters import gaussian_filter1d
|
||||||
from logging import info
|
from logging import debug
|
||||||
|
|
||||||
|
|
||||||
class FFTAnalyser(QtCore.QThread):
|
class FFTAnalyser(QtCore.QThread):
|
||||||
@ -66,9 +65,9 @@ class FFTAnalyser(QtCore.QThread):
|
|||||||
if not data.size:
|
if not data.size:
|
||||||
return
|
return
|
||||||
|
|
||||||
for n, f in enumerate(np.arange(0, 1, point_range), start=1):
|
for i, freq in enumerate(np.arange(0, 1, point_range), start=1):
|
||||||
# get the amps which are in between the frequency range
|
# get the amps which are in between the frequency range
|
||||||
amps = data[(f - point_range < data[:, 0]) & (data[:, 0] < f)]
|
amps = data[(freq - point_range < data[:, 0]) & (data[:, 0] < freq)]
|
||||||
if not amps.size:
|
if not amps.size:
|
||||||
point_samples.append(0)
|
point_samples.append(0)
|
||||||
else:
|
else:
|
||||||
@ -76,7 +75,7 @@ class FFTAnalyser(QtCore.QThread):
|
|||||||
amps.max()
|
amps.max()
|
||||||
* (
|
* (
|
||||||
(1 + self.sensitivity / 10 + (self.sensitivity - 1) / 10)
|
(1 + self.sensitivity / 10 + (self.sensitivity - 1) / 10)
|
||||||
** (n / 50)
|
** (i / 50)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user