Ich nahm Musik (hauptsächlich Anison) von einer CD und hörte sie mit Walkman, aber bevor ich es wusste, überstiegen meine Dateien 8000 Songs. Selbst wenn ich darüber nachdenke, eine Wiedergabeliste zu erstellen, ** dauert es sehr lange, meinen Lieblingsanison in die Wiedergabeliste zu werfen **, die Verbindungsinformationen aus der Künstlerliste zu überprüfen, Songs hinzuzufügen usw. ** Der Urlaub ist vorbei **. (Ich denke nicht, dass es für jemanden relevant ist, der Spotify, Apple Music usw. verwendet.) Es wäre schön, wenn ich diese Art von Arbeit genießen könnte, aber da ich es leid war, Wiedergabelisten zu erstellen, stellte ich fest, dass ** ich überhaupt nicht für die Erstellung von Wiedergabelisten geeignet war **. Glücklicherweise wurde mir klar, dass ** ich keine Wiedergabelisten erstellen kann, aber ich kann Programme schreiben **, also habe ich ein Programm erstellt, das automatisch Anison-Wiedergabelisten erstellt, aber es gab viele Dinge, die nicht funktionierten, also habe ich Informationen ausgetauscht. Ich habe auch einen Artikel geschrieben.
Obwohl die Einführung lang geworden ist, ist das diesmal erstellte Programm ein Programm, das ** anison Wiedergabeliste (m3u-Datei) ** aus ** vorhandenen Musikdateien (m4a, mp3, flac-Dateien) ** erstellt. Der Inhalt des Prozesses ist
Wenn Sie einen beliebigen Pfad angeben und die Schaltfläche Ausführen drücken, wird der auf dem PC gespeicherte Anison extrahiert und die Wiedergabelistendatei ausgegeben. Es ist auch möglich, eine Wiedergabeliste zu erstellen, indem Sie eine bestimmte Animation angeben, indem Sie den Arbeitsnamen angeben. Der Quellcode und die ausführbare Datei (für Windows) befinden sich auf GitHub. Überprüfen Sie sie daher ebenfalls.
Der Basiscode des Wiedergabelistengenerators lautet apg.py in dem auf github veröffentlichten Code. Ich habe auch den in PyQt5 implementierten GUI-Code apg_gui.py implementiert. Da dies jedoch nur die in apg.py definierte Klasse aufruft, können Sie eine Wiedergabeliste nur mit apg.py erstellen. In apg.py wird ** A ** nison ** P ** laylist ** G ** enerator als APG-Klasse abgekürzt und hat Funktionen, die 1 bis 3 der obigen Implementierung entsprechen. Ich werde. Die Details jedes Prozesses werden unten erklärt.
Die Funktion MakeAnisonDatabase in apg.py wird erklärt. Hier werden die Informationen von Anison in der Datenbank gespeichert. Der Grund für die Verwendung der Datenbank besteht darin, dass es sinnlos ist, jedes Mal, wenn Sie eine Wiedergabeliste erstellen, Anison-Daten und Musik zu erfassen. Sobald Sie eine Datenbank erstellt haben, können Sie die Zeit reduzieren, die zum Erstellen der zweiten und nachfolgender Wiedergabelisten erforderlich ist. Es ist das Ergebnis des Denkens. Ich muss es nur verschieben, also implementiere ich es, ohne tief über die Struktur der Datenbank nachzudenken (obwohl ich einfach keine Kenntnisse über die Datenbank habe ...). Die verwendete Bibliothek ist sqlite3. Der spezifische Code lautet wie folgt. Rufen Sie zunächst den Pfad der DL-CSV-Datei von Anison Generation ab. DL verfügt über drei Zip-Dateien, die in einer Datei namens anison.csv für Animationen, game.csv für Spiele und sf.csv für Spezialeffekte gespeichert sind (der ursprüngliche Zweck ist Animation, aber es ist eine große Sache. Ich benutze auch Spiele und Spezialeffekte. Wenn Sie den entpackten Ordner in den Datenordner legen, ist dies wie folgt.
./data/ --- anison/ -- anison.csv #Anime
| └ readme.txt
├ game/ --- game.csv #Spiel
| └ readme.txt
└ sf/--- sf.csv #Spezialeffekte
└ readme.txt
Jeder Ordner enthält auch eine Textdatei. Wenn Sie jedoch den folgenden Code ausführen, können Sie nur die CSV-Datei abrufen, selbst wenn Sie den entpackten Ordner so wie er ist in ./data ablegen.
path_data = "./data" #Ordner, in dem die von Anison Generation heruntergeladene CSV-Datei gespeichert wird
file_paths = [i for i in glob.glob(path_data + "/**", recursive=True) if os.path.splitext(i)[-1] == ".csv"] #Holen Sie sich nur den Pfad der CSV-Datei rekursiv
Registrieren Sie anschließend die Informationen in der CSV-Datei in der Datenbank. Da es nur drei CSV-Zieldateien gibt, anison.csv, game.csv und sf.csv, lesen Sie keine anderen Dateien. Der folgende Code erstellt Tabellen mit den Namen anison, game und sf und registriert 1000 Zeilen in der Datenbank. (Ich habe auf eine Website verwiesen, aber ich habe das Gefühl, dass sie sich nicht mit oder ohne ändert.)
data_name = ["anison.csv", "game.csv", "sf.csv"] #Der Name der von Anison Generation heruntergeladenen CSV-Datei
for file_path in file_paths:
if os.path.basename(file_path) in data_name: #Der Name der CSV-Datei lautet anison.csv, game.csv, sf.Wenn einer von csv
category = os.path.splitext(os.path.basename(file_path))[0]
# anison, game,Erstellen Sie eine Tabelle mit dem Namen sf
with sqlite3.connect(self.path_database)as con, open(file_path, "r", encoding="utf-8") as f:
cursor = con.cursor()
#Erstellen, wenn keine Tabelle vorhanden ist
cursor.execute("CREATE TABLE IF NOT EXISTS '%s'('%s', '%s', '%s', '%s', '%s', '%s')" % (category, "artist", "title", "anime", "genre", "oped", "order"))
command = "INSERT INTO " + category + " VALUES(?, ?, ?, ?, ?, ?)" #SQL-Anweisungsdefinition
lines = f.readlines() #CSV-Datei lesen
buffer = [] #Variablen zum gemeinsamen Registrieren von Daten
buffer_size = 1000 #Registrieren Sie 100 Artikel gleichzeitig
for i, line in tqdm(enumerate(lines[1:])): #Lesen Sie die CSV-Datei Zeile für Zeile
*keys, = line.split(",") #Holen Sie sich den Schlüssel für jede Zeile
#Holen Sie sich den Namen des Sängers, den Namen des Songs, die Sendereihenfolge, den OPED-Typ, den Anime-Namen und das Genre als Schlüssel
artist, title, order, oped, anime, genre = trim(keys[7]), trim(keys[6]), trim(keys[4]), trim(keys[3]), trim(keys[2]), trim(keys[1])
buffer.append([artist, title, anime, genre, oped, order])
if i%buffer_size == 0 or i == len(lines) - 1:
cursor.executemany(command, buffer) #SQL-Ausführung
buffer = []
#Löschen Sie doppelt registrierte Daten
cursor.executescript("""
CREATE TEMPORARY TABLE tmp AS SELECT DISTINCT * FROM """ + category + """;
DELETE FROM """ + category + """;
INSERT INTO """ + category + """ SELECT * FROM tmp;
DROP TABLE tmp;
""")
con.commit()
Die Trimmfunktion ist eine Funktion, die Zeichen, die beim Erstellen einer Datenbank oder Wiedergabeliste nicht erwünscht sind, durch andere Zeichen ersetzt und Zeichenfolgen wie Zeilenumbrüche und Kommas löscht. Außerdem gab es ein Problem beim Erstellen einer Wiedergabeliste, selbst wenn es einen Unterschied zwischen voller Breite und halber Breite gab. Daher wurden alle Zeichen, die in der Mojimoji-Bibliothek in Zeichen halber Breite konvertiert werden können, in Zeichen halber Breite geändert.
import mojimoji as moji
def trim(name):
name = name.replace("\n", "").replace('\'', '_').replace(" ", "").replace("\x00", "").replace("\"", "")
name = moji.zen_to_han(name)
return name.lower()
Holen Sie sich als Nächstes die Informationen der auf dem PC gespeicherten Musikdatei und registrieren Sie sie in der Datenbank.
Das Format der m3u-Datei, bei der es sich um eine Wiedergabelistendatei handelt, lautet wie folgt. Die Länge des Songs, der Titel des Songs und der Pfad zur Musikdatei sind für jeden Song erforderlich.
#EXTM3U
#EXTINF:Songlänge, Songtitel
Absoluter Pfad zur Datei
#EXTINF:Songlänge, Songtitel
Absoluter Pfad zur Datei
:
In der Funktion MakeMusiclibrary wird der Pfad der Musikdatei erfasst und die Musikdatei auf die gleiche Weise wie die Anison-Daten in der Datenbank registriert. Der Prozess des Erfassens von Anison-Daten hat sich in eine Musikdatei geändert, aber der grundlegende Prozess unterscheidet sich nicht wesentlich vom Prozess von ↑. Ich habe die folgende Funktion definiert, um die Informationen der Musikdatei zu erhalten.
from mutagen.flac import FLAC
from mutagen.mp3 import MP3
from mutagen.mp4 import MP4
def getMusicInfo(path):
length, audio, title, artist = 0, "", "", ""
if path.endswith(".flac"):
audio = FLAC(path)
artist = trim(audio.get('artist', [""])[0])
title = trim(audio.get('title', [""])[0])
length = audio.info.length
elif path.endswith(".mp3"):
audio = EasyID3(path)
artist = trim(audio.get('artist', [""])[0])
title = trim(audio.get('title', [""])[0])
length = MP3(path).info.length
elif path.endswith(".m4a"):
audio = MP4(path)
artist = trim(audio.get('\xa9ART', [""])[0])
title = trim(audio.get('\xa9nam', [""])[0])
length = audio.info.length
return audio, artist, title, length
Die Funktion getMusicInfo ruft den Songtitel, den Sängernamen und die Songlänge aus dem Dateipfad ab. Die Dateien, die die Musikbibliothek in der Datenbank registrieren, lauten wie folgt. Für den Namen und den Titel des Sängers wurden unbequeme Zeichen mit der Trimmfunktion konvertiert.
def makeLibrary(path_music):
music_files = glob.glob(path_music + "/**", recursive=True) #Holen Sie sich alle Dateien in der Bibliothek
#Erstellen Sie eine Tabelle mit dem Namen Bibliothek und registrieren Sie Musikdateien
with sqlite3.connect(self.path_database) as con:
cursor = con.cursor()
#Wenn keine Bibliothekstabelle vorhanden ist, erstellen Sie diese
cursor.execute("CREATE TABLE IF NOT EXISTS library(artist, title, length, path)")
#SQL-Anweisung
command = "INSERT INTO library VALUES(?, ?, ?, ?)"
buffer = []
for i, music_file in tqdm(enumerate(music_files)):
audio, artist, title, length = getMusicInfo(music_file) #Informationen zu Musikdateien aus dem Pfad abrufen
if audio != "":
buffer.append(tuple([trim(artist), trim(title), length, music_file]))
if i % 1000 == 0 or i == len(music_files) - 1:
cursor.executemany(command, buffer)
buffer = []
cursor.executescript("""
CREATE TEMPORARY TABLE tmp AS SELECT DISTINCT * FROM library;
DELETE FROM library;
INSERT INTO library SELECT * FROM tmp;
DROP TABLE tmp;
""")
con.commit()
Als nächstes werde ich die Funktion erklären, die eine Wiedergabeliste unter Verwendung der bisherigen Daten ausgibt.
Die Erklärung hier bezieht sich auf die Funktion generatePlaylist in apg.py (ich habe verschiedene Dinge zur Erklärung weggelassen ...). Zunächst wird der Name des Sängers aus den in der Datenbank registrierten Anison-Informationen ermittelt. Die SQL-Anweisung und der Ausführungsteil lauten wie folgt. Kategorie ist ein Tabellenname, der anison, game oder sf sein kann. Ersetzen Sie die erfasste Liste der Sängernamen durch eine entsprechende Variable. (Der Zugriff auf die Datenbank ist der gleiche wie im obigen Programm, daher wird er weggelassen.)
cursor.execute("SELECT DISTINCT artist FROM '%s'" % category)
artist_db = cursor.fetchall()
In ähnlicher Weise erhalten Sie den Namen des Sängers in der Musikbibliothek.
cursor.execute('SELECT artist FROM library')
artist_lib = sorted(set([artist[0] for artist in cursor.fetchall()]))
Stellen Sie als Nächstes fest, ob der Name des Sängers in der Musikbibliothek in der Liste der Sängernamen in der Anison-Datenbank enthalten ist, dh ob der Sänger in der Musikbibliothek möglicherweise den Anison gesungen hat. Ich denke, es ist eine Kultur, die Anison eigen ist, aber wenn Musik von einer CD importiert wird, kann der Name des Sängers der Charaktername sein (vgl. Name des Synchronsprechers). Andererseits wird die Sängerliste in der Anison-Datenbank (wahrscheinlich) nach dem Namen des Synchronsprechers registriert, sodass es nicht möglich ist, nach der genauen Übereinstimmung des Sängernamens zu suchen. Daher untersuchten wir die Ähnlichkeit zwischen dem Sänger in der Musikbibliothek und dem Sänger in der Anison-Datenbank und wählten den Sängernamen mit der höchsten Ähnlichkeit und der maximalen Ähnlichkeit, die den Schwellenwert überschreitet, als den Sänger, der möglicherweise Anison singt. Im Code (apg.py) entspricht es dem folgenden Teil.
#Für alle Künstler in der Bibliothek
for i, artist in artist_lib:
#Berechnen Sie die Ähnlichkeit von Künstlernamen
similarities = [difflib.SequenceMatcher(None, artist, a[0]).ratio() for a in artist_db]
if th_artist < max(similarities): #Wenn der maximale Ähnlichkeitswert über dem Schwellenwert liegt
#Holen Sie sich alle Song-Informationen des Zielkünstlers
info_list = self.getInfoDB('SELECT * FROM library WHERE artist LIKE \'' + artist + '\'', cursor)
Nachdem Sie den Sänger identifiziert haben, rufen Sie alle Songinformationen dieses Sängers in der Musikbibliothek ab und suchen Sie die Songs in der Musikbibliothek nach Anison. Die Tatsache, dass genaue Übereinstimmungen nicht für Sängernamen verwendet werden können, bedeutet auch, dass genaue Übereinstimmungen nicht für Songtitel verwendet werden können. Beispielsweise stimmt ein Titel wie ein Songname (Albumver.) Genau überein und wird nicht durchsucht. Daher überprüft die Musikliste auch die Ähnlichkeit.
#Es ist eine Fortsetzung der if-Anweisung von ↑
#Holen Sie sich alle Songs des Sängers mit dem höchsten Grad an Ähnlichkeit aus der Anison-Datenbank
cursor.execute("SELECT DISTINCT * FROM '%s' WHERE artist LIKE \'%%%s%%\'" % (category, artist_db[similarities.index(max(similarities))][0]))
title_list = cursor.fetchall() #Liste der Songs eines bestimmten Künstlers in der Anison-Datenbank
for info in info_list: #Finden Sie heraus, ob alle Songs in Ihrer Musikbibliothek anison sind
artist, title, length, path = info[0], info[1], info[2], info[3]
title_ratio = [difflib.SequenceMatcher(None, title, t[1]).ratio() for t in title_list] #Berechnen Sie die Ähnlichkeit mit den Songs in der Anison-Datenbank
if th_title < max(title_ratio): #Anison, wenn die Ähnlichkeit über der Schwelle liegt
t = title_list[title_ratio.index(max(title_ratio))]
lines.append(['#EXTINF: ' + str(int(length)) + ', ' + title + "\n" + path, t[-1]]) # .Variablen für die Ausgabe der m3u-Datei(aufführen)Hinzufügen
Nachdem Sie die Ähnlichkeit aller Künstler und die Ähnlichkeit der Songs berechnet haben, schreiben Sie die Informationen des in den variablen Zeilen enthaltenen Anison in eine Datei.
path_playlist = "./playlist/AnimeSongs.m3u"
with open(path_playlist, 'w', encoding='utf-16') as pl:
pl.writelines('#EXTM3U \n')
pl.writelines("\n".join([line[0] for line in lines]))
Sie haben jetzt eine Anison-Wiedergabeliste erstellt. Zur Erklärung gibt es einige Unterschiede zu dem auf github veröffentlichten Code. Wenn Sie also interessiert sind, überprüfen Sie bitte apg.py auf github.
Durch das Erstellen von drei Funktionen ist es möglich, vorerst eine Wiedergabeliste zu erstellen, aber ich möchte auf einige der Probleme eingehen, die bei dieser Implementierung aufgetreten sind.
Derzeit besteht das Problem, dass Songs, die nicht anison sind, beim Erstellen der Wiedergabeliste auch in die Wiedergabeliste aufgenommen werden. Wenn Sie beispielsweise die Animation BLEACH als Titel Ihrer Arbeit festlegen, wird zusätzlich zu UVERworlds D-technolife ein sehr ähnliches Lied namens D-technorize zur Wiedergabeliste hinzugefügt. Wenn Sie versuchen, eine Gundam UC-Wiedergabeliste zu erstellen, werden neben Aimers Re: I auch die Songs Re: far und Re: pray in die Gundam UC-Wiedergabeliste aufgenommen. Im Falle einer solchen Arbeit allein kann dies durch Erhöhen der Ähnlichkeitsschwelle von Liedern behoben werden. Da sich die Schwelle von Liedern jedoch je nach Animation unterscheidet, ist es derzeit schwierig, eine Wiedergabeliste von Anison zu erstellen, die nicht auf eine bestimmte Animation beschränkt ist. Es ist geworden. Ich denke, es hängt mit den folgenden Problemen zusammen, aber wenn ich eine gute Methode finde, würde ich sie gerne verbessern.
Derzeit ist die Datenbank nur ein temporärer Speicherort für Daten und wird am Ende mit der for-Anweisung verarbeitet. Wenn ich SQL intelligenter schreiben kann, wird sich die Erstellungszeit für Wiedergabelisten meiner Meinung nach verkürzen. Daher möchte ich den Code für die Datenbank in Zukunft neu schreiben.
Es war zu schwierig, eine Anison-Wiedergabeliste zu erstellen, daher habe ich eine Software erstellt, die automatisch eine Anison-Wiedergabeliste erstellt. Es gibt immer noch einige Probleme, aber ich denke, wir haben Software mit den minimalen Funktionen erstellt. Rückblickend war das Ergebnis, dass ** die Zeit, die für das Codieren aufgewendet wurde, die Zeit, die zum Erstellen einer Wiedergabeliste benötigt wurde, bei weitem überstieg **, aber ich wünschte, ich könnte Leute retten, die ähnliche Probleme haben. habe gedacht. Last but not least, wenn Sie Fehler oder Verbesserungen haben (insbesondere in Bezug auf die datenbankbezogene Verarbeitung), würde ich mich freuen, wenn Sie einen Kommentar abgeben könnten. Vielen Dank für das Lesen bis zum Ende.
2020/03/04 veröffentlicht
Recommended Posts