アイコン アイコン アイコン アイコン アイコン
2009/06/27(Sat)

Music&SaverにID3送信機能をつけてみる〜その4

ID3の読み取り部分を少し書き直しました。

//ID3タグのサイズを得る
bload play_file,head,4,6        ;play_file = MP3ファイルのパス
sdim bit : tag_size = 0

for i,0,4                ;下位7ビット取り出しX4バイト分
    byte = peek (head,i)
    a = ""
    for h,0,7
        x = byte \ 2        ;ただし頭の1ビットは飛ばす
        a = "" + x + a
        byte = byte / 2
    next
    bit = bit + a            ;文字列にする
next

len = strlen(bit)            ;2進数->10進数
counter = len - 1
repeat len
    binary = int(strmid(bit, cnt, 1))
    binary <<= counter
    tag_size += binary
    counter --
loop

;//フレームデータ取得
sdim tag_data,tag_size
sdim frame_data,tag_size
bload p_file,tag_data,tag_size,10

pointer = 0                ;データのポインタ
repeat
    if pointer + 5 > tag_size : break    ;フレームIDが取り出せなくなったらおしまい

    ;//フレームID            フレームIDってのはタグの名前のことです。常に4文字。
    name = ""
    byte = lpeek (tag_data,pointer) : if byte = 0 : pointer += 4 : continue    ;フレームIDがないときは4バイト進む
    lpoke name,0,byte
    pointer += 4

    ;//フレームサイズ        ;フレームIDの後にはフレームサイズ情報があります。4バイト
    size = 0
    size = lpeek (tag_data,pointer)
    size >>= 24
    pointer += 4

    pointer += 3            ;文字コードの処理はやりません。Shift-Jisとして扱います。

    ;//データ
    sdim data,size
    if size > 0 {            ;サイズゼロのフレームデータを書くソフトもあるみたいです。
        size-
        repeat size
            byte = peek (tag_data,pointer)
            poke data,cnt,byte
            pointer+
        loop

        newcom oReg,"VBScript.RegExp"    ;COM呼び出しを使って正規表現でエスケープする
        oReg("Global") = 1

        ;//&を&に
        oReg("Pattern") = "&"
        comres data
        oReg->"Replace" data,"&"

        ;//,を,に
        oReg("Pattern") = ","
        comres data
        oReg->"Replace" data,","

        ;//?を?に
        oReg("Pattern") = "\\?"
        comres data
        oReg->"Replace" data,"?"
    }

    frame_data = frame_data + name + "," + data + ","    ;フレームIDと内容をCSV形式にします
loop

タグ情報は、文字コードShift-Jisとしてエスケープするだけにしました。サーバー側でむにゃむにゃすれば問題はないようなので、クライアント側の仕事をできるだけ減らす、ということで。仕事を分け合うのが正解のような気もしますけども。

プレイリストから再生する場合、MP3ファイルが見つからないときは、そのファイル名を通知して終了するようにしてみました。

アイコン
2009/06/09(Tue)

Music&SaverにID3送信機能をつけてみる〜その3

結局、スタンドアロンとは行かず、「COMコンポーネント呼び出し」なるものを使って再生することにしました。なので、コンピューターにWindows Media Playerが入ってないと使えません。まぁ仕方ない。

で、ついでにプレイリストファイル(wpl)なんかも読んじゃったりしちゃったりと思ったんですが、マイクロソフトのWindows Media Player 7 SDKのページを読んでも、使い方が良く分からず。で、もうDOSコマンドでリスト作ってしまったほうが手っ取り早いということで、ボタンポチのdirコマンドでローテクに処理するようにしました。

クライアントであるMusic&Saverが送信するクエリは、POSTメソッドで「title=曲名&artist=アーティスト名&album=アルバム名」となっています。たとえばこれからグーグルの検索結果へのリンクを生成したりして遊びます。

また、クエリの送信先を指定するボックスにもクエリが書かれていた場合、それも追加して送信するようにしてみました。その仕様にのっかって、楽天のCD検索APIを利用させてもらって、楽天ブックスへのリンクを生成するスクリプトを書いて、→に貼り付けてみました。

アイコン
2009/06/02(Tue)

Music&SaverにID3送信機能をつけてみる〜その2

ダメでした。通信機能はまったく問題ありませんが、基幹の再生部分に問題がありました。

原因はわかりませんが、HSPでは、全てのMP3が再生できるわけではないようです。再生できずに閉じられたファイルのみでリストを作って、読み込ませて再生してみたところ、その全てが再生きませんでした。再生できないので、飛ばして次の曲にいってたようです。
HSP3で試したり、DirectX系の命令を使ってみたりしてもダメで、とにかく、HSPを通すと、ダメなものはダメなようです。

これじゃつまんないなぁ。但し書きしとかなくちゃ。

アイコン
2009/05/30(Sat)

Music&SaverにID3送信機能をつけてみる

以前作った音楽スクリンセイバを改造して、聴いた音楽の情報をネットにアップする機能をつけてみました。どっかできいたようなアレです。アレを入れたせいでMusic&Saverを全然使わなくなったので、せっかく作ったのにもったいないなと、hspsockを使えば出きそうだなと。とりあえず、テスト用の送信スクリプトと、受信用のperlスクリプトを書いて、アップさせてみたら、上手くいったので、実装してみました。あと一つだけ懸案事項。

「MCIコマンドで再生開始したらID3TAGをアップ。再生中かどうかを見て、再生中でなければループを抜けて次の曲」というふうにしたところが、再生してないのにループを抜けて、次の曲にいってしまってます。

調べて見たら、playコマンド発行後すぐには、"再生中"のステータスが返って来ないので、1回目のチェックで「再生中じゃない=演奏終了」と判定してしまい、実際には演奏してないのに次の曲にいってしまっているようでした。これが何回か起きるために、数曲分のデータが送信されてしまい、で、たまたまチェックに引っかかった曲が演奏される、ということのようです。

じゃぁってんで、「playコマンド発行したらループでステータス監視して、"再生中"を確認したらループ抜けてデータ送信。再度ループで"再生中"判定。"再生中"じゃなかったら次の曲」というふうにしたら、今度は、最初の再生開始チェックのループから抜けてこなくなりました。

HSPの問題なのか、Windowsの問題なのかわかりませんが、どうやらMCIのステータスは、じっと見てると返してこない、しかしほっとくといつのまにか返している、という仕様(?)のようです。

つまり、監視してると・・・
な、なによ!こっち見ないでよ!そんなに見つめたって、あんたなんかにステータス返してあげないんだから!

で、ほっとくと・・・
ステータス返してあげたんだから感謝しなさいよね!べ、べつにアンタのために返したわけじゃないわよ!そういう仕様なんだから仕方ないでしょ!

みたいな。

もとい。

ということは、playコマンド発行したら、何秒か空ループ回して、再生開始したころを見計らってステータスチェックのループ回せばいいのかな。

アイコン
2009/04/08(Wed)

選択範囲を引用する

カテゴリ:Logwing開発キ

管理ページの簡易エディタ用JavaScriptを応用して、マウスで選択した文字列に引用符をつけてコメント入力欄に表示する、というのをやってみました。

<script type="text/javascript">
<!--
var isIE = (navigator.appName.toLowerCase().indexOf("internet explorer")+1?1:0);    //IEかどうかの判定

function quote() {
	//選択範囲のテキストを取得
	if (isIE) {str = document.selection.createRange().text;}	//IEの場合
	else if(window.getSelection()) {str = document.getSelection();}	//IE意外

	//整形して引用符をつける
	if (str) {
		str = str.replace(/\r\n/g,"\n");
		str = str.replace(/\r/g,"\n");
		str = str.replace(/^/gm,">");
	}

	//テキストエリアの内容を読み込む
	var v = document.postform.text.value;

	//整形したテキストとテキストエリアの内容を足して表示
	document.postform.text.value = v + str;
}
//-->
</script>

<form method="post" action="post.cgi" name="postform">
<input type="button" onClick="javascript:quote();" value="選択範囲を引用する"><br>
<textarea name="text" ></textarea><br>
<input type="submit">
</form>

うまく動くようなので、ここのコメントフォームに実装してみました。

コードをから解ると思いますが、既にテキストエリアに入力されている文字列の後ろにくっつける仕様になってます。コメントするのに引用文を後から加えることはまずないとふんで、カーソル位置を読み取る処理はなくてもいいんではないかと。

アイコン