1.安装openssl
1.1 点击到官网安装,根据自己的电脑系统选择安装版本,下面是我安装的版本
1.2 点击下载好的exe文件,开始安装
1.3 指定安装路径
1.4 点击安装等待完成就好了
1.5 配置环境变量
右键此电脑->属性->高级系统设置->环境变量
点击Path后点击编辑,新建
进去安装好的openssl文件夹,进入bin文件夹,把路径复制下来,粘贴到环境变量中,点击确定
打开命令提示符cmd,输入以下命令
openssl -v
弹出这样的提示说明安装成功了
2.生成密钥信息文件
2.1 在项目中创建key文件和keyinfo文件
在文件夹中打开cmd,输入创建key文件的命令
openssl rand 16 > enc.key
手动创建enc.keyinfo文件,并输入内容,有3行内容
<key_uri>
<key_file>
<key_iv>
1. 第一行 <key_uri>
:
– 含义:这是客户端请求密钥的 URL。播放器在播放时会访问这个 URL 来获取密钥。
– 用途:用于告诉播放器在哪里可以找到加密所需的密钥。
– 示例:http://example.com/keys/key.key
2. 第二行 <key_file>
:
– 含义:这是密钥文件的路径,通常是服务器上存储密钥的本地路径。
– 用途:FFmpeg 在生成加密的 TS 文件时会使用这个密钥文件。
– 示例: enc.key
3. 第三行 <key_iv>
(可选):
– 含义:这是可选的初始化向量(IV),用于加密算法。如果不需要特定的 IV,可以省略这一行。
– 用途:在某些加密算法中,IV 用于增加加密的安全性,确保相同的明文在不同时间加密时生成不同的密文。
– 示例: 0x1234567890abcdef
(16 进制格式的 IV)
3. 上传视频文件并转换的接口
3.1 安装依赖
npm install express multer uuid fluent-ffmpeg
3.2 示例代码
//multer.js
//导入文件上传第三方包
const multer = require('multer')
//导入路径模块
const path = require('path')
//文件上传的配置
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/');
},
filename: function (req, file, cb) {
cb(null, Date.now() + path.extname(file.originalname));
}
})
//文件上传实例
const upload = multer({ storage: storage })
//将multer实例暴露出去
module.exports = upload
//upload.js
// 引入express软件包
const express = require('express')
//获取路由实例
const uploadRouter = express.Router()
//导入路径内置模块
const path = require('path')
//导入multer实例
const upload = require(path.resolve(__dirname,'..','utils','multer.js'))
//导入文件上传第三方包
const multer = require('multer')
//视频格式转换
const ffmpeg = require('fluent-ffmpeg');
//本地安装ffmpeg的路径
const ffmpegPath = path.join('e:','program','ffmpeg-7.0.2-essentials_build','bin','ffmpeg.exe');
//文件库
const fs = require('fs');
const { v4: uuidv4 } = require('uuid'); // 用于生成唯一的文件夹
//服务器地址
const baseURL = 'http://127.0.0.1:3000/uploads/'
// 设置 FFmpeg 的路径
ffmpeg.setFfmpegPath(ffmpegPath);
uploadRouter.post('/upload', function (req, res, next) {
upload.single('file')(req, res, (err) => {
if (err instanceof multer.MulterError) {
// 处理 Multer 错误
return res.status(500).send({ message: `Multer error: ${err.message}` });
} else if (err) {
// 处理其他错误
return res.status(500).send({ message: `Error: ${err.message}` });
}
// 检查文件是否上传
if (!req.file) {
return res.status(400).send({ message: 'No file uploaded' });
}
const file = req.file;
if(file.mimetype.startsWith('video')){
// 使用 UUID 生成唯一文件夹路径
const uniqueId = uuidv4();
const outputDir = path.join(__dirname,'..','uploads', uniqueId);
fs.mkdirSync(outputDir, { recursive: true });
const filePath = path.resolve(__dirname,'..', 'uploads', file.filename);
const m3u8FilePath = path.resolve(outputDir, 'output.m3u8');
//密钥信息的存放路径
const keyInfoFilePath = path.resolve(__dirname,'..','keys','enc.keyinfo');
//文件为视频文件
//使用 fluent-ffmpeg 将视频转换为加密后的 m3u8
ffmpeg(filePath)
.outputOptions([
'-hls_time 5', // 分片时长
`-hls_key_info_file ${keyInfoFilePath}`, // 指定加密信息
'-hls_playlist_type vod', // VOD 类型
`-hls_segment_filename ${outputDir}/segment_%03d.ts` // 防止 ts 文件重名
])
.output(m3u8FilePath)
.on('end', () => {
// 删除上传的原始文件
fs.unlinkSync(filePath);
// 返回生成的 m3u8 文件链接
res.send({ code:1,msg:'上传成功',data:`${baseURL}${uniqueId}/output.m3u8`});})
.on('error', (err) => {
console.error('Error:', err);
res.cc(0,'上传失败');
})
.run();
}else{
//其他文件(照片等)
res.send({ code:1,msg:'上传成功',data:`${baseURL}${req.file.filename}`});
}
});
})
//导出文件上传路由模块
module.exports = uploadRouter
3.3 效果展示
这就是整个视频文件上传到转换的流程