HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2022
0805
qwertycdの曲名を取得3解決


qwerty

リンク

2022/8/5(Fri) 22:56:21|NO.96914

mci命令などを使ってHSPでCDでの曲名を取得することって可能なんでしょうか?



この記事に返信する


TOMATO

リンク

2022/8/6(Sat) 07:40:55|NO.96917

MCIでは無理だと思います。

音楽CD から曲名を取得する仕組みが、iTunes やWindows Media Player にありますが、
音楽CD内のTOC情報を元にインターネット上のCDDBデータベースサーバーを参照して、
曲名を返すようになっています。
(つまり、音楽CD内に曲名が入っているわけではない)

CD-TEXT という音楽CD内に曲名を直接埋め込む規格もありますが、
互換性の問題からなのか採用している音楽CDは少ない模様…
https://studio.orque.jp/column/column_cdtext.html

CDDBデータベース自体は様々な企業や団体が運用していますが、
有名どころはGracnote社のCDDBデータベースですね。(事実上、これ一択じゃないかな?)

HSPで実装するにはかなり敷居が高いと思われます。

・音楽CDからTOC情報を抽出する
・TOC情報をGrecenote社などのCDDBデータベースへ送信し、結果を取得

ということをしないといけませんが、標準で仕組みが用意されていません。
以下サイトの内容をHSPで実装しないといけません。

CD-DAの再生 第1部(TOC情報の取得とCD-TEXTも抽出している模様)
http://hiroshi0945.seesaa.net/article/189083823.html

GracenoteのAPIを試してみた
https://aont.hateblo.jp/entry/20130413/1365826755



qwerty

リンク

2022/8/6(Sat) 18:00:23|NO.96918

なるほど....
HSPでやるのは難しいんですね。
回答ありがとうございました。



Cube

リンク

2022/8/8(Mon) 05:14:41|NO.96921

GracenoteのAPIは結構前に一般公開が停止してしまったのでMusicBrainzを使用してみます。

MusicBrainz
https://musicbrainz.org

MusicBrainzはDiskIDとtoc情報でCDを特定できますが、私の技術不足でDiscIDが算出できなかったので
tocのみで特定する方法です。(すみません)

DiscIDの算出方法はここに詳しく解説されています。
https://musicbrainz.org/doc/Disc_ID_Calculation

tocのみで特定する場合、CD自体が膨大にあり複数ヒットしてしまうので
ユーザー自身でヒットしたリストから特定する必要があります。

今回はwindowsがCDを読み込んだ際に生成される.cdaファイルからtocを読み出し算出します。
.cdaファイルの構造についてはここから (英語ですが)
https://en.wikipedia.org/wiki/.cda_file

検索用のtocデータは
(最初のトラック番号) + (最後のトラック番号) + (曲の全長) + (全トラックの開始位置)...
で構築できます


*start #include "hspinet.as" #include "hsp3utf.as" #uselib "Kernel32" #func GetLogicalDriveStrings "GetLogicalDriveStringsA" int,var #cfunc GetDriveType "GetDriveTypeA" var dim drives_info,30 sdim cda_data, 44 sdim toc_data, 1024 sdim drives_list, 1024 request_url_root = "https://musicbrainz.org/ws/2/" *search_drive //参考: http://gpsnmeajp.sblo.jp/article/181155322.html //ドライブ一覧を取得 GetLogicalDriveStrings 1024, drives_list null_cnt=0 //NULL文字で区切られているので、分離して文字列に repeat 1024 null_peek = peek(drives_list,cnt) if null_peek = 0 { null_cnt++ poke drives_list,cnt,',' }else{ null_cnt=0 } if null_cnt >= 2 { poke drives_list,cnt,0 break } loop //末端に付いた,を除去 drives_list = strtrim(drives_list,2,',') //文字列を分離して配列に split drives_list,",",drives //詳細情報取得 foreach drives drives_info(cnt) = GetDriveType(drives(cnt)) loop //CDROMドライブの特定 foreach drives if drives_info(cnt) = 5 : drive_letter_cdrom = drives(cnt) loop *read_toc ////////////////////////////////////////////////////////// //検索用のtocデータは //(最初のトラック番号) + (最後のトラック番号) + (曲の全長) + (全トラックの開始位置)... //で構築できる //cdaファイルの構造: https://en.wikipedia.org/wiki/.cda_file ////////////////////////////////////////////////////////// //cdaファイルのリスト作成 chdir drive_letter_cdrom dirlist cda_list, "*.*", 2 notesel cda_list cda_list_num = noteinfo(0) //cdaファイルを配列に格納 dim cda_list_dim, cda_list_num split cda_list, "\n", cda_list_dim //トラックの最初の番号と最終トラック番号を挿入 toc_data = "1+" + str(cda_list_num) + "+" toc_data_track = "" repeat cda_list_num //バッファにファイル読み込み bload drive_letter_cdrom + cda_list_dim(cnt), cda_data //それぞれの曲の開始位置を取得 toc_minutes = peek(cda_data, 38) toc_seconds = peek(cda_data, 37) toc_frames = peek(cda_data, 36) // 1/75秒おきに読み出されるので、すべてフレームに換算する toc_minutes = (toc_minutes * 60) * 75 toc_seconds = toc_seconds * 75 toc_all_track = toc_minutes + toc_seconds + toc_frames //送信用データ作成 //最終トラックのみデュレーションを取得 if cda_list_num = cnt+1 { toc_data_track += str(toc_all_track) toc_minutes_duration = peek(cda_data, 42) toc_seconds_duration = peek(cda_data, 41) toc_frames_duration = peek(cda_data, 40) //同様にフレーム換算 toc_minutes_duration = (toc_minutes_duration * 60) * 75 toc_seconds_duration = toc_seconds_duration * 75 //曲の全長を算出 //先にtoc_dataに挿入 toc_data += str(toc_minutes_duration + toc_seconds_duration + toc_frames_duration + toc_all_track) + "+" }else{ //全トラックの開始位置を控えておく toc_data_track += str(toc_all_track) + "+" } loop //toc_dataに後付 toc_data += toc_data_track *get_json netinit //GETリクエスト //&fmt=jsonをつけることでjsonで受け取れる (デフォルトはxml) //ヘッダに application/json でも有効 neturl request_url_root netrequest_get "discid/-?toc=" + toc_data + "&fmt=json" //レスポンス待機 repeat netexec wait_res if wait_res=1 : break await 1 loop //結果を変数へ netgetv responce_json_raw netterm *get_title album_title_all = "" //hsp3utfをインクルードしない場合変換が必要 //nkfcnv responce_json_raw, responce_json_raw, "s" //json読み込み jsonopen root_ptr,responce_json_raw jsongetobj releases_ptr,"releases",root_ptr jsonnext releases_ptr,releases_ptr,2 //tocの重複によりいくつか出てくる場合がある //そのため存在するタイトルはすべて読み込む while(releases_ptr != NULL) jsongets album_title,"title",releases_ptr jsonnext releases_ptr,releases_ptr,0 album_title_all += album_title + "\n" wend jsonclose mes album_title_all stop

曲名というよりアルバム名の取得ですね。

APIに関してはここで詳しく解説されています。
https://musicbrainz.org/doc/MusicBrainz_API



ONION software Copyright 1997-2023(c) All rights reserved.