加密目标文件

代码如下:

不建议进行二次加密,若二次加密必须要二次解密

package com.xgt.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));
}
/**
* 文件file进行加密
* @param fileUrl 文件路径
* @param key 密码
* @throws Exception
*/
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("加密成功");
}
/**
*
* @param fileName
* @param content 密钥
*/
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();
}
}
/**
* 解密
* @param fileUrl 源文件
* @param tempUrl 临时文件
* @param keyLength 密码长度
* @return
* @throws Exception
*/
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, 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;
}
/**
* 判断文件是否加密
* @param fileName
* @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 "异常";
}
}

加密和解密接口

    /**
* 加密视频
* @param fileName
*/
public void encryptVideo(String fileName){
try {
File file = new File(fileUrl);
FileToolUtil.judeDirExists(file);
/**
* 加密不可进行多次
* 判断是否有加密,加密过无需在加密
*/
if(!VideoEncodeUtil.readFileLastByte(fileUrl+"\\"+fileName,key.length()).equals(key)) {
VideoEncodeUtil.encrypt(fileUrl + "\\" + fileName, key);
}
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 解密视频
* @param fileName
*/
public String decryptVideo(String fileName) throws Exception { File file = new File(SystemConstant.VIDEO_TEMP_PATH);
FileToolUtil.judeDirExists(file);
return VideoEncodeUtil.decrypt(SAFETY_EDU_LOCAL_PATH + fileName,
SystemConstant.VIDEO_TEMP_PATH + fileName,
SystemConstant.VIDEO_ENCRYPT_DECRYPT_KEY.length());
}

播放加密视频方法(播放解密后的流):

    /**
* 播放加密MP4
* @param response
* @throws IOException
*/
@RequestMapping("/playMp4")
@ResponseBody
public void playMp4(HttpServletResponse response,String fileName) throws Exception { // TODO 测试联调结束后需删除
fileName = "edu/video/6689AC1A506133C13FDA593135E2D923.mp4";
String tempFilePath = SystemConstant.VIDEO_TEMP_PATH + fileName;
try { tempFilePath = videoMaterialService.decryptVideo(fileName);
// 解密过后的临时文件路径 FileInputStream inputStream = new FileInputStream(tempFilePath);
byte[] data = FileToolUtil.inputStreamToByte(inputStream);
String diskfilename = "final.mp4";
response.setContentType("video/mp4");
response.setHeader("Content-Disposition", "attachment; filename=\"" + diskfilename + "\"" );
System.out.println("data.length " + data.length);
response.setContentLength(data.length);
response.setHeader("Content-Range", "" + Integer.valueOf(data.length-1));
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Etag", "W/\"9767057-1323779115364\"");
OutputStream os = response.getOutputStream(); os.write(data);
//先声明的流后关掉!
os.flush();
os.close();
inputStream.close(); }catch (Exception e){
logger.error("....", e);
}finally {
VideoMaterialService.deleteVideoFile(tempFilePath);
} }

前端代码展示

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title> </head> <body> <video src="http://127.0.0.1:8004/rest/video/playMp4?fileName=11.mp4" controls="controls">
your browser does not support the video tag
</video> </body> </html>

Java通过流对MP4视频文件进行加密,H5 video播放流的更多相关文章

  1. atitit.mp4 视频文件多媒体格式结构详解

    atitit.mp4 视频文件多媒体格式结构详解 1. 一.基本概念1 2. MP4文件概述2 3. mp4是由一个个“box”组成的,2 4. 典型简化mp43 5. Fragments5 6. r ...

  2. H5网页播放器播不了服务器上的mp4视频文件

    打开IIS,在功能视图里找到MIME类型菜单,打开该菜单后鼠标右键添加.mp4扩展名的MIME类型video/mp4 其他视频文件播放不了估计也得在IIS里添加对应的MIME类型(从服务器下载文件时也 ...

  3. android获取mp4视频文件总时长和视频宽高<转>

    android使用 MediaMetadataRetriever 获取视频文件的 总时长 和视频的分辨率. 根据该方式获取视频信息可以看出不仅仅可以获取时长和分辨率,还能获取到其他的一些视频信息,不错 ...

  4. opencv::将两幅图像合并后,在同一个窗口显示;并将合并的图像流保存成视频文件

    /** * @file main-opencv.cpp * @date July 2014 * @brief An exemplative main file for the use of ViBe ...

  5. JAVA通过URL链接获取视频文件信息(无需下载文件)

    最近项目碰到一个大坑:APP上需要在获取视频列表时就获取视频的时长,但早期上传的时候数据库都没有保存这个数据,所以前段时间添加一个时长字段,在上传时手动输入视频时长,但是之前库中有上万条数据没这个信息 ...

  6. Java字符流和字节流对文件操作

    记得当初自己刚开始学习Java的时候,对Java的IO流这一块特别不明白,所以写了这篇随笔希望能对刚开始学习Java的人有所帮助,也方便以后自己查询.Java的IO流分为字符流(Reader,Writ ...

  7. java以流的形式输出文件

    原文:http://blog.csdn.net/liutt55/article/details/78126614 public void downProcessFile(HttpServletRequ ...

  8. 是用VLC API将RTSP流convert为视频文件

    一直在文档中找不到,接口设计的也不大好.不过终于在stackoverflow上找到解决方案了. 原来在LIbVLC库实例化的时候就需要传递相关的参数.我的代码大致是这样实现: const char * ...

  9. 关于m3u8格式的视频文件ts转mp4下载和key加密问题

    一,利用网站浏览器F12键,利用谷歌浏览器插件找到视频的.m3u8文件,并打开. 二,打开m3u8文件后,里面有很多.ts的链接,和key的链接. 三,保存为html文件,下载ts文件,代码如下:可加 ...

随机推荐

  1. CSS:如何清除a标签之间的默认留白间距

    即使我们使用了类似 *{margin: 0;padding: 0;} 这样的代码重置了浏览器默认样式,也会发现类似<a>标签这种inline-block元素,它们之间也还存在着间距. de ...

  2. [HNOI2010] 合唱队

    题目链接:https://www.luogu.org/problemnew/show/P3205 一个区间DP的题目. 设计状态为:\(dp1[i][j]\)表示当前区间为\([i,j]\),而且最后 ...

  3. 如何使用安卓4.4的SD卡?

    安卓4.4默认情况下,后安装的程序无权写入数据到SD卡中,那么是否我们就不能用了?看了很多文章,都说要Root,随后修改配置文件.我觉得这不是很好的方法,Root之后的安卓会有很大风险,这不是最好的办 ...

  4. React Native 搭建开发环境

    1.先安装node.js,https://nodejs.org/en/download/ 然后,双击下载好的.msi文件安装即可,安装完成后,打开终端,输出npm -v 即可查看我们刚才安装的node ...

  5. zTree第五章,zTree的nodes数据例子

    var nodes1 = [ { name: "小学", iconOpen: folderOpen, iconClose: folder, chkDisabled :true, c ...

  6. 为什么 SQLite 用 C 编写?

    简评:SQLite 官方出品. C是最好的选择 从 2000 年 5 月 29 日开始,SQLite 就选择了 C 语言.直到今天,C 也是实现 SQLite 这样软件库的最佳语言. C语言是实现 S ...

  7. scrapy连接MySQL

    Scrapy中连接MySQL所需要做的工作如下: 1.settings中需要设置的部分 # 启动管道组件 ITEM_PIPELINES = { 'QianChengWuYu.mongoDBPiplel ...

  8. java架构师之路,享学课堂VIP课程视频下载

    享学课堂并发编程:百度网盘 链接:https://pan.baidu.com/s/10O8oXC0yNRArUh3WKkXayg 提取码:o01s 更多视频获取方式请留言

  9. 接口自动化 之 unittest+ddt+openpyxl 综合

    前面写过python 之 unittest初探 和 python 之 unittest+ddt 两篇文章.在之前的文章中,写过可以再次优化.今天写第三篇的目的,就是在原有基础上,基于 openpyxl ...

  10. Laravel 视图调用model方法

    首先控制器 model 视图