# ffmpeg-hls-play
**Repository Path**: ocean_vane/ffmpeg-hls-play
## Basic Information
- **Project Name**: ffmpeg-hls-play
- **Description**: ffmpeg-hls-play
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2024-12-07
- **Last Updated**: 2025-07-30
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# m3u8 流式视频加密播放
## 功能背景
本方案的目的是通过 HLS (HTTP Live Streaming) 技术实现视频流的加密和播放。HLS 是一种广泛使用的流媒体协议,支持视频内容分片(segmenting),并能在 Web 或移动设备上进行高效播放。通过 AES-128 加密,可以对 HLS 流进行加密保护,防止视频内容被未授权访问。
## 实现思路
- **生成加密密钥**:使用 Node.js 的 `crypto` 模块生成 AES 密钥,该密钥将用于加密视频内容。
- **配置 HLS 加密流**:通过 `ffmpeg` 配置 HLS 视频流的加密,生成加密的 `.ts` 分片和 `m3u8` 索引文件。
- **创建 `keyinfo.txt`**:该文件指定加密密钥的 URL 或文件路径,以及加密方法(AES-128)。
- **搭建本地服务器**:使用 Express 搭建本地静态文件服务器,提供视频文件和密钥文件的访问。
- **测试播放**:使用 VLC 或支持 HLS 的浏览器来测试加密视频流的播放。
## 操作步骤
### 第一步:生成密钥
你可以手动生成一个随机的 AES 密钥,或者使用 Node.js 的 crypto 模块来生成:
```js
const crypto = require("crypto");
const fs = require("fs");
// 生成一个 256 位的 AES 密钥
const key = crypto.randomBytes(32); // 256 位
fs.writeFileSync("encryption.key", key); // 将密钥保存到文件中
```
这会在当前目录下生成一个 encryption.key 文件,它将用于加密视频流。而我们项目中可以将 encryption.key 文件放在 keys 目录下。
### 第二步:配置 HLS 加密流
- 这是没有加密的操作(这是测试 ffmpeg 是否正常工作)
```bash
ffmpeg -i input_video.mp4 -hls_time 10 -hls_list_size 0 -hls_segment_filename 'output_dir/%03d.ts' output_dir/index.m3u8
```
- 这是加密的操作(这是我们需要的加密操作)
```bash
ffmpeg -i input_video.mp4 -hls_time 10 -hls_list_size 0 -hls_key_info_file ./keyinfo.txt -hls_segment_filename 'output_dir/%03d.ts' output_dir/index.m3u8
```
### 第三步:创建 keyinfo.txt
keyinfo.txt 文件用于指定加密的密钥 URL 和本地密钥路径,格式如下:
```txt
http://localhost:3000/keys/encryption.key
/Users/v/Downloads/server/keys/encryption.key
```
### 第四步:服务器设置
```js
const express = require("express");
const path = require("path");
const app = express();
// 提供静态文件
app.use(express.static(path.join(__dirname, "public")));
app.use("/videos", express.static(path.join(__dirname, "output_dir")));
app.use("/keys", express.static(path.join(__dirname, "keys")));
// 设置默认路由到 index.html
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "public", "index.html"));
});
// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
```
### 第五步: 测试本地加密流
使用 VLC 媒体播放器测试(其它播放器也可以 IINA),你可以使用 VLC 媒体播放器来测试加密的 HLS 流。VLC 支持 HLS 并且可以处理加密的流。
- 打开 VLC 媒体播放器。
- 选择 媒体 -> 打开网络串流。
- 输入 http://localhost:3000/videos/index.m3u8,然后点击 播放。
如果 VLC 能够播放视频,那么说明你的 HLS 流是正确的,问题可能出在浏览器或 Video.js 的配置上。
### 第六步:创建 index.html
创建 index.html
需要注意不要使用 video.js,尝试 video.js 一直报错,无法正常运行。可以考虑使用 hls.js
```html
HLS.js Example
```
## 后续思考
- **密钥管理与安全性**:虽然本地密钥文件在开发阶段可行,但在生产环境中,密钥应存储在安全的地方,如密钥管理服务(KMS)中,以确保安全性。
- **流媒体优化**:可考虑进一步优化 HLS 流的生成,使用更细粒度的分段、不同的码率以支持自适应流(ABR)。
- **跨平台支持**:确保 HLS 流在不同设备、浏览器、操作系统上的兼容性,特别是需要支持 Safari、Chrome 等浏览器。
## 完善方向
- **自定义 IV**:目前的实现自动生成 IV,如果需要更高的安全性,可以为每个视频片段使用独特的 IV。
- **动态密钥更新**:可以考虑实现动态密钥更新机制,例如定期更换加密密钥,确保视频流的安全性。
- **视频播放器优化**:可以为页面添加播放控制功能,优化用户体验。
## 应用场景
- **在线教学平台**:保护版权内容,防止视频被盗用或未经授权访问。
- **媒体流服务**:为视频内容提供加密保护,确保用户只能在授权设备上观看。
- **企业视频共享**:内部使用的视频内容加密,确保敏感信息不会被泄露。
# 多分辨率视频播放控制
## 功能背景
在现代视频流媒体播放中,支持多种分辨率的视频流是提高用户体验的关键。尤其是在网络带宽不稳定或设备性能有限的情况下,能够根据用户设备和网络状况自动调整视频质量(例如分辨率)是非常重要的。HLS(HTTP Live Streaming)协议通过支持不同的分辨率和码率的视频流,能够让客户端在播放时根据网络状况自动选择最佳的视频分辨率和码率,从而提升视频播放的流畅度,减少卡顿现象。
此功能背景的核心目标是通过 HLS 协议和动态自适应流(Adaptive Bitrate Streaming)技术实现基于分辨率和网络状况的动态视频质量控制。
## 实现思路
为了实现多分辨率视频播放控制,我们需要做以下几项工作:
1. **生成多种分辨率的视频流**:使用工具如 `ffmpeg`,从原始视频生成多个不同分辨率和码率的 `.ts` 分片,并生成相应的 `m3u8` 播放列表文件。
2. **创建多分辨率的播放列表(Master Playlist)**:生成一个包含所有视频质量(分辨率和码率)的主播放列表(`master.m3u8`)。客户端会通过该主播放列表选择适合当前网络和设备性能的播放流。
3. **动态选择合适的分辨率**:客户端(使用如 `hls.js` 的库)根据当前网络带宽和设备性能自动选择最合适的视频流分辨率进行播放。
通过这些步骤,我们能够为用户提供一个无缝的自适应视频播放体验,根据不同的设备、网络条件和播放需求自动调整视频流的分辨率和码率。
## 操作步骤
### 第一步:配置多分辨率视频流
使用 `ffmpeg` 将一个视频转码为不同的分辨率和码率,以便为不同的网络条件和设备提供适应性强的播放流。例如,生成 1080p、720p、480p 等不同分辨率的流。
```bash
ffmpeg -i input_video.mp4 \
-map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 \
-c:v libx264 -crf 22 -c:a aac -ar 48000 \
-filter:v:0 scale=w=480:h=360 -maxrate:v:0 600k -b:a:0 64k \
-filter:v:1 scale=w=640:h=480 -maxrate:v:1 900k -b:a:1 128k \
-filter:v:2 scale=w=1280:h=720 -maxrate:v:2 900k -b:a:2 128k \
-var_stream_map "v:0,a:0,name:360p v:1,a:1,name:480p v:2,a:2,name:720p" \
-preset slow -hls_list_size 0 -threads 0 -f hls -hls_playlist_type event -hls_time 10 \
-hls_flags independent_segments -master_pl_name "master.m3u8" \
-hls_segment_filename "output_dir/%v_%03d.ts" \
-y "output_dir/playlist-%v.m3u8"
```
以上命令生成了三种不同分辨率的视频流,并将它们分别存储为 `playlist-360p`、`playlist-480p`和`playlist-720p`文件,且每种分辨率的视频流由多个 `.ts` 文件组成。
而且还会生成一个主播放列表 `master.m3u8`,它将包含所有不同分辨率的视频流和它们的码率信息。这样,客户端可以根据其网络状况选择合适的视频流。在 `master.m3u8` 文件中,`BANDWIDTH` 指定了该视频流的码率,`RESOLUTION` 指定了视频的分辨率。客户端会根据自己的网络带宽选择合适的分辨率流进行播放。
### 第二步:配置服务器和提供播放列表
将生成的视频流文件、分辨率播放列表和主播放列表都上传到服务器,确保客户端可以访问这些文件。在 Node.js 中,我们可以通过 Express 提供视频流的访问:
```js
const express = require("express");
const path = require("path");
const app = express();
// 提供静态文件
app.use(express.static(path.join(__dirname, "public")));
app.use("/videos", express.static(path.join(__dirname, "output_dir")));
app.use("/keys", express.static(path.join(__dirname, "keys")));
// 设置默认路由到 index.html
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "public", "index.html"));
});
// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
```
### 第三步:在客户端使用 `hls.js` 播放
客户端使用 `hls.js` 加载主播放列表并自动选择合适的分辨率播放流:
```html
HLS Player with Plyr.js
```
通过 `hls.js`,客户端能够加载 `master.m3u8` 文件并根据网络状况动态选择适合的分辨率进行播放。
## 后续思考
- **网络带宽动态调整**:目前的方案是基于网络状况选择适合的流,但实际使用中,网络带宽可能会随时间变化。因此,需要实现实时的带宽检测和流切换机制。
- **设备性能适配**:除了网络带宽,设备的性能也是决定视频质量的一个因素。未来可以扩展方案,增加设备性能检测(如 CPU、内存等),为不同设备选择合适的分辨率。
- **视频播放体验优化**:通过集成视频质量缓冲、平滑切换、低延迟等技术,进一步提升多分辨率视频播放的用户体验。
## 完善方向
- **自适应码率算法**:通过动态带宽检测,可以实现更精确的自适应码率调整,确保用户在不同网络环境下都能获得最佳体验。
- **多平台支持**:确保视频流在不同平台(如 iOS、Android、PC)上都能顺畅播放,特别是对移动设备的优化。
- **增强安全性**:在多分辨率流的基础上加强视频内容的保护,避免非法下载或盗用视频流。
## 应用场景
- **在线视频平台**:如 YouTube、Netflix 等大规模视频流媒体服务,支持不同网络状况和设备条件下的视频播放。
- **直播平台**:例如直播体育赛事或演唱会,可以根据用户的网络状况和设备性能动态调整视频质量。
- **教育平台**:如在线教育平台,提供高质量的视频教程,同时支持不同网络环境下流畅播放。
- **企业视频会议**:支持在不同带宽条件下进行视频会议,确保高质量的视频体验。
通过多分辨率视频播放控制,我们能够为用户提供更加流畅、个性化的观看体验,同时确保在各种网络和设备环境下的最佳视频质量。
# 加密多分辨率视频播放控制
## 操作步骤
### 第一步:配置加密多分辨率视频流
其它操作步骤不需要任何变化
```bash
ffmpeg -i input_video.mp4 \
-map 0:v:0 -map 0:a:0 \
-map 0:v:0 -map 0:a:0 \
-map 0:v:0 -map 0:a:0 \
-map 0:v:0 -map 0:a:0 \
-c:v:0 libx264 -crf 22 -c:a:0 aac -ar 48000 \
-filter:v:0 scale=w=480:h=360 -maxrate:v:0 600k -b:a:0 64k \
-filter:v:1 scale=w=640:h=480 -maxrate:v:1 900k -b:a:1 128k \
-filter:v:2 scale=w=1280:h=720 -maxrate:v:2 1500k -b:a:2 128k \
-filter:v:3 scale=w=1920:h=1080 -maxrate:v:3 2500k -b:a:3 128k \
-var_stream_map "v:0,a:0,name:360p v:1,a:1,name:480p v:2,a:2,name:720p v:3,a:3,name:1080p" \
-preset slow -hls_list_size 0 -threads 0 -f hls -hls_playlist_type event -hls_time 10 \
-hls_flags independent_segments -master_pl_name "master.m3u8" \
-hls_segment_filename "output_dir/%v_%03d.ts" \
-hls_key_info_file ./keyinfo.txt \
-y "output_dir/playlist-%v.m3u8"
```