H5-Video视频播放

  1. <video width="320" height="240" controls>
  2. <source src="movie.mp4" type="video/mp4">
  3. <source src="movie.ogg" type="video/ogg">
  4. </video>

详细参数使用说明:

  1. <video
  2. controls
  3. autoplay
  4. loop
  5. preload="auto"
  6. poster="img/popup-img.png"
  7. webkit-playsinline="true"
  8. playsinline="true"
  9. x5-video-player-type="h5"
  10. x5-video-player-fullscreen="true"
  11. x-webkit-airplay="allow"
  12. x5-video-orientation="portraint"
  13. style="object-fit:fill">
  14. <source src="video.mp4" type="video/mp4">
  15. <source src="video.ogg" type="video/ogg; codecs=dirac, speex">
  16. <p>你的浏览器不支持 <code>video</code> 标签.</p>
  17. </video>

如何防止视频连接被获取

正常模式下,在中直接使用了视频的地址,比如:movie.mp4。这样通过查看源代码或者F12能很快的定位到视频的全路径地址,那么如何控制视频地址不对外展示呢?
前端编写似乎还,不要暴露mp4等视频地址,编写方式如下:

视频地址换成后台请求地址,请求后台根据传入的id查询出对应的视频信息,将视频信息通过response流的模式写出,代码如下:

  1. @RequestMapping("/getVideo/{id}")
  2. public void getVideo(HttpServletRequest request,HttpServletResponse response,@PathVariable String id){
  3. //视频资源存储信息
  4. PageData pd = new PageData();
  5. pd.put("id",id);
  6. PageData filePd = sourceService.findVideoInfo(pd);
  7. response.reset();
  8. //获取从那个字节开始读取文件
  9. String rangeString = request.getHeader("Range");
  10. try {
  11. //获取响应的输出流
  12. OutputStream outputStream = response.getOutputStream();
  13. File file = new File(ParaUtil.localName+filePd.get("file_path").toString());
  14. if(file.exists()){
  15. RandomAccessFile targetFile = new RandomAccessFile(file, "r");
  16. long fileLength = targetFile.length();
  17. //播放
  18. if(rangeString != null){
  19. long range = Long.valueOf(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-")));
  20. //设置内容类型
  21. response.setHeader("Content-Type", "video/mp4");
  22. //设置此次相应返回的数据长度
  23. response.setHeader("Content-Length", String.valueOf(fileLength - range));
  24. //设置此次相应返回的数据范围
  25. response.setHeader("Content-Range", "bytes "+range+"-"+(fileLength-1)+"/"+fileLength);
  26. //返回码需要为206,而不是200
  27. response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
  28. //设定文件读取开始位置(以字节为单位)
  29. targetFile.seek(range);
  30. }else {//下载
  31. //设置响应头,把文件名字设置好
  32. response.setHeader("Content-Disposition", "attachment; filename="+filePd.get("name"));
  33. //设置文件长度
  34. response.setHeader("Content-Length", String.valueOf(fileLength));
  35. //解决编码问题
  36. response.setHeader("Content-Type","application/octet-stream");
  37. }
  38. byte[] cache = new byte[1024 * 300];
  39. int flag;
  40. while ((flag = targetFile.read(cache))!=-1){
  41. outputStream.write(cache, 0, flag);
  42. }
  43. }else {
  44. String message = "file:"+filePd.get("name")+" not exists";
  45. //解决编码问题
  46. response.setHeader("Content-Type","application/json");
  47. outputStream.write(message.getBytes(StandardCharsets.UTF_8));
  48. }
  49. outputStream.flush();
  50. outputStream.close();
  51. } catch (FileNotFoundException e) {
  52. } catch (IOException e) {
  53. }
  54. }

视频意外流失,如何控制视频不被传播

在我们实际运营过程中,可能会存在视频被流失的风险,一旦视频流失可能会对企业造成很大的影响,那么如何避免视频被流出呢?
通过java对视频流进行加解密处理,及时视频外流,也无法对视频进行播放。

  1. package com.qingfeng.util;
  2. import java.io.*;
  3. public class VideoEncodeUtil {
  4. public static void main(String[] args) throws Exception {
  5. encrypt("D:\\py交易\\11.mp4", "fuckyourself");
  6. decrypt("D:\\py交易\\11.mp4", "D:\\py交易\\22.mp4", 4);
  7. System.out.println(readFileLastByte("D:\\py交易\\11.mp4", 12));
  8. }
  9. /**
  10. * @title 文件file进行加密
  11. * @description 文件file进行加密
  12. * @author Administrator
  13. * @updateTime 2021/6/29 17:36
  14. */
  15. public static void encrypt(String fileUrl, String key)
  16. throws Exception {
  17. File file = new File(fileUrl);
  18. String path = file.getPath();
  19. if (!file.exists()) {
  20. return;
  21. }
  22. int index = path.lastIndexOf("\\");
  23. String destFile = path.substring(0, index) + "\\" + "abc";
  24. File dest = new File(destFile); //获取待加密文件的输入流
  25. InputStream in = new FileInputStream(fileUrl); //创建中转文件输出流
  26. OutputStream out = new FileOutputStream(destFile); //待加密文件的流
  27. byte[] buffer = new byte[1024];
  28. int r; //加密之后的文件的流
  29. byte[] buffer2 = new byte[1024];
  30. while ((r = in.read(buffer)) > 0) {
  31. for (int i = 0; i < r; i++) {
  32. byte b = buffer[i]; //buffer2[i]=b==255?0:++b;//每个字节加2加密
  33. b += 2;
  34. buffer2[i] = b;
  35. }
  36. out.write(buffer2, 0, r);
  37. out.flush();
  38. }
  39. in.close();
  40. out.close();
  41. file.delete();
  42. dest.renameTo(new File(fileUrl));
  43. appendMethodA(fileUrl, key);
  44. System.out.println("加密成功");
  45. }
  46. /**
  47. * @title appendMethodA
  48. * @description appendMethodA
  49. * @author Administrator
  50. * @updateTime 2021/6/29 17:42
  51. */
  52. public static void appendMethodA(String fileName, String content) {
  53. try { //打开一个随机访问文件流,按读写方式
  54. RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw"); //文件长度,字节数
  55. long fileLength = randomFile.length(); //将写文件指针移到文件尾。
  56. randomFile.seek(fileLength);
  57. randomFile.writeBytes(content);
  58. randomFile.close();
  59. } catch (IOException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. /**
  64. * @title 解密
  65. * @description 解密
  66. * @author Administrator
  67. * @updateTime 2021/6/29 17:40
  68. */
  69. public static String decrypt(String fileUrl, String tempUrl, int keyLength)
  70. throws Exception {
  71. File file = new File(fileUrl);
  72. if (!file.exists()) {
  73. return null;
  74. }
  75. File dest = new File(tempUrl);
  76. if (!dest.getParentFile().exists()) {
  77. dest.getParentFile().mkdirs();
  78. }
  79. //获取待解密的文件输入流
  80. InputStream is = new FileInputStream(fileUrl); //创建目标文件输出流,用来生成解密后的文件
  81. OutputStream out = new FileOutputStream(tempUrl);
  82. byte[] buffer = new byte[1024];
  83. byte[] buffer2 = new byte[1024];
  84. byte bMax = (byte) 255;
  85. long size = file.length() - keyLength;
  86. int mod = (int) (size % 1024);
  87. int div = (int) (size >> 10);
  88. int count = (mod == 0) ? div : (div + 1);
  89. int k = 1;
  90. int r;
  91. while (((k <= count) && ((r = is.read(buffer)) > 0))) {
  92. if ((mod != 0) && (k == count)) {
  93. r = mod;
  94. }
  95. for (int i = 0; i < r; i++) {
  96. byte b = buffer[i]; //buffer2[i]=b==0?bMax:--b;//每个字节减2解码
  97. b -= 2;
  98. buffer2[i] = b;
  99. }
  100. out.write(buffer2, 0, r);
  101. k++;
  102. }
  103. out.close();
  104. is.close();
  105. return tempUrl;
  106. }
  107. /*** 判断文件是否加密
  108. *@paramfileName
  109. *@return*
  110. * 加密成功返回key
  111. * 加密失败返回非key的字符串*/
  112. public static String readFileLastByte(String fileName, int keyLength) {
  113. File file = new File(fileName);
  114. if (!file.exists()) {
  115. return "没有文件";
  116. }
  117. StringBuffer str = new StringBuffer();
  118. try { //打开一个随机访问文件流,按读写方式
  119. RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw"); //文件长度,字节数
  120. long fileLength = randomFile.length(); //将写文件指针移到文件尾。
  121. for (int i = keyLength; i >= 1; i--) {
  122. randomFile.seek(fileLength - i);
  123. str.append((char) randomFile.read());
  124. }
  125. randomFile.close();
  126. return str.toString();
  127. } catch (IOException e) {
  128. e.printStackTrace();
  129. }
  130. return "异常";
  131. }
  132. }