最新消息:文章中包含代码时,请遵守代码高亮规范!

【原创】音频的切割

PHP Alex 425浏览 0评论

项目中要求无权限的用户只能播放前三分钟的音频,解决思路。提供一个通过id获取音频地址的Api,过程中如果用户无权限则返回一个切割过后的音频。

切割:通过文件的大小/音频的时长获取到比特率,再通过你要截取的时长*比特率得到切割时指正的位置。

fseek:控制件指针偏移

ftell:获取当前指针的位置。

<?php
/**
 * Created by PhpStorm.
 * User: Alex
 * DateTime: 18-5-10上午10:57
 */
namespace ApiBundle\Controller;
use ApiBundle\MP3File;

class AudioCut{
 public $error_message;
 protected $data_buffer=1048576;
 public $audio_time_length;//音频时长
 public $start_time;//截取开始时间
 protected $byte_per_second;//比特率
 protected $old_file;//旧文件地址
 protected $new_file;//新文件地址
 protected $input_data;//读取数据
 protected $output_data;//输出数据
 protected $type;//0保存前段1保存后段
 protected $audio_file_size;//旧音频文件大小

 function __construct($old_file){
 $this->old_file=$old_file;
 }

 public function cut($start_time,$type){
 $new_file = $this->savaPath();

 $this->new_file=$new_file;
 $this->start_time=$start_time;
 $this->type=$type;

 //TODO 设置旧音频时长
 $this->setAudioTimeLength();
 $this->setAudioFileSize();
 $this->setBytePerSecond();
 $this->openInputAudio();
 $this->openOutputAudio();
 $this->makeNewAudio($this->type);
 $this->closeOutputAudio();
 $this->closeInputAudio();

 return $new_file;
 }

 /**
 * 目录地址
 *
 * @return string
 */
 public function savaPath(){
 //目录地址
 $path_name = date('Y-m');
 $path = 'upload' . DIRECTORY_SEPARATOR . $path_name;

 if(!file_exists($path)) {
 $dirs = explode('/' , $path);
 $count = count($dirs);
 $path = '.';
 for ($i = 0; $i < $count; ++$i) {
 $path .= '/' . $dirs[$i];
 if(!is_dir($path)){//不是目录
 if(!mkdir($path,0755)){
 }
 }
 }
 }

 $file_name = uniqid()."cache.".'mp3';

 return $path.DIRECTORY_SEPARATOR.$file_name;
 }

 /**
 * 设置旧音频大小
 */
 public function setAudioFileSize(){
 $this->audio_file_size=@filesize($this->old_file);
 }

 /**
 * 比特率设置
 */
 function setBytePerSecond(){
 $this->byte_per_second=(integer)($this->audio_file_size/$this->audio_time_length);
 }

 /**
 * 设置音频时长
 */
 function setAudioTimeLength(){
 $this->audio_time_length = $this->getAudioTimeByPath($this->old_file);
 }

 /**
 * 根据地址获取时长
 *
 * @param $path
 * @return int
 */
 function getAudioTimeByPath($path){
 $mp3 = new MP3File($path);
 $a = $mp3->getDurationEstimate();
 $mp3->getDuration();
 $audio_time_arr = $mp3::formatTime($a);
 if(!empty($audio_time_arr)){
 return $audio_time_arr['hours']*60*60+$audio_time_arr['minutes']*60+$audio_time_arr['seconds'];
 }else{
 return 0;
 }
 }

 /**
 * 保存
 *
 * @param $type
 */
 function makeNewAudio($type){
 //TODO 起始位置
 $start_position=$this->start_time*$this->byte_per_second;
 if($type==1){
 fseek($this->input_data,$start_position);
 while(!@feof($this->input_data)){
 @fwrite($this->output_data,@fread($this->input_data,$this->data_buffer));
 }
 }else{
 while(@ftell($this->input_data)<=((integer)$start_position)){
 @fwrite($this->output_data,@fread($this->input_data,($this->byte_per_second/2)));
 }
 }
 }

 /**
 * 打开
 *
 * @return bool
 */
 function openInputAudio(){
 if(file_exists($this->old_file)){
 $this->input_data=fopen($this->old_file,"r");
 $result=true;
 }else{
 $this->error("打开文件错误");
 $result=false;
 }
 return $result;
 }

 /**
 * 关闭
 *
 * @return bool
 */
 function closeInputAudio(){
 if(@fclose($this->input_data)){$result=true;}
 else{
 $this->error("操作输入文件错误");
 $result=false;
 }
 return $result;
 }

 /**
 * 关闭
 *
 * @return bool
 */
 function openOutputAudio(){
 $this->output_data=@fopen($this->new_file,"w");
 if($this->output_data){
 $result=true;
 }else{
 $this->error("创建文件错误");
 $result=false;
 }

 return $result;
 }

 /**
 * 关闭
 *
 * @return bool
 */
 function closeOutputAudio(){
 if(@fclose($this->output_data)) {
 $result=true;
 }else{
 $this->error("操作输出文件错误");
 $result=false;
 }
 return $result;
 }

 /**
 * 错误
 *
 * @param $error_message
 */
 function error($error_message){
 $this->error_message.=$error_message."<br>";
 }
}

部分代码面向谷歌编写,存在问题:现在只可以获取常见音频的时长,无法获取如mid,wma格式音频时长。

转载时请注明出处及相应链接,本文永久地址:https://blog.yayuanzi.com/23974.html


pay_weixin
pay_weixin
微信打赏
pay_weixin
支付宝打赏
感谢您对作者Alex的打赏,我们会更加努力!    如果您想成为作者,请点我

发表我的评论
取消评论

表情