需求:上传视频后,点击链接可以在PC和手机端播放预览,包括苹果手机
1.相关工具类
1.1文件上传工具类
package resources.util;import common.util.FileOperateUtil;
import common.util.HttpClientUtil;
import net.sf.json.JSONObject;
import org.apache.commons.httpclient.util.DateUtil;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
public class FileUploadTool {TransfMediaTool transfMediaTool = new TransfMediaTool();private static long upload_maxsize = 800 * 1024 * 1024;private static String[] allowFiles = {".rar", ".doc", ".docx", ".zip",".pdf", ".txt", ".swf", ".xlsx", ".gif", ".png", ".jpg", ".jpeg",".bmp", ".xls", ".mp4", ".flv", ".ppt", ".avi", ".mpg", ".wmv",".3gp", ".mov", ".asf", ".asx", ".vob", ".wmv9", ".rm", ".rmvb"};private static String[] allowFLV = {".avi", ".mpg", ".wmv", ".3gp",".mov", ".asf", ".asx", ".vob"};private static String[] allowAVI = {".wmv9", ".rm", ".rmvb"};public JSONObject createFile(MultipartFile multipartFile, HttpServletRequest request, String staticRes, String from, String userId, String orgCode) {boolean bflag = false;String fileName = multipartFile.getOriginalFilename().toString();fileName = FileOperateUtil.produceFileName(fileName);if (multipartFile.getSize() != 0 && !multipartFile.isEmpty()) {bflag = true;if (multipartFile.getSize() <= upload_maxsize) {bflag = true;if (this.checkFileType(fileName)) {bflag = true;} else {bflag = false;System.out.println("文件类型不允许");}} else {bflag = false;System.out.println("文件大小超范围");}} else {bflag = false;System.out.println("文件为空");}if (bflag) {String logoPathDir = staticRes + "/video/" + orgCode + "/" + from + "/" + userId + "/" + DateUtil.formatDate(new Date(), "yyyy-MM-dd" );File logoSaveFile = new File(logoPathDir);if (!logoSaveFile.exists()) {logoSaveFile.mkdirs();}String name = fileName.substring(0, fileName.lastIndexOf("."));System.out.println("文件名称:" + name);String newFileName = this.getName(fileName);String fileEnd = this.getFileExt(fileName);String fileNamedirs = logoPathDir + File.separator + newFileName + fileEnd;System.out.println("保存的路径:" + fileNamedirs);File filedirs = new File(fileNamedirs);try {FileOperateUtil.inputCopy(multipartFile.getInputStream(), filedirs);} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}String fileDir = logoPathDir + newFileName + fileEnd;StringBuilder builder = new StringBuilder(fileDir);String finalFileDir = builder.substring(1);String size = this.getSize(filedirs);String aviPath = logoSaveFile.getAbsolutePath();JSONObject result = new JSONObject();result.put("fileName", newFileName+fileEnd);result.put("size", size);result.put("contentType", HttpClientUtil.getMimeType(filedirs.getName()));String localUrl = request.getContextPath() + "/down/video/" + orgCode + "/" + from + "/" + userId + "/" + DateUtil.formatDate(new Date(), "yyyy-MM-dd") + "/" + fileName;result.put("localUrl", localUrl);return result;} else {return null;}} else {return null;}}private boolean checkFileType(String fileName) {Iterator<String> type = Arrays.asList(allowFiles).iterator();while (type.hasNext()) {String ext = type.next();if (fileName.toLowerCase().endsWith(ext)) {return true;}}return false;}private boolean checkMediaType(String fileEnd) {Iterator<String> type = Arrays.asList(allowFLV).iterator();while (type.hasNext()) {String ext = type.next();if (fileEnd.equals(ext)) {return true;}}return false;}private boolean checkAVIType(String fileEnd) {Iterator<String> type = Arrays.asList(allowAVI).iterator();while (type.hasNext()) {String ext = type.next();if (fileEnd.equals(ext)) {return true;}}return false;}private String getFileExt(String fileName) {return fileName.substring(fileName.lastIndexOf("."));}private String getName(String fileName) {Iterator<String> type = Arrays.asList(allowFiles).iterator();while (type.hasNext()) {String ext = type.next();if (fileName.contains(ext)) {String newFileName = fileName.substring(0, fileName.lastIndexOf(ext));return newFileName;}}return "";}private String getSize(File file) {String size = "";long fileLength = file.length();DecimalFormat df = new DecimalFormat("#.00");if (fileLength < 1024) {size = df.format((double) fileLength) + "BT";} else if (fileLength < 1048576) {size = df.format((double) fileLength / 1024) + "KB";} else if (fileLength < 1073741824) {size = df.format((double) fileLength / 1048576) + "MB";} else {size = df.format((double) fileLength / 1073741824) + "GB";}return size;}
}
2.视频上传代码的实现
@PostMapping("/video")public ResultVO uploadVideo(HttpServletRequest request, MultipartFile file, String from, String userId, String orgCode) {String message = "";JSONObject entity = null;FileUploadTool fileUploadTool = new FileUploadTool();ModelMap map = new ModelMap();try {entity = fileUploadTool.createFile(file, request, staticRes, from, userId, orgCode);if (entity != null) {
message = "上传成功";map.put("entity", entity);map.put("result", message);} else {message = "上传失败";map.put("result", message);}} catch (Exception e) {e.printStackTrace();}return new ResultVO(ResultCode.SUCCESS, entity);}
3.视频下载PC播放以及手机播放的实现
@GetMapping("/video/**")public ResultVO downVideo(HttpServletRequest request, HttpServletResponse response) throws IOException {String fileUrl = request.getRequestURI();try {fileUrl = URLDecoder.decode(fileUrl, "UTF-8");} catch (UnsupportedEncodingException e1) {e1.printStackTrace();}fileUrl = fileUrl.substring(fileUrl.indexOf("/video") + 6);String imgPath = staticRes + "/video" + fileUrl;String realPath = imgPath;File tmFile = new File(realPath);if ((!tmFile.exists()) || tmFile.length() < 1) {throw new RuntimeException("文件不存在!");}try {String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);sendVideo(request, response, tmFile, fileName);} catch (IOException e) {e.printStackTrace();}return new ResultVO(ResultCode.SUCCESS, "下载成功");}private void sendVideo(HttpServletRequest request, HttpServletResponse response, File file, String fileName) throws FileNotFoundException, IOException {RandomAccessFile randomFile = new RandomAccessFile(file, "r");long contentLength = randomFile.length();String range = request.getHeader("Range");int start = 0, end = 0;if (range != null && range.startsWith("bytes=")) {String[] values = range.split("=")[1].split("-");start = Integer.parseInt(values[0]);if (values.length > 1) {end = Integer.parseInt(values[1]);}}int requestSize = 0;if (end != 0 && end > start) {requestSize = end - start + 1;} else {requestSize = Integer.MAX_VALUE;}byte[] buffer = new byte[4096];response.setContentType("video/mp4");response.setHeader("Accept-Ranges", "bytes");response.setHeader("ETag", fileName);response.setHeader("Last-Modified", new Date().toString());if (range == null) {response.setHeader("Content-length", contentLength + "");} else {response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);long requestStart = 0, requestEnd = 0;String[] ranges = range.split("=");if (ranges.length > 1) {String[] rangeDatas = ranges[1].split("-");requestStart = Integer.parseInt(rangeDatas[0]);if (rangeDatas.length > 1) {requestEnd = Integer.parseInt(rangeDatas[1]);}}long length = 0;if (requestEnd > 0) {length = requestEnd - requestStart + 1;response.setHeader("Content-length", "" + length);response.setHeader("Content-Range", "bytes " + requestStart + "-" + requestEnd + "/" + contentLength);} else {length = contentLength - requestStart;response.setHeader("Content-length", "" + length);response.setHeader("Content-Range", "bytes " + requestStart + "-" + (contentLength - 1) + "/" + contentLength);}}ServletOutputStream out = response.getOutputStream();int needSize = requestSize;randomFile.seek(start);while (needSize > 0) {int len = randomFile.read(buffer);if (needSize < buffer.length) {out.write(buffer, 0, needSize);} else {out.write(buffer, 0, len);if (len < buffer.length) {break;}}needSize -= buffer.length;}randomFile.close();out.close();}