php分片上传视频

Posted tjg888888

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php分片上传视频相关的知识,希望对你有一定的参考价值。

页面内容

#uploadVideo
      text-align: center;
      line-height: 30px;
      font-size: 12px;
      overflow: hidden;
      display: inline-block;
      /*position: absolute;*/
      width: 100px;
      height: 30px;
      background-color: #ccc;
      border: 1px solid #000;
      border-radius: 4px;
      margin-top: 100px;
      margin-left: -303px;
      margin-bottom: -40px;
    

#progress
         display: inline-block;
      width: 300px;
      height: 20px;
      background-color:#f7f7f7;
      box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);
      border-radius:4px;
      background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);
      margin-bottom: 160px;
      margin-left: 51px;
   
 
    #finish
      background-color: #149bdf;
      background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);
      background-size:40px 40px;
      height: 100%;
   
 

<div>
                     <video controls="controls" id="thumbnail-preview-video" src="http://oss.zhhmgj.com/test/2.mp4" type="video/mp4" style="cursor: pointer;width: 280px;height: 210px;"></video>
                    <div id="progress">
                        <div id="finish" style="width: 0%;" progress="0"></div>
                    </div>
                     <span id="uploadVideo">
                          <input type="file" id="video_url" name="file" size="1" class='file' />
                          <a href="#" class="upVideo">上传视频</a >
                    </span>
                    <a href="#" class="fileMerge" id="fileMerges">合并压缩</a>

</div>

     //视频分片上传开始
      var fileForm = document.getElementById("video_url");
       var upload = new Upload();
       fileForm.onchange = function()
           var fileVIdeo =  document.getElementById("video_url").files[0];
           var video_name=fileVIdeo['name'];
        // //获取视频时长开始
         var url = URL.createObjectURL(fileVIdeo);
         var audioElement = new Audio(url);
         audioElement.addEventListener("loadedmetadata", function (_event)
             var duration = audioElement.duration;
             var video_time=Math.ceil(duration);
             $('#video_time').val(video_time);
         );
         $('#video_name').val(video_name);
         upload.addFileAndSend(this);
       
    //上传类
     function Upload()
     var xhr = new XMLHttpRequest();
     var form_data = new FormData();
     const LENGTH = 1024 * 1024*10;
     var start = 0;
     var end = start + LENGTH;
     var blob;
     var blob_num = 1;
     var is_stop = 0
     //对外方法,传入文件对象
     this.addFileAndSend = function(that)
       var file = that.files[0];
       blob = cutFile(file);
       sendFile(blob,file);
       blob_num += 1;
    
     //停止文件上传
     this.stop = function()
       xhr.abort();
       is_stop = 1;
    
     //切割文件
     function cutFile(file)
       var file_blob = file.slice(start,end);
       start = end;
       end = start + LENGTH;
       return file_blob;
     ;
     //发送文件
     function sendFile(blob,file)
       var total_blob_num = Math.ceil(file.size / LENGTH);
       form_data.append('file',blob);
       form_data.append('blob_num',blob_num);
       form_data.append('total_blob_num',total_blob_num);
       form_data.append('file_name',file.name);
        $('#total_blob_num').val(total_blob_num);
       xhr.open('POST','/admin/Alioss/handleaudio',false);
       xhr.onreadystatechange = function ()
         var progress;
         var progressObj = document.getElementById('finish');
         if(total_blob_num == 1)
           progress = '100%';
         else
             progress = Math.min(100,(blob_num/total_blob_num)* 100 ) +'%';
        
         progressObj.style.width = progress;
         if(progress=='100%')
             is_stop=1;
        
         var t = setTimeout(function()
           if(start < file.size && is_stop === 0)
            blob = cutFile(file);
             sendFile(blob,file);
             blob_num += 1;
           else
             setTimeout(t);
          
         ,1000);
      
       xhr.send(form_data);

    
  

  //视频分片上传结束

 //视频合成压缩开始
  $('.fileMerge').click(function()
       var formData = new FormData();
       var totalBlobNum=$('#total_blob_num').val();
       var fileName=$('#video_name').val();
     formData.append('totalBlobNum', totalBlobNum);
     formData.append('fileName', fileName);
     formData.append('formerly_name', fileName);
       //提交后台处理
          $.ajax(
           url: '/admin/Alioss/fileMerge',
           type: 'POST',
           cache: false,
           data:formData,
           dataType: "JSON",
           processData: false,
           contentType: false
          ).done(function(res)
           if(res.code == 1)
               //视频压缩
               $.ajax(
               url: '/admin/Alioss/compress',
              type: 'POST',
               cache: false,
               data:formData,
               dataType: "JSON",
               processData: false,
               contentType: false
              ).done(function(res)
               if(res.code == 1)
                   $('#video_data').val(res.url);
                   document.getElementById("thumbnail-preview-video").src = res.url;
                   alert(res.msg);
               else
                  alert(res.msg);
               
              ).fail(function(res)

              );
           else
               alert(res.msg);
           
          ).fail(function(res)

          );
   )
  //视频合成压缩结束

分片上传接口

function handleaudio(Request $request)
        //第一步 分片上传
        //接收参数
        $file_url=$request->file('file');
        $tmpPath=$file_url->getInfo()['tmp_name'];
        $blobNum=$request->param('blob_num');
        $totalBlobNum=$request->param('total_blob_num');
        $fileName=$request->param('file_name');
        $blob_num=$blobNum+1;        
        //继续分片上传
        $this->touchDir(self::video_path);
        $filename = self::video_path.'/'.$blobNum.$fileName;
        move_uploaded_file($tmpPath,$filename);

   

//建立上传文件夹
    function touchDir($filepath='')
        if(!file_exists($filepath))
            return mkdir($filepath);
        else
            return true;
       
   

//视频文件合成
    function fileMerge(Request $request)//$blobNum='',$totalBlobNum='',$filepath='',$fileName=''
        $data=$request->param();
        if(empty($data['totalBlobNum']) || empty($data['fileName']))
            $rs['code']=0;
            $rs['msg']='参数缺失';
            $rs['data']=[];
            echo json_encode($rs);exit();
       
        $totalBlobNum=$data['totalBlobNum'];
        $filepath=self::video_path;
        $fileName=$data['fileName'];
        //分片视频进行合并处理
        $blob = '';
        for($i=1; $i<= $totalBlobNum; $i++)
            $blob .= file_get_contents($filepath.'/'.$i.$fileName);
       
        file_put_contents($filepath.'/'. $fileName,$blob);
        //合并完后分片的视频删除
        for($i=1; $i<= $totalBlobNum; $i++)
            @unlink($filepath.'/'.$i.$fileName);
       
        $rs['code']=1;
        $rs['msg']='文件合成成功';
        $rs['data']=[];
        echo json_encode($rs);exit();
   

//视频文件压缩 上传oss
    function compress(Request $request)
        $data=$request->param();
        if(empty($data['formerly_name']))
            $rs['code']=0;
            $rs['msg']='参数缺失';
            $rs['data']=[];
            echo json_encode($rs);exit();
       
        $catalogue=self::video_path.'/';//要压缩的视频目录
        $formerly_name=$data['formerly_name'];//要压缩的视频原文件名
        $after_name='新'.$formerly_name;//压缩之后的视频文件名
        $cmd="ffmpeg -i $catalogue$formerly_name -s 360x640 -b:v 862k $catalogue$after_name";//2>&1
        $commandOutput =exec($cmd,$output,$status);
        if($status==0)
            @unlink($catalogue.$formerly_name);
            //上传oss
            $file_url=$catalogue.$after_name;
            $content=file_get_contents($file_url);
            $object=self::catalogue.'/'.$after_name;
            $OssClient=new OssClient(self::accessKeyId,self::accessKeySecret,self::endpoint);
            $result=$OssClient->putObject(self::bucket,$object,$content);
            if(!empty($result))
                if(!empty($result['info']))
                    if($result['info']['http_code']==200)
                        @unlink($catalogue.$after_name);
                        $rs['code'] = 1;
                        $rs['msg'] = '上传成功';
                        $rs['url'] = 'http://oss.zhhmgj.com/'.self::catalogue.'/'.$after_name;
                        echo json_encode($rs);exit();
                    else
                        $rs['code'] = 0;
                        $rs['msg'] = '阿里云返回上传状态码不正确';
                        $rs['url'] = "";
                        echo json_encode($rs);exit();
                   
                else
                        $rs['code'] = 0;
                        $rs['msg'] = '返回上传详细信息失败';
                        $rs['url'] = "";
                        echo json_encode($rs);exit();
               
            else
                        $rs['code'] = 0;
                        $rs['msg'] = '上传失败';
                        $rs['url'] = "";
                        echo json_encode($rs);exit();

           
       
   

Web Uploader + php视频分片上传

参考技术A 由于最近项目中遇到有做视频上传的功能,决定写一篇文章详细说明大文件上传的原理和使用Baidu WebFE(FEX)团队开发的文件上传插件WebUploader。

利用前端框架WebUploader配置进行对大文件的分片(由Baidu官方测试,每5M一个分片是效率最高的),这里,我的服务端是php,所以需要修改php.ini里面的post_max_size配置,默认是2M,我这里改的是8M。

服务端php接收分片,WebUploader插件会提供一个GUID,可以利用GUID加任意个性化信息做分片名(当然,分片序号需要加上),当所有分片上传完毕后,调用合并请求,对分片进行合并即可。

上传前,我会计算整个文件的MD5值到我们的资源库去查找是否已有相同资源,如果有的话,直接文件共享即可。

首先,我们需要创建对应的文件夹

其实服务端做的事情相对比较简单了,每上传的分片写到一个文件里去,最后把分片按照序号合并起来即可。

用户上传大文件的时候或多或少会有中断,断网的情况,这个时候服务器就会出现多的分片碎片,这个完全占用服务器存储空间的,所以我们需要对这些所谓的垃圾文件做处理,我们可以设置碎片文件的过期时间,如果超过时间还存在的话,进行删除,或者当天删除前一天的分片文件夹也是可以的,这样相对来说比较省事。

以上是关于php分片上传视频的主要内容,如果未能解决你的问题,请参考以下文章

PHP大文件分片上传/多线程上传

PHP大文件分片上传/多线程上传

大文件分片上传的实现前后台完整版

b/s 大文件分片上传处理

大文件分片上传,断点续传,秒传 实现

HTML5实现大文件分片上传示例