javaweb文件上传下载 视频转GIF

效果图如下,h5资源请查看 发布网站





用到的工具为FFmpeg,简单的运用即可实现视频转GIF,简单强大。

准备FFmpeg调用方法

 /**
   * 视频转码
   *
   * @param ffmpegPath   转码工具的存放路径
   * @param upFilePath   用于指定要转换格式的文件,要截图的视频源文件
   * @param codcFilePath 格式转换后的的文件保存路径
   * @param mediaPicPath 截图保存路径
   * @return
   * @throws Exception
   */
  public static boolean executeCodecs(String ffmpegPath, String upFilePath, String codcFilePath,
                                      String mediaPicPath) throws Exception {
    // 创建一个List集合来保存转换视频文件为flv格式的命令
    List<String> convert = new ArrayList<String>();
    convert.add(ffmpegPath); // 添加转换工具路径
    convert.add("-i"); // 添加参数"-i",该参数指定要转换的文件
    convert.add(upFilePath); // 添加要转换格式的视频文件的路径
    convert.add("-qscale");     //指定转换的质量
    convert.add("6");
    convert.add("-ab");  //设置音频码率
    convert.add("64");
    convert.add("-ac");  //设置声道数
    convert.add("2");
    convert.add("-ar");  //设置声音的采样频率
    convert.add("22050");
    convert.add("-r");  //设置帧频
    convert.add("24");
    convert.add("-y"); // 添加参数"-y",该参数指定将覆盖已存在的文件
    convert.add(codcFilePath);

    boolean mark = true;
    ProcessBuilder builder = new ProcessBuilder();
    try {
      builder.command(convert);
      builder.redirectErrorStream(true);
      Process videoProcess = builder.start();
      new PrintStream(videoProcess.getInputStream()).start();
      videoProcess.waitFor();

      return true;
//      builder.command(cutpic);
//      builder.redirectErrorStream(true);
      // 如果此属性为 true,则任何由通过此对象的 start() 方法启动的后续子进程生成的错误输出都将与标准输出合并,
      //因此两者均可使用 Process.getInputStream() 方法读取。这使得关联错误消息和相应的输出变得更容易
//      builder.start();
    } catch (Exception e) {
      mark = false;
      System.out.println(e);
      e.printStackTrace();
    }
    return mark;
  }

测试过程中,当调用此方法时,mark结果是瞬间返回的,也就是说转换过程是异步的,当参数返回时,有可能还并没有生成GIF图片,所以就需要监听转换进度。方法如下,测试通过。

Process videoProcess = builder.start();
      new PrintStream(videoProcess.getInputStream()).start();
      videoProcess.waitFor();

我创建的是java web项目,文件上传和转换如下

package main.controller;


import main.ConverVideo;
import main.entity.Media;
import main.util.FileUtil;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.*;
import java.io.*;
import java.util.Arrays;
import java.util.List;

/**
 * Created by Administrator on 2017-06-19.
 */
@WebServlet("/controller/MediaService")
public class MediaService extends HttpServlet {


  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doPost(request, response);
  }


  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    //得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
    String savePath = this.getServletContext().getRealPath("/videos/upload");
    File file = new File(savePath);
    //判断上传文件的保存目录是否存在
    if (!file.exists() && !file.isDirectory()) {
      System.out.println(savePath+"目录不存在,需要创建");
      //创建目录
      file.mkdir();
    }
    String filename="";
    //消息提示
    String message = "";
    try{
      //使用Apache文件上传组件处理文件上传步骤:
      //1、创建一个DiskFileItemFactory工厂
      DiskFileItemFactory factory = new DiskFileItemFactory();
      //2、创建一个文件上传解析器
      ServletFileUpload upload = new ServletFileUpload(factory);
      //解决上传文件名的中文乱码
      upload.setHeaderEncoding("UTF-8");
      //3、判断提交上来的数据是否是上传表单的数据
      if(!ServletFileUpload.isMultipartContent(request)){
        //按照传统方式获取数据
        return;
      }
      //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
      List<FileItem> list = upload.parseRequest(request);
      for(FileItem item : list){
        //如果fileitem中封装的是普通输入项的数据
        if(item.isFormField()){
          String name = item.getFieldName();
          //解决普通输入项的数据的中文乱码问题
          String value = item.getString("UTF-8");
          //value = new String(value.getBytes("iso8859-1"),"UTF-8");
          System.out.println(name + "=" + value);
        }else{//如果fileitem中封装的是上传文件
          //得到上传的文件名称,
          filename = item.getName();

          //允许上传的文件类型asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv
          String fileType = "mp4,wmv,rmvb,mov,avi,flv,mpg,asx,asf";
          //允许上传的文件最大大小(100M,单位为byte)
          int maxSize = 1024*1024*100;
          //判断文件大小是否超限
          if (item.getSize() > maxSize)
          {
            item.delete();
            JOptionPane.showMessageDialog(null, "文件大小超过限制!应小于" + maxSize
                / 1024 / 1024 + "M");
            return;
          }
          //获取文件后缀名
          String extName = filename.substring(filename.indexOf(".") + 1).toLowerCase().trim();

          //判断是否为允许上传的文件类型
          if ( !Arrays.<String> asList(fileType.split(",")).contains(extName))
          {
            item.delete();
            JOptionPane.showMessageDialog(null, "文件类型不正确,必须为" + fileType
                + "的文件!");
            return ;
          }

          System.out.println(filename);
          if(filename==null || filename.trim().equals("")){
            continue;
          }
          //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
          //处理获取到的上传文件的文件名的路径部分,只保留文件名部分
          filename = filename.substring(filename.lastIndexOf("\\")+1);
          //获取item中的上传文件的输入流
          InputStream in = item.getInputStream();
          //创建一个文件输出流
          FileOutputStream out = new FileOutputStream(savePath + System.getProperty("file.separator") + filename);
          //创建一个缓冲区
          byte buffer[] = new byte[1024];
          //判断输入流中的数据是否已经读完的标识
          int len = 0;
          //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
          while((len=in.read(buffer))>0){
            //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
            out.write(buffer, 0, len);
          }
          //关闭输入流
          in.close();
          //关闭输出流
          out.close();
          //删除处理文件上传时生成的临时文件
          item.delete();
          message = "文件上传成功!";
        }
      }
    }catch (Exception e) {
      message= "文件上传失败!";
      e.printStackTrace();

    }
    boolean flag = false;    //转码成功与否的标记
    // 获取配置的转换工具(ffmpeg.exe)的存放路径
    String ffmpegPath = getServletContext().getRealPath("/tools/ffmpeg.exe");
    String uploadFile = getServletContext().getRealPath("/videos/upload/"+filename);
    String codcFilePath = getServletContext().getRealPath("/videos/temp/"+filename.substring(0,filename.lastIndexOf("."))+".gif");
    String mediaPicPath = getServletContext().getRealPath("/videos/images/"+filename.substring(0,filename.lastIndexOf("."))+".jpg");
    //转码
    System.out.println(ffmpegPath+"\n-----------------------------------");
    try {
      flag = ConverVideo.executeCodecs(ffmpegPath, uploadFile, codcFilePath, mediaPicPath);
    } catch (Exception e) {
      System.out.println(e.getMessage());
      e.printStackTrace();
    }

    if(flag){
      //转码成功,向数据表中添加该视频信息
      message = "<li>上传成功!</li>";
    }else{
      message = "上传失败";
    }
    System.out.print(message);
    FileUtil.clearFile("/tools/server/videos");
    request.setAttribute("gifpath","/videos/temp/"+filename.substring(0,filename.lastIndexOf("."))+".gif");
    request.setAttribute("message",message);
    request.setAttribute("filename",filename.substring(0,filename.lastIndexOf("."))+".gif");
    request.setAttribute("downurl","/controller/DownLoadServlet");
    request.getRequestDispatcher("/showgif.jsp").forward(request, response);
//    if("/play".equals(path)){
//      String idstr = request.getParameter("id");
//      int mediaId = -1;
//      Media media = null;
//      if(null!=idstr){
//        mediaId = Integer.parseInt(idstr);
//      }
//      request.setAttribute("media", media);
//      request.getRequestDispatcher("media_player.jsp").forward(request, response);
//    }
  }
}

转换成功后,界面展示,下载

package main.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/controller/DownLoadServlet")
public class DownLoadServlet extends HttpServlet {


  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    //得到要下载的文件名
    String fileName = request.getParameter("filename");  //
    fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
    //上传的文件都是保存在/WEB-INF/upload目录下的子目录当中
    String fileSaveRootPath=this.getServletContext().getRealPath("/videos/temp");
//    //通过文件名找出文件的所在目录
//    String path = findFileSavePathByFileName(fileName,fileSaveRootPath);
    //得到要下载的文件
    File file = new File(fileSaveRootPath + System.getProperty("file.separator") + fileName);
    //如果文件不存在
    if(!file.exists()){
      request.setAttribute("message", "您要下载的资源已被删除!!");
      request.getRequestDispatcher("/index.jsp").forward(request, response);
      return;
    }
    //处理文件名
    String realname = fileName.substring(fileName.indexOf("_")+1);
    //设置响应头,控制浏览器下载该文件
    response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
    //读取要下载的文件,保存到文件输入流
    FileInputStream in = new FileInputStream(file.getPath());
    //创建输出流
    OutputStream out = response.getOutputStream();
    //创建缓冲区
    byte buffer[] = new byte[1024];
    int len = 0;
    //循环将输入流中的内容读取到缓冲区当中
    while((len=in.read(buffer))>0){
      //输出缓冲区的内容到浏览器,实现文件下载
      out.write(buffer, 0, len);
    }
    //关闭文件输入流
    in.close();
    //关闭输出流
    out.close();
  }

  /**
   * @Method: findFileSavePathByFileName
   * @Description: 通过文件名和存储上传文件根目录找出要下载的文件的所在路径
   * @Anthor:孤傲苍狼
   * @param filename 要下载的文件名
   * @param saveRootPath 上传文件保存的根目录,也就是/WEB-INF/upload目录
   * @return 要下载的文件的存储目录
   */
  public String findFileSavePathByFileName(String filename,String saveRootPath){
    int hashcode = filename.hashCode();
    int dir1 = hashcode&0xf;  //0--15
    int dir2 = (hashcode&0xf0)>>4;  //0-15
    String dir = saveRootPath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
    File file = new File(dir);
    if(!file.exists()){
      //创建目录
      file.mkdirs();
    }
    return dir;
  }

  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风晴03

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值