・曲をそれぞれ解析し、アーティスト,歌手,曲の重複数など順位を調べる
Windows11
Visual Studio 2022 (Community)
Python 3.9(64bit)
# -*- coding: shift-jis -*-は、パスに日本語(マルチバイト文字)がある場合に必要
import os を先に書く
import os
# -*- coding: shift-jis -*-
dir_path = r"ミュージックフォルダまでのパス"
files = []
res = {}
res2 = {}
songs = {}
ジャケット画像を設定している場合はjpgファイル、ミュージックフォルダにはdesktop.iniがあるので拡張子からそれらを弾く
自分の持っているファイルの曲番号は2桁か3桁(01,001など)なので、空白位置からどっちか調べ、番号を消した状態で曲名をsongsに追加する(曲別ランキングに使用)
def add_file(path):
for name in os.listdir(path):
if len(name) > 4:
if name[-4:] == ".mp3":
if name[2] == ' ':
if name[3:-4] in songs:
songs[name[3:-4]] += 1
else:
songs[name[3:-4]] = 1
elif name[3] == ' ':
if name[4:-4] in songs:
songs[name[4:-4]] += 1
else:
songs[name[4:-4]] = 1
files.append(path + "\\" + name)
continue
elif name[-4:] == ".jpg" or name[-4:] == ".ini":
continue
add_file(path + "\\" + name)
TPE1タグにアーティスト情報が載っている(○○ Feat.△△ など)
TPE1タグを取得するライブラリは存在するが、文字化けするので使用しない。
なので、自力でバイナリーデータから取得し、文字コードの変換をする。
検索用のtarget ("TPE1")は、UTF-8でエンコードしておけば何とかなる
今のところ、文字コードは UTF-8,Shift-JIS,UTF-16のいずれかで対応できたので、try-exceptを使いしらみつぶしに変換する
ヌル文字はここで削除する(utf-16を除く)
def get_tpe1(path):
target = "TPE1".encode("utf-8")
with open(path,"br") as f:
data = f.read()
i = data.find(target) + 7
tmp = data[i + 4:i + 3 + data[i]]
rt = ""
if not i == -1:
try:
return tmp.replace(b"\x00",b"").decode("utf-8")
except Exception:
try:
return tmp.replace(b"\x00",b"").decode("shift-jis")
except Exception:
return tmp.decode("utf-16")
else:
return ""
取得したデータをソートして、ランキング(多い順)で表示する
アーティスト名とFeat以降の区切りを見つける
アーティスト名のみ(l = -1 + 5 つまり4)の場合は、アーティスト名のみを取得
replace()を使いアーティスト名の統一、名前の区切りの統一をしておく(例:ゴジマジP→ラマーズP Feat.初音ミク&鏡音リン→Feat.初音ミク,鏡音リン)
このプログラムでは、すべてのアーティスト名の別名には対応していないので注意(多い/有名なものだけ) すべて対応するのは非常に大変
add_file(dir_path)
print("曲数: ",len(files))
print("種類: ",len(songs))
for path in files:
ats = get_tpe1(path)
if not ats == "":
if "loves" in ats:
l = ats.lower().find("loves") + 5
else:
l = ats.lower().find("feat.") + 5
if not l == 4:
artist = ats[:l - 6] if ats[l - 6] == " " else ats[:l - 5]
artist = artist.replace("ryo","supercell").replace("ゴジマジP","ラマーズP").replace("ピノキオP","ピノキオピー").replace("ちょむP","TakeponG (ちょむP)").replace("1640mP","40mP").replace("じん (自然の敵P)","じん").replace("wowaka (現実逃避P)","wowaka").replace("マチゲリータP","マチゲリータ")
feats = ats[l:].replace(" ","").replace("x",",").replace("&",",").replace("+",",").replace("・",",").replace("、",",")
if ("鏡音リン" in feats) and (not ("鏡音レン" in feats)) and ("レン" in feats):
feats = feats.replace("レン","鏡音レン")
featsl = feats.split(",")
if artist in res2:
res2[artist] += 1
else:
res2[artist] = 1
for feat in featsl:
if feat in res:
res[feat] += 1
else:
res[feat] = 1
elif not len(ats) == 0:
artist = ats[:-1] if ats[-1] == " " else ats
artist = artist.replace("ryo","supercell").replace("ゴジマジP","ラマーズP").replace("ピノキオP","ピノキオピー").replace("ちょむP","TakeponG (ちょむP)").replace("1640mP","40mP").replace("じん (自然の敵P)","じん").replace("wowaka (現実逃避P)","wowaka").replace("マチゲリータP","マチゲリータ")
if artist in res2:
res2[artist] += 1
else:
res2[artist] = 1
sigma = [sum(res.values()),sum(res2.values())]
res = sorted(res.items(), key = lambda x : x[1], reverse = True)
res2 = sorted(res2.items(), key = lambda x : x[1], reverse = True)
songs = sorted(songs.items(), key = lambda x : x[1], reverse = True)
print("")
print("歌手別ランキング")
for result in res:
print(result," ",result[1] / sigma[0] * 100,"%")
print("")
print("アーティスト名ランキング")
for result2 in res2:
print(result2," ",result2[1] / sigma[1] * 100,"%")
print("")
print("曲別ランキング")
for song in songs:
print(song)
input()
import os
# -*- coding: shift-jis -*-
dir_path = r"C:\Users\森悟\Music"
files = []
res = {}
res2 = {}
songs = {}
def add_file(path):
for name in os.listdir(path):
if len(name) > 4:
if name[-4:] == ".mp3":
if name[2] == ' ':
if name[3:-4] in songs:
songs[name[3:-4]] += 1
else:
songs[name[3:-4]] = 1
elif name[3] == ' ':
if name[4:-4] in songs:
songs[name[4:-4]] += 1
else:
songs[name[4:-4]] = 1
files.append(path + "\\" + name)
continue
elif name[-4:] == ".jpg" or name[-4:] == ".ini":
continue
add_file(path + "\\" + name)
def get_tpe1(path):
target = "TPE1".encode("utf-8")
with open(path,"br") as f:
data = f.read()
i = data.find(target) + 7
tmp = data[i + 4:i + 3 + data[i]]
rt = ""
if not i == -1:
try:
return tmp.replace(b"\x00",b"").decode("utf-8")
except Exception:
try:
return tmp.replace(b"\x00",b"").decode("shift-jis")
except Exception:
return tmp.decode("utf-16")
else:
return ""
add_file(dir_path)
print("曲数: ",len(files))
print("種類: ",len(songs))
for path in files:
ats = get_tpe1(path)
if not ats == "":
if "loves" in ats:
l = ats.lower().find("loves") + 5
else:
l = ats.lower().find("feat.") + 5
if not l == 4:
artist = ats[:l - 6] if ats[l - 6] == " " else ats[:l - 5]
artist = artist.replace("ryo","supercell").replace("ゴジマジP","ラマーズP").replace("ピノキオP","ピノキオピー").replace("ちょむP","TakeponG (ちょむP)").replace("1640mP","40mP").replace("じん (自然の敵P)","じん").replace("wowaka (現実逃避P)","wowaka").replace("マチゲリータP","マチゲリータ")
feats = ats[l:].replace(" ","").replace("x",",").replace("&",",").replace("+",",").replace("・",",").replace("、",",")
if ("鏡音リン" in feats) and (not ("鏡音レン" in feats)) and ("レン" in feats):
feats = feats.replace("レン","鏡音レン")
featsl = feats.split(",")
if artist in res2:
res2[artist] += 1
else:
res2[artist] = 1
for feat in featsl:
if feat in res:
res[feat] += 1
else:
res[feat] = 1
elif not len(ats) == 0:
artist = ats[:-1] if ats[-1] == " " else ats
artist = artist.replace("ryo","supercell").replace("ゴジマジP","ラマーズP").replace("ピノキオP","ピノキオピー").replace("ちょむP","TakeponG (ちょむP)").replace("1640mP","40mP").replace("じん (自然の敵P)","じん").replace("wowaka (現実逃避P)","wowaka").replace("マチゲリータP","マチゲリータ")
if artist in res2:
res2[artist] += 1
else:
res2[artist] = 1
sigma = [sum(res.values()),sum(res2.values())]
res = sorted(res.items(), key = lambda x : x[1], reverse = True)
res2 = sorted(res2.items(), key = lambda x : x[1], reverse = True)
songs = sorted(songs.items(), key = lambda x : x[1], reverse = True)
print("")
print("歌手別ランキング")
for result in res:
print(result," ",result[1] / sigma[0] * 100,"%")
print("")
print("アーティスト名ランキング")
for result2 in res2:
print(result2," ",result2[1] / sigma[1] * 100,"%")
print("")
print("曲別ランキング")
for song in songs:
print(song)
input()
出力にファイル数×0.014秒くらいかかる(以下の量だと37秒くらい)
TPE1タグの表記形式のばらつきの関係上、歌手別ランキングの数値/種類の値が%と一致しないので注意
Feat.以降がないファイル(特にSupernova,STARDOMシリーズ)は特定不可能なため
曲数: 2647
種類: 2074
歌手別ランキング
('初音ミク', 1286) 53.49417637271215 %
('鏡音リン', 275) 11.43926788685524 %
('巡音ルカ', 177) 7.362728785357738 %
('GUMI', 168) 6.988352745424292 %
('鏡音レン', 101) 4.201331114808652 %
('KAITO', 86) 3.577371048252912 %
('レン', 83) 3.4525790349417633 %
('MEIKO', 66) 2.7454242928452577 %
('神威がくぽ', 33) 1.3727121464226288 %
('IA', 27) 1.123128119800333 %
('MAYU', 20) 0.8319467554076538 %
('重音テト', 17) 0.7071547420965058 %
('結月ゆかり', 7) 0.2911813643926789 %
...
アーティスト名ランキング
('OSTER project', 97) 3.664525878352852 %
('DECO*27', 95) 3.5889686437476387 %
('40mP', 82) 3.0978466188137515 %
('doriko', 76) 2.871174914998111 %
('livetune', 76) 2.871174914998111 %
('TunEdge Music-ASCAP And Or Slynth Music-BMI', 74) 2.7956176803928976 %
('デッドボールP', 55) 2.07782395164337 %
('蝶々P', 55) 2.07782395164337 %
('supercell', 47) 1.775595013222516 %
('ナユタン星人', 44) 1.662259161314696 %
('Dios / シグナルP', 43) 1.6244805440120893 %
('黒うさP', 38) 1.4355874574990555 %
('トラボルタ', 34) 1.2844729882886285 %
('cosMo@暴走P', 33) 1.2466943709860219 %
('mothy_悪ノP', 33) 1.2466943709860219 %
('ピノキオピー', 31) 1.1711371363808085 %
('Last Note.', 30) 1.1333585190782016 %
('otetsu', 30) 1.1333585190782016 %
('ゆうゆ', 30) 1.1333585190782016 %
('八王子P', 30) 1.1333585190782016 %
('HMOとかの中の人。', 29) 1.095579901775595 %
('daniwellP', 26) 0.9822440498677748 %
('さつき が てんこもり', 26) 0.9822440498677748 %
('ひとしずく x やま△', 26) 0.9822440498677748 %
('みきとP', 25) 0.9444654325651681 %
('Nem', 24) 0.9066868152625615 %
('ラマーズP', 24) 0.9066868152625615 %
('KEMU VOXX', 23) 0.8689081979599547 %
('sasakure.UK', 23) 0.8689081979599547 %
('うたたP', 22) 0.831129580657348 %
...
曲別ランキング
('[Secret Track]', 10)
('ロミオとシンデレラ', 10)
('ココロ', 10)
('右肩の蝶', 9)
('千本桜', 9)
('トリノコシティ', 8)
('悪ノ召使', 8)
('-ハロー、プラネット。', 8)
('ルカルカ★ナイトフィーバー', 8)
('リンリンシグナル', 7)
('メルト', 7)
('炉心融解', 7)
('メランコリック', 7)
('いろは唄', 7)
('Yellow', 7)
('初音ミクの消失', 6)
('初音ミクの激唱', 6)
('サンドリヨン', 6)
('Packaged', 6)
('サイハテ', 6)
('恋スルVOC@LOID', 6)
('ローリンガール', 6)
('ぽっぴっぽー', 6)
('えれくとりっく・えんじぇぅ', 6)
('ダブルラリアット', 6)
('タイムマシン', 5)
('妄想スケッチ', 5)
('二息歩行', 5)
('歌に形はないけれど', 5)
('Weekender Girl', 5)
('悪ノ娘', 5)
('on the rocks', 5)
('マージナル', 5)
('初めての恋が終わる時', 5)
('ネトゲ廃人シュプレヒコール', 5)
('カンタレラ', 5)
('パラジクロロベンゼン', 5)
('Just Be Friends', 5)
('FREELY TOMORROW', 5)
('結ンデ開イテ羅刹ト骸', 5)
('from Y to Y', 5)
('ハジメテノオト', 5)
('こっち向いて Baby', 5)
('カラフル x メロディ', 5)
('愛言葉', 4)
('ゆめゆめ', 4)
('モノクロアクト', 4)
('インビジブル', 4)
('Tell Your World', 4)
('RIP=RELEASE', 4)
('PIANO-GIRL', 4)
('恋色病棟', 4)
('ミラクルペイント', 4)
('星屑ユートピア', 4)
('ワールドイズマイン', 4)
('Starduster', 4)
('カゲロウデイズ', 4)
('深海少女', 4)
('上弦の月', 4)
('1925', 4)
('No Logic', 4)
('腐れ外道とチョコレゐト', 4)
('ハッピーシンセサイザ', 4)
('マトリョシカ', 4)
('いーあるふぁんくらぶ', 4)
('私の時間', 4)
('ワールズエンド・ダンスホール', 4)
('え- あぁ、そう。', 4)
('Fire◎Flower', 4)
('シリョクケンサ', 3)
('ドレミファロンド', 3)
('夢地図', 3)
('キリトリセン', 3)
...