zoukankan      html  css  js  c++  java
  • Java通过流对MP4视频文件进行加密,H5 video播放流

    加密目标文件

    代码如下:

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

    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>
  • 相关阅读:
    Vagrant 扩大磁盘根目录
    阿里云 轻量应用服务器 vnc 远程桌面连接
    图片加水印C#源代码
    Asp.net网站Pdf加水印C#源代码
    [FAQ] uni-app 如何让页面不展示返回箭头图标
    [PHP] composer, PHP Fatal error: Allowed memory size of xx bytes exhausted
    [FE] uni-app 导航栏开发指南
    [FE] uni-app 动态改变 navigationBarTitleText 导航标题
    [FE] yarn, npm 切换镜像源
    [FAQ] Phpstorm 代码提示功能失效问题
  • 原文地址:https://www.cnblogs.com/Java-Starter/p/9300292.html
Copyright © 2011-2022 走看看