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(); } }); }
使用的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); } }
————————————————
文章转载自:https://blog.csdn.net/weixin_44135162/article/details/111505727
版权声明:本文由“憨小猪”发布,如需转载请注明出处。