ingest 让 SRS 主动去拉别人的流,方向和推流正好相反。 它适合「源是一批文件,要当直播播出去」。
11.4.2 的主配置管「别人推给我」,这一节管「我去拉别人」。 11.4.4 换回落盘那一侧,讲 HLS 切片。
一、方向是反的
平时是推流端连上来推,ingest 是 SRS 自己发起连接。
配置里那个 url 是「源在哪」,不是「谁来推」。
一份最小的拉流配置:
listen 19350;
exec.ffmpeg ./objs/ffmpeg/bin/ffmpeg;
ingest {
enabled on;
input { type file; url ./doc/1.mp4; }
engine { enabled on; }
}
注意 listen 是 19350,不是 1935:
拉流服务和主服务是两个进程,端口要分开。
exec.ffmpeg 指向一个真的 ffmpeg 可执行文件,路径写错启动就报找不到。
二、perfile 怎么排
perfile 的意思是「目录里每个文件各算一路」:
文件名直接变成流名,不用一个一个写 input 块。
这里最容易误判的是循环方式:
它默认是「一个文件播完换下一个」,不是每个文件各自循环。
三个文件分别是 2 秒、4 秒、3 秒,一轮就是 9 秒。
想让单个文件反复播,得靠 loop 那一组参数。
这个机制适合什么场景? 适合「几段宣传片轮流播」这种伪直播。 不适合「一段内容无限循环」——那种情况一轮只有一个文件。
三、循环播不是直播
最需要记住的一点:ingest 播文件不是直播。
观众看到的时间戳是文件里的,不是当前时间。
所以它顶替不了真正的直播源。
按数据算一下这个「循环」有多密: 一轮 9 秒,一天就是 9600 轮。 也就是说这批内容一天会被重复播 9600 遍。 这个量级下,观众随便进都是在看「第几轮的第几秒」。
用它的时候心里要有数: 它是「录像循环播放器」,不是「直播」。 要做真直播,还是得让推流端连上来推。
四、动手 Demo:ingest 的三个源文件——排一轮要多久
造三个长短不同的 mp4,把时长真读出来, 再算一轮多久、一天能播几轮。
for name, nf in (("lesson1.mp4", 50),
("lesson2.mp4", 100),
("lesson3.mp4", 75)):
path = make_mp4(name, nf) # 真编一段
c = av.open(path)
sec = c.duration / 1000000.0 # 微秒换秒
c.close()
print(name, "%.2f 秒" % sec)
total = 2.0 + 4.0 + 3.0
print("一轮", total, "秒")
for label, span in (("1 小时", 3600), ("1 天", 86400)):
print(label, int(span / total), "轮")
实跑输出:
--------------------------------------------------------------------
ingest.conf——它反过来去拉别人
--------------------------------------------------------------------
**① 方向正好是反的**
**平时是别人推给 SRS,`ingest` 是 SRS 主动去拉别人。**
**它适合「源是一批文件,要当直播播出去」这种场合。**
ingest.conf
------------------------------------------------------------
listen 19350;
exec.ffmpeg ./objs/ffmpeg/bin/ffmpeg;
ingest {
enabled on;
input {
type file;
url ./doc/1.mp4;
}
engine {
enabled on;
perfile {
audio_enable on;
}
}
}
**`perfile` 的意思是「目录里每个文件各算一路」:**
**文件名直接变成流名,不用一个一个写 input 块。**
**② 真做三个源文件,看 perfile 怎么排**
**造三个长短不同的 mp4,把时长真读出来。**
文件 流名 帧数 时长秒 字节
---------------------------------------------------------
lesson1.mp4 lesson1 50 2.00 11328
lesson2.mp4 lesson2 100 4.00 20677
lesson3.mp4 lesson3 75 3.00 15961
**三个文件首尾相接算一轮,一轮 9.00 秒。**
**这是 `perfile` 最容易误判的地方:它默认是「一个文件播完换下一个」,**
**不是每个文件各自循环。想让单个文件反复播,得靠 `loop` 那一组参数。**
**③ 一轮之后会怎样**
时长 轮数 总字节
----------------------------------
1 小时 400 18.3 MB
1 天 9600 439.1 MB
30 天 288000 12.9 GB
**一天 9600 轮,也就是说这批内容会被反复播 9600 遍。**
**这提醒一件事:`ingest` 播文件不是「直播」,是「录像循环」。**
**观众看到的时间戳是文件里的,不是当前时间,**
**所以别拿它顶替真正的直播源。**
**另一个要注意的是 `exec.ffmpeg`:**
**它指向一个真的 ffmpeg 可执行文件,路径写错会在启动时报找不到。**
**SRS 源码包里 `objs/ffmpeg/bin/ffmpeg` 是 `./configure --with-ffmpeg` 编出来的,**
**没开这个开关的话,这个文件根本不存在。**
三个文件 2 秒、4 秒、3 秒,一轮 9 秒。
一小时 400 轮,一天 9600 轮,这就是「循环」的真实密度。
注意 perfile 是一轮一个文件地走,不是三路同时播。
真读时长要用容器头里的 duration,别按帧数自己乘。
30 秒实验
- 把三个文件换成一个 9 秒的文件,猜轮数变不变——不变,一轮还是 9 秒。
- 关掉
engine,看还会不会转流——不会,input只管读,转出去要靠engine。 - 把
exec.ffmpeg指向不存在的路径,猜什么时候报错——启动就报,比编到一半才发现好查。
常见误区
- 「
ingest是别人推给我」——反了,是 SRS 主动去拉。 - 「
perfile每个文件各自循环」——是一轮一个文件地走。 - 「
ingest播文件就是直播」——时间戳是文件的,不是当前时间。
自测三问(点开对答案)
1. `ingest` 的 `url` 指的是什么? —— **源在哪**,不是谁来推。 2. `perfile` 一轮怎么走? —— **一个文件播完换下一个**,不是各自循环。 3. 为什么说 `ingest` 播文件不是直播? —— **观众看到的时间戳来自文件**,和当前时间无关。- ☐ (本节完,下一节 11.4.4 hls.conf)