跳转到内容

YouTube — 视频平台

公司录了一批内部培训视频,存在共享网盘里。每次新人入职要从一堆文件夹里翻找对应的培训视频,经常找不到或者找错。HR 希望有一个培训视频列表页,按类别整理好,新人打开就能直接看。视频文件已经有了,不需要上传功能,做个展示页就行。

用纯前端搭建一个分类视频列表页面,支持筛选和 HTML5 播放。

用纯前端实现一个培训视频列表页,要求:
1. 视频数据硬编码为 JSON 数组,每个视频有 id、title、description、category、duration、videoUrl、thumbnail 字段
2. 准备 12 个示例视频条目,分为「新人入职」「技术培训」「产品知识」三个分类
3. videoUrl 使用公开的示例视频地址(如 sample-videos.com 的 MP4)
4. 页面顶部有分类筛选标签栏(全部 + 三个分类)
5. 视频列表用卡片布局(缩略图 + 标题 + 时长 + 分类标签)
6. 点击卡片弹出模态框,用 HTML5 <video> 播放器播放视频
7. 播放器支持播放/暂停、进度条、音量、全屏
8. 支持按标题搜索过滤
9. 响应式布局,移动端一列,桌面端三列
10. 单个 HTML 文件,不需要后端
输出一个可以直接打开的 HTML 文件。
  • 页面正常打开,视频卡片列表显示
  • 分类筛选切换正常
  • 搜索过滤功能有效
  • 点击卡片弹出播放器
  • 视频可以正常播放和控制
  • 移动端布局自适应
  • HTML5 Video API 的使用 → M1
  • 响应式布局设计模式 → M1
  • 纯前端应用的适用边界 → M8

培训视频列表页上线后效果不错,各部门都想把自己的培训视频也放上去。但是现在添加视频要改代码里的 JSON 数组,每次都要找你帮忙。部门负责人希望能自己上传视频,填写标题和描述,上传后就能直接看到。视频大小一般在 50MB-200MB 之间。

搭建支持视频上传和元数据管理的后端服务,视频存储到本地文件系统。

用 Go + Gin + SQLite 实现一个视频管理平台,要求:
1. 数据库模型:Video(id, title, description, category, duration, file_path, file_size, status, created_at)
2. API 接口:
- POST /api/videos/upload — multipart 表单上传视频文件(限制 500MB)
- GET /api/videos — 视频列表(支持分页、分类筛选)
- GET /api/videos/:id — 视频详情
- DELETE /api/videos/:id — 删除视频(同时删除文件)
- GET /api/videos/:id/stream — 视频流式播放(支持 Range 请求)
3. 视频文件存储到 ./uploads/videos/ 目录,以 UUID 重命名
4. 上传时校验文件类型(只允许 mp4, webm, mov)
5. 上传时用 ffprobe 获取视频时长(如果可用,否则记录为 0)
6. 前端页面:
- 上传表单(拖拽上传 + 进度条)
- 视频列表页(卡片布局 + 分类筛选 + 分页)
- 视频播放页(HTML5 播放器)
7. Gin 配置:请求体最大 500MB,超时 5 分钟
输出完整项目结构和代码。
  • 视频上传成功,文件保存到 uploads 目录
  • 上传进度条正常显示
  • 文件类型校验生效(上传 .txt 被拒绝)
  • 视频列表分页加载正常
  • 视频流式播放正常(支持拖动进度条)
  • 删除视频同时清理文件
  • 500MB 以内的视频可以完整上传
  • Multipart 文件上传处理 → M1
  • HTTP Range 请求实现视频流式播放 → M13
  • 文件类型校验和安全性 → M1
  • 本地文件存储管理策略 → M17
  • SQLite 作为轻量级存储的适用场景 → M2

V3「视频太大(2GB)上传经常失败,海外分公司看视频一直缓冲」

Section titled “V3「视频太大(2GB)上传经常失败,海外分公司看视频一直缓冲」”

平台用了三个月,问题越来越多。市场部上传了一个 2GB 的年会视频,上传到 80% 时网络波动导致失败,只能从头再传。海外分公司的同事反馈看视频一直在缓冲,720p 都卡。而且所有视频都是原始格式上传的,有人传了 4K 原片,手机端播放完全扛不住。团队需要一套完整的视频处理方案。

实现分片断点续传、异步视频转码和 CDN 分发,支持大文件和全球访问。

用 Go + Gin 实现一个支持大视频处理的平台,要求:
1. 分片上传 API:
- POST /api/upload/init — 初始化上传(返回 uploadID,记录文件信息)
- POST /api/upload/chunk — 上传单个分片(5MB/片,携带 uploadID + chunkIndex)
- POST /api/upload/complete — 合并分片(校验所有分片完整性,合并为完整文件)
- GET /api/upload/status/:uploadID — 查询已上传分片(用于断点续传)
2. 分片临时存储在 ./tmp/chunks/{uploadID}/ 目录
3. 异步转码 Worker:
- 上传完成后将转码任务写入内存队列(channel)
- Worker 消费任务,用 ffmpeg 转码为 360p、720p、1080p 三个版本
- 转码状态通过 API 可查询:GET /api/videos/:id/transcode-status
- 视频状态流转:uploading → processing → ready → error
4. 视频播放接口支持清晰度切换:GET /api/videos/:id/stream?quality=720p
5. CDN 友好设计:
- 视频响应带 Cache-Control 长缓存头
- ETag 支持
- 文件路径按日期分目录:/videos/2024/01/15/{uuid}/720p.mp4
6. 前端页面:
- 分片上传组件(显示进度、支持暂停/继续/断点续传)
- 视频播放页带清晰度切换按钮
- 管理页面显示转码状态
7. PostgreSQL 存储视频元数据和转码任务状态
输出完整项目结构、代码和 Docker Compose 配置。
  • 分片上传功能正常(大文件被拆分为 5MB 分片)
  • 断点续传有效(中断后重新上传只传缺失分片)
  • 分片合并后文件完整(MD5 校验一致)
  • 转码任务自动触发并完成
  • 三个清晰度版本生成正确
  • 视频播放支持清晰度切换
  • 缓存头正确设置
  • 转码失败时状态正确标记为 error
  • 分片上传与断点续传协议设计 → M1
  • 异步任务队列(channel → 消息队列的前身) → M5
  • 视频转码流水线和 ffmpeg 使用 → M9
  • CDN 缓存策略和 HTTP 缓存头 → M13
  • 文件存储目录设计(按日期分片) → M17
  • 视频状态机设计 → M2
  • 从单体到 Worker 分离的架构演进 → M8
  • 自适应码率的设计思路(HLS/DASH 的前置知识) → M16

V4「用户说视频加载慢,手机端更明显」

Section titled “V4「用户说视频加载慢,手机端更明显」”

平台用户达到 1000 人,用户反馈视频加载慢,特别是手机端在 4G 网络下经常卡顿。目前视频只有固定清晰度的 MP4 文件,浏览器必须等下载到一定量才能开始播放。手机用户流量有限,却被迫加载高清版本。另外,视频列表页加载也变慢了,因为每个视频的缩略图都是前端从视频里截取的。

实现 HLS 自适应码率流媒体,预生成多分辨率转码和缩略图,优化视频压缩参数。

在现有视频平台基础上,实现自适应码率流媒体和视频优化,要求:
1. HLS 自适应码率流媒体(Adaptive Bitrate Streaming):
- 转码时除了生成 MP4,额外生成 HLS 格式(.m3u8 + .ts 分片)
- 生成 master playlist 包含多个清晰度:360p(800kbps)、720p(2.5Mbps)、1080p(5Mbps)
- 每个 ts 分片时长 6 秒
- 播放器自动根据网络带宽切换清晰度
- GET /api/videos/:id/hls/master.m3u8 — 返回 master playlist
2. 多分辨率转码优化:
- ffmpeg 参数优化:使用 H.264 High Profile、CRF 编码(CRF=23 平衡质量和大小)
- 双通编码(two-pass)提升压缩效率
- 关键帧间隔对齐 ts 分片边界(GOP = 帧率 × 分片时长)
- 转码后视频大小对比原始文件,记录压缩率
3. 缩略图生成:
- 上传视频后自动截取第 1 秒画面作为封面缩略图
- 生成视频时间线预览图(每 10 秒截取一帧,拼接为 sprite sheet)
- 缩略图统一压缩为 WebP 格式,宽度 320px
- GET /api/videos/:id/thumbnail — 返回封面缩略图
- GET /api/videos/:id/sprite — 返回时间线预览图
4. 视频压缩优化:
- 音频统一转为 AAC 128kbps
- 去除视频元数据中不必要的信息(moov atom 前置加速起播)
- 视频文件 faststart 处理(moov atom 移到文件头部)
5. 前端播放器升级:
- 集成 hls.js 播放 HLS 流
- 显示当前播放码率和网络带宽
- 进度条悬停显示时间线预览图
- 支持手动切换清晰度和自动模式
输出转码脚本、HLS 配置、前端播放器代码和性能对比数据。
  • HLS master playlist 包含多个清晰度流
  • 播放器自动根据带宽切换清晰度
  • 手动切换清晰度无缝衔接
  • 缩略图自动生成并正确显示
  • 时间线预览图在进度条悬停时显示
  • moov atom 前置后视频起播速度明显加快
  • 压缩后视频质量可接受,大小显著减小
  • 移动端播放流畅(4G 网络下自动降到低码率)
  • HLS 自适应码率流媒体原理(master playlist + variant streams) → M13
  • 视频编码参数优化(H.264 Profile、CRF、GOP) → M9
  • 缩略图和 sprite sheet 生成策略 → M9
  • moov atom 前置和 faststart 优化起播速度 → M13
  • hls.js 前端播放器集成 → M1
  • 从固定码率到自适应码率的演进 → M8

V5「转码队列积压,新上传的视频要等 1 小时」

Section titled “V5「转码队列积压,新上传的视频要等 1 小时」”

平台用户增长到 1 万人,每天上传 200+ 视频。转码 Worker 只有一个,队列积压严重,新上传的视频平均要等 1 小时才能观看。付费企业用户投诉他们的培训视频不能及时上线。而且 Worker 挂掉后队列里的任务全丢了,只能重新上传。团队急需提升转码吞吐量和可靠性。

部署专用转码 Worker 集群,引入优先级队列(付费用户优先),实现并行转码,通过 WebSocket 推送转码进度通知。

将视频转码系统升级为分布式高可用架构,要求:
1. 消息队列替换内存 channel:
- 使用 RabbitMQ(或 Redis Stream)作为转码任务队列
- 任务消息包含:video_id, priority, source_path, target_qualities
- 消息持久化,Worker 崩溃后任务不丢失
- 消费确认机制(ack/nack),转码失败自动重试(最多 3 次)
2. 优先级队列:
- 定义优先级:urgent(付费用户) > high(管理员) > normal(普通用户)
- 不同优先级使用不同队列,Worker 优先消费高优先级队列
- API 支持提升任务优先级:POST /api/admin/transcode/:id/priority
3. 专用转码 Worker 集群:
- Worker 作为独立进程,支持水平扩展(启动多个实例)
- 每个 Worker 同时处理 2 个转码任务(并发控制)
- Worker 注册和心跳机制,管理端可查看活跃 Worker 列表
- Worker 资源监控:CPU、内存使用率
4. 并行转码:
- 同一视频的不同清晰度版本并行转码(360p、720p、1080p 同时进行)
- 任何一个清晰度完成即可播放(渐进式可用)
- 全部完成后更新视频状态为 ready
5. WebSocket 实时通知:
- 客户端连接 WebSocket:/ws/transcode/:video_id
- 推送转码进度:{quality: "720p", progress: 65, eta: "30s"}
- 推送状态变更:processing → partial_ready → ready
- 前端实时显示每个清晰度的转码进度条
6. 转码任务管理后台:
- 队列长度和等待时间监控
- 按状态筛选任务(pending/processing/completed/failed)
- 失败任务手动重试
- Worker 负载均衡状态
输出 Worker 代码、消息队列配置、WebSocket 服务和管理后台页面。
  • 任务写入消息队列并持久化
  • Worker 崩溃重启后未完成任务自动重新消费
  • 付费用户视频优先转码(插队验证)
  • 多 Worker 实例并行消费不重复
  • 同一视频多清晰度并行转码
  • 720p 先完成即可播放,不等其他清晰度
  • WebSocket 推送进度实时更新
  • 失败任务自动重试最多 3 次
  • 管理后台显示队列和 Worker 状态
  • 消息队列(RabbitMQ/Redis Stream)实现任务分发 → M5
  • 优先级队列设计和多队列消费策略 → M5
  • Worker 集群水平扩展和并发控制 → M8
  • WebSocket 实时推送通知 → M13
  • 消费确认和重试机制保证可靠性 → M5
  • 渐进式可用的用户体验优化 → M1
  • 从单 Worker 到分布式 Worker 集群的演进 → M8

V6「海外用户占 30%,视频缓冲严重」

Section titled “V6「海外用户占 30%,视频缓冲严重」”

平台全球化运营,用户超过 10 万,海外用户占 30%。东南亚和欧洲用户反馈视频缓冲严重,首次播放要等 10 秒以上。分析发现所有视频文件都存储在国内单一机房,海外用户每次请求都要跨洋传输。热门视频(如公司年度总结)被数万人重复拉取,源站带宽成本飙升。另外,大量 3 年前的旧视频几乎没人看,却占据了昂贵的 SSD 存储。

实现多 CDN 分发策略,边缘节点缓存热门内容,基于观看历史预加载视频,部署区域转码服务器,用冷存储降低旧视频存储成本。

将视频平台升级为全球化分发架构,要求:
1. 多 CDN 策略:
- 对接至少两家 CDN 提供商(如 CloudFront + Cloudflare)
- CDN 选择逻辑:根据用户地理位置选择最优 CDN
- CDN 故障自动切换(健康检查 + fallback)
- 视频 URL 签名防盗链(时间戳 + token 签名,有效期 2 小时)
2. 边缘缓存优化:
- 热门视频主动推送到边缘节点(push 模式)
- 冷门视频按需拉取并缓存(pull 模式)
- 缓存策略:HLS ts 分片缓存 24 小时,master playlist 缓存 5 分钟
- 边缘节点缓存命中率监控(目标 > 90%)
3. 智能预加载:
- 基于用户观看历史推荐下一个可能观看的视频
- 当前视频播放到 80% 时,预加载推荐视频的前 3 个 ts 分片
- 用户个人主页预加载最近观看系列的下一集
- 预加载带宽限制:不超过当前播放带宽的 20%
4. 区域转码服务器:
- 主要区域(亚洲、欧洲、北美)各部署转码 Worker
- 用户上传视频路由到最近的区域转码
- 转码完成后视频分发到全球 CDN
- 跨区域视频元数据同步(数据库主从复制)
5. 存储成本优化:
- 存储分层:热存储(SSD,30 天内视频)→ 温存储(HDD,30-180 天)→ 冷存储(对象存储/归档,180 天以上)
- 自动迁移策略:定时任务扫描视频最后访问时间,自动降级存储层
- 冷存储视频被访问时自动恢复到热存储(恢复时间 < 30 秒)
- 存储成本报表:按层级统计存储量和费用
6. 全局监控:
- 各区域播放质量指标:首帧时间、缓冲率、码率切换次数
- CDN 带宽费用实时监控
- 用户体验评分(QoE Score)
输出多 CDN 配置、预加载算法、存储迁移脚本、区域部署方案和监控大盘设计。
  • 不同地区用户命中不同 CDN 节点
  • CDN 故障时自动切换到备用 CDN
  • 视频 URL 签名验证通过,过期链接被拒绝
  • 热门视频边缘缓存命中率 > 90%
  • 视频播放到 80% 时预加载下一个视频
  • 区域转码服务器就近处理上传
  • 旧视频自动迁移到冷存储
  • 冷存储视频被访问时自动恢复
  • 全局播放质量指标正常采集
  • 带宽费用报表准确
  • 多 CDN 策略和故障切换机制 → M13
  • 边缘缓存 push/pull 模式和命中率优化 → M4
  • URL 签名防盗链设计 → M1
  • 基于用户行为的智能预加载算法 → M9
  • 多区域部署和就近路由 → M17
  • 存储分层(热/温/冷)和自动迁移策略 → M17
  • 数据库主从复制实现跨区域同步 → M3
  • 播放质量指标(QoE)监控 → M15
  • 从单机房到全球化分发的架构演进 → M8