臭鱼烂虾分享小站 v2.1 完工小结

技术栈

  • 后端:PHP 8.3 + SQLite(零外部依赖,单文件部署)

  • 视频:ffmpeg 转 480p HLS,每片~100KB,配合 FRP 小带宽也丝滑

  • 部署:1Panel + Nginx,独立域名 new.nlook.top,跟主站吐槽博客物理隔离

核心功能

  • 视频:批量添加、二级分类、分类内选集、循环播放开关、隐藏 / 显示

  • 用户:名字登录、管理员 / 普通用户、分类级屏蔽(谁能看哪个分类)、公告可见性开关

  • 体验:按账号续播(刷新 / 换设备接着看)、评论 + 管理员回复、多图轮播附件

  • 公告:登录弹窗 + 个人中心可重看,支持 Markdown(分割线、有序列表、图片居中)

  • 后台:全部右侧抽屉操作,列表分页 15 条,按更新时间倒序,CSRF 校验

为什么爽

  • 一个切片 100KB,所有人打开都秒播,不用等缓冲

  • SQLite 单文件,备份就是拷一个 .db

  • 前后端都是我自己撸的,没有任何框架包袱

  • 主站写心情,副站放视频,域名分开互不暴露

从 ffmpeg 切 HLS 开始,一路写到用户权限细分、公告系统、续播记忆,两天迭代了 9 轮代码评审。小而美的东西,最让人上头。


建设踩坑实录(v2.1)

项目:基于 PHP 8.3 + SQLite + HLS 的个人视频分享站 周期:2 天,9 轮迭代 部署:1Panel + Nginx,独立域名 nlook.top


一、视频处理与传输

1. HLS 切片大小怎么定

问题:直接传 MP4,小带宽用户加载卡顿明显。 方案:用 ffmpeg 压到 480p 后切 HLS,每片控制在~100KB。 关键命令思路:

  • -c:v libx264 -preset veryfast -crf 28 压体积

  • -hls_time 2 每片约 2 秒

  • -hls_list_size 0 生成完整 m3u8

效果:客户端要哪片拉哪片,首屏秒开,FRP 内网穿透也不卡。

2. Web 静态资源也可以学 HLS 的思路

问题:一个网页 2MB+(CSS/JS/ 图片一堆),首屏加载慢。 结论:Nginx 本身就是 "要哪个文件回哪个文件",关键是:

  • 资源要小、要分文件、要能并行缓存

  • 别把所有 JS 打成一个大 bundle

  • 图片走懒加载、WebP、响应式尺寸


二、部署与域名

3. 证书域名不匹配(ERR_CERT_COMMON_NAME_INVALID)

现象:新域名 new.nlook.top 打开报证书错误。 原因:1Panel 站点配置里 ssl_certificate 路径指到了老主站 CrossTime 目录下的证书,跟新域名对不上。 解决:在 1Panel 面板里给新站点重新申请 / 绑定证书,路径切到 /www/sites/<新站点>/ssl/。 教训:换域名先看 nginx 配置里的证书路径是不是跟着站点走,别复制老配置。

4. 主站和副站要物理隔离

背景:主站是吐槽内容,副站放视频。 方案:分开域名、分开站点目录、分开证书。不要共用一个域名路径,否则主站被墙 / 被查会连坐副站。


三、后台编辑器集成(Vditor 翻车实录)

5. Vditor 静态资源 404 连环坑

问题:嵌入 Vditor 4.0 后控制台一堆 404。 根因:Vditor 的 cdn 配置指向包根目录,它自己会拼 /dist/...,文件目录结构必须严格匹配:

admin/lib/vditor/dist/├── index.css├── index.min.js├── js/│   ├── i18n/zh_CN.js      ← 不是平铺在根目录│   ├── lute/lute.min.js   ← Markdown 引擎,3.7MB,必须│   ├── icons/ant.js│   └── highlight.js/...├── css/content-theme/...└── images/emoji/...

解决:直接下完整 tgz 解压,别一个个文件抠。

6. 上传图片路径相对路径 bug

现象:后台编辑器里插图后,图片裂了,控制台请求 /admin/uploads/xxx.gif 404。 原因:上传接口返回 uploads/xxx.gif(相对路径),在 admin 页面浏览器会拼成 /admin/uploads/...。 解决:接口返回 /uploads/xxx.gif(前导斜杠,从网站根开始)。数据库里仍存 uploads/xxx.gif(服务端文件操作用相对路径)。

7. 最终放弃 Vditor

原因:小屏幕上分屏编辑体验太差,工具栏挤成一团。 决策:回退到原生 textarea + 自带 mdToHtml(支持标题 粗斜体 列表 链接 图片 行内代码 分割线 / 有序列表)。 教训:富文本编辑器是给桌面端用的,移动端后台别硬上。简单 textarea + 预览按钮反而好用。


四、Windows 环境踩坑

8. PowerShell here-string 吞正则捕获组

现象:用 PowerShell 写前端 JS 正则替换,1/1/2 全变成空字符串。 原因:PowerShell 双引号字符串会把 $1 当变量解析。 解决:

  • 用单引号 here-string @'...'@(不解析变量)

  • 或者把 JS 块写到临时文件,再用 PowerShell 按行号拼接

  • 不要在 PowerShell 里硬写带 $ 的正则

9. Edit 工具频繁报 "File has not been read yet"

现象:刚 Read 过的文件,Edit 还是报错。 解决:改用 PowerShell 按行号切片替换,或者先完整 Read 整个文件再 Edit。


五、安全与数据

10. 代码评审修的 9 项

问题修复
隐藏视频对非管理员可见查询加 visible=1 过滤
评论内容 XSS输出统一 esc() 转义
每请求写调试日志删掉 _debug_session.txt
初始密码明文散落写入 data/initial_credentials.txt
删视频残留封面 评论 续播记录级联清理
每次请求都跑迁移 SQL用 schema_version 缓存跳过
续播上报太频繁位置变化 ≥10 秒才 POST
后台 POST 无 CSRF 校验所有 POST 加 token

11. 续播记录从 localStorage 升级到数据库

问题:localStorage 换设备 / 换浏览器就丢。 方案:按账号存 watch_progress 表(user_id + video_id + position)。 节流:前端每 10 秒位置变化才上报一次,别拖慢视频。


六、权限设计

12. 用户权限分层

  • 一级:能不能登录(名字在白名单里就行)

  • 二级:分类级屏蔽(这个用户不能看哪个分类)

  • 三级:公告可见性(默认能看,可单独关闭)

  • 管理员:不受以上限制

13. Markdown 渲染补全

  • --- *** ___ → 分割线

  • 1. xxx 1) xxx 1、xxx → 有序列表

  • 所有图片自动居中(display:block; margin:auto)


七、经验总结

  1. 小带宽场景下,HLS 切片思路可以推广到所有静态资源:小文件、分块、按需加载。

  2. 第三方编辑器 / 库先在小屏幕测一遍再决定要不要集成。

  3. 文件路径要么全相对、要么全绝对,别混用,尤其在子目录页面里。

  4. Windows + PowerShell 写代码时,涉及 ****$** 的字符串一律走临时文件拼接**。

  5. SQLite 单文件够用就别上 MySQL,备份就是拷一个文件。

  6. 权限设计要分层:登录、分类、公告,三层独立开关,别揉一起。

后端技术 / 臭鱼烂虾的分享站 0 字 0 行 crosstime
2026-09-25T05:40:53.293693437Z 2026-09-25T05:47:43.088462707Z