H5 视频分片上传

1、主要标签

<input  type="file" id="upload_video_input" accept="video/*"  hidden onChange={(e)=>this.changeUploadVideo(e)}/>
<video id="movie" style={{width:'100%',height:'100%'}} src={currentVideo} preload="auto" > </video>

注释:<input> 上传文件标签

           <video> 上传的视频回显

          currentVideo:全局变量,上传视频的地址

2、上传触发事件  onChange={(e)=>this.changeUploadVideo(e)}

const chunkIds          //存储分片上传结果

changeUploadVideo = e =>{
        const that = this
        console.log(e.target.files)
        const file = e.target.files[0]
        const size = file.size            // 上传文件的大小
        const sizeM = file.size/1024/1024 // 单位是M兆    用于限制上传视频的大小
        const name = file.name            // 上传视频名称
    
        // 获得 上传资源的时长   
        const url = URL.createObjectURL(file);
        //经测试,发现audio也可获取视频的时长
        const audioElement = new Audio(url);
        let duration;
        audioElement.addEventListener("loadedmetadata", function (_event) {
            duration = audioElement.duration;    // 上传视频的秒数        
        })
                     
        chunkIds =[]                     // 每次上传之前清空当前视频分片ids

        this.synchroUpload(file,0)       // 同步递归上传
                                        
        //this.asynchronouslyUpload(file)    // 异步上传
                        
 }

注意:如果需要做视频秒数满足限制才允许上传,那面需要注意上传监听事件的执行与上传方法的执行顺序

3.1、同步请求,通过递归调用分片上传----synchroUpload

    // 同步分片上传  递归   
    synchroUpload = (file,number) =>{
        const shardSize = 0.5 * 1024 * 1024      //以0.5MB为一个分片
        const shardCount = Math.ceil(file.size / shardSize);  //总片数
        if(number<shardCount){
            //计算每一片的起始与结束位置
            const start = number* shardSize,
            end = Math.min(file.size, start + shardSize);
            //构造一个表单,FormData是HTML5新增的
            const formData = new FormData();
            formData.append("data", file.slice(start,end));  //slice方法用于切出文件的一部分
            formData.append("name", file.name);
            formData.append("total", shardCount);  //总片数
            const currentChunk = number+1;
            formData.append("chunk",currentChunk);        //当前是第几片

            const url = "xxx/h5/upload/file_part"
            axios.post(url,formData,{
                header:{
                    "Content-Type":"multipart/form-data;name=chunk; boundary="+new Date().getTime()
                }
            }).then(res=>{
                console.log("分片上传成功",currentChunk)
                chunkIds.push(number)
                this.synchroUpload(file,number+1)  // 递归上传
            },err=>{
                console.log("失败分片",currentChunk)
                return
            })
        }else{
            if(chunkIds.length === shardCount){  // 所有分片上传完成   
                this.mergeVideo(file.name)    // 合并分片
            }
            
        }

    }

3.2、异步请求上传分片----asynchronouslyUpload

    // 异步上传 分片上传    
    asynchronouslyUpload = (file) =>{
        const shardSize = 0.5 * 1024 * 1024   //以4MB为一个分片
        const shardCount = Math.ceil(file.size / shardSize);  //总片数
        for(var i=0;i<shardCount;++i){
            //计算每一片的起始与结束位置
            const start = i* shardSize,
            end = Math.min(file.size, start + shardSize);
            //构造一个表单,FormData是HTML5新增的
            const formData = new FormData();
            const startTime = new Date().getTime()
            formData.append("data", file.slice(start,end));  //slice方法用于切出文件的一部分
            
            formData.append("name", file.name);
            formData.append("total", shardCount);        //总片数
            const currentChunk = i+1;
            formData.append("chunk",currentChunk);                  //当前是第几片    

            const url = "xxx/h5/upload/file_part"
            axios.post(url,formData,{
                header:{
                    "Content-Type":"multipart/form-data;name=chunk; boundary="+new Date().getTime()
                }
            }).then(res=>{
                 chunkIds.push(i)
                 if(chunkIds.length === shardCount){
                     this.mergeVideo(file.name)                 // 合并分片
                 }
                 console.log("分片上传成功",currentChunk)
            },err=>{
                console.log("失败分片",currentChunk)
            })
        }
    }

4、合并视频分片----mergeVideo

    let  currentVideo       // 视频上传成功后的地址,video标签回显播放

    // 合并视频
    mergeVideo = (fileName) =>{
        const url =`xxx/h5/upload/merge?fileName=${fileName}`
        axios.post(url).then(res=>{
            //video_url 接口约定返回的,完成视频的地址url
            if(res.data.video_url && res.data.video_url !==""){
                console.log(res.data.video_url)
                currentVideo = res.data.video_url
            }else{
                console.log("合并视频失败")
            }
        },err=>{
           console.log("合并视频失败")
        })
    }

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值