php分片上传_大视频文件_js异步上传大文件

前端部分:

切割文件,然后递归上传,开始使用循环,但是循环时 不可以异步上传,分片的顺序会乱,只能同步,但是同步的时候,进度条那里就不好使了,最后改成递归异步,问题都解决了,开心;

<input id="video" type="file" name="video">
<input id="video_url" type="hidden" name="video_url" value="">
//视频分段
    $("#video").change(function(){
        videupload();
    })

    var bytesPerPiece = 1024 * 1024 * 3; // 每个文件切片大小定为3MB
    var nub = 0; //进度条
    var n = 0;
    var start = 0; //切割 起始下标
    var end = 0; //切割 结束下标
    function videupload() {
        var blob = document.getElementById("video").files[0];
        var filesize = blob.size;
        var filename = blob.name;
        var totalPieces = Math.ceil(filesize / bytesPerPiece); //切片份数
        var pian_num = Math.round(100 / totalPieces); //计算每片视频 进度条走的百分比
        
        if (n < totalPieces) {
            end = start + bytesPerPiece;
            var chunk = blob.slice(start,end);//切割文件
            start = end;
        } else {
            return false;
        }
        var formData = new FormData();
        formData.append("file", chunk, filename);
        formData.append("totalPieces", totalPieces);
        formData.append("num", n+1);
        formData.append('filename',filename);
        $.ajax({
            url: '/assessment/Video/fenduanUpload',
            type: 'POST',
            dataType: 'json',
            // async:false,
            data: formData,
            processData: false,
            contentType: false,
            success:function(data){
                // console.log(data)
                if (data.st == "success") {
                    $("#video_url").val(data.data['video_url'])
                    $("#videochoose").addClass("selected").html(filename);
                    nub = 100;
                } else {
                    nub += pian_num;
                }
                //进度条
                $("#tiao").css('width',nub+'%');
                n++;
                videupload();
            }
        });
    }

后端PHP 代码:

使用的CI4框架,先将文件上传到服务器,在进行合并,最终删除掉分片文件,

框架其实无所谓,就是上传文件那里,每个框架都封装的都不太一样  其他都没啥区别;

    /*
     * [视频分片上传]
     */
    public function fenduanUpload() {
        $video = $this->request->getFile('file');
        $num = $this->request->getPost('num' , FILTER_SANITIZE_STRING); //第几个视频片段
        $totalPieces = $this->request->getPost('totalPieces' , FILTER_SANITIZE_STRING); //视频片段总数
        $filename = $this->request->getPost('filename' , FILTER_SANITIZE_STRING); //视频名
        if ($video) {
            //视频片段存放路径,没有就创建
            $video_path = FCPATH . '/uploads/admin/training/video';
            if (!is_dir($video_path)) {
                mkdir($video_path , '0777' ,true);
            }
            $videoPath = 'uploads/admin/training/video/'.date('Y').'/'.date('m').'/'.date('d').'/';
            //视频片段 文件名
            $video_name = $filename.'_'.$num;
            //异动文件到指定目录
            $video->move($videoPath, $video_name);
            //判断是否最后一个分片 合并分片
            $path = $this->fileMerge($num,$totalPieces,$videoPath,$filename);
            if ($path) {
                $data['video_url'] = $path;
                //删除分片文件
                $this->deleteFileBlob($totalPieces,$videoPath,$filename);
                return $this->showJsonMsg('success', '视频上传成功' , '' , $data);
            } else {
                return $this->showJsonMsg('error', '视频分片上传中');
            }
        }
    }

    /*
     * [合并分片文件]
     * $num 第几个文件分片
     * $totalPieces 文件分片总数
     * $videoPath 文件分片存放路径
     * $fileName 文件分片名
     * return $path 返回合并后文件路径
     */
    Public function fileMerge($num , $totalPieces , $videoPath , $fileName) {
        //判断是否最后一个分片文件 是就合并
        if($num == $totalPieces) {
            $blob = '';
            //循环读取视频 分片文件 
            for($i=1; $i<= $totalPieces; $i++){
                $blob .= file_get_contents($videoPath.$fileName.'_'.$i);
            }
            //将循环出的视频文件字符串 写入文件中,生成最终视频文件 LOCK_EX 标记可以防止多人同时写入
            $path = $videoPath.time().$fileName;
            $result = file_put_contents($path, $blob, FILE_APPEND | LOCK_EX);
            if ($result) {
                return $path;
            }else {
                return false;
            }
        }else{
            return false;
        }
    }

    /*
     * [删除分片文件]
     * $totalPieces 文件分片总数
     * $videoPath 文件分片存放路径
     * $fileName 文件分片名
     */
    public function deleteFileBlob($totalPieces , $videoPath , $fileName) {
        for($i=1; $i<= $totalPieces; $i++){
            unlink($videoPath.$fileName.'_'.$i);
        }
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值