Gin存储文件与oss对象存储(二)
Gin存储文件与oss对象存储(二)
Gin存储文件与oss对象存储(二)
概述
朋友们大家好啊,这一篇笔记我们来简单记录一下前端在Vue2项目中base64转图片,在文件上传时实现分片上传、断点续传功能;最后将视频文件存储到OSS对象存储,转码为M3U8格式在Web前端实现HLS播放。
前端base64转图片
后端直接返回base64
格式字符串不需要做额外的数据封装,格式转换在客户端进行,按照上一篇笔记的做法,后端将某个路径下的图片取回并转换成base64
编码的图像字符串返回给web前端,前端接收后将该转换成图像。
...
this.base64Data= res.data.pic;
this.imageSrc='data:image/png;base64,'+this.base64Data;
this.convertBase64ToImage();
...
convertBase64ToImage(){
const img =newImage();// 创建一个Image对象
img.src=this.imageSrc;
img.onload=() =>{
const canvas =document.createElement('canvas');// 创建一个canvas对象
const context = canvas.getContext('2d');
canvas.width= img.width;// 设置canvas长宽与图像保持一致
canvas.height= img.height;
context.drawImage(img,0,0);
const imageURL = canvas.toDataURL('image/png');// 调用canvas的toDataURL方法
this.imageSrc= imageURL;// 更新 imageSrc
};
},
分片传输与断点续传
分片传输有不少好处,上传时将大文件分割成多个小分片进行上传,能提高文件的上传速度、减少内存消耗。而断点续传可以在传输中断后继续传输,提高数据传输的稳定性和可靠性,避免重复传输整个大文件、节省了时间和带宽。简易实现的思路是前端将大文件分割成同等大小的分片(最后一片除外),调用后端接口将分片上传,上传完成后再告诉后端将分片合成文件。至于最简单的断点续传实现,本次没有在后端做校验,只在前端实现记录上传分片索引实现的断点续传功能。
前端思路与实现
那我们可以将分片传输分成两步,将文件分片再上传。
文件通过input
组件上传后,通过handleFileChange
函数处理,获取用户选择的第一个文件(event.target.files[0]),event是触发事件的对象,target指的是事件的目标元素。当点击开始上传时调用uploadFile
方法,判断文件是否为空或是否已暂停上传。然后根据chunkSize切割分片,分出来之后调用reader.readAsArrayBuffer
方法,readAsArrayBuffer
会异步执行,将读取文件数据到内存中,完成后会触发onloadend
事件上传单个分片,直到所有分片传输完成。
// 放几个按钮
<div class="user-upload-file">
<input type="file"ref="fileInput"@change="handleFileChange"/>
<button @click="uploadFile">开始上传</button>
<button @click="pauseUpload">暂停上传</button>
<button @click="resumeUpload">继续上传</button>
<button @click="cancelUpload">取消上传</button>
</div>
...
<script>
exportdefault{
...
data(){
return{
file:null,// 存储选择的文件
chunkSize:5*1024*1024,// 每片 分片大小设置为5M
totalChunks:0,// 所有分片总数
currentChunk:0,// 初始化分片索引
isPaused:false,// 是否暂停上传
}
},
...
methods:{
handleFileChange(event){
this.file =event.target.files[0];
this.totalChunks =Math.ceil(this.file.size /this.chunkSize);// 计算总分片数
this.currentChunk =0;// 当前分片索引是0
this.isPaused =false;// 没有在暂停传输
},
async uploadFile(){
if(!this.file){
alert("没有文件上传");
return;
}
while(this.currentChunk <this.totalChunks){
if(this.isPaused){
console.log("上传已暂停")
return;
}
const start =this.currentChunk *