当前位置: 首页 > news >正文

MinIO中视频转换为HLS协议并进行AES加密

一、视频切片进行AES加密

  1. win10下载FFmpeg D:\ProgramFiles\ffmpeg
    在这里插入图片描述

  2. 把ffmpeg的绝对路径配置进来

package cn.teaching.jlk.module.infra.framework.utils;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;@Service
public class FFmpegPathResolver {@Value("${ffmpeg.path.linux:/usr/bin/ffmpeg}")private String linuxPath;@Value("${ffmpeg.path.win:D:/ffmpeg/bin/ffmpeg.exe}")private String windowsPath;public String getFFmpegPath() {return System.getProperty("os.name").toLowerCase().contains("win")? windowsPath : linuxPath;}
}
  1. 从MinIo下载视频到本地,切片完成之后进行AES加密上传到MinIo
import cn.hutool.core.util.HexUtil;
import cn.teaching.jlk.module.infra.framework.file.core.client.FileClient;
import cn.teaching.jlk.module.infra.framework.utils.FFmpegPathResolver;
import jakarta.annotation.Resource;
import net.bramp.ffmpeg.FFmpeg;
import net.bramp.ffmpeg.FFmpegExecutor;
import net.bramp.ffmpeg.builder.FFmpegBuilder;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.SecureRandom;
import java.util.stream.Stream;// 4. HLS 切片服务 (异步处理)
@Service
@EnableAsync
public class HlsConversionService {@Value("${hls.segment-duration}")private int segmentDuration;@Autowiredprivate FileService fileService;@Resourceprivate FileConfigService fileConfigService;@Resourceprivate FFmpegPathResolver ffmpegPathResolver;@Asyncpublic void convertToHls(String sourceObject, String videoId, String keyUri) {try {// 1. 从MinIO下载原始视频到临时文件Path tempDir = Files.createTempDirectory("hls_conversion");Path inputFile = tempDir.resolve("source.mp4");FileClient client = fileConfigService.getMasterFileClient();byte[] fileContent = fileService.getFileContent(client.getId(), sourceObject);Files.write(inputFile, fileContent);// 2. 创建输出目录Path outputDir = tempDir.resolve("output");Files.createDirectories(outputDir);// 3. 创建密钥文件Path keyInfoFile = tempDir.resolve("enc.keyinfo");Path keyFile = tempDir.resolve("enc.key");String hexKey = generateHexKey();// 3.1生成 key 文件Files.write(keyFile, getKeyBytes());// 3.2生成 keyinfo 文件String keyInfoContent = keyUri + "\n" + keyFile.toAbsolutePath().toString() + "\n" + hexKey;Files.write(keyInfoFile, keyInfoContent.getBytes());// 4. 执行FFmpeg转换FFmpeg ffmpeg = new FFmpeg(ffmpegPathResolver.getFFmpegPath());FFmpegBuilder builder = new FFmpegBuilder().setInput(inputFile.toString()).addOutput(outputDir.resolve("playlist.m3u8").toString()).setFormat("hls").addExtraArgs("-hls_time", String.valueOf(segmentDuration)).addExtraArgs("-hls_key_info_file", keyInfoFile.toString()).addExtraArgs("-hls_playlist_type", "vod").addExtraArgs("-hls_segment_filename", outputDir.resolve("segment_%03d.ts").toString()).addExtraArgs("-hls_flags", "independent_segments").addExtraArgs("-g", "48").addExtraArgs("-sc_threshold", "0").addExtraArgs("-c:v", "libx264").addExtraArgs("-c:a", "aac").addExtraArgs("-b:v", "2000k").addExtraArgs("-b:a", "128k").done();FFmpegExecutor executor = new FFmpegExecutor(ffmpeg);executor.createJob(builder).run();// 5. 上传切片文件到MinIOuploadHlsFiles(outputDir, videoId);// 6. 清理临时文件FileUtils.deleteDirectory(tempDir.toFile());} catch (Exception e) {throw new RuntimeException("HLS conversion failed", e);}}/*** 获取 AES 密钥* @return*/public byte[] getKeyBytes() {String hexKey = "a1b2c3d4e5f678901234567890abcdef";return HexUtil.decodeHex(hexKey);}private String generateHexKey() {byte[] key = new byte[16];new SecureRandom().nextBytes(key);StringBuilder sb = new StringBuilder();for (byte b : key) {sb.append(String.format("%02x", b & 0xFF));}return sb.toString();}private void uploadHlsFiles(Path outputDir, String videoId) {try (Stream<Path> paths = Files.walk(outputDir)) {paths.filter(Files::isRegularFile).forEach(file -> {String objectName = videoId + "/" + file.getFileName().toString();try (InputStream is = Files.newInputStream(file)) {fileService.createFile(file.getFileName().toString(),objectName, is.readAllBytes(), false);} catch (Exception e) {throw new RuntimeException("HLS file upload failed", e);}});} catch (Exception e) {throw new RuntimeException("HLS file upload failed", e);}}
}

二、防下载技术组合拳

  1. MinIO 桶策略
{"Version": "2012-10-17","Statement": [{"Effect": "Deny","Principal": "*","Action": "s3:GetObject","Resource": "arn:aws:s3:::video-bucket/*","Condition": {"StringNotLike": {"aws:Referer": ["https://your-domain.com/*"]}}}]
}
  1. Nginx 代理加固
location ~ \.(m3u8|ts|key)$ {proxy_pass http://minio-server;# 关键防御头add_header X-Content-Type-Options "nosniff";add_header Content-Disposition "inline";add_header Content-Security-Policy "default-src 'self'";# 限制Range请求(防下载工具)if ($http_range) {return 416;}
}
  1. 动态水印叠加
// 使用FFmpeg实时叠加用户专属水印
FFmpegBuilder builder = new FFmpegBuilder().setInput(inputUrl).addOutput(outputUrl).addExtraArgs("-vf", "drawtext=text='User %{userId}': fontcolor=white@0.5: fontsize=24: box=1: boxcolor=black@0.5: x=10: y=10").done();
  1. 禁用右键/快捷键
<template><div @contextmenu.prevent @keydown.prevent="blockShortcuts"><video ref="videoEl" controls></video></div>
</template><script>
function blockShortcuts(e) {const forbiddenKeys = [67, 83, 85]; // C, S, Uif (e.ctrlKey && forbiddenKeys.includes(e.keyCode)) {e.preventDefault();alert('禁止操作');}
}
</script>
http://www.lryc.cn/news/574465.html

相关文章:

  • Python Polars库详解:高性能数据处理的新标杆
  • pyqt多界面
  • LangChain网页自动化PlayWrightBrowserToolkit
  • gRPC 静态库链接到 DLL 的风险与潜在问题
  • 鸿蒙开发深入解析:Service Ability(后台任务)全面指南
  • 深度解析|智能汽车操作系统技术突破:从架构演进到产业重构
  • 比翼双飞,影像的迁徙之旅
  • 基于目标驱动的分布式敏捷开发
  • GPPT(Graph Pre-training and Prompt Tuning)项目复现
  • 生成FUCK代币,并用程序进行转账的过程
  • C++字符串的行输入
  • 查询sqlserver数据库中,数据占的空间和索引占的空间
  • 鸿蒙HarmonyOS 5 开发实践:LazyForEach在通讯录应用中的高效渲染(附:代码)
  • 前端vue2每三十秒被动接受后端服务器发送过来得数据
  • 前端react使用 UmiJS 构建框架 在每次打包时候记录打包时间并在指定页面显示
  • Linux 启动过程流程图
  • PDF全能转换工具,支持图片转PDF,多图合并转PDF,word转PDF,PDF转WORD,PDF转图片
  • TouchDIVER Pro触觉手套:虚拟现实中的多模态交互新选择
  • Flask(五) 表单处理 request.form
  • 鸿蒙开发深入解析:Data Ability 数据共享机制全面指南
  • Java并发编程中高效缓存设计的哲学
  • 【格与代数系统】示例2
  • PyTorch 实现的 GlobalPMFSBlock_AP_Separate:嵌套注意力机制在多尺度特征聚合中的应用
  • 关于 pdd:anti_content参数分析与逆向
  • C#图书管理系统笔记(残缺版)
  • 【数据标注师】词性标注2
  • 【AI News | 20250623】每日AI进展
  • 基于 SpringBoot+JSP 的医疗预约与诊断系统设计与实现
  • 华为OD机试_2025 B卷_矩形相交的面积(Python,100分)(附详细解题思路)
  • leetcode82.删除排序链表中的重复元素II