简介:EasyDarwin是一款基于标准HTTP/RTSP协议的开源流媒体服务器,这份Windows x86_64平台的v7.3.17.0325压缩包面向需要快速搭建视频直播、监控或转码服务的开发者和运维人员,也适合通过实际部署学习流媒体协议的学生与初级工程师。资源共1354个文件,整体约10.96MB,包含js、css、html等前端控制台页面,png、gif、svg等界面素材,以及xml、conf配置文件、exe主程序与bat服务脚本,目录结构清晰,便于按模块查阅与二次开发。目前已有1513人学习下载。除EasyDarwinServer.exe外,压缩包还带有Nginx相关配置、AdminLTE风格管理界面和多种格式的图标素材,内置安装与卸载服务脚本,可一键注册为Windows服务;支持H.264、MPEG-4、MJPEG等格式的流媒体接入,提供实时转码、多级转发、RESTful API及日志监控能力。配合ffmpeg推流、VLC拉流示例,可快速理解流发布与播放的完整链路,是在Windows环境入门流媒体服务器搭建与调试的实用资源。1. Windows 流媒体服务端:先跑起来,再谈优化做视频接入的工程师,多少都有过被 RTSP 拉流搞到怀疑人生的时刻:几十路摄像头要同时接入,前端还要 Web 端、小程序端和播放器端都能看,延时还不能太离谱。我之前图省事,拿 FFmpeg 脚本一条一条转推,进程管理一多就翻车;换了一套 Windows 平台的流媒体服务端压缩包之后,配置项直接写成服务,半小时跑通,后续维护也轻松很多。这套资源就是典型的 x86_64 版服务端,适合安防项目、直播转输和内部视频平台用。先跑通,再慢慢聊里面值得注意的坑。2. 解压、注册服务、确认端口:把压缩包变成能用的进程流媒体服务端和普通软件不一样,它不是打开 UI 就能用的工具,更像一个需要长期驻留的后台进程。所以拿到压缩包后的第一步,不是双击 exe 看界面,而是把目录结构、运行身份、服务注册三件事理清楚。2.1 先把目录结构和运行环境摸一遍下载下来的压缩包解压后,我先不看文档,而是把目录结构扫一遍。这套 Windows 服务端一般会分成几个固定职责的目录:可执行文件和启动脚本放在 bin 或根目录,配置放在 conf,日志输出到 logs,录像文件单独放 record。我的习惯是解压到不带空格和中文的纯路径下,比如D:\MediaServer,避免后面写脚本、配计划任务时被引号和编码坑到。cd /d D:\MediaServer dir /b :: 常规会看到 bin 或 conf 之类的目录说明:cd /d是切盘符并将工作目录切过去,dir /b只列出文件名和目录名,信息最干净。如果发现logs目录已经存在,说明之前至少成功启动过一次,已经写入了日志;如果只有一个空目录,大概率是首次运行前的初始状态。参数说明:路径可以换成你机器上任意目录,但注意两点:一是不要放系统盘根目录,权限问题多;二是路径中不要混用中英文引号。后续注册 Windows 服务的时候,binPath参数对空格非常敏感,路径带空格就得额外加引号转义,容易踩坑。运行环境方面,先确认系统是 x64:Windows Server 2016/2019/2022 或 Win10/11 都行,但系统必须是 64 位。如果机器上缺 Visual C++ 运行库,服务可能启动即失败,表现是事件日志里有0xc000007b之类的错误。所以我会先装一遍常用运行库,再启动服务。2.2 注册成 Windows 服务:开机自启与崩溃恢复有些版本的压缩包里带install.bat,可以一键注册服务;没有的话,用sc.exe手动注册也很快。我的建议是:不管有没有批处理,都尽量用服务方式跑,不要直接双击 exe。因为服务能设置开机自启、失败自动重启,配合计划任务能做到无人值守。cd D:\MediaServer # 如果有安装脚本,以管理员身份运行它 .\install.bat # 如果没有,就用 sc.exe 手动创建 sc.exe create streamserver binPath= "D:\MediaServer\streamserver.exe -d" start= auto逻辑说明:sc.exe create是 Windows 自带的服务注册命令,streamserver是服务名,binPath指向服务端可执行文件,-d表示以守护模式运行,让进程留在后台而不是占据一个控制台窗口。start= auto表示开机自启。参数说明:sc.exe的语法比较古老,=后面必须有一个空格,写成binPath="D:\..."会报参数格式错误。所以尽量照抄这种带空格的写法。服务名可以用任意字母数字串,但要和启动脚本里的名字保持一致,后面所有Start-Service/Stop-Service都用这个服务名。创建完服务后,统一用 PowerShell 管理:Start-Service streamserver Get-Service streamserver Restart-Service streamserver参数说明:Start-Service是立即启动,Get-Service查看状态,Restart-Service在修改配置后重启。如果你发现服务启动后又自动停止,先看日志文件,不要反复点启动,否则会积累一堆残留进程。2.3 端口和防火墙:拉流失败的第一个开关服务端跑起来以后,最常问的一句话是“服务在跑,为什么我的播放器拉不到流?”答案多半在端口。默认情况下,RTSP 监听一个端口,HTTP 管理端口用来出 HLS/HTTP-FLV 流和调 API。不同构建的默认值不完全一样,我一般直接打开配置文件里搜 port。配置项作用常见默认值备注HttpPort管理端口/API端口10008Web 播放地址也走这个RtspPortRTSP 拉流监听端口554 或 8554被占用就换高位端口HlsPortHLS/HTTP-FLV 端口复用 HttpPort一般不用单独开RecordPath录像文件存储目录record相对路径要注意修改配置后必须重启服务,这一步经常有人漏。重启后验证端口在监听:netstat -ano | findstr ":554" netstat -ano | findstr ":10008"逻辑说明:netstat -ano列出所有 TCP 连接的本地地址与 PID,findstr过滤出端口对应行。只要看到LISTENING状态,说明服务端已经在端口上监听了。参数说明:如果554被系统或其他软件占用,就改成8554,然后播放地址里的端口也要跟着改。很多局域网外的设备拉不到流,其实是 Windows 防火墙默认拦了入站规则。添加一条防火墙规则就能解决:New-NetFirewallRule -DisplayName "MediaServer-RTSP" -Direction Inbound -Protocol TCP -LocalPort 554,8554,10008 -Action Allow说明:这条命令同时开放三个 TCP 端口,LocalPort可以写多个,用逗号隔开。如果你所在公司网络有硬件防火墙,还要在出口设备上做端口映射或放行规则。端口是流媒体服务端的第一道关卡,我每次排查也是从netstat开始。3. 拉流转流配置实战:把 RTSP 摄像头变成 Web 端能播的地址服务端能跑,接下来就进入正题:把摄像头的 RTSP 流拉进来,再转成 Web、小程序能直接播放的协议。这一步涉及源端配置、输出协议选择和音频兼容性,最容易一手一脚踩雷。3.1 添加摄像头通道:RTSP 源地址保存与启用现在的摄像头基本都支持 RTSP 协议,地址格式通常是rtsp://用户名:密码@IP:端口/流路径。服务端要做的是主动去拉这个地址,而不是等播放器来才拉流。所以配置里最关键的是源地址、传输协议、是否启用三项。{ "name": "camera_01", "type": "rtsp", "url": "rtsp://username:password@192.168.10.20:554/stream1", "enabled": true, "protocol": "tcp" }逻辑说明:enabled置为 true 表示服务端启动后马上建立拉流连接,不需要等播放器来触发。protocol指定走 TCP 还是 UDP 拉流,我几乎全部用 TCP。UDP 在局域网可能挺快,但只要网络有丢包,画面就是花屏和马赛克,TCP 虽然稍微增加延时,但稳定得多。参数说明:URL 里的密码不能随意填。如果摄像头密码里包含@、:、/这类字符,必须做 URL 编码,否则服务端解析源地址时会把密码截断。比如@要写成%40。另外别把用户名密码明文写在前端播放地址里,播放器访问要用转出来的服务端地址,而不是直接暴露摄像头源地址。改完配置后,有的服务端支持热加载,有的需要重启。我的习惯是统一重启服务,然后去看日志或管理界面,确认通道状态从connecting变成online。如果一直是offline,先把源地址在 VLC 里播放一遍,确认摄像头本身能出流,再回来查服务端配置。3.2 转成 HLS 和 HTTP-FLV:不同端用不同协议拉流只是第一步,难点在输出。播放器不能直接播 RTSP,原生浏览器更是碰都不碰。所以服务端要同时输出多种协议:HTTP-FLV 给 Web 端用,HLS 给小程序和苹果端用,RTMP 给老牌播放器或推流平台用。我在模拟项目X里一般是同时开三种输出。{ "stream": "camera_01", "outputs": [ { "type": "http-flv", "enabled": true }, { "type": "hls", "enabled": true }, { "type": "rtmp", "enabled": false } ] }逻辑说明:这段配置告诉服务端把camera_01这一路流同时输出为 HTTP-FLV 和 HLS。HTTP-FLV 延时较低,适合走 Web 播放器的 flv.js;HLS 兼容性最好,小程序端基本都认它。RTMP 没用到就先关掉,省资源也少一条可能的端口冲突。播放地址通常长这样:HTTP-FLV:http://服务器IP:10008/live/camera_01.flvHLS:http://服务器IP:10008/live/camera_01.m3u8RTSP:rtsp://服务器IP:8554/camera_01参数说明:URL 中的live是应用名,camera_01是流名称,必须和配置里的通道名称对应。如果你改了通道名,播放地址也要同步改。端口写错是最常见的问题,尤其是 RTSP 端口如果改成 8554,播放地址不要还按默认 554 去写。3.3 音频编码兼容:画面正常但没声音,多半在这画面能出但没声音,是拉流转流里很隐蔽的坑。摄像头的音频编码通常是 AAC 或 G.711,G.711 在 HLS 里兼容性很差,很多播放器直接静音;HTTP-FLV 对音频采样率也有限制,44.1kHz 和 48kHz 之外可能出现音画不同步。我一般在服务端做一层轻量转码,只转音频,不碰视频,这样 CPU 压力小,又能保证播放端能出声。{ "transcode": { "video": "copy", "audio": "aac", "audio_bitrate": 96, "audio_sample_rate": 48000 } }逻辑说明:video设置为copy表示视频流不重新编码,直接拷贝到输出流,这是省 CPU 的关键;audio设置为aac表示把音频统一转成 AAC,兼容性最好。如果源流是 H.265,Web 播放器基本不支持,这时候video也要改成h264,但代价是 CPU 占用会明显上涨。参数说明:audio_bitrate设 96kbps 对普通监控对讲足够,如果音质要求高可以提到 128;audio_sample_rate固定 48000 能避开 FLV 分段时的采样率不匹配。转码不是越大越好,调研过的人都知道,不合理的全转码会把一台 8 核服务器拖到 80% 以上,所以能 copy 就 copy。4. 延时与并发调优:把延迟从秒级压到几百毫秒服务端跑通、能播放,并不代表能交付。监控类项目对延迟要求没那么苛刻,但直播或远程操控场景里,如果画面比现场慢两三秒,操作起来就很别扭。延迟来自一整条链路,不能只盯服务端一个点。4.1 链路瓶颈:延迟到底消耗在哪从摄像头到播放器,延迟至少分三段:摄像头编码缓存、服务端转发缓存、播放器缓冲。很多人在服务端调半天,结果发现是 VLC 默认缓存设了 1 秒,根本原因不在服务端。我的排查顺序是:先看摄像头 GOP,再看服务端缓存,最后看播放器缓冲。摄像头编码环节,关键参数是 GOP 长度,也就是两个关键帧之间的间隔。GOP 越大,编码效率越高,但流中间被切开时,播放器必须等到下一个关键帧才能出画面。如果摄像头 GOP 设成 4 秒,那无论服务端怎么调,首屏很难低于 4 秒。所以我建议把摄像头 GOP 调到 1 到 2 秒。服务端环节,关键参数是缓存区大小和协议缓冲区。有些服务端默认开很大的缓存来抗丢包,导致转发链路多加几十到几百毫秒。对局域网项目,这个缓存可以适当调小;对公网链路,不能一刀切。播放器环节,VLC、PotPlayer、hls.js 都有自己的缓冲策略。hls.js 默认会把 3 个分片缓冲完才开始播,这本身就带来一个分片时长的延迟。4.2 关键参数与推荐值我在模拟项目X里试过一组参数,局域网场景下能把 Web 端 HLS 延迟从大约 5 秒压到 2 秒以内,HTTP-FLV 可以控制在 1 秒以内。这组参数不保证所有服务端通用,但方向是对的。位置参数推荐值说明摄像头GOP 长度1-2 秒太长直接拖首屏摄像头编码码率2-4 Mbps过高会增加转发压力服务端RTSP 拉流协议TCP稳定,丢包少服务端缓存区大小512KB-1MB局域网可小,公网可略大服务端HLS 分片时长2 秒4 秒延迟会明显翻倍服务端HLS 分片数量3-6 个不要设 0 无限保留播放器缓冲策略低延迟模式关闭过大的自动缓冲服务端配置代码块示例:{ "rtsp": { "transport": "tcp", "cacheSizeInKB": 1024 }, "hls": { "segmentDuration": 2, "segmentCount": 6, "lowLatency": true } }逻辑说明:rtsp.transport决定拉流协议,tcp牺牲一点网络效率换取稳定性;cacheSizeInKB是服务端收到的音视频数据缓冲,越小延迟越低,但小到丢包时就会卡顿,所以局域网用 1024KB 起步,公网可以往上加。hls.segmentDuration是每个分片时长,2 秒让播放器拿到第一个分片后更快启动;lowLatency开启后服务端尽量在分片尚在写入时就通知播放器,属于 LL-HLS 的思路。参数说明:如果你发现改完这些参数后播放端反而卡顿,把cacheSizeInKB从 1024 提到 2048,优先保流畅,再回来看延迟。直播和监控的取舍不一样,监控宁可延时大一点,也不能花屏。4.3 实际测量:不要凭感觉调参数调优必须有数据。我一般用ffprobe读取播放流的起始时间,和当前系统时间做差,估算延迟。这个方法不精确,但足够判断趋势。ffprobe -v error -show_entries format=start_time -of default=noprint_wrappers=1 "http://127.0.0.1:10008/live/camera_01.flv"逻辑说明:start_time是流里的时间戳起点,如果这个值和当前时间差得很多,说明链路里有较大的缓冲。连续测三次,每次间隔十秒,如果start_time越来越落后,说明延迟在积累,问题大概率在 HLS 分片数量太多或播放器缓冲没清理。参数说明:-v error只输出错误信息,避免刷屏;-of default=noprint_wrappers=1让输出只留数值,方便脚本解析。实际使用时把 IP、端口、流名换成你自己的地址。局域网测一次,公网再测一次,能看出是网络延迟还是服务端缓冲的问题。5. 避坑实录:五个常见问题我全都踩过中间那几章讲的是标准配置,实际交付时真正耗时的是下面这些场景。每条都是我在真实环境里翻过车的记录,按“现象、原因、解决”三段写,照着排查能省很多时间。5.1 服务正在运行,但外网拉不到流现象:服务端本机用http://127.0.0.1:10008/live/camera_01.flv能正常播放,但另一台电脑、另一个办公室网络就是连不上。原因:绝大部分情况是 Windows 防火墙默认拦截入站端口,或者是公司出口路由没有做端口映射。服务端进程活着,不代表端口对外可达。解决:先用netstat -ano | findstr ":10008"确认端口在监听,然后添加防火墙入站规则。如果服务器在公网,还要在路由器或云安全组里放行对应端口。注意 HTTP-FLV 和管理端口一般同一个端口,不要只放 RTSP 端口而漏了 HTTP 端口。netstat -ano | findstr ":10008"说明:如果输出为空,说明服务端没在这个端口监听,先查配置;如果输出有LISTENING但外部不通,才去查防火墙和路由。5.2 RTSP 拉流时断时续,播放器频繁缓冲现象:刚接通时正常,过几十秒画面卡住,再等几秒又恢复,反反复复。查看服务端日志,发现拉流连接也在断开重连。原因:源摄像头默认走 UDP 传输,局域网有线还好,无线网络或者跨三层环境丢包严重,UDP 会把丢失的数据包直接丢弃,播放器拿不到完整视频帧。解决:把服务端拉流协议强制改成 TCP。在通道配置里设置protocol: "tcp",重启服务再看日志。VLC 里调试源地址时也加上rtsp_transport=tcp,确认不是摄像头端问题。{ "protocol": "tcp" }说明:这条配置放在对应通道的配置项里。部分服务端还支持udp_multicast,但安防场景少用,不推荐。改完如果还断,检查摄像头码率是不是超过网卡能力,或者网线/无线链路质量太差。5.3 Windows 休眠导致半夜流全部中断现象:白天一切正常,第二天早上发现所有通道离线,服务端进程还在,但录像文件从某个时间点起就没有新增了。原因:Windows 默认电源计划会在空闲一段时间后进入睡眠或休眠,网络适配器和 CPU 都被挂起,流媒体服务自然停止拉流。这是 Windows 服务器做流媒体服务最常见的坑。解决:把电源计划设置为高性能,禁用休眠和睡眠;同时把服务属性里的“恢复失败后自动重启”打开。powercfg /change standby-timeout-ac 0 powercfg /change hibernate-timeout-ac 0说明:standby-timeout-ac和hibernate-timeout-ac为 0 表示永不进入待机和休眠。也可以去控制面板“电源选项”里点选“从不”。如果服务器在机房,这个操作可以极大减少隔夜掉线的概率。5.4 HLS 播放延迟越来越大,画面越看越落后现象:刚打开播放页面时延迟很小,播放五分钟后再看,画面比实时慢了一分多钟,而且还在继续拉大。原因:播放器一直在累积缓冲。HLS 的机制是不断请求新的 m3u8 索引,如果播放器处理不过来,比如视频解码速度低于实时编码速度,它就在本地积压分片,导致延迟越来越大。服务端如果保留的分片数量无限,也会加剧。解决:服务端把 HLS 分片数量限制在 3 到 6 个,不要设 0 表示无限保留。播放器端使用hls.js时,把liveSyncDuration调小,让播放器尽可能追着直播边缘走。<script> const config = { liveSyncDuration: 3, liveMaxLatencyDuration: 10 }; if (Hls.isSupported()) { const hls = new Hls(config); hls.loadSource("http://ip:10008/live/camera_01.m3u8"); } </script>说明:liveSyncDuration设置播放器距离直播边缘的目标秒数,3 表示尽量只落后 3 秒;liveMaxLatencyDuration是最大容忍延迟,超过后播放器主动跳帧或重同步。这段代码适用于 hls.js 播放 HLS 场景,本地原生播放器可以忽略。5.5 录像文件没生成或只有 0KB现象:配置了录像存储,record目录也存在,但服务运行一段时间后发现没有录像文件,或者文件是 0KB,播放打不开。原因:服务以 Windows 服务方式运行时,默认账户可能是Local System,它对record目录没有写权限;或者配置里用的是相对路径record,服务的工作目录不在解压目录,写到了别的地方。解决:把录像目录配置成绝对路径,比如D:\MediaServer\record,然后给这个目录添加服务运行账户的写权限。也可以手动创建目录后,用icacls赋予权限。icacls D:\MediaServer\record /grant "NETWORK SERVICE:(OI)(CI)M"说明:NETWORK SERVICE是 Windows 服务常见的运行账户,(OI)(CI)表示对文件和子目录都继承权限,M表示修改权限。如果服务运行账户配置成了本地管理员,也可以直接授权给Everyone或Users,但安全起见只给服务账户权限更好。改完权限后重启服务,再等待一小段时间查看录像文件是否开始写入。6. 进阶验证:用 API 做设备巡检与自动重启服务端稳定运行后,我一般会用它的管理 API 写一个小巡检脚本,代替人工每天去看页面。管理 API 通常能拿到通道在线状态、流统计信息、录像记录,这些数据足够做三层判断:通道全部在线说明拉流正常,有离线说明摄像头或网络有问题,进程不见了说明服务端本身挂了。curl http://127.0.0.1:10008/api/v1/streams逻辑说明:这条命令从管理 API 拉取所有流通道的列表和状态。返回结果通常是 JSON 数组,里面每个元素包含流名称、在线状态、拉流地址等信息。如果 API 路径不同,看服务端自带的接口文档,一般会在配置文件的http部分标出。拿到接口数据后,配合 PowerShell 做一个最简单的自动巡检:统计离线通道数,超过阈值就重启服务端,并写入 Windows 事件日志,方便回头排查。$r = Invoke-RestMethod "http://127.0.0.1:10008/api/v1/streams" $offline = $r | Where-Object { $_.status -eq "offline" } if ($offline.Count -gt 3) { Write-EventLog -LogName Application -Source MediaServer -EventId 1001 -EntryType Warning -Message "离线通道超过3路,重启服务" Restart-Service streamserver }说明:Invoke-RestMethod会把返回 JSON 转成 PowerShell 对象,$_ .status是每条流的在线状态。离线数量超过 3 时触发重启,阈值可以根据项目规模调整。重启服务后,还要等一段时间再看 API,确认通道恢复了。不要无脑重启,要先看是单路离线还是全部离线,全部离线才可能是服务端崩溃。上线前我还会强制走一遍验证清单:端口监听是否正常、摄像头源流能否拉通、HLS 和 HTTP-FLV 两种播放地址是否可播、录像文件是否落盘、外网端口是否通。从那以后,每次交付这套服务端,我都会把电源休眠、服务自动重启、端口防火墙三件事先钉死,再谈优化,省去了大量半夜被叫起来处理的麻烦。希望帮到你。本文还有配套的精品资源,点击获取
简介:EasyDarwin是一款基于标准HTTP/RTSP协议的开源流媒体服务器,这份Windows x86_64平台的v7.3.17.0325压缩包面向需要快速搭建视频直播、监控或转码服务的开发者和运维人员,也适合通过实际部署学习流媒体协议的学生与初级工程师。资源共1354个文件,整体约10.96MB,包含js、css、html等前端控制台页面,png、gif、svg等界面素材,以及xml、conf配置文件、exe主程序与bat服务脚本,目录结构清晰,便于按模块查阅与二次开发。目前已有1513人学习下载。除EasyDarwinServer.exe外,压缩包还带有Nginx相关配置、AdminLTE风格管理界面和多种格式的图标素材,内置安装与卸载服务脚本,可一键注册为Windows服务;支持H.264、MPEG-4、MJPEG等格式的流媒体接入,提供实时转码、多级转发、RESTful API及日志监控能力。配合ffmpeg推流、VLC拉流示例,可快速理解流发布与播放的完整链路,是在Windows环境入门流媒体服务器搭建与调试的实用资源。1. Windows 流媒体服务端:先跑起来,再谈优化做视频接入的工程师,多少都有过被 RTSP 拉流搞到怀疑人生的时刻:几十路摄像头要同时接入,前端还要 Web 端、小程序端和播放器端都能看,延时还不能太离谱。我之前图省事,拿 FFmpeg 脚本一条一条转推,进程管理一多就翻车;换了一套 Windows 平台的流媒体服务端压缩包之后,配置项直接写成服务,半小时跑通,后续维护也轻松很多。这套资源就是典型的 x86_64 版服务端,适合安防项目、直播转输和内部视频平台用。先跑通,再慢慢聊里面值得注意的坑。2. 解压、注册服务、确认端口:把压缩包变成能用的进程流媒体服务端和普通软件不一样,它不是打开 UI 就能用的工具,更像一个需要长期驻留的后台进程。所以拿到压缩包后的第一步,不是双击 exe 看界面,而是把目录结构、运行身份、服务注册三件事理清楚。2.1 先把目录结构和运行环境摸一遍下载下来的压缩包解压后,我先不看文档,而是把目录结构扫一遍。这套 Windows 服务端一般会分成几个固定职责的目录:可执行文件和启动脚本放在 bin 或根目录,配置放在 conf,日志输出到 logs,录像文件单独放 record。我的习惯是解压到不带空格和中文的纯路径下,比如D:\MediaServer,避免后面写脚本、配计划任务时被引号和编码坑到。cd /d D:\MediaServer dir /b :: 常规会看到 bin 或 conf 之类的目录说明:cd /d是切盘符并将工作目录切过去,dir /b只列出文件名和目录名,信息最干净。如果发现logs目录已经存在,说明之前至少成功启动过一次,已经写入了日志;如果只有一个空目录,大概率是首次运行前的初始状态。参数说明:路径可以换成你机器上任意目录,但注意两点:一是不要放系统盘根目录,权限问题多;二是路径中不要混用中英文引号。后续注册 Windows 服务的时候,binPath参数对空格非常敏感,路径带空格就得额外加引号转义,容易踩坑。运行环境方面,先确认系统是 x64:Windows Server 2016/2019/2022 或 Win10/11 都行,但系统必须是 64 位。如果机器上缺 Visual C++ 运行库,服务可能启动即失败,表现是事件日志里有0xc000007b之类的错误。所以我会先装一遍常用运行库,再启动服务。2.2 注册成 Windows 服务:开机自启与崩溃恢复有些版本的压缩包里带install.bat,可以一键注册服务;没有的话,用sc.exe手动注册也很快。我的建议是:不管有没有批处理,都尽量用服务方式跑,不要直接双击 exe。因为服务能设置开机自启、失败自动重启,配合计划任务能做到无人值守。cd D:\MediaServer # 如果有安装脚本,以管理员身份运行它 .\install.bat # 如果没有,就用 sc.exe 手动创建 sc.exe create streamserver binPath= "D:\MediaServer\streamserver.exe -d" start= auto逻辑说明:sc.exe create是 Windows 自带的服务注册命令,streamserver是服务名,binPath指向服务端可执行文件,-d表示以守护模式运行,让进程留在后台而不是占据一个控制台窗口。start= auto表示开机自启。参数说明:sc.exe的语法比较古老,=后面必须有一个空格,写成binPath="D:\..."会报参数格式错误。所以尽量照抄这种带空格的写法。服务名可以用任意字母数字串,但要和启动脚本里的名字保持一致,后面所有Start-Service/Stop-Service都用这个服务名。创建完服务后,统一用 PowerShell 管理:Start-Service streamserver Get-Service streamserver Restart-Service streamserver参数说明:Start-Service是立即启动,Get-Service查看状态,Restart-Service在修改配置后重启。如果你发现服务启动后又自动停止,先看日志文件,不要反复点启动,否则会积累一堆残留进程。2.3 端口和防火墙:拉流失败的第一个开关服务端跑起来以后,最常问的一句话是“服务在跑,为什么我的播放器拉不到流?”答案多半在端口。默认情况下,RTSP 监听一个端口,HTTP 管理端口用来出 HLS/HTTP-FLV 流和调 API。不同构建的默认值不完全一样,我一般直接打开配置文件里搜 port。配置项作用常见默认值备注HttpPort管理端口/API端口10008Web 播放地址也走这个RtspPortRTSP 拉流监听端口554 或 8554被占用就换高位端口HlsPortHLS/HTTP-FLV 端口复用 HttpPort一般不用单独开RecordPath录像文件存储目录record相对路径要注意修改配置后必须重启服务,这一步经常有人漏。重启后验证端口在监听:netstat -ano | findstr ":554" netstat -ano | findstr ":10008"逻辑说明:netstat -ano列出所有 TCP 连接的本地地址与 PID,findstr过滤出端口对应行。只要看到LISTENING状态,说明服务端已经在端口上监听了。参数说明:如果554被系统或其他软件占用,就改成8554,然后播放地址里的端口也要跟着改。很多局域网外的设备拉不到流,其实是 Windows 防火墙默认拦了入站规则。添加一条防火墙规则就能解决:New-NetFirewallRule -DisplayName "MediaServer-RTSP" -Direction Inbound -Protocol TCP -LocalPort 554,8554,10008 -Action Allow说明:这条命令同时开放三个 TCP 端口,LocalPort可以写多个,用逗号隔开。如果你所在公司网络有硬件防火墙,还要在出口设备上做端口映射或放行规则。端口是流媒体服务端的第一道关卡,我每次排查也是从netstat开始。3. 拉流转流配置实战:把 RTSP 摄像头变成 Web 端能播的地址服务端能跑,接下来就进入正题:把摄像头的 RTSP 流拉进来,再转成 Web、小程序能直接播放的协议。这一步涉及源端配置、输出协议选择和音频兼容性,最容易一手一脚踩雷。3.1 添加摄像头通道:RTSP 源地址保存与启用现在的摄像头基本都支持 RTSP 协议,地址格式通常是rtsp://用户名:密码@IP:端口/流路径。服务端要做的是主动去拉这个地址,而不是等播放器来才拉流。所以配置里最关键的是源地址、传输协议、是否启用三项。{ "name": "camera_01", "type": "rtsp", "url": "rtsp://username:password@192.168.10.20:554/stream1", "enabled": true, "protocol": "tcp" }逻辑说明:enabled置为 true 表示服务端启动后马上建立拉流连接,不需要等播放器来触发。protocol指定走 TCP 还是 UDP 拉流,我几乎全部用 TCP。UDP 在局域网可能挺快,但只要网络有丢包,画面就是花屏和马赛克,TCP 虽然稍微增加延时,但稳定得多。参数说明:URL 里的密码不能随意填。如果摄像头密码里包含@、:、/这类字符,必须做 URL 编码,否则服务端解析源地址时会把密码截断。比如@要写成%40。另外别把用户名密码明文写在前端播放地址里,播放器访问要用转出来的服务端地址,而不是直接暴露摄像头源地址。改完配置后,有的服务端支持热加载,有的需要重启。我的习惯是统一重启服务,然后去看日志或管理界面,确认通道状态从connecting变成online。如果一直是offline,先把源地址在 VLC 里播放一遍,确认摄像头本身能出流,再回来查服务端配置。3.2 转成 HLS 和 HTTP-FLV:不同端用不同协议拉流只是第一步,难点在输出。播放器不能直接播 RTSP,原生浏览器更是碰都不碰。所以服务端要同时输出多种协议:HTTP-FLV 给 Web 端用,HLS 给小程序和苹果端用,RTMP 给老牌播放器或推流平台用。我在模拟项目X里一般是同时开三种输出。{ "stream": "camera_01", "outputs": [ { "type": "http-flv", "enabled": true }, { "type": "hls", "enabled": true }, { "type": "rtmp", "enabled": false } ] }逻辑说明:这段配置告诉服务端把camera_01这一路流同时输出为 HTTP-FLV 和 HLS。HTTP-FLV 延时较低,适合走 Web 播放器的 flv.js;HLS 兼容性最好,小程序端基本都认它。RTMP 没用到就先关掉,省资源也少一条可能的端口冲突。播放地址通常长这样:HTTP-FLV:http://服务器IP:10008/live/camera_01.flvHLS:http://服务器IP:10008/live/camera_01.m3u8RTSP:rtsp://服务器IP:8554/camera_01参数说明:URL 中的live是应用名,camera_01是流名称,必须和配置里的通道名称对应。如果你改了通道名,播放地址也要同步改。端口写错是最常见的问题,尤其是 RTSP 端口如果改成 8554,播放地址不要还按默认 554 去写。3.3 音频编码兼容:画面正常但没声音,多半在这画面能出但没声音,是拉流转流里很隐蔽的坑。摄像头的音频编码通常是 AAC 或 G.711,G.711 在 HLS 里兼容性很差,很多播放器直接静音;HTTP-FLV 对音频采样率也有限制,44.1kHz 和 48kHz 之外可能出现音画不同步。我一般在服务端做一层轻量转码,只转音频,不碰视频,这样 CPU 压力小,又能保证播放端能出声。{ "transcode": { "video": "copy", "audio": "aac", "audio_bitrate": 96, "audio_sample_rate": 48000 } }逻辑说明:video设置为copy表示视频流不重新编码,直接拷贝到输出流,这是省 CPU 的关键;audio设置为aac表示把音频统一转成 AAC,兼容性最好。如果源流是 H.265,Web 播放器基本不支持,这时候video也要改成h264,但代价是 CPU 占用会明显上涨。参数说明:audio_bitrate设 96kbps 对普通监控对讲足够,如果音质要求高可以提到 128;audio_sample_rate固定 48000 能避开 FLV 分段时的采样率不匹配。转码不是越大越好,调研过的人都知道,不合理的全转码会把一台 8 核服务器拖到 80% 以上,所以能 copy 就 copy。4. 延时与并发调优:把延迟从秒级压到几百毫秒服务端跑通、能播放,并不代表能交付。监控类项目对延迟要求没那么苛刻,但直播或远程操控场景里,如果画面比现场慢两三秒,操作起来就很别扭。延迟来自一整条链路,不能只盯服务端一个点。4.1 链路瓶颈:延迟到底消耗在哪从摄像头到播放器,延迟至少分三段:摄像头编码缓存、服务端转发缓存、播放器缓冲。很多人在服务端调半天,结果发现是 VLC 默认缓存设了 1 秒,根本原因不在服务端。我的排查顺序是:先看摄像头 GOP,再看服务端缓存,最后看播放器缓冲。摄像头编码环节,关键参数是 GOP 长度,也就是两个关键帧之间的间隔。GOP 越大,编码效率越高,但流中间被切开时,播放器必须等到下一个关键帧才能出画面。如果摄像头 GOP 设成 4 秒,那无论服务端怎么调,首屏很难低于 4 秒。所以我建议把摄像头 GOP 调到 1 到 2 秒。服务端环节,关键参数是缓存区大小和协议缓冲区。有些服务端默认开很大的缓存来抗丢包,导致转发链路多加几十到几百毫秒。对局域网项目,这个缓存可以适当调小;对公网链路,不能一刀切。播放器环节,VLC、PotPlayer、hls.js 都有自己的缓冲策略。hls.js 默认会把 3 个分片缓冲完才开始播,这本身就带来一个分片时长的延迟。4.2 关键参数与推荐值我在模拟项目X里试过一组参数,局域网场景下能把 Web 端 HLS 延迟从大约 5 秒压到 2 秒以内,HTTP-FLV 可以控制在 1 秒以内。这组参数不保证所有服务端通用,但方向是对的。位置参数推荐值说明摄像头GOP 长度1-2 秒太长直接拖首屏摄像头编码码率2-4 Mbps过高会增加转发压力服务端RTSP 拉流协议TCP稳定,丢包少服务端缓存区大小512KB-1MB局域网可小,公网可略大服务端HLS 分片时长2 秒4 秒延迟会明显翻倍服务端HLS 分片数量3-6 个不要设 0 无限保留播放器缓冲策略低延迟模式关闭过大的自动缓冲服务端配置代码块示例:{ "rtsp": { "transport": "tcp", "cacheSizeInKB": 1024 }, "hls": { "segmentDuration": 2, "segmentCount": 6, "lowLatency": true } }逻辑说明:rtsp.transport决定拉流协议,tcp牺牲一点网络效率换取稳定性;cacheSizeInKB是服务端收到的音视频数据缓冲,越小延迟越低,但小到丢包时就会卡顿,所以局域网用 1024KB 起步,公网可以往上加。hls.segmentDuration是每个分片时长,2 秒让播放器拿到第一个分片后更快启动;lowLatency开启后服务端尽量在分片尚在写入时就通知播放器,属于 LL-HLS 的思路。参数说明:如果你发现改完这些参数后播放端反而卡顿,把cacheSizeInKB从 1024 提到 2048,优先保流畅,再回来看延迟。直播和监控的取舍不一样,监控宁可延时大一点,也不能花屏。4.3 实际测量:不要凭感觉调参数调优必须有数据。我一般用ffprobe读取播放流的起始时间,和当前系统时间做差,估算延迟。这个方法不精确,但足够判断趋势。ffprobe -v error -show_entries format=start_time -of default=noprint_wrappers=1 "http://127.0.0.1:10008/live/camera_01.flv"逻辑说明:start_time是流里的时间戳起点,如果这个值和当前时间差得很多,说明链路里有较大的缓冲。连续测三次,每次间隔十秒,如果start_time越来越落后,说明延迟在积累,问题大概率在 HLS 分片数量太多或播放器缓冲没清理。参数说明:-v error只输出错误信息,避免刷屏;-of default=noprint_wrappers=1让输出只留数值,方便脚本解析。实际使用时把 IP、端口、流名换成你自己的地址。局域网测一次,公网再测一次,能看出是网络延迟还是服务端缓冲的问题。5. 避坑实录:五个常见问题我全都踩过中间那几章讲的是标准配置,实际交付时真正耗时的是下面这些场景。每条都是我在真实环境里翻过车的记录,按“现象、原因、解决”三段写,照着排查能省很多时间。5.1 服务正在运行,但外网拉不到流现象:服务端本机用http://127.0.0.1:10008/live/camera_01.flv能正常播放,但另一台电脑、另一个办公室网络就是连不上。原因:绝大部分情况是 Windows 防火墙默认拦截入站端口,或者是公司出口路由没有做端口映射。服务端进程活着,不代表端口对外可达。解决:先用netstat -ano | findstr ":10008"确认端口在监听,然后添加防火墙入站规则。如果服务器在公网,还要在路由器或云安全组里放行对应端口。注意 HTTP-FLV 和管理端口一般同一个端口,不要只放 RTSP 端口而漏了 HTTP 端口。netstat -ano | findstr ":10008"说明:如果输出为空,说明服务端没在这个端口监听,先查配置;如果输出有LISTENING但外部不通,才去查防火墙和路由。5.2 RTSP 拉流时断时续,播放器频繁缓冲现象:刚接通时正常,过几十秒画面卡住,再等几秒又恢复,反反复复。查看服务端日志,发现拉流连接也在断开重连。原因:源摄像头默认走 UDP 传输,局域网有线还好,无线网络或者跨三层环境丢包严重,UDP 会把丢失的数据包直接丢弃,播放器拿不到完整视频帧。解决:把服务端拉流协议强制改成 TCP。在通道配置里设置protocol: "tcp",重启服务再看日志。VLC 里调试源地址时也加上rtsp_transport=tcp,确认不是摄像头端问题。{ "protocol": "tcp" }说明:这条配置放在对应通道的配置项里。部分服务端还支持udp_multicast,但安防场景少用,不推荐。改完如果还断,检查摄像头码率是不是超过网卡能力,或者网线/无线链路质量太差。5.3 Windows 休眠导致半夜流全部中断现象:白天一切正常,第二天早上发现所有通道离线,服务端进程还在,但录像文件从某个时间点起就没有新增了。原因:Windows 默认电源计划会在空闲一段时间后进入睡眠或休眠,网络适配器和 CPU 都被挂起,流媒体服务自然停止拉流。这是 Windows 服务器做流媒体服务最常见的坑。解决:把电源计划设置为高性能,禁用休眠和睡眠;同时把服务属性里的“恢复失败后自动重启”打开。powercfg /change standby-timeout-ac 0 powercfg /change hibernate-timeout-ac 0说明:standby-timeout-ac和hibernate-timeout-ac为 0 表示永不进入待机和休眠。也可以去控制面板“电源选项”里点选“从不”。如果服务器在机房,这个操作可以极大减少隔夜掉线的概率。5.4 HLS 播放延迟越来越大,画面越看越落后现象:刚打开播放页面时延迟很小,播放五分钟后再看,画面比实时慢了一分多钟,而且还在继续拉大。原因:播放器一直在累积缓冲。HLS 的机制是不断请求新的 m3u8 索引,如果播放器处理不过来,比如视频解码速度低于实时编码速度,它就在本地积压分片,导致延迟越来越大。服务端如果保留的分片数量无限,也会加剧。解决:服务端把 HLS 分片数量限制在 3 到 6 个,不要设 0 表示无限保留。播放器端使用hls.js时,把liveSyncDuration调小,让播放器尽可能追着直播边缘走。<script> const config = { liveSyncDuration: 3, liveMaxLatencyDuration: 10 }; if (Hls.isSupported()) { const hls = new Hls(config); hls.loadSource("http://ip:10008/live/camera_01.m3u8"); } </script>说明:liveSyncDuration设置播放器距离直播边缘的目标秒数,3 表示尽量只落后 3 秒;liveMaxLatencyDuration是最大容忍延迟,超过后播放器主动跳帧或重同步。这段代码适用于 hls.js 播放 HLS 场景,本地原生播放器可以忽略。5.5 录像文件没生成或只有 0KB现象:配置了录像存储,record目录也存在,但服务运行一段时间后发现没有录像文件,或者文件是 0KB,播放打不开。原因:服务以 Windows 服务方式运行时,默认账户可能是Local System,它对record目录没有写权限;或者配置里用的是相对路径record,服务的工作目录不在解压目录,写到了别的地方。解决:把录像目录配置成绝对路径,比如D:\MediaServer\record,然后给这个目录添加服务运行账户的写权限。也可以手动创建目录后,用icacls赋予权限。icacls D:\MediaServer\record /grant "NETWORK SERVICE:(OI)(CI)M"说明:NETWORK SERVICE是 Windows 服务常见的运行账户,(OI)(CI)表示对文件和子目录都继承权限,M表示修改权限。如果服务运行账户配置成了本地管理员,也可以直接授权给Everyone或Users,但安全起见只给服务账户权限更好。改完权限后重启服务,再等待一小段时间查看录像文件是否开始写入。6. 进阶验证:用 API 做设备巡检与自动重启服务端稳定运行后,我一般会用它的管理 API 写一个小巡检脚本,代替人工每天去看页面。管理 API 通常能拿到通道在线状态、流统计信息、录像记录,这些数据足够做三层判断:通道全部在线说明拉流正常,有离线说明摄像头或网络有问题,进程不见了说明服务端本身挂了。curl http://127.0.0.1:10008/api/v1/streams逻辑说明:这条命令从管理 API 拉取所有流通道的列表和状态。返回结果通常是 JSON 数组,里面每个元素包含流名称、在线状态、拉流地址等信息。如果 API 路径不同,看服务端自带的接口文档,一般会在配置文件的http部分标出。拿到接口数据后,配合 PowerShell 做一个最简单的自动巡检:统计离线通道数,超过阈值就重启服务端,并写入 Windows 事件日志,方便回头排查。$r = Invoke-RestMethod "http://127.0.0.1:10008/api/v1/streams" $offline = $r | Where-Object { $_.status -eq "offline" } if ($offline.Count -gt 3) { Write-EventLog -LogName Application -Source MediaServer -EventId 1001 -EntryType Warning -Message "离线通道超过3路,重启服务" Restart-Service streamserver }说明:Invoke-RestMethod会把返回 JSON 转成 PowerShell 对象,$_ .status是每条流的在线状态。离线数量超过 3 时触发重启,阈值可以根据项目规模调整。重启服务后,还要等一段时间再看 API,确认通道恢复了。不要无脑重启,要先看是单路离线还是全部离线,全部离线才可能是服务端崩溃。上线前我还会强制走一遍验证清单:端口监听是否正常、摄像头源流能否拉通、HLS 和 HTTP-FLV 两种播放地址是否可播、录像文件是否落盘、外网端口是否通。从那以后,每次交付这套服务端,我都会把电源休眠、服务自动重启、端口防火墙三件事先钉死,再谈优化,省去了大量半夜被叫起来处理的麻烦。希望帮到你。本文还有配套的精品资源,点击获取