🎬 第二章 VLC播放器及二次开发应用
📄 一句话概括

「打开网络串流」填的是一个地址,背后决定体验的却是一个数字:缓冲毫秒数。 它买的是「抗抖动」,付的是「起播时间」。

📝 本节和前面几节的关系

上一节把 VLC 的功能列成四个出口,这一节专讲「从网络收进来」这一侧。 第一章讲过传输方式与协议,那是「数据怎么来」;这一节讲「来了之后先攒多少」。 协议细节看 🎬 流媒体直播原理及应用。

一、三种打开方式

VLC 里打开网络流有三个入口,效果一样: 菜单「媒体 → 打开网络串流」,粘贴地址。 快捷键 Ctrl+N。 直接把地址拖进窗口,或者命令行 vlc 地址。

地址的形态决定它走哪条协议:

地址形态 走的协议 典型场景
http://…m3u8 HLS 直播、点播分发
http://…flv HTTP-FLV 低延迟直播
rtmp://… RTMP 推流地址(VLC 也能拉)
rtsp://… RTSP 监控摄像头
udp://@239.… UDP 组播 企业内网、IPTV

注意最后一行那个 @:udp://@239.1.1.1:1234 里的 @ 表示「加入这个组播组」, 不带 @ 是「监听这个端口」。 这个符号是 VLC 自己的约定,不是标准 URL 语法,所以别的软件不认。

二、缓冲到底在缓什么

网络送来的数据不是匀速的:TCP 会一阵一阵地给(窗口、拥塞控制),UDP 更是可能连续丢一片。 而播放要求匀速。

缓冲区就是那个「把不匀速变成匀速」的水箱:进水忽快忽慢,出水必须稳定,中间靠水位吸收波动。

水位由两个数决定: 缓冲时长:水箱里至少存多少秒的内容才开始放。 到达速率:进水比出水快,水位才涨得起来。

第二个条件常被忽略:如果网络只有 80 KB/s,而片子要 120 KB/s, 那么水位永远涨不到目标值,播放器会一直转圈。 这时候把缓冲调大只会让用户等更久,不会让它播出来。

demo 里量了这个关系:缓冲 1000 毫秒要攒 8593 字节,在 100 KB/s 的到达速率下只要 0.08 秒; 而抗断流的能力正好等于缓冲时长本身。

三、VLC 的默认值是多少

图形界面里那个「缓冲」默认是 1000 毫秒。 命令行里对应 --network-caching=1000。

这个默认值有它的时代背景:VLC 诞生时主流是 ADSL 与 WiFi-G,抖动大, 1000 毫秒是「大多数时候够用、又不至于等太久」的折中。

今天它明显偏保守:局域网里 1000 毫秒纯属多余(可以设 100 到 200), 跨国链路上又常常不够(要设 3000 以上)。所以真正的产品都会把这个值做成「可调且自适应」。

还有一组相关的参数容易混:

参数 管什么 默认
network-caching 网络流的缓冲毫秒 1000
live-caching 采集设备的缓冲 300
file-caching 本地文件的缓冲 300
disc-caching 光盘的缓冲 300

分开设是有道理的:网络抖动大、文件几乎不抖,用同一个值会让本地播放也白等一秒。

四、为什么有时候越调越卡

很多人遇到过:卡顿,于是把缓冲调大,结果更卡。 这不是错觉,原因有两个。

原因一:缓冲大,seek 就迟钝。你拖进度条,播放器要清空一大箱水再重新灌, 这一下就是好几秒的等待。

原因二:缓冲大,掩盖了真正的问题。网络带宽本来就不够(到达速率低于码率), 调大缓冲只是把「卡在开头」变成「卡在半路」——因为水箱早晚会见底。

正确的诊断顺序是: 先看「到达速率 vs 码率」,不够就是带宽问题,调缓冲没用。 够的话再看抖动:偶尔断一下,就调大缓冲。 如果是持续的小幅断续,问题可能在丢包与重传,不在缓冲。

一句话:缓冲治的是「抖动」,治不了「带宽不足」。 先分清是哪一种,再动手调。

五、动手 Demo:缓冲区是拿起播时间换抗抖动

这段拿一个真实文件算出平均字节率,再按四种缓冲设置算「要攒多久」与「能扛多久断流」。 两列放一起看,才看得出这是个交换。

size = os.path.getsize(p)
dur = 150 / 30.0
bps = size / dur

for ms in (200, 1000, 3000, 5000):
    need = bps * ms / 1000.0        # 要攒的字节
    T([u"%d 毫秒" % ms, u"%.0f" % need,
       u"%.2f 秒" % (need / (100 * 1024.0)),
       u"%.1f 秒" % (ms / 1000.0)], [0, 0, 0, 0])

实跑输出:

--------------------------------------------------------------------
缓冲区是拿起播时间换抗抖动
--------------------------------------------------------------------
**打开网络串流时那个「缓冲」毫秒数,本质是「先攒多少秒的内容再开始播」。**
**攒得越多,越不怕网络抖;但起播也越慢。**

  测试片 42966 字节、5.0 秒,平均 **8593 字节每秒**。
  **注意这个码率低得离谱**——测试片画面极简,只有几十 kbps。真实 1080p 是它的两百多倍,
  所以下面那些「攒够要多久」在真实场景里要放大两个数量级。

**假设数据以每秒 100 KB 的速度到达**(比片子的码率高,所以能追上):

  缓冲设置      要攒的字节     攒够要多久     能扛多久断流
  ------------------------------------------------------------
  200 毫秒      1719           0.02 秒        0.2 秒
  1000 毫秒     8593           0.08 秒        1.0 秒
  3000 毫秒     25780          0.25 秒        3.0 秒
  5000 毫秒     42966          0.42 秒        5.0 秒

**看最后两列的关系**:**「攒够要多久」是起播延迟,「能扛多久断流」等于缓冲时长本身。**
  缓冲设 200 毫秒:起播快,但网络断半秒就卡。
  缓冲设 5 秒:断五秒都不怕,但点开要等好几秒。

**VLC 的默认值是 1000 毫秒**,
这是个折中——**局域网里显得多余,跨国链路上又不够。**所以真正做产品时这个值要能调,
而且最好能自适应。

**还有一个常被忽略的点**:
**缓冲区只能在「到达速率高于码率」时攒起来。**如果网络只有 80 KB/s 而片子要 120 KB/s,
**缓冲永远攒不满,播放器会一直转圈直到超时**——这时候调大缓冲只会让用户等更久。

这段测试片的码率只有几十 kbps,因为它画面极简、libx264 几乎不用花比特。 所以「攒够要多久」那一列小得不真实。

真实 1080p 按 5 Mbps 算,1000 毫秒就要攒 625 KB,在 8 Mbps 的家宽上也要 0.6 秒才攒够。 这就是为什么 4K 直播的起播总要等好几秒——码率越高,同样时长的缓冲越难攒满。

最后一行那个关系值得单独记:「能扛多久断流」在数值上就等于「缓冲时长」。缓冲 3 秒, 就能扛 3 秒的完全断流。这是它唯一真正买到的东西。

30 秒实验

  1. 在 VLC 里打开一个网络流,把缓冲从 1000 改成 100,观察起播速度与卡顿次数。
  2. 再改成 5000,观察起播速度与拖动进度条的响应。
  3. 用手机开热点限速,重复上面两次,看哪种设置最稳。

常见误区

  1. 以为缓冲越大越稳。 它只治抖动,不治带宽不足;而且会让起播与拖动变慢。
  2. 以为卡顿都是网络问题。 也可能是解码跟不上(4K 软解)、或者磁盘读不过来。
  3. 把 udp://@239.1.1.1 里的 @ 当成装饰。 它是 VLC 的约定, 带不带决定是「加入组播组」还是「监听端口」。
自测三问(点开对答案) 1. 缓冲 3 秒能扛多长时间的完全断流? —— 3 秒。抗断流能力在数值上就等于缓冲时长。 2. 网络只有 80 KB/s 而片子要 120 KB/s,把缓冲调大有用吗? —— 没用。缓冲永远攒不满,播放器会一直转圈。这是带宽问题,不是抖动问题。 3. 为什么 VLC 的 network-caching 默认 1000 毫秒,而 file-caching 只有 300? —— 因为网络抖动远大于本地磁盘读取,两者需要的缓冲量本来就不同。

缓冲区只是 VLC 众多可调项里的一个。下一节看它的技术特点:为什么它能做得这么「可调」。

相关笔记