added song value via stft function

This commit is contained in:
Alexander Karpov 2024-01-15 21:59:54 +03:00
parent dba8bc9ba4
commit 8309f105fd
9 changed files with 812 additions and 118 deletions

View File

@ -53,6 +53,7 @@ class Meta:
"album", "album",
"liked", "liked",
"meta", "meta",
"volume",
] ]
extra_kwargs = { extra_kwargs = {
"slug": {"read_only": True}, "slug": {"read_only": True},

View File

@ -0,0 +1,20 @@
# Generated by Django 4.2.8 on 2024-01-15 17:28
import django.contrib.postgres.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("music", "0015_usermusicprofile"),
]
operations = [
migrations.AddField(
model_name="song",
name="volume",
field=django.contrib.postgres.fields.ArrayField(
base_field=models.IntegerField(), null=True, size=None
),
),
]

View File

@ -1,3 +1,4 @@
from django.contrib.postgres.fields import ArrayField
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
@ -47,6 +48,7 @@ class Song(BaseImageModel, ShortLinkModel):
) )
meta = models.JSONField(blank=True, null=True) meta = models.JSONField(blank=True, null=True)
likes = models.IntegerField(default=0) likes = models.IntegerField(default=0)
volume = ArrayField(models.IntegerField(), null=True)
def get_absolute_url(self): def get_absolute_url(self):
return reverse("music:song", kwargs={"slug": self.slug}) return reverse("music:song", kwargs={"slug": self.slug})

View File

@ -3,7 +3,9 @@
from pathlib import Path from pathlib import Path
from random import randint from random import randint
import librosa
import mutagen import mutagen
import numpy as np
from mutagen.id3 import ID3 from mutagen.id3 import ID3
from PIL import Image, UnidentifiedImageError from PIL import Image, UnidentifiedImageError
@ -59,3 +61,25 @@ def process_mp3_file(path: str, user_id: int) -> None:
load_track(path, image_pth, user_id, author, album, name) load_track(path, image_pth, user_id, author, album, name)
if image_pth and os.path.exists(image_pth): if image_pth and os.path.exists(image_pth):
os.remove(image_pth) os.remove(image_pth)
def analyze_music_loudness(mp3_file):
y, sr = librosa.load(mp3_file, sr=None)
frame_length = int(0.5 * sr)
stft = np.abs(librosa.stft(y, n_fft=frame_length, hop_length=frame_length))
rms_energy = librosa.feature.rms(
S=stft, frame_length=frame_length, hop_length=frame_length
)[0]
scaling_factor = 10000
scaled_rms_energy = rms_energy * scaling_factor
# Convert the scaled RMS energy to a list of integers
rms_energy_integers = [int(x) for x in scaled_rms_energy]
return rms_energy_integers
def set_song_volume(song: Song):
mp3_file = song.file.path
song.volume = analyze_music_loudness(mp3_file)
song.save(update_fields=["volume"])

View File

@ -4,6 +4,7 @@
from django.dispatch import receiver from django.dispatch import receiver
from akarpov.music.models import Album, Author, PlaylistSong, Song, SongUserRating from akarpov.music.models import Album, Author, PlaylistSong, Song, SongUserRating
from akarpov.music.services.file import set_song_volume
from akarpov.music.services.info import update_album_info, update_author_info from akarpov.music.services.info import update_album_info, update_author_info
@ -14,6 +15,12 @@ def auto_delete_file_on_delete(sender, instance, **kwargs):
os.remove(instance.file.path) os.remove(instance.file.path)
@receiver(post_save, sender=Song)
def song_create(sender, instance: Song, created, **kwargs):
if instance.volume is None:
set_song_volume(instance)
@receiver(post_save, sender=Author) @receiver(post_save, sender=Author)
def author_create(sender, instance, created, **kwargs): def author_create(sender, instance, created, **kwargs):
if created: if created:

View File

@ -6,8 +6,8 @@
urlpatterns = [ urlpatterns = [
path("", views.music_landing, name="landing"), path("", views.music_landing, name="landing"),
path("upload", views.load_track_view, name="load"), path("upload", views.load_track_view, name="upload"),
path("upload_file", views.load_track_file_view, name="upload"), path("upload_file", views.load_track_file_view, name="upload_file"),
path("<str:slug>", views.song_view, name="song"), path("<str:slug>", views.song_view, name="song"),
path("album/<str:slug>", views.album_view, name="album"), path("album/<str:slug>", views.album_view, name="album"),
path("author/<str:slug>", views.author_view, name="author"), path("author/<str:slug>", views.author_view, name="author"),

View File

@ -2,7 +2,7 @@
{% block content %} {% block content %}
<h1>Welcome to music app</h1> <h1>Welcome to music app</h1>
<p>This is mainly the backend of music, you should consider using side clients like: <a href="https://next.akarpov.ru/msuic">otomir23's client</a></p> <p>This is mainly the backend of music, you should consider using side clients like: <a href="https://next.akarpov.ru/music">otomir23's client</a></p>
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
{% if last_fm_account %} {% if last_fm_account %}
<p>Last.fm connected to {{ last_fm_account }}, <a href="{% url 'music:lastfm_connect' %}">reconnect</a></p> <p>Last.fm connected to {{ last_fm_account }}, <a href="{% url 'music:lastfm_connect' %}">reconnect</a></p>
@ -12,4 +12,13 @@
{% else %} {% else %}
<p>Login to connect last.fm account</p> <p>Login to connect last.fm account</p>
{% endif %} {% endif %}
{% if request.user.is_superuser %}
<p>
<a href="{% url 'music:upload' %}">Upload</a>
</p>
<p>
<a href="{% url 'music:upload_file' %}">Upload file</a>
</p>
{% endif %}
{% endblock %} {% endblock %}

858
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -113,13 +113,14 @@ django-elasticsearch-dsl = "^8.0"
elasticsearch-dsl = "^8.11.0" elasticsearch-dsl = "^8.11.0"
numpy = "1.25.2" numpy = "1.25.2"
deep-translator = "1.4.2" deep-translator = "1.4.2"
textract = {git = "https://github.com/Alexander-D-Karpov/textract.git", branch = "master"}
django-otp = "^1.3.0" django-otp = "^1.3.0"
qrcode = {extras = ["pil"], version = "^7.4.2"} qrcode = {extras = ["pil"], version = "^7.4.2"}
spotdl = "^4.2.4" spotdl = "^4.2.4"
fuzzywuzzy = "^0.18.0" fuzzywuzzy = "^0.18.0"
python-levenshtein = "^0.23.0" python-levenshtein = "^0.23.0"
pylast = "^5.2.0" pylast = "^5.2.0"
textract = {git = "https://github.com/Alexander-D-Karpov/textract.git"}
librosa = "^0.10.1"
[build-system] [build-system]