SpeedVideo 常用 CLI 命令与工具详解

SpeedVideo 视频测试源拉流验证工具链实测:curl 响应头/Range/计时分解、ffprobe 片源体检、ffmpeg 模拟播放/首帧时延/拉流录制、ab 并发压测,含 FFmpeg static 构建段错误排障实录。

SpeedVideoSpeedVideoFFmpeg流媒体2026/10/25

SpeedVideo 常用 CLI 命令与工具详解

目标:把「向 SpeedVideo 视频测试源拉流并量化验证」要用到的命令行工具一次讲透——curl 做 HTTP 层验证与计时分解、ffprobe 做片源体检、ffmpeg 做模拟播放与首帧时延测量、ab 做并发压测。每条命令均给出实测回显,已在 Ubuntu 24.04 客户端环境对运行中的测试源(HTTP 8080 / HTTPS 8443)逐项实测通过。测试源搭建见本专栏《SpeedVideo Docker Compose 部署指南》,参数调法见《SpeedVideo 配置参数详解》,本篇不重复部署过程。

一、环境信息

  • 测试源服务器:Apache HTTP Server 2.4.69,HTTP 8080、HTTPS 8443,片源为 5 档固定码率 MP4 + 一路 HLS(hls/sv-1080p)
  • 客户端操作系统:Ubuntu 24.04.5 LTS(x86_64)
  • 客户端工具版本:curl 8.5.0;FFmpeg/ffprobe 7.0.2(static 构建)与 6.1.1(发行版仓库版,排障对照用);ab(ApacheBench)2.4.69(随 apache2-utils)
  • 示例片源:clips/sv-1080p-5000k.mp4(1920×1080、20 秒、视频码率约 5.1 Mbps)、hls/sv-1080p/index.m3u8(10 个 2 秒分片)
  • 本文命令默认在测试客户端上执行,URL 中的 127.0.0.1 换成服务器 IP 即为远程用法

二、工具概览

工具作用安装方式对应 SpeedVideo 指标
curlHTTP 层验证:响应头、Range 分段、计时分解、限速与鉴权验证系统自带(apt install curl)首帧时延、下载速率的 HTTP 层采集原理
ffprobe片源体检:容器格式、编码、分辨率、码率、时长apt install ffmpeg 或官方 static 构建片源参数核对(测试前确认片源没配错)
ffmpeg模拟播放:完整拉流解码、首帧时延测量、拉流录制同上首帧时延、卡顿(解码帧数与时长比对)
ab并发压测:小文件与片源的吞吐、延迟分布apt install apache2-utils服务器并发承载能力(对齐官方 10 并发标定)

💡 技术拓展:「首帧时延」这类体验指标有协议层与解码层两种测法——

测法工具测到的是什么
HTTP 层计时curl -w首字节时间(TTFB)+ 下载总时长,不含解码
解码层计时ffmpeg -frames:v 1 计时含 Demux + 解码出第一帧的完整耗时,最接近用户感知
应用层评分SpeedVideo 客户端综合首帧/卡顿/速率算出的 vMOS

本文 4.3 节与 6.3 节分别实测前两种;vMOS 评分需官方客户端,不在本篇范围。

三、前置条件

  1. 测试源服务运行中,健康端点可达:
$ curl -s http://127.0.0.1:8080/healthz.txt
ok
  1. 客户端已装好 curl、FFmpeg/ffprobe、ab;ffprobe -version 第一行能输出版本号即正常。
  2. 本文所有回显均为实测定稿,因机器性能不同,读者复测时数值(耗时、speed)会有差异,状态码与结构应一致。

四、curl:HTTP 层验证与计时

curl 是测试源验证的第一件工具:不真正解码视频,只验证「服务器给的响应对不对、快不快」。

4.1 片源响应头检查

对 MP4 片源发 HEAD 请求,确认状态码、长度、类型与缓存头:

$ curl -sI http://127.0.0.1:8080/clips/sv-1080p-5000k.mp4
HTTP/1.1 200 OK
Server: Apache/2.4.69 (Unix) OpenSSL/3.5.7
ETag: "c99987-65ea5ffd4c9dc"
Accept-Ranges: bytes
Content-Length: 13212039
Access-Control-Allow-Origin: *
Cache-Control: max-age=60
Content-Type: video/mp4

要点逐项:Accept-Ranges: bytes 表示支持分段(播放器拖动进度的基础);Content-Type: video/mp4 正确;Access-Control-Allow-Origin: * 允许 Web 播放器跨域;Cache-Control: max-age=60 为 MP4 档短缓存策略(配置出处见《SpeedVideo 配置参数详解》5.5 节)。

4.2 Range 分段请求(模拟播放器拖动/分片加载)

用 Range 头只取前 1024 字节,验证服务器支持 206 断点续传:

$ curl -s -o /dev/null -D - -H 'Range: bytes=0-1023' http://127.0.0.1:8080/clips/sv-1080p-5000k.mp4
HTTP/1.1 206 Partial Content
Server: Apache/2.4.69 (Unix) OpenSSL/3.5.7
Last-Modified: Sun, 25 Oct 2026 08:28:35 GMT
ETag: "c99987-65ea5ffd4c9dc"
Accept-Ranges: bytes
Content-Length: 1024
Access-Control-Allow-Origin: *

返回 206 Partial Content 且 Content-Length: 1024 与请求区间一致——若此处返回 200 全量,说明分段能力失效,需要排查配置。

4.3 计时分解(首字节时间与下载速率)

curl -w 的计时变量可以把一次下载拆成 DNS、建连、首字节、总时长四段,这正是 SpeedVideo 类工具在 HTTP 层采集「响应快慢」的原理:

$ curl -s -o /dev/null -w 'dns=%{time_namelookup}s connect=%{time_connect}s ttfb=%{time_starttransfer}s total=%{time_total}s bytes=%{size_download} speed=%{speed_download}B/s\n' http://127.0.0.1:8080/clips/sv-720p-1500k.mp4
dns=0.000010s connect=0.000129s ttfb=0.000565s total=0.001979s bytes=4200410 speed=2122491157B/s

连测三次(实测回显):

dns=0.000010s connect=0.000129s ttfb=0.000565s total=0.001979s bytes=4200410 speed=2122491157B/s
dns=0.000011s connect=0.000110s ttfb=0.000656s total=0.001754s bytes=4200410 speed=2394760547B/s
dns=0.000011s connect=0.000144s ttfb=0.000593s total=0.001757s bytes=4200410 speed=2390671599B/s

本机回环下 TTFB 在 0.6ms 级、速率 2GB/s 级(内存级回环,无网络瓶颈)——这正是「隔离服务器变量后测网络」的对照基线:把同一命令放到跨网链路执行,数值差就是网络引入的部分。

4.4 限速片源实测(弱网模拟验证)

测试源对 2160p 档配置了 2000 KB/s 限速(mod_ratelimit),用于模拟弱网。下载 31MB 片源验证限速是否生效:

$ curl -s -o /dev/null -w "time=%{time_total}s speed=%{speed_download}B/s\n" http://127.0.0.1:8080/clips/sv-2160p-12000k.mp4
time=15.046049s speed=2068563B/s

实测速率 2068563 B/s ≈ 2020 KB/s,与配置值 2000 KB/s 吻合(2068/2000 偏差在 4% 以内,含 HTTP 头与调度开销);31.1MB ÷ 15.0s 与之一致。对比 4.3 节不限速档位的 GB/s 级速率,限速档成功构造了「慢网络」场景。

4.5 鉴权片源请求

/secure/ 路径配置了 Basic 鉴权(演示账号 root,密码 q1w2e3r4),用于验证客户端的鉴权播放能力:

$ curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/secure/auth-check.txt
401
$ curl -s -u root:q1w2e3r4 -w "\n%{http_code}\n" http://127.0.0.1:8080/secure/auth-check.txt
authenticated

200

未带凭据返回 401(响应头含 WWW-Authenticate: Basic realm="SpeedVideo Test Source" 挑战),带正确凭据返回 200 与文件内容 authenticated。

五、ffprobe:片源体检

拉流测试前先 probe 片源,确认「服务器发的片」参数与预期一致——片源配错(码率、分辨率不对)会让整轮测试结论作废。

5.1 远程探测 MP4 片源

ffprobe 可直接读 HTTP URL(只下载 moov 元数据与少量帧头,不拉全片):

$ ffprobe -v error -show_entries format=format_name,duration,size,bit_rate \
    -show_entries stream=codec_name,codec_type,width,height,r_frame_rate \
    -of default=noprint_wrappers=1 http://127.0.0.1:8080/clips/sv-1080p-5000k.mp4
codec_name=h264
codec_type=video
width=1920
height=1080
r_frame_rate=30/1
codec_name=aac
codec_type=audio
r_frame_rate=0/0
format_name=mov,mp4,m4a,3gp,3g2,mj2
duration=20.000000
size=13212039
bit_rate=5284815

核对点:视频流 h264、1920×1080、30fps,音频 aac;时长 20.000 秒、文件 13212039 字节、总码率 5284815 bps ≈ 5.2 Mbps——与《SpeedVideo Docker Compose 部署指南》4.2 节制片表中的 1080p/5Mbps 档完全一致。

5.2 远程探测 HLS 清单

ffprobe 读 m3u8 会自动解析清单并展开分片:

$ ffprobe -v error -show_entries format=format_name,duration \
    -show_entries stream=codec_name,codec_type,width,height \
    -of default=noprint_wrappers=1 http://127.0.0.1:8080/hls/sv-1080p/index.m3u8
codec_name=h264
codec_type=video
width=1920
height=1080
codec_name=aac
codec_type=audio
codec_name=h264
codec_type=video
width=1920
height=1080
codec_name=aac
codec_type=audio
format_name=hls
duration=20.000000

format_name=hls 确认按 HLS 解封装成功;流信息出现两组是因为清单展开后分片各报一次,参数一致(h264 1080p + aac);总时长 20 秒 = 10 个 2 秒分片,与制片参数吻合。

5.3 清单与分片的纯文本核对

HLS 本质是文本清单 + ts 分片,curl 即可核对结构,不依赖 ffprobe:

$ curl -s http://127.0.0.1:8080/hls/sv-1080p/index.m3u8 | head -8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:2.000000,
seg_000.ts
#EXTINF:2.000000,
$ curl -sI http://127.0.0.1:8080/hls/sv-1080p/seg_000.ts | grep -E 'HTTP|Content-Length|Content-Type'
HTTP/1.1 200 OK
Content-Length: 914996
Content-Type: video/mp2t

#EXT-X-PLAYLIST-TYPE:VOD 表明是点播清单(客户端可一次拉全部分片);分片返回正确的 video/mp2t 类型与 914996 字节长度。

六、ffmpeg:拉流播放实测

ffprobe 只读元数据,ffmpeg 才是「真播放」——把码流完整拉下来解码一遍,帧数、时长、速度全部可量化。

6.1 空输出播放 MP4(完整拉流 + 解码验证)

-f null - 表示解码后丢弃输出,只验证「能否完整拉流并解码」:

$ ffmpeg -hide_banner -nostats -i http://127.0.0.1:8080/clips/sv-1080p-5000k.mp4 -f null -
(输出节选,实测末尾)
[out#0/null @ 0xdd54a40] video:258KiB audio:1876KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown
frame=  600 fps=0.0 q=-0.0 Lsize=N/A time=00:00:20.00 bitrate=N/A speed=46.2x

判读:frame= 600 = 20 秒 × 30fps 全帧解码,无丢帧;time=00:00:20.00 与片长一致;speed=46.2x 表示解码速度是实时的 46 倍(本机解码能力远超播放需求,瓶颈只能在网络侧——这正是测试源想要的前提)。

6.2 空输出播放 HLS

HLS 拉流客户端内部会按清单顺序拉 10 个分片,用发行版仓库的 ffmpeg(6.1.1)实测(static 构建在此场景有已知稳定性问题,见八节排障实录):

$ ffmpeg -hide_banner -nostats -i http://127.0.0.1:8080/hls/sv-1080p/index.m3u8 -f null -
(输出节选,实测末尾)
[out#0/null @ 0x6121d3a61ec0] video:281kB audio:1878kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
frame=  600 fps=0.0 q=-0.0 Lsize=N/A time=00:00:20.01 bitrate=N/A speed=45.4x

600 帧 / 20.01 秒全量解码,与 MP4 档结果一致——两条协议路径(渐进下载、HLS 切片)交付的是同一份内容。

6.3 首帧时延测量

用 -frames:v 1 只解码第一帧,再用 shell 时间戳包住整条命令计时,得到「用户点播放键到看到画面」的解码层近似值:

$ s=$(date +%s%N); ffmpeg -v error -i http://127.0.0.1:8080/clips/sv-1080p-5000k.mp4 -frames:v 1 -f null -; e=$(date +%s%N); echo "首帧耗时 $(( (e-s)/1000000 )) ms"
首帧耗时 44 ms

本机回环实测三次:44 ms、49 ms、45 ms——50ms 级出第一帧。把它放到跨网/弱网链路重测,增量即为网络引入的首帧时延,与 4.3 节的 TTFB 对照可分离「网络等首字节」与「下载+解码」两部分开销。

6.4 拉流录制到本地

-c copy 不解码直接转封装落盘,用于「把测试源上的片抓回来存档/比对」:

$ ffmpeg -hide_banner -y -i http://127.0.0.1:8080/clips/sv-720p-2500k.mp4 -c copy ./recorded-720p-2500k.mp4
(输出节选,实测末尾)
[out#0/mp4 @ 0x5697283b9ac0] video:6332kB audio:313kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.334823%
size=    6667kB time=00:00:19.98 bitrate=2732.2kbits/s speed= 653x
$ ffprobe -v error -show_entries format=duration,size,bit_rate -of default=noprint_wrappers=1 ./recorded-720p-2500k.mp4
duration=20.000000
size=6826971
bit_rate=2730788

录制文件 6826971 字节(源文件 6826970 字节,1 字节差来自转封装时 moov 元数据重新排布),时长与总码率与源一致——链路内容无损。speed=653x 说明 -c copy 模式下瓶颈只在网络下载。

七、ab:并发压测

ab(ApacheBench,apache2-utils 包)测试服务器的并发承载:小文件端点测请求处理能力,大文件片源测吞吐能力。在服务器本机执行(排除网卡瓶颈,先看服务进程上限)。

7.1 健康端点压测(小文件、高并发)

$ ab -n 2000 -c 100 http://127.0.0.1:8080/healthz.txt
(输出节选,实测关键行)
Failed requests:        0
Requests per second:    21336.75 [#/sec] (mean)
Time per request:       4.687 [ms] (mean)
Time per request:       0.047 [ms] (mean, across all concurrent requests)
Transfer rate:          6084.31 [Kbytes/sec] received

100 并发 2000 请求零失败,单进程事件模型下 21337 req/s——小端点处理能力充足。

7.2 片源压测(大文件吞吐)

$ ab -n 40 -c 10 http://127.0.0.1:8080/clips/sv-1080p-3000k.mp4
(输出节选,实测关键行)
Failed requests:        0
Requests per second:    538.44 [#/sec] (mean)
Time per request:       18.572 [ms] (mean)
Time per request:       1.857 [ms] (mean, across all concurrent requests)
Transfer rate:          4239279.27 [Kbytes/sec] received

10 并发拉 8MB 片源:538 req/s、吞吐约 4.24 GB/s(回环内存级)。对照官方套件「10 并发」标定,服务进程本身绰绰有余;真实环境的瓶颈会出现在网卡/链路上——把 ab 放到跨网客户端执行,吞吐掉到哪档,网络能力就是哪档。

八、注意事项(排障实录)

FFmpeg 7.0.2 static 构建探测 HLS/TS 偶发段错误。 实测过程实录:同一台客户端上,johnvansickle 官方 static 构建(7.0.2)对 MP4 探测与播放始终正常,但对 HLS 清单/TS 分片的探测先成功后连续崩溃:

$ ffprobe -v error ... http://127.0.0.1:8080/hls/sv-1080p/index.m3u8
Segmentation fault (core dumped)      # 退出码 139
$ dmesg | tail -2
ffprobe[288571]: segfault at 2a060 ip 000000000002a060 sp 00007ffe4bc990d8 error 14

定位过程:先怀疑服务端——用 curl 拉同一清单与分片均返回 200 且字节数正确(见 5.3 节),服务端无责;再换输入方式——HTTP URL 与本地文件两种喂法都崩,锁定为 static 构建自身在 mpegts 解封装路径上的缺陷。解决方案:换发行版仓库版 ffmpeg/ffprobe(apt install ffmpeg,本机为 6.1.1-3ubuntu5),同命令连续多次执行全部成功(5.2/6.2 节回显即仓库版输出)。教训:「能播 MP4」不代表「HLS 链路无恙」,两条封装路径要分别验证;静态构建崩溃时先换发行版版本对照,别急着改服务器。

ab 压测大文件要控制请求数。 1080p 档单文件 8MB,-n 40 -c 10 即产生约 320MB 传输;盲目放大 -n 会先打满客户端内存与回环带宽,得到的是客户端瓶颈而非服务器瓶颈。

计时类数值只在同机对照有意义。 4.3/6.3 节的毫秒级数值是回环基线,跨机引用无意义;正确用法是「同一客户端对同一服务器,改一个变量(网络路径/限速档)再测一次」。

九、常见问题

Q1:ffprobe 远程探测卡在连接上不动? 先 curl -s -o /dev/null -w "%{http_code}\n" <URL> 确认 HTTP 层通(应 200);401 说明路径落在鉴权区(加凭据或换公开片源),403/404 按《SpeedVideo 配置参数详解》5.2 节排查目录权限与文件名。

Q2:ffmpeg 拉流时报 Server returned 404 Not Found? URL 文件名打错(片源文件名含码率档位,大小写敏感)。用部署篇的片源表逐个字符核对,或先 curl -sI 确认 200 再交给 ffmpeg。

Q3:ab 报 apr_socket_recv: Connection reset by peer? 并发过高且开了长连接选项时偶发;本文命令不带 -k(每请求独立连接)已规避。若必须测 KeepAlive,加 -k 并把 -c 降到 50 以下。

Q4:怎么验证 HTTPS 侧的拉流? 把 URL 换成 https://127.0.0.1:8443/...,curl 加 -k 跳过自签名证书校验即可;ffmpeg/ffprobe 对自签名站点加 -tls_verify 0 前的常规做法是先把 CA 导入系统信任库,测试环境更简单的办法是 HTTP 侧测功能、HTTPS 侧只验通断(curl -skI https://127.0.0.1:8443/healthz.txt 应返回 200)。

十、参考链接