fix normalizing audio removing thumbnail and metadata

This commit is contained in:
csd4ni3l
2025-06-24 10:05:43 +02:00
parent b9ced9e935
commit 4d0acd5ebb
3 changed files with 53 additions and 20 deletions

View File

@@ -1,11 +1,10 @@
from mutagen.easyid3 import EasyID3 from mutagen.easyid3 import EasyID3
from pydub import AudioSegment
import arcade, arcade.gui, os, json, threading, subprocess import arcade, arcade.gui, os, json, threading, subprocess
from arcade.gui.experimental.focus import UIFocusGroup from arcade.gui.experimental.focus import UIFocusGroup
from utils.utils import UIFocusTextureButton, ensure_yt_dlp from utils.utils import ensure_yt_dlp, adjust_volume
from utils.constants import button_style from utils.constants import button_style
from utils.preload import button_texture, button_hovered_texture from utils.preload import button_texture, button_hovered_texture
@@ -132,14 +131,9 @@ class Downloader(arcade.gui.UIView):
return return
if self.settings_dict.get("normalize_audio", True): if self.settings_dict.get("normalize_audio", True):
self.yt_dl_buffer = "Normalizing audio..."
try: try:
audio = AudioSegment.from_file("downloaded_music.mp3") adjust_volume("downloaded_music.mp3", self.settings_dict.get("normalized_volume", -8))
if int(audio.dBFS) != self.settings_dict.get("normalized_volume", -8):
change = self.settings_dict.get("normalized_volume", -8) - audio.dBFS
audio = audio.apply_gain(change)
audio.export("downloaded_music.mp3", format="mp3")
except Exception as e: except Exception as e:
self.yt_dl_buffer = f"ERROR: Could not normalize volume due to an error: {e}" self.yt_dl_buffer = f"ERROR: Could not normalize volume due to an error: {e}"

View File

@@ -3,11 +3,10 @@ import arcade, pyglet
from utils.preload import * from utils.preload import *
from utils.constants import button_style, slider_style, audio_extensions, discord_presence_id from utils.constants import button_style, slider_style, audio_extensions, discord_presence_id
from utils.utils import FakePyPresence, UIFocusTextureButton, Card, extract_metadata, get_audio_thumbnail_texture, truncate_end, get_wrapped_text from utils.utils import FakePyPresence, UIFocusTextureButton, Card, extract_metadata, get_audio_thumbnail_texture, truncate_end, get_wrapped_text, adjust_volume
from math import ceil from math import ceil
from thefuzz import process, fuzz from thefuzz import process, fuzz
from pydub import AudioSegment
from arcade.gui.experimental.scroll_area import UIScrollArea, UIScrollBar from arcade.gui.experimental.scroll_area import UIScrollArea, UIScrollBar
@@ -134,6 +133,9 @@ class Main(arcade.gui.UIView):
# Controls # Controls
self.control_box = self.ui_box.add(arcade.gui.UIBoxLayout(size_hint=(0.95, 0.1), space_between=10, vertical=False)) self.control_box = self.ui_box.add(arcade.gui.UIBoxLayout(size_hint=(0.95, 0.1), space_between=10, vertical=False))
self.current_music_thumbnail_image = self.control_box.add(arcade.gui.UIImage(texture=music_icon, width=self.window.width / 25, height=self.window.height / 15))
self.current_music_label = self.control_box.add(arcade.gui.UILabel(text=truncate_end(self.current_music_name, int(self.window.width / 30)) if self.current_music_name else "No songs playing", font_name="Roboto", font_size=16)) self.current_music_label = self.control_box.add(arcade.gui.UILabel(text=truncate_end(self.current_music_name, int(self.window.width / 30)) if self.current_music_name else "No songs playing", font_name="Roboto", font_size=16))
self.time_label = self.control_box.add(arcade.gui.UILabel(text="00:00", font_name="Roboto", font_size=16)) self.time_label = self.control_box.add(arcade.gui.UILabel(text="00:00", font_name="Roboto", font_size=16))
@@ -415,13 +417,7 @@ class Main(arcade.gui.UIView):
self.current_music_label.text = "Normalizing audio..." self.current_music_label.text = "Normalizing audio..."
self.window.draw(delta_time) self.window.draw(delta_time)
try: try:
audio = AudioSegment.from_file(music_path) adjust_volume(music_path, self.settings_dict.get("normalized_volume", -8))
if int(audio.dBFS) != self.settings_dict.get("normalized_volume", -8):
change = self.settings_dict.get("normalized_volume", -8) - audio.dBFS
audio = audio.apply_gain(change)
audio.export(music_path, format="mp3")
except Exception as e: except Exception as e:
logging.error(f"Couldn't normalize volume for {music_path}: {e}") logging.error(f"Couldn't normalize volume for {music_path}: {e}")
@@ -437,7 +433,8 @@ class Main(arcade.gui.UIView):
self.current_length = self.loaded_sounds[music_name].get_length() self.current_length = self.loaded_sounds[music_name].get_length()
self.current_music_name = music_name self.current_music_name = music_name
self.current_music_label.text = truncate_end(music_name, int(self.window.width / 25)) self.current_music_thumbnail_image.texture = self.thumbnails[music_path]
self.current_music_label.text = truncate_end(music_name, int(self.window.width / 30))
self.time_label.text = "00:00" self.time_label.text = "00:00"
self.progressbar.max_value = self.current_length self.progressbar.max_value = self.current_length
self.progressbar.value = 0 self.progressbar.value = 0

View File

@@ -1,6 +1,8 @@
import logging, sys, traceback, os, re, platform, urllib.request, textwrap, io, base64 import logging, sys, traceback, os, re, platform, urllib.request, textwrap, io, base64, tempfile
from mutagen.easyid3 import EasyID3 from mutagen.easyid3 import EasyID3
from mutagen.id3 import ID3
from mutagen import File from mutagen import File
from pydub import AudioSegment
from PIL import Image from PIL import Image
from utils.constants import menu_background_color from utils.constants import menu_background_color
import pyglet, arcade, arcade.gui import pyglet, arcade, arcade.gui
@@ -267,3 +269,43 @@ def get_audio_thumbnail_texture(audio_path: str, window_resolution: tuple) -> ar
from utils.preload import music_icon from utils.preload import music_icon
return music_icon return music_icon
def adjust_volume(input_path, volume):
try:
easy_tags = EasyID3(input_path)
tags = dict(easy_tags)
tags = {k: v[0] if isinstance(v, list) else v for k, v in tags.items()}
except Exception as e:
tags = {}
try:
id3 = ID3(input_path)
apic_frames = [f for f in id3.values() if f.FrameID == "APIC"]
cover_path = None
if apic_frames:
apic = apic_frames[0]
ext = ".jpg" if apic.mime == "image/jpeg" else ".png"
temp_cover = tempfile.NamedTemporaryFile(delete=False, suffix=ext)
temp_cover.write(apic.data)
temp_cover.close()
cover_path = temp_cover.name
else:
cover_path = None
except Exception as e:
cover_path = None
audio = AudioSegment.from_file(input_path)
if int(audio.dbFS) == volume:
return
export_args = {
"format": "mp3",
"tags": tags
}
if cover_path:
export_args["cover"] = cover_path
change = volume - audio.dBFS
audio.apply_gain(change)
audio.export(input_path, **export_args)