先说一个结论:这个视频直播点播平台被我骂了半年“垃圾”,但它至今还在我手底下的服务器里稳稳跑着,甚至帮我扛过一场三百人同时在线的小型技术分享直播。它是那种典型的功能能用、代码稀烂、界面丑到爆炸、文档约等于没有的系统。我一开始只是因为着急交付一个内网培训视频系统,在开源社区里翻了半天,图省事就把它拿下来改了改。结果一用就是一年多,越用越摸透它的脾气,也越觉得这套“垃圾”方案在特定场景下其实非常能打。
这篇使用记录不是做广告,也不是劝退,就是把我在这个平台上从部署、推流、点播,到排查各种奇怪问题的完整过程写下来。如果你也在纠结“要不要用一个便宜甚至免费的方案来搭内部直播点播”,这篇东西应该能帮你省下不少时间。
1. 我为什么要给“垃圾平台”写一份使用记录
1.1 平台的来历:不是买的,是拼的
这个平台不是一个成熟商业产品,更像是一个开发者个人搞出来的开源项目,后端是PHP,直播转发层用了Nginx的RTMP模块,点播文件直接放服务器目录,数据库里连用户表都没有,后台只有一个简陋的API Key管理。我当时拿到手里第一反应是:这玩意儿能收到钱吗?界面粗糙,逻辑混乱,唯一的好处是部署特别简单,解压丢进Nginx的web目录,导入一个SQL文件,改两行配置就能跑起来。
因为交付时间紧,我没有时间从零开发一套管理后台,也不想花几万块去买商业系统。于是我就把它当成一个“底子很烂但能跑”的方案来用。我前后花了大概两个晚上,把它的播放器换成了更通用的hls.js,又给后台加了几行简单的上传进度显示,勉强看起来像一个正经系统了。如果你问我后不后悔,我的答案是:不后悔,但前提是你得清楚它是一台“手动挡汽车”,不是“自动驾驶”。
1.2 它在什么场景下确实能干活
我主要的应用场景有两个,一个是公司内部的月度技术分享直播,另一个是给新员工录制的产品培训点播视频。这两个场景的共同点是并发不高、视频数量不多、对播放体验要求中等。第一次用的时候,我没抱任何期望,结果一场四十多分钟的直播,全程没有断流,后台观看人数峰值到过一百多人,延迟大概在五秒左右,对内部会议来说完全能接受。
它真正适合的是那种“预算极低、又不想被云服务厂商绑定”的使用场景。比如你手头有一台2核4G的云服务器,带宽5Mbps,想做一个面向几十个人或者几百个人的视频服务,这个平台能吃的资源非常少,跑起来比很多商业平台还轻。但反过来,它的后遗症也很明显:没有自动转码队列、没有统计报表、没有回收站,任何文件删错就是真没了。所以你要是打算上这个方案,先问自己一句:我有没有精力去手动维护它的日常运转?
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 先摸清它的老底:功能模块和天生缺陷
2.1 实际功能就这三块:直播、点播、后台管理
别看界面简陋,它核心该有的链路倒是一个不少。直播方面,它支持RTMP推流,服务器收到流之后会自动切成HLS切片,生成一个m3u8地址供网页播放。整个过程中,Nginx负责接流和切片,PHP后台只负责在数据库里登记直播间信息,生成推流地址和播放地址。
点播方面就更简单了,你把MP4文件通过后台的上传表单扔到服务器,系统会按日期生成一个存储目录,然后再往数据库里插一条记录。播放的时候,后台会套一层防盗链参数,验证通过之后才能读到文件内容。说白了,它就是一个“带播放壳的文件管理器”,没有任何转码能力,你上传的是什么编码格式,播放器就得兼容什么编码格式。
后台管理是整个系统里最“凑合”的部分。它只有一个管理员账号,没有角色权限区分。所有直播和点播记录都堆在一个列表里,连搜索都没做。我后来实在受不了,自己写了一个几十行的PHP脚本,按日期和标题做模糊查询,才勉强能用。如果你对后台体验有要求,建议提前做好“自研补丁”的心理准备。
2.2 所谓“垃圾”的实锤:三个绕不过去的设计问题
第一个问题是没有自动转码。我一开始不懂,把一段用手机录的4K视频直接传上去,结果同事点开就卡。后来查了下,服务器的CPU根本扛不住浏览器对4K视频的软解。这个平台在这方面几乎是零考虑,它默认你上传什么就播什么。要解决这个问题,只能自己在服务器上装FFmpeg,定时跑转码任务,把大文件压成1080p甚至720p的H.264视频。
第二个问题是并发能力没有做任何保护机制。它的播放接口没有限流,也没有缓存策略。如果同时有几十个人点开同一个视频,Nginx会直接去磁盘读大文件,很容易把带宽打满。我把视频目录挂到系统盘之外,然后手动给m3u8的目录加了expires缓存头,情况才好了很多。
第三个问题是最让我头疼的:它没有任务队列,所有需要后台跑的操作,比如切片回收、临时文件清理、转码触发,全都依赖服务器上的crontab定时任务。一旦服务器重启,某些crontab项没自动起来,或者脚本里的路径写死了,整个系统的“自动维护”就会悄悄停摆,表面上还能播视频,实际上后台日志已经堆积如山了。这些问题单拎出来每一个都算不上大坑,但它们凑在一起,就构成了“垃圾”的全部理由。
3. 直播功能使用记录:从创建直播间到OBS推流
3.1 直播间创建与地址获取
直播间创建流程非常直接,进入后台,点“新建直播”,填一个标题、选一个分类,保存后会生成一组地址。这里要特别注意,它生成的是两套地址:一套是给OBS之类的推流软件用的RTMP地址,通常长这样:rtmp://你的域名:1935/live/直播ID?key=推流密钥;另一套是给观众用的播放地址,格式是http://你的域名:8080/live/直播ID.m3u8。
我强烈建议你拿到地址后立刻自己去浏览器里打开一次播放地址,因为很多新手在这一步就出问题了。比如服务器的防火墙没放行1935端口或者8080端口,推流地址和播放地址全都不通,后台却显示“直播已创建”。这种状态很迷惑人,你点“开始直播”,OBS显示连接成功,观众却什么都看不到。我的做法是在创建阶段就用telnet或者在线端口检测工具把端口全部扫一遍,确认两个端口都是通的,再同步给同事。
另外,这个平台的直播ID是自增数字,也就是说别人如果知道规律,可以猜到下一个直播间的地址。虽然播放地址里带了key参数可以验证,但早期的版本如果key为空就会放行,这个坑我必须标注一下:一定要确保每个直播间都生成强密钥,别图省事留空。
3.2 OBS推流参数和为什么建议软编
我用OBS推流半年多,踩了不少参数坑,最后固定下来一套稳如老狗的配置。先说视频编码,我选的软件编码器x264,码率控制在2.5Mbps,关键帧间隔设为2秒,这个间隔之所以重要,是因为HLS切片默认每一片也是2秒,如果你关键帧间隔和切片时长不一致,播放端可能会出现画面跳帧或者卡顿。
音频我用AAC编码,码率给128kbps,采样率44100Hz。这里有一个很容易被忽略的细节:如果你的直播素材里有网络播放的视频片段,声音采样率是48000Hz,OBS转换后偶尔会有爆音。我后来统一把OBS的音频采样率锁定在44100Hz,再用滤镜做标准化处理,问题就消失了。
分辨率方面,除非你讲的内容需要看Excel表格里的细节,否则我建议直接推1080p就行,不要碰2K或者4K。因为平台的HLS切片和播放都是单进程模式,高码率推流会把服务器的CPU打满,导致画面帧率下降,反而影响体验。我的旧服务器是2核4G,实测推1080p + 2.5Mbps,CPU占用率大约在50%到70%之间,还算能扛。
3.3 播放端接入的三种方式
观众看直播的时候,我们不强制安装任何App,直接用浏览器打开就行。最省事的接入方式是把播放地址放进一个网页里,用video标签配合hls.js就能播。如果你的播放器需要兼容IE这种老古董,可以再套一层video.js,但我不建议为了老浏览器牺牲性能,内网用户基本都换现代浏览器了。
第二种方式是直接在系统后台生成的“观看页”里播,这个页面自带简单的聊天窗口,但聊天数据只存在内存里,刷新就没了,实际体验非常勉强。我用过一次之后就再也不用了,只是把它作为没有前端开发能力时的兜底方案。
第三种方式是我自己定制的:不打开系统自带的观看页,而是写一个最小的HTML页面,只引入hls.js,通过JavaScript读取播放地址,初始化播放器,然后把这个页面挂在公司内部的导航站里。这样观众的使用路径短,页面打开快,就算直播平台后台挂了,这个页面依然可以从Nginx那里直接读取m3u8文件播放。这种方式把直播链路中“后台数据库”从播放链路里摘了出去,提升了稳定性。
4. 点播功能使用记录:上传、转码、播放全流程
4.1 上传约定与目录规范
点播文件上传是后台提供的表单功能,但因为它没有断点续传,也没有进度条,我直接用起来非常痛苦。后来我自己写了一个上传脚本,在服务器上开了一个共享目录,让同事把视频文件扔进去,再由我用rsync同步到正式的存储目录。
目录规划上,我按/data/vod/年份/月份/文件名这种结构存,方便后面定时清理。这里有一个切身体会:不管后台再怎么乱,文件目录一定要保持自己的习惯。因为系统数据库一旦出问题,恢复数据最直接的方式就是按目录把文件重新导入,这时候有规律的目录结构就是你的救命稻草。
上传之后,一定要检查文件权限。这个平台对文件可读性的要求很隐蔽,如果上传的MP4文件权限是644,Nginx的worker进程读不到,播放器会拿到404或者403。我的经验是统一chown给运行Nginx的用户,再chmod 644,然后写进部署文档里,避免大家各自上传后出现权限混乱。
4.2 转码任务触发机制与手动兜底
前面说了平台本身不转码,所以我自己在服务器上部署了一套转码脚本。核心脚本逻辑很简单,就是定期扫描一个“待转码”目录,发现MP4文件后就调用FFmpeg,把它转成H.264编码的MP4。命令大概是这样的:
bash复制ffmpeg -i input.mp4 -c:v libx264 -preset medium -crf 23 -s 1920x1080 \
-c:a aac -b:a 128k -movflags +faststart output.mp4
这里-preset medium是转码速度和压缩率的平衡,-crf 23是画质控制参数,数值越低画质越好但文件越大。我一般把原始视频保留在/data/vod/source/下,转码后的文件放到/data/vod/ready/下,这样即便转码出问题,原始文件还在,不会一损俱损。
转码脚本每半小时跑一次,用crontab触发。但这里就暴露了这个平台的“垃圾”属性:没有任务队列,如果同一时间有多个文件在转码,FFmpeg会一次性把所有任务都跑起来,直接把CPU打满。我后来在脚本里加了并发限制,同一时间只允许转两个文件:
bash复制wait_until_free() {
while [ "$(pgrep -c ffmpeg)" -ge 2 ]; do
sleep 5
done
}
转码完成之后,脚本会调用平台的入库接口,把这个文件的记录写进数据库,然后删除待转码目录里的原始文件。整个过程看起来很顺利,但我还是建议你隔几天就去服务器上看一眼ffmpeg进程是否正常退出,因为一旦遇到损坏的视频文件,FFmpeg可能会挂住不退出,占着进程不干活。
4.3 播放鉴权和防盗链的凑合方案
点播播放地址的鉴权逻辑很简单:后台生成一个带时间戳的签名,拼在文件路径后面,Nginx检查签名有效才返回文件。具体签名方式大致是md5(密钥 + 文件路径 + 过期时间),Nginx里用secure_link模块验证。
刚开始我根本没开防盗链,结果内网有人把点播链接发到外网去了,白白消耗了带宽。后来我把防盗链打开,并且把过期时间设成了6小时,这样既不影响同事白天下载观看,也能避免链接被无限转发。
如果你需要更严格的鉴权,比如只看五分钟预览,就需要自己写一个动态的播放链接生成接口。我在后台加了一个简单的play_token逻辑,每次用户点播放按钮时,向后端请求一个带当前用户名的临时链接,链接有效期两小时。虽然这个平台没有用户系统,但至少通过IP加时间戳的方式,把播放权限收敛到了一定范围内。
5. 实际跑起来踩过的坑:完整排查链路记录
5.1 直播画面卡成PPT:从播放端一路查到OBS推流端
有一次月度分享直播,开场五分钟就有同事反映画面卡成PPT,声音倒是正常的。我第一反应是服务器带宽不够,因为会议室有几十个人同时在看。
我先检查了服务器的实时带宽,用iftop看了下,流量只有不到10Mbps,按理说带宽瓶颈不至于。接着我去看Nginx的RTMP模块状态,在/rtmp_stat页面看到推流码率掉到了300Kbps左右,而OBS端设置的是2.5Mbps。这意味着推流端或者中间网络确实有问题,不是观看环节的带宽不够。
然后我让主讲人重启OBS,问题依旧。最后排查到主讲人的无线网络环境:他用的是公司访客WiFi,信号强度只有两格,上行速率不稳。我让他换到有线网络后,码率立刻恢复正常。这个坑给我最大的教训是:直播链路的问题,一定要从推流端往播放端查,而不是一卡就加带宽。先看推流状态,再看切片进程,最后才是出口带宽,顺序反了会浪费好几个小时。
5.2 点播视频打不开:排查路径让我怀疑人生
还有一次,同事反馈后台里新增的一个点播视频点开就转圈,永远加载不出来。我先看了文件在不在,确认文件躺在/data/vod/ready/下,大小也正常。然后用curl直接访问文件地址,发现返回200,但浏览器就是无法播放。
后来我打开ffprobe看了一眼文件流信息,发现这个视频是HEVC编码。平台没有转码能力,文件直接入库,而很多浏览器对HEVC支持很差,尤其内网Windows系统的Chrome,基本播不了。我只好去手动跑了一遍转码命令,把它转成H.264,然后播放恢复正常。
从这次之后,我把入库接口的脚本改成了“先探测编码格式,再决定是否转码”。只要发现视频编码不是h264,就拒绝直接入库,自动走转码流程。这会多花几分钟,但能避免后面用户看到黑屏或者转圈。
5.3 后台任务“假死”:定时任务为什么会悄悄掉链子
这个平台最坑的一次事故,是我发现直播的录像没有被自动清理,服务器磁盘被塞满了。原因是平台自带的一个清理脚本依赖服务器时间,它在每天凌晨3点执行,但服务器在某个时间点被重启过,NTP同步没起来,时间差了整整6个小时,导致脚本运行环境失效,日志里全是一堆错误。
这种问题用眼睛看不出来,表面上一且正常,只有磁盘爆了才发现。我的解决方案是给所有定时任务加了“心跳日志”,每个任务执行完都往/var/log/vod-platform/cron.log里写一行记录,并用logrotate按天切割。同时,我在服务器上多安排了一个磁盘空间监控脚本,使用率超过80%就发告警到钉钉群。有了这套兜底,清理任务再假死我都能第一时间知道。
6. 长期运维下来的心得:怎么让它从“垃圾”变得“够用”
6.1 写几个小脚本,把缺失的能力补回来
这个平台用了一年多,我用几个脚本把它缺的能力补了个七七八八。第一个是转码脚本,负责把上传的视频统一转成H.264编码;第二个是磁盘清理脚本,按日期删除超过30天的直播录像切片;第三个是链接检测脚本,定期扫描数据库里的播放链接,发现文件丢失就自动标记下线。
这几个脚本本身都不复杂,加起来不到两百行Shell。但它们解决的都是平台“不提供”的能力,相当于给一台只有底盘和发动机的车装上了方向盘和座椅。如果你决定用类似的方案,我的建议是先花一天时间把这些脚本写好,而不是等到出问题再临时补。临时补的脚本通常只会解决眼前问题,留不下长远价值。
6.2 花半天做的改造,让使用体验提升一大截
我到后期做了一次比较大的改造,把平台默认的播放页面整个换掉了。新页面还是用hls.js,但是加上了倍速播放、记忆播放进度、画中画,还支持点播目录按时间倒序排列。这些功能在后台上根本看不出来,但对使用者来说,体验提升非常明显。
改造过程中最花时间的不是写前端,而是梳理后台数据库里那些毫无意义的字段。我后来发现,很多字段在代码里根本没用到,纯粹是作者早期设计时预留的。所以我干脆用phpMyAdmin导出一份字段说明,把有用的字段标注出来,其余全部忽略。这件事做完之后,我再写任何对接脚本都不需要猜字段含义了。
6.3 说实话:哪些人千万别用这套方案
虽然我说这个“垃圾平台”能干活,但我还是得劝一部分人放弃。如果你需要一个稳定的大规模直播服务,比如上万人同时观看的线上发布会,别用它,直接用商业云直播;如果你需要完整的用户体系、付费点播、版权保护,也别用它,因为它连最基本的用户登录都要自己造轮子。
另外,如果你没有Linux服务器的基础知识,对Nginx、FFmpeg、crontab这些概念一头雾水,那你用这套方案会非常痛苦。它的运维门槛摆在那里,不是看一篇使用记录就能全部解决的。我个人更建议这类用户直接用SaaS服务,省心省力。
但如果你和我一样,手上有一台闲置服务器,需要给几十个内部同事折腾一套“能播就行”的视频直播点播平台,并且乐意花点时间去摸清它的脾气,那么这套方案绝对值得一试。它在资源占用、部署成本、可定制性上的优势,是很多商业系统给不了的。我到现在还在用着它,甚至还考虑过把它替换成更新的方案,但每次算完迁移成本,都觉得算了——毕竟它已经从一个“垃圾平台”,被我调教成了一个真的能扛事的工具。
