今日學習
關注博主,每天分享實戰技術和優秀資源推薦(有好資源可以推薦給博主)。
博主一直做開源產品,目前已開源多款后臺架構,開源地址:
H5-Video視頻播放
詳細參數使用說明:
如何防止視頻連接被獲取
正常模式下易語言與access數據庫,在中直接使用了視頻的地址,比如:movie.mp4。這樣通過查看源代碼或者F12能很快的定位到視頻的全路徑地址易語言與access數據庫,那么如何控制視頻地址不對外展示呢?
前端編寫似乎還,不要暴露mp4等視頻地址,編寫方式如下:
視頻地址換成后臺請求地址,請求后臺根據傳入的id查詢出對應的視頻信息,將視頻信息通過流的模式寫出,代碼如下:
@RequestMapping("/getVideo/{id}")
public void getVideo(HttpServletRequest request,HttpServletResponse response,@PathVariable String id){
//視頻資源存儲信息
PageData pd = new PageData();
pd.put("id",id);
PageData filePd = sourceService.findVideoInfo(pd);
response.reset();
//獲取從那個字節開始讀取文件
String rangeString = request.getHeader("Range");
try {
//獲取響應的輸出流

OutputStream outputStream = response.getOutputStream();
File file = new File(ParaUtil.localName+filePd.get("file_path").toString());
if(file.exists()){
RandomAccessFile targetFile = new RandomAccessFile(file, "r");
long fileLength = targetFile.length();
//播放
if(rangeString != null){
long range = Long.valueOf(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-")));
//設置內容類型
response.setHeader("Content-Type", "video/mp4");
//設置此次相應返回的數據長度
response.setHeader("Content-Length", String.valueOf(fileLength - range));
//設置此次相應返回的數據范圍
response.setHeader("Content-Range", "bytes "+range+"-"+(fileLength-1)+"/"+fileLength);
//返回碼需要為206,而不是200
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
//設定文件讀取開始位置(以字節為單位)
targetFile.seek(range);
}else {//下載
//設置響應頭,把文件名字設置好
response.setHeader("Content-Disposition", "attachment; filename="+filePd.get("name"));
//設置文件長度
response.setHeader("Content-Length", String.valueOf(fileLength));
//解決編碼問題
response.setHeader("Content-Type","application/octet-stream");
}
byte[] cache = new byte[1024 * 300];
int flag;
while ((flag = targetFile.read(cache))!=-1){
outputStream.write(cache, 0, flag);
}
}else {
String message = "file:"+filePd.get("name")+" not exists";
//解決編碼問題
response.setHeader("Content-Type","application/json");
outputStream.write(message.getBytes(StandardCharsets.UTF_8));
}
outputStream.flush();
outputStream.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}

}
視頻意外流失,如何控制視頻不被傳播
在我們實際運營過程中,可能會存在視頻被流失的風險,一旦視頻流失可能會對企業造成很大的影響,那么如何避免視頻被流出呢?
通過java對視頻流進行加解密處理,及時視頻外流,也無法對視頻進行播放。
package com.qingfeng.util;
import java.io.*;
public class VideoEncodeUtil {
public static void main(String[] args) throws Exception {
encrypt("D:\\py交易\\11.mp4", "fuckyourself");
decrypt("D:\\py交易\\11.mp4", "D:\\py交易\\22.mp4", 4);
System.out.println(readFileLastByte("D:\\py交易\\11.mp4", 12));
}
/**
* @title 文件file進行加密
* @description 文件file進行加密
* @author Administrator
* @updateTime 2021/6/29 17:36
*/
public static void encrypt(String fileUrl, String key)
throws Exception {
File file = new File(fileUrl);
String path = file.getPath();
if (!file.exists()) {
return;
}
int index = path.lastIndexOf("\\");
String destFile = path.substring(0, index) + "\\" + "abc";
File dest = new File(destFile); //獲取待加密文件的輸入流
InputStream in = new FileInputStream(fileUrl); //創建中轉文件輸出流
OutputStream out = new FileOutputStream(destFile); //待加密文件的流
byte[] buffer = new byte[1024];
int r; //加密之后的文件的流
byte[] buffer2 = new byte[1024];
while ((r = in.read(buffer)) > 0) {

for (int i = 0; i < r; i++) {
byte b = buffer[i]; //buffer2[i]=b==255?0:++b;//每個字節加2加密
b += 2;
buffer2[i] = b;
}
out.write(buffer2, 0, r);
out.flush();
}
in.close();
out.close();
file.delete();
dest.renameTo(new File(fileUrl));
appendMethodA(fileUrl, key);
System.out.println("加密成功");
}
/**
* @title appendMethodA
* @description appendMethodA
* @author Administrator
* @updateTime 2021/6/29 17:42
*/
public static void appendMethodA(String fileName, String content) {
try { //打開一個隨機訪問文件流,按讀寫方式
RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw"); //文件長度,字節數
long fileLength = randomFile.length(); //將寫文件指針移到文件尾。
randomFile.seek(fileLength);
randomFile.writeBytes(content);
randomFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @title 解密
* @description 解密
* @author Administrator
* @updateTime 2021/6/29 17:40

*/
public static String decrypt(String fileUrl, String tempUrl, int keyLength)
throws Exception {
File file = new File(fileUrl);
if (!file.exists()) {
return null;
}
File dest = new File(tempUrl);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
//獲取待解密的文件輸入流
InputStream is = new FileInputStream(fileUrl); //創建目標文件輸出流,用來生成解密后的文件
OutputStream out = new FileOutputStream(tempUrl);
byte[] buffer = new byte[1024];
byte[] buffer2 = new byte[1024];
byte bMax = (byte) 255;
long size = file.length() - keyLength;
int mod = (int) (size % 1024);
int div = (int) (size >> 10);
int count = (mod == 0) ? div : (div + 1);
int k = 1;
int r;
while (((k <= count) && ((r = is.read(buffer)) > 0))) {
if ((mod != 0) && (k == count)) {
r = mod;
}
for (int i = 0; i < r; i++) {
byte b = buffer[i]; //buffer2[i]=b==0?bMax:--b;//每個字節減2解碼
b -= 2;
buffer2[i] = b;
}
out.write(buffer2, 0, r);
k++;
}

out.close();
is.close();
return tempUrl;
}
/*** 判斷文件是否加密
*@paramfileName
*@return*
* 加密成功返回key
* 加密失敗返回非key的字符串*/
public static String readFileLastByte(String fileName, int keyLength) {
File file = new File(fileName);
if (!file.exists()) {
return "沒有文件";
}
StringBuffer str = new StringBuffer();
try { //打開一個隨機訪問文件流,按讀寫方式
RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw"); //文件長度,字節數
long fileLength = randomFile.length(); //將寫文件指針移到文件尾。
for (int i = keyLength; i >= 1; i--) {
randomFile.seek(fileLength - i);
str.append((char) randomFile.read());
}
randomFile.close();
return str.toString();
} catch (IOException e) {
e.printStackTrace();
}
return "異常";
}
}
Tags:實戰視頻教程