【NodeJs】使用ffmpeg把任意视频文件格式转为加密后的m3u8文件

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 效果展示

这就是整个视频文件上传到转换的流程

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值