最近写个上传MP3的功能,为了方便运营的同学操作,需要上传完MP3后自动获取音乐时长,然后自动插入到input里,关于MP3获取时长的类有好几个,试过之后决定采用下面这种方法。

// 调用方法:
$mp3 = new MP3File($filename);
$a = $mp3->getDurationEstimate();
$b = $mp3->getDuration();
$duration = $mp3::formatTime($b);
// 返回的是一个包含时分秒的数组
class MP3File
{protected $filename;public function __construct($filename){$this->filename = $filename;}public static function formatTime($duration) //as hh:mm:ss{//return sprintf("%d:%02d", $duration/60, $duration%60);$hours = floor($duration / 3600);$minutes = floor( ($duration - ($hours * 3600)) / 60);$seconds = $duration - ($hours * 3600) - ($minutes * 60);// return sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds);return array('hours'=>$hours, 'minutes'=>$minutes, 'seconds'=>$seconds);}//Read first mp3 frame only...  use for CBR constant bit rate MP3spublic function getDurationEstimate(){return $this->getDuration($use_cbr_estimate=true);}//Read entire file, frame by frame... ie: Variable Bit Rate (VBR)public function getDuration($use_cbr_estimate=false){$fd = fopen($this->filename, "rb");$duration=0;$block = fread($fd, 100);$offset = $this->skipID3v2Tag($block);fseek($fd, $offset, SEEK_SET);while (!feof($fd)){$block = fread($fd, 10);if (strlen($block)<10) { break; }//looking for 1111 1111 111 (frame synchronization bits)else if ($block[0]=="\xff" && (ord($block[1])&0xe0) ){$info = self::parseFrameHeader(substr($block, 0, 4));if (empty($info['Framesize'])) { return $duration; } //some corrupt mp3 filesfseek($fd, $info['Framesize']-10, SEEK_CUR);$duration += ( $info['Samples'] / $info['Sampling Rate'] );}else if (substr($block, 0, 3)=='TAG'){fseek($fd, 128-10, SEEK_CUR);//skip over id3v1 tag size}else{fseek($fd, -9, SEEK_CUR);}if ($use_cbr_estimate && !empty($info)){ return $this->estimateDuration($info['Bitrate'],$offset); }}return round($duration);}private function estimateDuration($bitrate,$offset){$kbps = ($bitrate*1000)/8;$datasize = filesize($this->filename) - $offset;return round($datasize / $kbps);}private function skipID3v2Tag(&$block){if (substr($block, 0,3)=="ID3"){$id3v2_major_version = ord($block[3]);$id3v2_minor_version = ord($block[4]);$id3v2_flags = ord($block[5]);$flag_unsynchronisation  = $id3v2_flags & 0x80 ? 1 : 0;$flag_extended_header    = $id3v2_flags & 0x40 ? 1 : 0;$flag_experimental_ind   = $id3v2_flags & 0x20 ? 1 : 0;$flag_footer_present     = $id3v2_flags & 0x10 ? 1 : 0;$z0 = ord($block[6]);$z1 = ord($block[7]);$z2 = ord($block[8]);$z3 = ord($block[9]);if ( (($z0&0x80)==0) && (($z1&0x80)==0) && (($z2&0x80)==0) && (($z3&0x80)==0) ){$header_size = 10;$tag_size = (($z0&0x7f) * 2097152) + (($z1&0x7f) * 16384) + (($z2&0x7f) * 128) + ($z3&0x7f);$footer_size = $flag_footer_present ? 10 : 0;return $header_size + $tag_size + $footer_size;//bytes to skip}}return 0;}public static function parseFrameHeader($fourbytes){static $versions = array(0x0=>'2.5',0x1=>'x',0x2=>'2',0x3=>'1', // x=>'reserved');static $layers = array(0x0=>'x',0x1=>'3',0x2=>'2',0x3=>'1', // x=>'reserved');static $bitrates = array('V1L1'=>array(0,32,64,96,128,160,192,224,256,288,320,352,384,416,448),'V1L2'=>array(0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384),'V1L3'=>array(0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320),'V2L1'=>array(0,32,48,56, 64, 80, 96,112,128,144,160,176,192,224,256),'V2L2'=>array(0, 8,16,24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160),'V2L3'=>array(0, 8,16,24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160),);static $sample_rates = array('1'   => array(44100,48000,32000),'2'   => array(22050,24000,16000),'2.5' => array(11025,12000, 8000),);static $samples = array(1 => array( 1 => 384, 2 =>1152, 3 =>1152, ), //MPEGv1,     Layers 1,2,32 => array( 1 => 384, 2 =>1152, 3 => 576, ), //MPEGv2/2.5, Layers 1,2,3);//$b0=ord($fourbytes[0]);//will always be 0xff$b1=ord($fourbytes[1]);$b2=ord($fourbytes[2]);$b3=ord($fourbytes[3]);$version_bits = ($b1 & 0x18) >> 3;$version = $versions[$version_bits];$simple_version =  ($version=='2.5' ? 2 : $version);$layer_bits = ($b1 & 0x06) >> 1;$layer = $layers[$layer_bits];$protection_bit = ($b1 & 0x01);$bitrate_key = sprintf('V%dL%d', $simple_version , $layer);$bitrate_idx = ($b2 & 0xf0) >> 4;$bitrate = isset($bitrates[$bitrate_key][$bitrate_idx]) ? $bitrates[$bitrate_key][$bitrate_idx] : 0;$sample_rate_idx = ($b2 & 0x0c) >> 2;//0xc => b1100$sample_rate = isset($sample_rates[$version][$sample_rate_idx]) ? $sample_rates[$version][$sample_rate_idx] : 0;$padding_bit = ($b2 & 0x02) >> 1;$private_bit = ($b2 & 0x01);$channel_mode_bits = ($b3 & 0xc0) >> 6;$mode_extension_bits = ($b3 & 0x30) >> 4;$copyright_bit = ($b3 & 0x08) >> 3;$original_bit = ($b3 & 0x04) >> 2;$emphasis = ($b3 & 0x03);$info = array();$info['Version'] = $version;//MPEGVersion$info['Layer'] = $layer;//$info['Protection Bit'] = $protection_bit; //0=> protected by 2 byte CRC, 1=>not protected$info['Bitrate'] = $bitrate;$info['Sampling Rate'] = $sample_rate;//$info['Padding Bit'] = $padding_bit;//$info['Private Bit'] = $private_bit;//$info['Channel Mode'] = $channel_mode_bits;//$info['Mode Extension'] = $mode_extension_bits;//$info['Copyright'] = $copyright_bit;//$info['Original'] = $original_bit;//$info['Emphasis'] = $emphasis;$info['Framesize'] = self::framesize($layer, $bitrate, $sample_rate, $padding_bit);$info['Samples'] = $samples[$simple_version][$layer];return $info;}private static function framesize($layer, $bitrate,$sample_rate,$padding_bit){if ($layer==1)return intval(((12 * $bitrate*1000 /$sample_rate) + $padding_bit) * 4);else //layer 2, 3return intval(((144 * $bitrate*1000)/$sample_rate) + $padding_bit);}
}

PHP获取MP3时长类相关推荐

  1. python 获取mp3时长(时间长度)

    python 获取mp3时长(时间长度) 第一种方法 import librosa import time def get_mp3_duration(audio_path):""& ...

  2. 播放器ocx插件——自动获取MP3时长

    函数 wmp.currentPlaylist.appendItem(media) # 添加音频@media入播放列表 wmp.controls.play() # 播放 wmp.controls.sto ...

  3. html javascript 音频、视频、 mp3 、mp4 的播放、暂停、重新播放、获取音频时长、视频自动全屏播放

    html javascript 音频.视频. mp3 .mp4 的播放.暂停.重新播放.获取音频时长 视频 https://www.bilibili.com/video/BV1WE411o7Ft?fr ...

  4. java在linux转化mp3,linux下微信/qq的aud、silk音频文件格式与mp3格式互转,获取音频时长的方法,附问题分析和java代码。...

    安装ffmpeg ffmpeg -codecs -可以看出ffmpeg默认的MP3格式无法编码为其它格式[D.A.L mp3]D=解码 E=编码 A=AudioCodec L=有损压缩 需要安装lam ...

  5. linux下微信/qq的aud、silk音频文件格式与mp3格式互转,获取音频时长的方法,附问题分析和java代码。

    安装ffmpeg ffmpeg -codecs -可以看出ffmpeg默认的MP3格式无法编码为其它格式[D.A.L mp3]D=解码 E=编码 A=AudioCodec L=有损压缩 需要安装lam ...

  6. java获取视频时长(实测可行)

    因为数据库视频表有一段时间丢失维护duration字段, 现在有需求需要用到此字段,只能再重新获取一遍, 更新表.哎!!! 先奉上 https://github.com/opensourceteams ...

  7. iOS 录音,获取录音时长及格式转换

    转载请注明出处!!! 在APP中,我们也会遇到调用录音的功能,那么如何录音呢?并且在iOS中录音格式是wav或者caf格式的,和安卓不通用,为了达到通用的效果,我们还需要把他转换成通用格式.近期我遇到 ...

  8. android获取小程序音频时长,最新微信小程序获取音频时长与实时获取播放进度...

    #微信小程序获取音频时长与实时获取播放进度 在小程序官方文档中 audio 注意:1.6.0 版本开始,该组件不再维护.建议使用能力更强的 wx.createInnerAudioContext 接口 ...

  9. 最新微信小程序获取音频时长与实时获取播放进度

    #微信小程序获取音频时长与实时获取播放进度 在小程序官方文档中 audio 注意:1.6.0 版本开始,该组件不再维护.建议使用能力更强的 wx.createInnerAudioContext 接口 ...

  10. java获得U盘根目录、读取图片视频头文件信息、获取视频时长

    1.获得U盘根目录,例如我们取名U盘名称为"测试U盘",一般插入U盘后,在系统的H盘 /** * 得到系统U盘根目录 */ public String findURootPath( ...

最新文章

  1. 被迫重构代码,这次我干掉了 if-else
  2. hdu1166 敌兵布阵
  3. C语言矩阵M*N节省空间的算法(附完整源码)
  4. 在乌班图中将py3设置为默认解释器
  5. android webview权限申请_android - 在运行时向摄像机请求WebView权限 - 堆栈内存溢出...
  6. Mendix:低代码与无代码的异同点与用例
  7. 慕课python就业班加微信_给初学python的朋友的一些忠告和建议
  8. html如何隐藏盒子的边框线,用DIV和CSS做一个实线边框的红色盒子
  9. MSA移动安全联盟 获取OAID 异常问题
  10. 木疙瘩离线版导出html,木疙瘩的功能介绍和特色
  11. java 罗马数字_罗马数字 | 学步园
  12. 闲的没事,自己动手修改上兴3.2源代码
  13. NOIP2011(提高组)DAY2---观光公交(vijosP1741)
  14. 服务器上用U盘安装Linux系统详细步骤
  15. 工程数学 计算方法 第五章 数值积分
  16. java h5模板引擎_详解SpringBoot+Thymeleaf 基于HTML5的现代模板引擎
  17. Java 北大青鸟 第一学期 第三章 选择结构(一) 上级练习+课后作业
  18. 单节锂电池充电管理芯片IC电路图
  19. 跳线架和配线架,二者你分得清吗?
  20. ccf-csp202006

热门文章

  1. 杭州地铁首末站周边停车场正酝酿停车收费优惠
  2. 震惊了!鸿蒙又多了一种开发方式Ets,让更多的人赶上红利!
  3. php学习日志(5)-解决Windows Live Writer错误:WindowsLive.Writer.CoreServices.HttpRequestHelper的类型初始值设定发生异常...
  4. 淘宝七天自动确认收货,让你设计,可以怎么实现?(附源码)
  5. 单片机学习(三)8位数码管显示8个字符的程序及详解
  6. 计算任意2个日期内的工作日(没有考虑到国定假日
  7. SAP 因谁而腾飞?NetApp
  8. windows, macos 和 linux 各平台的哈希校验方法汇总
  9. 使用itext实现pdf图片签章
  10. ajax同步导致浏览器假死