用google大神很難找到3GP的File Format 提供一個用PHP寫的, 很實用喔 <? function Get3GPInfo($videofn, $debug=false) { $info = array(); $FHeader = "NSize/a4Type/a4Brand/NVersion"; $length = 4+4+4+4; $fp = fopen($videofn, "rb"); $data = fread($fp, $length); $Header = unpack("@0/$FHeader", $data); if(substr($Header['Brand'], 0, 3) !== '3gp') return false; $data = fread($fp, $Header['Size']-$length); $Header['CompatibleBrand'] = $data; $info['Type'] = $Header['Type']; $info['Brand'] = $Header['Brand']; $info['CompatibleBrand'] = $Header['CompatibleBrand']; if($debug) { echo "<br>Header: "; print_r($Header); echo "<br>"; } $bk = " "; while(!feof($fp)) { $f_Atom = "NSize/a4Name"; $l_Atom = 4+4; $data = fread($fp, $l_Atom); if(!$data) break; $Atom = unpack("@0/$f_Atom", $data); //print_r($Atom); $p_Atom = ftell($fp); //echo "<br>"; switch($Atom['Name']) { case 'moov': $level = 0; break; case 'mdat': $level = 0; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'mvhd': $level = 1; $data = fread($fp, $Atom['Size']-$l_Atom); $f_mvhd = "H2Version/H6Flag/H8CreationTime/H8ModificationTime/NTimeScale/NDuration/x80NotUse"; $array = unpack("@0/$f_mvhd", $data); $info['Len'] = $array['Duration']/$array['TimeScale']; break; case 'trak': $level = 1; break; case 'iods': $level = 1; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'tkhd': $level = 2; $f_tkhd = "H2Version/H6Falg/H8CTime/H8MTime/NTrackID/x4R1/NDruation/x52R2/NTrackWidth/NTrackHeight"; $data = fread($fp, $Atom['Size']-$l_Atom); $array = unpack("@0/$f_tkhd", $data); $info['Track']['ID'][] = $array['TrackID']; $info['Track']['Width'][] = $array['TrackWidth'] >> 16; $info['Track']['Height'][] = $array['TrackHeight'] >> 16; break; case 'tref': $level = 2; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'rtng': $level = 2; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'uuid': if($level < 3) $level = 2; else $level = 3; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'mdia': $level = 2; //$data = fread($fp, $Atom['Size']-$l_Atom); break; case 'mdhd': $level = 3; $f_mdhd = "H2Version/H6Flag/H8CTime/H8MTime/NTimeScale/NDuration/x4R"; $data = @fread($fp, $Atom['Size']-$l_Atom); $array = unpack("@0/$f_mdhd", $data); $info['Track']['Len'][] = $array['Duration'] / $array['TimeScale']; $TimeScale = $array['TimeScale']; break; case 'hdlr': $level = 3; $f_hdlr = "H2Version/H6Flag/a4Type/a4Subtype/a4Manufacturer/H8CFlag/H8CMask"; $l_hdlr = 1+3+4+4+4+4+4; $data = fread($fp, $l_hdlr); $array = unpack("@0/$f_hdlr", $data); $info['Track']['Type'][] = $array['Subtype']; $TrackType = $array['Subtype']; $data = @fread($fp, $Atom['Size']-$l_Atom-$l_hdlr); break; case 'minf': $level = 3; //$data = fread($fp, $moov['Size']-$l_moov); break; case 'smhd': $level = 4; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'vmhd': $level = 4; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'hmhd': $level = 4; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'nmhd': $level = 4; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'dinf': $level = 4; //$data = fread($fp, $Atom['Size']-$l_Atom); break; case 'dref': $level = 5; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'stbl': $level = 4; //$data = fread($fp, $Atom['Size']-$l_Atom); break; case 'stsd': $level = 5; $f_stsd = "H2Version/H6Falg/NEntries/NDescSize/a4DataFormat/x6Reserved/H4DataIndex"; $l_stsd = 1+3+4+4+4+6+2; $data = fread($fp, $l_stsd); $array = unpack("@0/$f_stsd", $data); $info['Track']['DataFormat'][] = $array['DataFormat']; $data = @fread($fp, $Atom['Size']-$l_Atom-$l_stsd); break; case 'stts': $level = 5; $f_stts = "H2Version/H6Flag/NEntries"; $l_stts = 1+3+4; $data = fread($fp, $l_stts); $array = unpack("@0/$f_stts", $data); $f_stts_e = "NSampleCount/NSampleDuration"; $l_stts_e = 4+4; $TotalSampleDuration = 0; for($i=0; $i < $array['Entries']; $i++) { $data = fread($fp, $l_stts_e); $t_array = unpack("@0/$f_stts_e", $data); $TotalSampleDuration += $t_array['SampleDuration']; } if($TrackType == 'vide') { $AvgSampleDuration = $TotalSampleDuration / $array['Entries']; $info['FrameRate'] = $TimeScale / $AvgSampleDuration; } //$data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'stss': $level = 5; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'stsc': $level = 5; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'stsz': $level = 5; $data = fread($fp, 4); //$array = unpack("NEntries", fread($fp, 4)); //$s = $Atom['Size']-$l_Atom-4; //$f = "NSampleSize/N".($s/4-1)."SampleCount"; $f = "NSampleSize/NSampleCount"; $data = fread($fp, 8); $array = unpack("@0/$f", $data); if($array['SampleSize']) { $TotalSize = $array['SampleSize'] * $array['SampleCount']; $info['Track']['Bitrate'][] = intval(($TotalSize / $info['Len'] * 8 / 1000 + 0.005)* 100) / 100; } else { $TotalSize = 0; for($i = 0; $i < $array['SampleCount']; $i++) { $t_array = unpack("@0/NEntrySize", fread($fp, 4)); $TotalSize += $t_array['EntrySize']; } $info['Track']['Bitrate'][] = intval(($TotalSize / $info['Len'] * 8 / 1000 + 0.005)* 100) / 100; } $info['Track']['DataSize'][] = $TotalSize; break; case 'meta': $level = 3; $data = @fread($fp, $Atom['Size']-$l_Atom); break; case 'udta': if($level > 1) $level = 2; else $level = 1; //$data = fread($fp, $Atom['Size']-$l_Atom); break; case 'hnti': if($level > 0) $level = 3; else $level = 1; break; case 'sdp ': if($level > 0) $level = 4; else $level =2; $f_sdp = "a".($Atom['Size']-$l_Atom)."SDP"; $data = fread($fp, $Atom['Size']-$l_Atom); $array = unpack("@0/$f_sdp", $data); $info['Track']['SDP'][] = $array['SDP']; break; case 'rtp ': $level = 4; $f_sdp = "a".($Atom['Size']-$l_Atom)."RTP"; $data = fread($fp, $Atom['Size']-$l_Atom); $array = unpack("@0/$f_sdp", $data); break; case 'stco': $level = 5; $data = @fread($fp, $Atom['Size']-$l_Atom); break; default: $level = 0; $data = @fread($fp, $Atom['Size']-$l_Atom); break; } if($debug) { for($i=0; $i < $level; $i++) echo "$bk"; echo "|-".$Atom['Name'].": "; if(count($array) > 0) print_r($array); echo "<br>"; } $array = array(); }//while(!feof($fp)); //ftell($fp) < $Atom['Size']-$l_moov); fclose($fp); return $info; } $info = Get3GPInfo(GET['fn'], GET['d']); if(!$info) { echo "Not 3gp file!!!"; exit; } echo "<br><br>"; echo "Type: ".$info['Type']."<br>"; echo "Brand: ".$info['Brand']."<br>"; echo "CompatibleBrand: ".$info['CompatibleBrand']."<br>"; echo "Len: ".$info['Len']." Secs<br>"; echo "FrameRate: ".$info['FrameRate']."<br>"; for($i=0,$j=0; $i < count($info['Track']['Type']); $i++) { echo "<br>"; echo "Track".($i+1)." ID: ".$info['Track']['ID'][$i]."<br>"; echo "Track".($i+1)." Type: ".$info['Track']['Type'][$i]."<br>"; echo "Track".($i+1)." Format: ".$info['Track']['DataFormat'][$i]."<br>"; echo "Track".($i+1)." DataSize: ".$info['Track']['DataSize'][$i]." bytes<br>"; echo "Track".($i+1)." Len: ".$info['Track']['Len'][$i]." secs<br>"; echo "Track".($i+1)." Bitrate: ".$info['Track']['Bitrate'][$i]." kbps<br>"; echo "Track".($i+1)." Width: ".$info['Track']['Width'][$i]."<br>"; echo "Track".($i+1)." Height: ".$info['Track']['Height'][$i]."<br>"; if($info['Track']['Type'][$i] == 'hint') echo "Track".($i+1)." SDP: ".$info['Track']['SDP'][$j++]."<br>"; } ?>