/*
* MP3 クラス
*
* rel. 0.1
*
* Copyright (c) 2000 Sumatra Solutions srl http://www.sumatrasolutions.com
* Ludovico Magnocavallo ludo@sumatrasolutions.com
*
* ライセンスの種類: GNU GPL http://www.gnu.org/ copyleft/gpl.html
*
*
* Perl Apache::MP3 モジュール (L. Stein) -- Apache ベースの mp3 サーバーを作成するための優れたモジュール
* Perl MP3::Info (C. Nandor) - - 非常に複雑で難しい内容ですが便利です
* Java クラス de.vdheide.mp3 (J. Vonderheide) -- 素晴らしい内容で、読みやすく、synchronize() メソッドをデバッグする必要がありました
*
* ID3v2 タグのサポートは未完了
*
* MP3 ヘッダーのリファレンス (http://www.mp3-tech.org/)
*
* // クイック スタート:
* $mp3 = new MP3($myfilepath);
* $mp3->get_info(); // $mp3->info 配列内のファイル情報
* $mp3->get_id3(); // $mp3->id3 配列の id3 情報
* $mp3->send_pls($HTTP_HOST) // プレイリスト URL 内のファイルへの物理パスを使用します
* $mp3->stream() // ファイルをブラウザにストリーミングします
*
* $Id: mp3.php,v 1.10 2000/07/18 11:05:16 ludo Exp $
*
*/
クラス MP3 {
var $id3_genres_array = array(
'ブルース', 'クラシック ロック'、'カントリー'、'ダンス'、'ディスコ'、'ファンク'、'グランジ'、'ヒップホップ'、'ジャズ'、'メタル'、'ニューエイジ'、'オールディーズ'、'その他'、'ポップ」、「R&B」、「ラップ」、「レゲエ」、「ロック」、「テクノ」、「インダストリアル」、
「オルタナティブ」、「スカ」、「デスメタル」、「いたずら」、「サウンドトラック」、ユーロテクノ」、「アンビエント」、「トリップホップ」、「ボーカル」、「ジャズ+ファンク」、「フュージョン」、「トランス」、「クラシック」、「インストゥルメンタル」、「アシッド」、「ハウス」、
「ゲーム」、「サウンドクリップ」、「ゴスペル」、「ノイズ」、「オルタナロック」、「ベース」、「ソウル」、「パンク」、「スペース」、「瞑想的」、「インストゥルメンタルポップ」、「インストゥルメンタルロック」 、「エスニック」、「ゴシック」、「ダークウェーブ」、
「テクノインダストリアル」、「エレクトロニック」、「ポップフォーク」、「ユーロダンス」、「ドリーム」、「サザンロック」、「コメディ」、「カルト」 、「ギャングスタ」、「トップ 40」、「クリスチャン ラップ」、「ポップ/ファンク」、「ジャングル」、「ネイティブ アメリカン」、「キャバレー」、
「ニュー ウェーブ」、「サイカデリック」、「レイブ」、「ショーチューンズ」 '、'トレーラー'、'ローファイ'、'トライバル'、'アシッドパンク'、'アシッドジャズ'、'ポルカ'、'レトロ'、'ミュージカル'、'ロックンロール'、'ハードロック'、'フォーク」、「フォーク/ロック」、「ナショナル フォーク」、
「スイング」、「ファスト フュージョン」、「ビボブ」、「ラテン」、「リバイバル」、「ケルティック」、「ブルーグラス」、「アバンギャルド」、「ゴシック」ロック」、「プログレッシブ ロック」、「サイケデリック ロック」、「シンフォニック ロック」、「スロー ロック」、「ビッグ バンド」、
「コーラス」、「イージーリスニング」、「アコースティック」、「ユーモア」、「スピーチ」、「シャンソン」、「オペラ」、「室内楽」、「ソナタ」、「交響曲」、「戦利品ベース」、「プリムス」 、「ポルノ グルーヴ」、「風刺」、「スロー ジャム」、「クラブ」、「タンゴ」、「サンバ」、
「フォークロア」、「バラード」、「パワー バラード」、「リズミック ソウル」、「フリースタイル」、 「デュエット」、「パンクロック」、「ドラムソロ」、「アカペラ」、「ユーロハウス」、「ダンスホール」
);
var $info_bitrates = array(
1 => array(
1 => array( 0 => 0, 16 => 32, 32 =&g t; 64、48 => 96、64 => 128 、80、96 => => 416, 224 => 448, 240 => false)、
=> array( 0 => 0, 16 => 48, 48 => 56, 64 => 64、80 => 96、128 => 160、176 => t ; 256, 208 => 320, 224 => false),
=> 0 => 16 => 40 48 => ; 48、64 => 56、80 => 80、128 => 160、176 => 192 、 192 => 224、208 => 256、224 => false)、
配列(
1 => array( 0 => 0, 16 = > 32、32 => 48、48 => 56、64 => 64、80 => 80、96 => 96、112 => 112、128 => 128、144 => 144、160 => 160、176 => 176、192 => 192、208 => 224、224 => 256、240 => false)、
2 => array( 0 => 0, 16 => 8, 32 => 16, 48 => 24, 64 => 32, 80 => 40, 96 => 48, 112 => 56, 128 => 64、144 => 96、176 => 144、240 =>
3 => array( 0 => 0, 16 => 8, 32 => 16, 48 => 24, 64 => 32, 80 => 40, 96 => 48, 112 => 56, 128 => 64、144 => 96、176 => 144、240 =>
) 、
);
var $info_versions = array(0 => "予約済み", 1 => "MPEG バージョン 1", 2 => "MPEG バージョン 2", 2.5 => "MPEG バージョン 2.5");
var $info_layers = array("予約済み", "レイヤー I", "レイヤー II", "レイヤー III");
var $info_sampling_rates = array(
0 =>array(0 => false, 4 => false, 8 => false, 12 => false),
1 => array(0 => "44100 Hz"、4 => "48000 Hz"、8 => "32000 Hz"、12 => false)、
2 => array(0 => "22050 Hz"、4 => "24000 Hz"、8 => "16000 Hz"、12 => false)、
2.5 => array(0 => "11025 Hz", 4 => "12000 Hz", 8 => "8000 Hz", 12 => false),
);
var $info_channel_modes = array(0 => "ステレオ"、64 => "ジョイント ステレオ"、128 => "デュアル チャネル"、192 => "シングル チャネル");
var $file = "";
var $fh = false;
var $error = false;
var $id3_parsed = false;
var $id3 = array(
/* 「タグ」 => 「」,
「タイトル」 => 「不明」
「作者」 => 「不明」、
「アルバム」 => ",
「年」 => 「不明」,
「コメント」 => 「不明」,
「ジャンルid」 => 0,
「ジャンル」 => 「不明」
*/ );
var $url = "";
var $info = array();
function mp3($file, $exitonerror=true) {
if (file_exists($file)) {
$this->file = $file;
$this->fh = fopen($this->file,"r");
グローバル $HTTP_HOST、$PHP_SELF;
$this->url = "http://$HTTP_HOST/$PHP_SELF";
} else {
$this->error = "そのようなファイルはありません";
if ($exitonerror) $this->exitonerror();
}
}
function exitonerror() {
echo($this->error);
終了します。
}
function set_id3($title = "", $author = "", $album = "", $year = "", $comment = "", $genre_id = 0) {
$this->error = false;
$this->wfh = fopen($this->file,"a");
fseek($this->wfh, -128, SEEK_END);
fwrite($this->wfh, Pack("a3a30a30a30a4a30C1", "TAG", $title, $author, $album, $year, $comment, $genre_id), 128);
fclose($this->wfh);
}
function get_id3() {
$this->id3_parsed = true;
fseek($this->fh, -128, SEEK_END);
$line = fread($this->fh, 10000);
if (preg_match("/^TAG/", $line)) {
$this->id3 = unpack("a3tag/a30title/a30author/a30album/a4year/a30comment/C1genre_id", $line);
$this->id3["genre"] = $this->id3_genres_array[$this->id3]["genre_id"]];
return(true);
} else {
$this->error = "idv3 タグが見つかりません";
return(false);
}
}
// get_info() ヘルパーメソッド
function Calculate_length($id3v2_tagsize = 0) {
$length = Floor(($this->info["filesize"] - $ id3v2_tagsize) / $this->gt; info["ビットレート"] * 0.008);
$min = フロア($length / 60);
$min = strlen($min) == 1 ? "0$分" : $分;
$sec = $length % 60;
$sec = strlen($sec) == 1 ? "0$秒" : $秒;
return("$min:$sec");
}
function get_info() {
// $this->get_id3v2header();
$sec = $this->synchronize();
// echo("2 バイト目 = $秒 " . decbin($秒) . "
");
$third = ord(fread($this->fh, 1));
$fourth = ord(fread($this->fh, 1));
$this->info["version_id"] = ($second & 16) > 0 ? ( ($秒 & 8) > 0 ? 1 : 2 ) : ( ($秒 & 8) > 0 ? 0 : 2.5 );
$this->info["version"] = $this->info_versions[ $this->info]["version_id"] ];
$this->info["layer_id"] = ($second & 4) > 0 ? ( ($秒 & 2) > 0 ? 1 : 2 ) : ( ($秒 & 2) > 0 ? 3 : 0 ); ;
$this->info["layer"] = $this->info_layers[ $this->info]["layer_id"] ];
$this->info["保護"] = ($秒 & 1) > 0 ? "CRC なし" : "CRC";
$this->info["bitrate"] = $this->info_bitrates[ $this->info]["version_id"] ][ $this->info]["layer_id"] ][ ($ 3 番目 & 240) ];
$this->info["sampling_rate"] = $this->info_sampling_rates[ $this->info]["version_id"] ][ ($third & 12)];
$this->info["padding"] = ($third & 2) > 0 ? "オンオフ";
$this->info["private"] = ($third & 1) > 0 ? "オンオフ";
$this->info["channel_mode"] = $this->info_channel_modes[$fourth & 192];
$this->info["著作権"] = ($fourth & 8) > 0 ? "オンオフ";
$this->info["original"] = ($fourth & 4) > 0 ? "オンオフ";
$this->info["filesize"] = filesize($this->file);
$this->info["length"] = $this->calculate_length();
}
function synchronize() {
$finished = false;
rewind($this->fh);
while (!$finished) {
$skip = ord(fread($this->fh, 1));
// echo("inside synchronize() Skip = $skip " .decbin($skip) . "
");
while ($skip != 255 && !feof($this->fh)) {
$skip = ord(fread($this->fh, 1));
// echo("inside synchronize() Skip = $skip " .decbin($skip) . "
");
}
if (feof($this->fh)) {
$this->error("情報ヘッダーが見つかりません");
if ($exitonerror) $this->exitonerror();
}
$store = ord(fread($this->fh, 1));
// echo("inside synchronize() store = $store " .decbin($store) . "
");
if ($store >= 225) {
$finished = true;
} else if (feof($this->fh)) {
$this->error("情報ヘッダーが見つかりません");
if ($exitonerror) $this->exitonerror();
}
}
return($store);
}
function get_id3v2header() {
$bytes = fread($this->fh, 3);
if ($bytes != "ID3") {
echo("ID3 タグなし");
return(false);
}
// メジャーバージョンとマイナーバージョンを取得します
$major = fread($this->fh, 1);
$minor = fread($this->fh, 1);
echo("ID3v$major.$minor");
}
function stream() {
if (!$this->id3_parsed) {
$this->get_id3();
}
header("ICY 200 OKrn");
header("icy-notice1:このストリームにはシャウトキャスト/アイスキャスト互換プレーヤーが必要です。
rn");
header("icy-notice2:php MP3 class
rn");
header("icy-name:" . (count($this->id3) > 0 ? $this->id3["title"] . " - " . $this->id3["author" ] . " - " . $this->id3["アルバム"] : $this-> ファイル);
header("icy-genre:" . (count($this->id3) > 0 ? $this->id3["genre"] : "unspecified") . "rn");
header("icy-url:bbbrn");
header("icy-pub:1rn");
header("icy-br:320rn");
rewind($this->fh);
fpassthru($this->fh);
}
function send_playlist_header($numentries = 1) {
header("Content-Type: audio/mpegurl;");
echo("[プレイリスト]rnrn");
echo("NumberOfEntries=$numentriesrn");
}
function send_pls($server) {
$this->send_playlist_header();
$path = "/";
$path_array =explode("/", dirname($this->file));
while(list($key,$val) = each($path_array)) {
$path .= 空($val) ? "" : rawurlencode($val);
}
$path .= "/";
$file = rawurlencode(preg_replace("/.mp3$/", "", Basename($this->file)));
echo("File1=http://$server$path$file.mpsrn");
}
function close() {
@fclose($this->fh);
}
}
?>