ホームページ > バックエンド開発 > PHPチュートリアル > PHPを使った音声ファイル情報の解析と読み書きの詳細解説(WMA、MP3対応)_PHPチュートリアル

PHPを使った音声ファイル情報の解析と読み書きの詳細解説(WMA、MP3対応)_PHPチュートリアル

WBOY
リリース: 2016-07-21 15:10:58
オリジナル
1006 人が閲覧しました

コードをコピーします コードは次のとおりです:

// AudioExif.class.php
// PHP を使用してオーディオ ファイルのヘッダー情報を読み書きします
// 現在は WMA と MP3 形式のみをサポートし、一般的に使用されるいくつかの形式のみをサポートします ヘッダー情報
/ /
// 書き込み情報はタイトル、アーティスト、著作権、説明をサポートします
// 年、ジャンル、アルバムタイトル )
// このうち、mp3 と wma は若干異なり、具体的に返される情報はさらに多い可能性がありますが、上記のみです情報を書き込むことができます
// mp3はTrack(トラック番号書き込み)もサポートします
// MP3ファイルのID3v1をサポートします ID3v2もサポートされ、読み取り時にはv2が優先され、書き込み時には常にv1が書き込まれ、必要に応じてv2が書き込まれます
//
// 使用方法: (wma は Unicode アクセスを使用するため、mb_convert_encoding() 拡張機能も必要です
// 返されたデータと書き込まれたデータはすべて ANSI エンコードされます。つまり、保存されているものはすべて表示されます ( Chinese_GB2312 )
/ /
// require ('AudioExif.class.php');
// $AE = new AudioExif
// $file = '/path/to/test.mp3';
//
// 1. チェックファイルが完了したかどうか (wma の場合のみ、mp3 は常に true を返します)
//
// $AE-> CheckSize($file);
//
// 2. 情報を読み取り、戻り値はキー名の説明については、上記を参照してください
//
// print_r($AE->GetInfo($file)) ;
//
// 3. 2 番目のパラメーターである情報を書き込みます。はハッシュ配列です。キー->値です。サポートについては上記を参照してください。mp3 も Track
をサポートしています。// 最初のパラメータが必要なファイル パスは、これによって決定できます。プログラムは次のように記述します。
// $pa = array('Title' = > '新しいタイトル', 'AlbumTitle' => '新しいアルバム名');
// $AE->SetInfo($file, $ pa);
//
//
// その他: このプラグ-in は、wma および mp3 ファイル形式のドキュメントと Web ページの収集と検索に多くの時間を費やしました。これが皆さんのお役に立てれば幸いです
// 実際、インターネット プログラムにはすでに類似したものがたくさんあります。 wma が少なすぎるため、win プラットフォームでは M$ の
// API を介してのみ操作でき、MP3 は unix/linux コマンドラインから操作できることはほとんどありません。そのため、このモジュールを特別に作成しました
//
//バグを見つけた場合、パッチを提出する場合、またはより堅牢にするための改善を行った場合は、教えてください。
// (ID3 と Wma のファイル形式と構造については、インターネット上で参考資料を見つけることができるはずです)
//
if (!extension_loaded('mbstring'))
{
trigger_error('AudioExifにはPHP拡張モジュール`mbstring`が必要です', E_USER_WARNING);
return true;
}
// Main Class
class AudioExif
{
// public vars
var $_wma = false;
var $_mp3 = false;
//
関数を構築します
AudioExif()
{
// 何もすることはありません
}
// ファイルサイズをチェックします
function CheckSize($ file)
{
$handler = &$this->gt;_get_handler($file);
if (!$handler) return false;
return $handler->check_size($file);
}
// を取得infomations
function GetInfo($file)
{
$handler = &$this->_get_handler($file);
if (!$handler) return false;
return $handler->get_info($file);
}
// infomations
関数を書き込みます SetInfo($file, $pa)
{
if (!is_writable($file))
{
trigger_error('AudioExif: file `' . $file . '' は上書きできません', E_USER_WARNING ;
}
// プライベートメソッド
function &_get_handler($file)
{
$ext = strto lower(strrchr($file, '.'));
$ret = false;
if ($ext == '.mp3' )
{ // MP3
$ret = &$this->_mp3;
if (!$ret) $ret = new _Mp3Exif();
}
else if ($ext == '.wma ')
{//wma
ext。' 'ファイル。
{
// 最後の "" を削除します
$str = substr($str, 0, -2);
return mb_convert_encoding($str, 'GBK', 'UCS-2LE');
}
// gb2312 => DBCS
function gbk_dbcs($str)
{
$str = mb_convert_encoding($str, 'UCS-2LE', 'GBK');
$str .= "";
return $str;
}
// ファイル exif
class _AudioExif
{
var $fd;
var $head;
var $head_off;
var $head_buf;

// ファイルハンドラーを初期化します
function _file_init($fpath, $write = false)
{
$mode = ($write ? 'rb+' : 'rb');
$this->fd = @fopen($fpath, $mode);
if (!$this->fd)
{
trigger_error('AudioExif : `' . $fpath . '' はモード `' . '', E_USER_WARNING);
return false;
}
$this->head = false;
$this-> head_off = 0;
$this->head_buf = '';
return true;
}
// head_buf からバッファを読み取り、オフポインタを移動します
function _read_head_buf($len)
{
if ($len < = 0) return NULL;
$buf = substr($this->head_buf, $this->head_off, $len);
$this->head_off += strlen($buf);
return $buf;
}
// 1 つの short 値を読み取ります
function _read_head_short()
{
$ord1 = ord(substr($this->head_buf, $this->head_off, 1));
$ord2 = ord(substr( $this->head_buf, $this->head_off+1, 1));
$this->head_off += 2;
return ($ord1 + ($ord2<<8));
}
// ファイルを保存します head
function _file_save($head, $olen, $nlen = 0)
{
if ($nlen == 0) $nlen = strlen($head);
if ($nlen == $olen )
{
// 短い
flock($this->fd, LOCK_EX);
fseek($this->fd, 0, SEEK_SET);
fwrite($this->fd, $head, $nlen );
flock($this->fd, LOCK_UN);
}
else
{
// より長い、バッファが必要
$stat = fstat($this->fd);
$fsize = $stat[' size'];
// buf が必要です (4096?) 应该不会 nlen - olen > 4096 吧
$woff = 0;
$roff = $olen;
// 最初のバッファを読み取ります
flock($this->fd, LOCK_EX);
fseek($this->fd, $roff, SEEK_SET);
$buf = fread($this->fd, 4096);
// 開始をシークする
fseek($this->fd, $woff, SEEK_SET);
fwrite($this->fd, $head , $nlen);
$woff += $nlen;
// woff を求めてデータを書き込みます
do
{
$buf2 = $buf;
$roff += 4096;
if ($roff & $fsize )
{
fseek($this->fd, $roff, SEEK_SET);
$buf = fread($this->fd, 4096);       
}
//最後のバッファーを保存
$ len2 = strlen($ buf2); ;
$woff += $len2;
}
while ($roff ftruncate($this->fd, $woff);
flock($this->fd, LOCK_UN);
}
}
// ファイルを閉じる
function _file_deinit()
{
if ($this->fd)
{
fclose($this->gt;fd);
$this->fd = false;
}
}
}
// wma class
class _WmaExif extends _AudioExif
{
var $items1 = array('タイトル', 'アーティスト', '著作権', '説明', '予約');
var $items2 = array('年' , 'Genre', 'AlbumTitle');
// ファイル サイズ (長さ) をチェックします。ファイルが無効である可能性があります
function check_size($file)
{
$ret = false;
if (!$this->_file_init($file) )) return true;
if ($this->_init_header())
{
$buf = fread($this->fd, 24);
$tmp = unpack('H32id/Vlen/H8unused', $ブフ);
if ($tmp['id'] == '3626b2758e66cf11a6d900aa0062ce6c')
{
$stat = fstat($this->fd);
$ret = ($stat['size'] == ($this- >head['len'] + $tmp['len']));
}
}
$this->_file_deinit();
return $ret;
}
// 情報を設定します (情報を保存します)
function set_info($file, $pa)
{
// pa を確認します
settype($pa, 'array');
if (!$this->_file_init($file, true)) return false;
if (!$this->_init_header())
{
$this->_file_deinit();
return false;
}

// 古いヘッダーを解析し、新しいヘッダーを生成します
$head_body = '';
$st_found = $ex_found = false;
$head_num = $this->head['num'];
while (($tmp = $this->_get_head_frame()) && ($head_num > 0))
{
$head_num--;
if ($tmp['id'] == '3326b2758e66cf11a6d900aa0062ce6c')
{ // 標準情報
// 1-4
$ st_found = true;
$st_body1 = $st_body2 = ' ';      
$lenx = unpack('v5', $this->_read_head_buf(10));
$tmp['len'] -= 34;  // 10 + 24
for ($i = 0; $i < count($this->items1); $i++)
{
$l = $lenx[$i+1];
$k = $ this->items1[$i];
$tmp['len'] -= $l;
$data = $this->_read_head_buf($l);
if (isset($pa[$k]) ) $data = gbk_dbcs($pa[$k]);
$st_body2 .= $data;
$st_body1 .= Pack('v', strlen($data));
}
// 左の長さ
if ( $tmp['len'] > $st_body2 .= $this->_read_head_buf($tmp['len']);
// head_body に保存
$head_body .= Pack('H32VH8', $tmp ['id'], strlen($st_body1 . $st_body2)+24, $tmp['unused']);
$head_body .= $st_body1 . $st_body2; 
}
else if ($tmp['id'] == '40a4d0d207e3d21197f000a0c95ea850')
{ // 拡張情報
$ex_found = true;

$inum = $this->_read_head_short ();
$inum2 = $inum;
$tmp['len'] -= 26;  // 24 + 2
$et_body = '';
while ($tmp['len'] > 0 && $inum > 0)
{
// 属性名
$nlen = _short( );
$nbuf = $this->_read_head_buf($nlen);
// フラグと値の長さ
$flag = $this->_read_head_short();
$vlen = $this->_read_head _short() ;
$vbuf = $this->_read_head_buf($vlen);
// 長さを設定します
$tmp['len'] -= (6 + $nlen + $vlen);
$inum--;
/ / データを保存しますか?
$name = dbcs_gbk($nbuf);
$k = substr($name, 3);
if (in_array($k, $this->items2) && isset($pa[$k ]))
{
$vbuf = gbk_dbcs($pa[$k]);
$vlen($vbuf);
unset($pa[$k]);
}
$et_body .= Pack(' v'、$nlen) 。 $nbuf 。 Pack('vv', $flag, $vlen) 。 $vbuf;
}
// 新しいタグ挿入??
foreach ($this->items2 as $k)
{
if (isset($pa[$k]))
{
$inum2++;
$nbuf = gbk_dbcs('WM/' . $k);
$nlen = strlen($nbuf);
$vbuf = gbk_dbcs($pa[$k]);
$vlen = strlen($vbuf);
$et_body 。 = パック('v', $nlen) 。 $nbuf 。 Pack('vv', 0, $vlen) 。 $vbuf;
}
}
// left buf?
if ($tmp['len'] > 0) $et_body .= $this->_read_head_buf($tmp['len']);
/ / head_body に保存します
$head_body .= Pack('H32VH8v', $tmp['id'], strlen($et_body)+26, $tmp['unused'], $inum2);
$head_body .= $et_body; 
}
else
{
// 他の頭のフレームはそのままにしておきます
$head_body .= Pack('H32VH8', $tmp['id'], $tmp['len'], $tmp['unused']);
if ($tmp['len'] > 24) $head_body .= $this->_read_head_buf($tmp['len']-24);
}
}
// st が見つかりません?
if (!$st_found)
{
$st_body1 = $st_body2 = '';
foreach ($this->items1 as $k)
{
$data = (isset($pa) [$k]) ? gbk_dbcs($pa[$k]) : "");
$st_body1 .= Pack('v', strlen($data));
$st_body2 .= $data;
}

// head_body に保存します
$head_body .= Pack('H32Va4', '3326b2758e66cf11a6d900aa0062ce6c', strlen($st_body1 . $st_body2)+24, '');
$head_body .= $st_body1 . $st_body2;
$this->head['num']++;
}
// ex が見つかりません?
if (!$ex_found)
{
$inum = 0;
$et_body = '';
foreach ($this->items2 as $k)
{
$nbuf = gbk_dbcs('WM/' . $k);
$vbuf = (isset($pa[$k]) ? gbk_dbcs($pa[$ k]) : "");
$et_body .= Pack('v', strlen($nbuf)) 。 $nbuf 。 Pack('vv', 0, strlen($vbuf)) 。 $vbuf;
$inum++;
}
$head_body .= Pack('H32Va4v', '40a4d0d207e3d21197f000a0c95ea850', strlen($et_body)+26, '', $head_body .= $et_body;
$this ->head['num']++;
}
// 保存後
$new_len = strlen($head_body) + 30;
$old_len = $this->head['len'];
if ( $new_len < $old_len)
{
$head_body .= str_repeat("", $old_len - $new_len);
$new_len = $old_len;
}
$tmp = $this->head;
$head_buf = Pack('H32VVVH4', $tmp['id'], $new_len, $tmp['len2'], $tmp['num'], $tmp['unused']);
$head_buf .= $head_body;
$this->_file_save($head_buf, $old_len, $new_len);
// ファイルを閉じて return
$this->_file_deinit();
return true;
}
// 情報を取得
function get_info ($file)
{
$ret = array();
if (!$this->_file_init($file)) return false;
if (!$this->_init_header())
{
$this ->_file_deinit();
return false;
}
// head_buf からデータを取得します
$head_num = $this->head['num'];  // head_frame の数
while (($tmp = $this->_get_head_frame()) && $head_num > 0)
{
$head_num--;
if ($tmp['id'] == '3326b2758e66cf11a6d900aa006 2ce6c ')
{ // 標準情報
$lenx = unpack('v*', $this->_read_head_buf(10));
for ($i = 1; $i <= count($this-> items1); $i++)
{
$k = $this->items1[$i-1];
$ret[$k] = dbcs_gbk($this->_read_head_buf($lenx[$i])) ;
}
}
else if ($tmp['id'] == '40a4d0d207e3d21197f000a0c95ea850')
{ // 拡張情報
$inum = $this->_read_head_short();
$tmp['len '] -= 26;
しながら($ inum&gt; 0 && $ tmp ['len']&gt; 0)
{
//属性name $ nlen = $ this-&gt; _read_head_short(); nlen);
// フラグと値の長さ
$flag = $this->_read_head_short();
$vlen = $this->_read_head_short();
$vbuf = $this->_read_head_short() ($vlen );
//xx
$ tmpを更新['len'] - =(6 + $ nlen + $ vlen); $name, 3);
if (in_array($k, $this->items2))
{ // すべて文字列値 (他のタグについては false を参照)
$ret[$k] = dbcs_gbk($vbuf );
}
}
}
else
{ // のみスキップ
if ($tmp['len'] > 24) $this->head_off += ($tmp['len'] - );
}
}
$this->_file_deinit();
return $ret;
}
// ヘッダーを取得?
function _init_header()
{
fseek($this->fd, 0, SEEK_SET) ;
$buf = fread($this->fd, 30);
if (strlen($buf) != 30) return false;
$tmp = unpack('H32id/Vlen/Vlen2/Vnum/H4unused', $ buf);
if ($tmp['id'] != '3026b2758e66cf11a6d900aa0062ce6c')
return false;
$this->head_buf = fread($this->fd, $tmp['len'] - 30) ;
$this->head = $tmp;
return true;
}
// _get_head_frame()
function _get_head_frame()
{
$buf = $this->_read_head_buf(24); 
if (strlen($buf) != 24) return false;
$tmp = unpack('H32id/Vlen/H8unused', $buf);
return $tmp;
}
}
// mp3 クラス (そうでない場合) IDv2 を選択し、IDv1) を選択します)
class _Mp3Exif extends _AudioExif
{
var $head1;
var $genres = array('ブルース','クラシック ロック','カントリー','ダンス','ディスコ','ファンク','グランジ、ヒップホップ、ジャズ、メタル、ニューエイジ、オールディーズ、その他、ポップ、R&B、ラップ、レゲエ、ロック、 「テクノ」、「インダストリアル」、「オルタナティブ」、「スカ」、「デスメタル」、「いたずら」、「サウンドトラック」、「ユーロテクノ」、「アンビエント」、「トリップホップ」、「ボーカル」、」ジャズ+ファンク、フュージョン、トランス、クラシック、インストゥルメンタル、アシッド、ハウス、ゲーム、サウンドクリップ、ゴスペル、ノイズ、オルタナロック、 「ベース」、「ソウル」、「パンク」、「スペース」、「瞑想的」、「インストゥルメンタル ポップ」、「インストゥルメンタル ロック」、「エスニック」、「ゴシック」、「ダークウェーブ」、「テクノ インダストリアル」、「エレクトロニック」 '、'ポップ フォーク'、'ユーロダンス'、'ドリーム'、'サザン ロック'、'コメディ'、'カルト'、'ギャングスタ'、'トップ 40'、'クリスチャン ラップ'、'ポップ/ファンク'、'ジャングル」、「ネイティブ アメリカン」、「キャバレー」、「ニュー ウェーブ」、「サイカデリック」、「レイブ」、「ショーチューンズ」、「トレーラー」、「ローファイ」、「トライバル」、「アシッド パンク」、「アシッド」 Jazz','Polka','Retro','Musical','Rock & Roll','Hard Rock','Unknown');
// MP3 は常に true を返します
function check_size($file)
{
return true ;
}
// 情報を取得します
function get_info($file)
{
if (!$this->_file_init($file)) return false; 
$ret = false;
if ($this->_init_header())
{
$ret = ($this->head ? $this->gt;_get_v2_info() : $this->_get_v1_info()) ;
$ret['meta'] = $this->_get_meta_info();
}
$this->_file_deinit();
return $ret;
}
// 情報を設定します
function set_info($file, $pa)
{
if (!$this->gt;_file_init($file, true) ) return false;
if ($this->_init_header())
{
// 常に v1 情報を保存します
$this->_set_v1_info($pa);    
// 必要に応じて v2 を最初に設定します
$this->_set_v2_info($pa);
}
$this->_file_deinit();
return true;
}
// ヘッダー情報を取得します[v1+v2] , file_init
の後に呼び出します function _init_header()
{
$this->head1 = false;
$this->head = false;
// まずID3v1の取得を試みます
fseek($this->fd, - 128, SEEK_END);
$buf = fread($this->fd, 128);
if (strlen($buf) == 128 && substr($buf, 0, 3) == 'TAG')
{
$tmp = unpack('a3id/a30Title/a30Artist/a30AlbumTitle/a4 Year/a28Description/CReserved/CTrack/CGenre', $buf);
$this->head1 = $tmp;    
}
// ID3v2の取得を試みます
fseek($this->fd, 0, SEEK_SET);
$buf = fread($this->fd, 10);
if (strlen($buf) == 10 && substr($buf, 0, 3) == 'ID3')
{
$tmp = unpack('a3id/Cver/Crev/Cflag/C4size', $buf);
$tmp['size'] = ($tmp['size1'] unset($tmp['size1'], $tmp['size2'], $tmp['size3'], $tmp['size4']);
$this->head = $tmp;
$this->head_buf = fread($this->fd, $tmp['size']);
}
return ($this->head1 || $this->head);
}
// v1 情報を取得します
function _get_v1_info()
{
$ret = array();
$tmpa = array('タイトル', 'アーティスト', '著作権', '説明', '年', 'アルバムタイトル') ;
foreach ($tmpa as $tmp)
{
$ret[$tmp] = $this->head1[$tmp];
if ($pos = strpos($ret[$tmp], ""))
$ret[$tmp] = substr($ret[$tmp], 0, $pos);
}
// ジャンルをカウント、[Track]
if ($this->head1['Reserved'] = = 0) $ret['Track'] = $this->head1['Track'];
else $ret['Description'] .= chr($ret['Reserved']) 。 chr($ret['Track']);
// ジャンルidx
$g = $this->head1['ジャンル'];
if (!isset($this->genres[$g])) $ ret['Genre'] = 'Unknown';
else $ret['Genre'] = $this->genres[$g];
// 値を返す
$ret['ID3v1'] = 'yes' ;
$ret を返す;
}
// v2 情報を取得します
function _get_v2_info()
{
$ret = array();
$items = array( 'TCOP'=>'著作権', 'TPE1'=>'アーティスト', 'TIT2' =>'タイトル', 'TRCK'=> 'トラック',
'TCON'=>'ジャンル', 'COMM'=>'説明', 'TYER'=>'年', 'TALB '=>'AlbumTitle');
while (true)
{
$buf = $this->_read_head_buf(10);
if (strlen($buf) != 10) Break;    
$tmp = unpack('a4fid/Nsize/nflag', $buf);
if ($tmp['size'] == 0) Break;
$tmp['dat'] = $this->_read_head_buf( $tmp['size']);
// 0x6000 (11000000 00000000)
if ($tmp['flag'] & 0x6000) continue;
// データをマッピングします
if ($k = $items[$tmp[ 'fid']])
{ // 最初の文字が "" の場合はスキップします
if (substr($tmp['dat'], 0, 1) == "") $tmp['dat'] = substr ($tmp['dat'], 1);
$ret[$k] = $tmp['dat'];
}
}
// ジャンルをリセット
if ($g = $ret['Genre' ])
{
if (substr($g,0,1) == '(' && substr($g,-1,1) == ')') $g = substr($g, 1, -1 );
if (is_numeric($g))
{
$g = intval($g);
$ret['Genre'] = (isset($this->genres[$g]) ? $this- >genres[$g] : 'Unknown');
}
}
$ret['ID3v1'] = 'no';
return $ret;
}
// MP3のメタ情報を取得
function _get_meta_info()
{
// 先頭の buf: 0xff
$off = 0;
if ($this->head) $off = $this->head['size'] + 10;
fseek($this ->fd, $off, SEEK_SET);
while (!feof($this->fd))
{
$skip = ord(fread($this->fd, 1));
if ($スキップ == 0xff) ブレーク;
}
if ($skip != 0xff) return false;
$buf = fread($this->fd, 3);
if (strlen($buf) != 3) return false;
$tmp = unpack(' C3', $buf);
if (($tmp[1] & 0xf0) != 0xf0) return false;
// メタ情報を取得します
$meta = array();
// mpeg バージョンを取得します
$meta ['mpeg'] = ($tmp[1] & 0x08 ? 1 : 2);
$meta['layer'] = ($tmp[1] & 0x04) ? (($tmp[1] & 0x02) ? 1 : 2) : (($tmp[1] & 0x02) ? 3 : 0);
$meta['epro'] = ($tmp[1] & 0x01) ? 'いいえ' : 'はい';
// ビットレート
$bit_rates = array(
1 => array(
1 => array(0,32,64,96,128,160,192,224,256,288,320,352,384, 416,448,0),
2 => 配列(0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0),
3 => array(0,32,40,48,56,64,80,96,112,128,160,192,224,256, 320,0)
),
2 => ; 配列(
1 => 配列(0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0),
2 => 配列(0,8,16,24,32,40,48,56, 64,80,96,112,128,144,160,0),
3 => array(0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0)
)
);
$i = $ meta['mpeg'];
$j = $meta['layer'];
$k = ($tmp[2]>>4);
$meta['bitrate'] = $bit_rates[$i ][$j][$k];
// サンプルレート
$sam_rates = array(1=>array(44100,48000,32000,0), 2=>array(22050, 24000,16000,0));
$meta['samrate'] = $sam_rates[$i][$k];
$meta["padding"] = ($tmp[2] & 0x02) ? 'オン' : 'オフ';
$meta["プライベート"] = ($tmp[2] & 0x01) ? 'on' : 'off';
// mode & mode_ext
$k = ($tmp[3]>>6);
$channel_modes = array('stereo', 'ジョイントステレオ', 'デュアルチャンネル' , '単一チャンネル');
$meta['mode'] = $channel_modes[$k];
$k = (($tmp[3]>>4) & 0x03);
$extend_modes = array( 'MPG_MD_LR_LR', 'MPG_MD_LR_I', 'MPG_MD_MS_LR', 'MPG_MD_MS_I');
$meta['ext_mode'] = $extend_modes[$k];
$meta['copyright'] = ($tmp[3] & 0x08) )? 'はい' : 'いいえ';
$meta['original'] = ($tmp[3] & 0x04) ? 'はい' : 'いいえ';
$emphasis = array('none', '50/15 マイクロ秒', 'rreserved', 'CCITT J 17');
$k = ($tmp[3] & 0x03);
$meta['emphasis'] = $emphasis[$k];
return $meta;
}
// v1 情報を設定します
function _set_v1_info($pa)
{
// ID3v1 (単純化)
$off = - 128;
if (!($tmp = $this->head1))
{
$off = 0;
$tmp['id'] = 'TAG';
$tmp['Title'] = $tmp ['アーティスト'] = $tmp['アルバムタイトル'] = $tmp['年'] = $tmp['説明'] = '';
$tmp['予約'] = $tmp['トラック'] = $tmp['Genre'] = 0;
}

// 基本項目
$items = array('Title', 'Artist', 'Copyright', 'Description', ' Year', 'AlbumTitle');
foreach ($items as $k)
{
if (isset($pa[$k])) $tmp[$k] = $pa[$k];
}
// ジャンルインデックス
if (isset($ pa['Genre']))
{
$g = 0;
foreach ($this->genres as $gtmp)
{
if (!strcasecmp($gtmp, $pa['Genre']))
Break;
$g++;
}
$tmp['ジャンル'] = $g;
}
if (isset($pa['Track'])) $tmp['Track'] = intval($pa['Track']);
// データをパックします
$buf = Pack('a3a30a30a30a4a28CCC', $ tmp['id'], $tmp['タイトル'], $tmp['アーティスト'], $tmp['アルバムタイトル'],
$tmp['年'], $tmp['説明'], 0, $tmp['トラック'], $tmp['ジャンル']);
flock($this->fd, LOCK_EX);
fseek($this->fd, $off, SEEK_END);
fwrite($ this->fd, $buf, 128);
flock($this->fd, LOCK_UN);
}
// v2 情報を設定します
function _set_v2_info($pa)
{
if (!$this-> ;head)
{ // ID3 を挿入
return;  // 没有就算了
/**
$tmp = array('id'=>'ID3','ver'=>3,'rev'=>0,'flag'=>0);
$tmp['size'] = -10;  // +10 =>; 0
$this->head = $tmp;
$this->head_buf = '';
$this->head_off = 0;
**/
}
$items = array( 'TCOP'=>'著作権', 'TPE1'=>'アーティスト', 'TIT2'=>'タイトル', 'TRAC'=>'トラック',
'TCON'=>'ジャンル', 'COMM'=>'説明', 'TYER'=>'年', 'TALB'=>' AlbumTitle');
$head_body = '';
while (true)
{
$buf = $this->_read_head_buf(10);
if (strlen($buf) != 10) Break;
$tmp = unpack('a4fid/Nsize/nflag', $buf);
if ($tmp['size'] == 0) Break;
$data = $this->_read_head_buf($tmp['size']);
if (($k = $items[$tmp['fid']]) && isset($pa[$k]))
{
// データの前に "" を付ける必要があります [replace]
$data = " 「。」 $pa[$k];
unset($pa[$k]);
}
$head_body .= Pack('a4Nn', $tmp['fid'], strlen($data), $tmp['flag ']) 。 $data;
}
// アイテムを反転し、新しいタグを設定します
$items = array_flip($items);
foreach ($pa as $k => $v)
{
if ($fid = $items [$k])
{
$head_body .= Pack('a4Nn', $fid, strlen($v) + 1, 0) . 「」。 $v;
}
}
// 新しい長さ
$new_len = strlen($head_body) + 10;
$old_len = $this->head['size'] + 10;
if ($new_len < $ old_len)
{
$head_body .= str_repeat("", $old_len - $new_len);
$new_len = $old_len;    
}
// size1,2,3,4 を数えます、ヘッダーは含めません
// 较為的算法... :p (28bytes integer)
$size = array();
$nlen = $new_len - 10;
for ($i = 4; $i > 0; $i--)
{
$size[$i] = ($nlen & 0x7f);
$nlen >>= 7;
}
$tmp = $this->head;
//echo "old_len : $old_len new_len: $new_len ";
$head_buf = Pack('a3CCCCCCC', $tmp['id'], $tmp['ver' ], $tmp['rev'], $tmp['flag'],
$size[1], $size[2], $size[3], $size[4]);
$head_buf .= $ head_body;
$this->_file_save($head_buf, $old_len, $new_len);
}
}
?>

www.bkjia.com本当http://www.bkjia.com/PHPjc/326999.html技術記事次のようにコードをコピーします: ?php // AudioExif.class.php // PHP を使用してオーディオ ファイルのヘッダー情報を読み書きします // 現在、WMA と MP3 のみがサポートされており、一般的に使用されるものはいくつかのみサポートされています。
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート