视频下载功能(SpringBoot+Vue)

5 阅读3分钟

最近刚工作,有一个视频下载的需求,在查询一些文章后,解决了这个问题。所以,在这里简单记录一下。参考文章在最后。

后端:

Controller层

@RestController
@RequestMapping("/download")
public class Download{
    @GetMapping("/downloadVideo")
     public void downloadVideo(@RequestParam String fileName,@RequestParam String url,HttpServletResponse response) throws IOException {
    
        //验证参数合法性
        if(StrUtil.isEmpty(url)){
           System.out.println("路径错误");
           return;
        }
    
        File file = new File(url);
        //验证文件是否存在
        if (!file.exists() || file.isDirectory()) {
           System.out.println("文件不存在");
           return;
        }
        
        //创建一个文件输入流,用于读取文件内容
        FileInputStream fis = new FileInputStream(file);
        
        //设置响应头,指示浏览器以附件形式下载文件,并设置下载文件名为‘fileName’
        response.setHeader("content-disposition","attachment;filename="+fileName);
        
        //获取响应的输出流,用于将文件内容写入响应体。
        ServletOutputStream sos = response.getOutputStream();
        
        //创建一个8KB的缓冲区,用于读取文件内容。
        byte[] buffer = new byte[1024*8];
        int len = 0;
        //循环读取文件内容到缓冲区,直到文件读取完。
        while((len = fis.read(buffer)) != -1){
           sos.write(buffer,0,len);
        }
        //关闭文件输入流,释放资源。
        fis.close();
    }
    
  }

前端

页面中下载按钮绑定的方法

//record是使用了ant-design-vue中的table组件,获取了那一行的数据
  downloadVideo(record){
      //这里的url之后可以换成视频所在服务器地址
      downloadFile('/download/downloadVideo',record.fileName,{url:"E:\\A_JNTP_MieHuoJi\\视频素材\\地铁.mp4",fileName:record.fileName})
  },

文件下载方法

/**
 * 下载文件
 * @param url 文件路径
 * @param fileName 文件名
 * @param parameter
 * @returns {*}
 */
export function downloadFile(url, fileName, parameter) {
  return downFile(url, parameter).then((data) => {
      
     //如果没有内容返回,下载失败
    if (!data || data.size === 0) {
      Vue.prototype['$message'].warning('文件下载失败')
      return
    }
    
    
    if (typeof window.navigator.msSaveBlob !== 'undefined') {
        //兼容IE浏览器
      window.navigator.msSaveBlob(new Blob([data]), fileName)
    } else {
       //Blob构造函数将数据包装成Blob对象,createObjectURL方法生成一个临时URL来引用这个Blob对象。
      let url = window.URL.createObjectURL(new Blob([data]))
      //创建一个隐藏的<a>元素,用于触发下载。
      let link = document.createElement('a')
      //将链接元素设置为隐藏。
      link.style.display = 'none'
      //设置链接的href属性为之前生成的Blob URL。
      link.href = url
      //设置链接的download属性,以便指定下载文件的名称。
      link.setAttribute('download', fileName)
      //将链接元素添加到DOM中。
      document.body.appendChild(link)
      //模拟点击链接,触发下载。
      link.click()
      document.body.removeChild(link) //下载完成移除元素
      window.URL.revokeObjectURL(url) //释放掉blob对象
    }
  })
}

axios请求 这里是用了我自己封装好的axios。

/**
 * 下载文件
 * @param url
 * @param parameter
 * @returns {*}
 */
export function downFile(url,parameter){
  return axios({
    url: url,
    params: parameter,
    method:'get' ,
    responseType: 'blob'  //这个很重要
  })
}

responseType:'blob'的使用场景和作用
1.文件下载
当你希望从服务器下载一个文件(例如图片、视频、文档等)并在客户端处理时,设置responseType: 'blob'是必要的。这样客户端会将响应数据解析为Blob对象,而不是默认的字符串或JSON。
2.处理二进制数据
对于需要处理二进制数据的场景,例如显示图片、播放视频,或者上传下载文件等,Blob类型的数据非常合适,因为它能够表示不可变的、原始数据的类文件对象。

参考文章:cloud.tencent.com/developer/a…
本文部分内容源自chatGPT,只做参考学习,愿各位大佬指点。