ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java使用FFmpeg(自定义cmd)系列之MP4 转码 HLS m3u8 AES128 加密

2021-06-28 13:33:40  阅读:492  来源: 互联网

标签:encKeyInfoFilePath enc FFmpeg 自定义 转码 m3u8 keyinfo AES128 key


使用ffmpeg 自定义的cmd命令MP4 转码 HLS m3u8 AES128 加密,废话不多说,代码说话:
不用我们安装FFmpeg,项目自动依赖ffmpeg,已经有开源实现:https://github.com/a-schild/jave2

下面的代码基于:3.1.1 version

maven坐标:

<dependency>
 <groupId>ws.schild</groupId>
 <artifactId>jave-all-deps</artifactId>
 <version>3.1.1</version>
</dependency>

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * 优点:各种浏览器,手机,小程序都能兼容,通用性很好。
   缺点:公开的算法,还原也十分简单,有很多影音嗅探工具能直接下载还原,加密效果很弱,防小白可以。
   
    ①新建一个记事本,取名enc.key(名字可以随便取),添加16个字节的自定义的AES128加密的密匙,如:
		hsjissmart123456
		
	②新建一个文件,enc.keyinfo,添加如下内容(注意:enc.keyinfo里面的enc.key路径绝对路径)
		http://localhost:8080/enc.key
		xxx\enc.key
		
	③这里需要把enc.key和enc.keyinfo放在同一目录下
	
 * @Description:(MP4 转码 HLS m3u8 AES128 加密)   
 * @author: HeShengjin
 * @date:   2021年6月28日 上午11:00:26    
 * @Copyright:
 */
public class FfmpegCmdHls4M3u8EncTest {	
	//加密文件路径,如:enc.key、enc.keyinfo、m3u8文件、ts文件等
	private static String ENC_DIRECTORY = "I:\\test-ffmpeg\\enc";
	
	//执行成功0,失败1
	private static int CODE_SUCCESS = 0;
	private static int CODE_FAIL = 1;
	
	//将荣耀视频测试.MP4 --> HLS m3u8 AES128 加密(//注意绝对路径///)
	//视频路径:I:\\test-ffmpeg\\荣耀视频测试.mp4
	//$encInfoPath、$encPath是需要替换的ENC_DIRECTORY文件路径
	private static String cmd_enc = " -y -i I:\\test-ffmpeg\\荣耀视频测试.mp4 -hls_time 12 -hls_key_info_file $encInfoPath -hls_playlist_type vod -hls_segment_filename $encPath\\encfile_12s_%3d.ts $encPath\\荣耀视频测试_HLS.m3u8 ";


	/**
	 * 第一步:创建enc.keyinfo文件
	 * 第二步:HLS m3u8 AES128 加密
	 * @param: @param args      
	 * @return: void      
	 * @throws
	 */
    public static void main(String[] args) {
	  
	    //异步执行
    	//第一步:创建enc.keyinfo文件等
    	CompletableFuture<String> completableFutureTask = CompletableFuture.supplyAsync(() ->{	
    		//创建enc.keyinfo文件,返回文件地址
		    String encKeyInfoFilePath = null;
		    
		    //目录enc
			File encFilePathDir = new File(ENC_DIRECTORY);
            if (!encFilePathDir.exists()) {// 判断目录是否存在     
            	encFilePathDir.mkdir();   
            }
            
		    //写入文件内容enc.key
            BufferedWriter bwkey = null;
		    //写入文件内容enc.keyinfo
            BufferedWriter bwkeyInfo = null;
            
            try{//文件
            	String encKeyFilePath = ENC_DIRECTORY + "\\enc.key";
            	encKeyInfoFilePath = ENC_DIRECTORY + "\\enc.keyinfo";
            	File fileKey = new File(encKeyFilePath);
            	File fileKeyInfo = new File(encKeyInfoFilePath);
            	
            	//初始化存在删除
            	if(fileKey.exists()) {
        			fileKey.delete();
        		}
            	if(fileKeyInfo.exists()) {
            		fileKeyInfo.delete();
        		}
            	bwkey = new BufferedWriter(new FileWriter(fileKey));
            	bwkeyInfo = new BufferedWriter(new FileWriter(fileKeyInfo));
            	
            	//写入key--自定义的AES128加密的密匙
            	bwkey.write("hsjissmart123456");
            	//写入keyInfo
            	//密匙URL地址,可以对该URL鉴权
            	bwkeyInfo.write("http://localhost:8000/enc.key");
            	bwkeyInfo.newLine();
            	//全路径,绝对路径
            	bwkeyInfo.write(encKeyFilePath);
            	
            	bwkey.flush();
            	bwkeyInfo.flush();
    		}catch(IOException e){
    			e.printStackTrace();
    			//恢复默认
    			encKeyInfoFilePath = null;
    		} finally{
    			try {
    				//一定要关闭文件
    				bwkey.close();
    				bwkeyInfo.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
    		}
	        return encKeyInfoFilePath;
	  }, ThreadPoolExecutorUtils.pool);
      //异步执行
      //第二步:HLS m3u8 AES128 加密
	  CompletableFuture<Integer> completableFutureTaskHls = completableFutureTask.thenApplyAsync((String encKeyInfoFilePath)->{
		  if(encKeyInfoFilePath == null || encKeyInfoFilePath.length() == 0) {return CODE_FAIL;}
		  System.out.println("第一步:创建enc.keyinfo文件,成功!");
		  Integer codeTmp =  cmdExecut(cmd_enc.replace("$encInfoPath", encKeyInfoFilePath).replace("$encPath", ENC_DIRECTORY));
		  if(CODE_SUCCESS != codeTmp) {return CODE_FAIL;}
		  System.out.println("第二步:HLS m3u8 AES128 加密,成功!");
		  return codeTmp;
	  }, ThreadPoolExecutorUtils.pool);
	  
	    //获取执行结果
	    //code=0表示正常
	    try {
		    System.out.println(String.format("获取最终执行结果:%s", completableFutureTaskHls.get() == CODE_SUCCESS ? "成功!" : "失败!"));
		} catch (InterruptedException e) {
			Thread.currentThread().interrupt();
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	    
    }
    
    /**
     * 
     * @Description: (执行ffmpeg自定义命令)   
     * @param: @param cmdStr
     * @param: @return      
     * @return: Integer      
     * @throws
     */
    public static Integer cmdExecut(String cmdStr) {
		  //code=0表示正常
	      Integer code  = null;	   
		  FfmpegCmd ffmpegCmd = new FfmpegCmd();			  			  
		  /**
		   * 错误流
		   */
		  InputStream errorStream = null;		
		  try {
				//destroyOnRuntimeShutdown表示是否立即关闭Runtime
				//如果ffmpeg命令需要长时间执行,destroyOnRuntimeShutdown = false
			
				//openIOStreams表示是不是需要打开输入输出流:
				//	       inputStream = processWrapper.getInputStream();
				//	       outputStream = processWrapper.getOutputStream();
				//	       errorStream = processWrapper.getErrorStream();
			   ffmpegCmd.execute(false, true, cmdStr);
			   errorStream = ffmpegCmd.getErrorStream();		   
			   
			    //打印过程
			    int len = 0;
		        while ((len=errorStream.read())!=-1){
		            System.out.print((char)len);
		        }
			   
			   //code=0表示正常
			   code = ffmpegCmd.getProcessExitCode();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				//关闭资源
				ffmpegCmd.close();
			}
		  //返回
		  return code;
    }
    
}

在这里插入图片描述
在这里插入图片描述
效果:
在这里插入图片描述
播放:
在这里插入图片描述
gitee:https://gitee.com/hsjjsh123/test-ffmpeg

标签:encKeyInfoFilePath,enc,FFmpeg,自定义,转码,m3u8,keyinfo,AES128,key
来源: https://blog.csdn.net/HSJ0170/article/details/118300242

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有