oss

Liquidsoap 把播出静音纳入程序设计

8 条来源 5 条一手来源 已翻译 2026年9月17号

正在加载阅读与收藏统计…
正文
巴黎塞纳河畔的环形广播大厦,前景是横跨河面的钢制鲁埃勒桥。

巴黎广播大厦与鲁埃勒桥,Edison McCullen 摄于 2018 年 5 月 17 日。法国广播电台公开了其 Liquidsoap 流媒体配置;照片呈现了广播机构所在的环境。CC BY-SA 4.0。[2][7]

设想主持人在直播节目进行到一半时断开连接。接下来播出的,可以是一段备用录音,可以是音乐播放列表里的曲目,也可以是一片寂静。Liquidsoap 是一门用于组织媒体流的开源语言,这项选择可以直接写进程序结构。沿着下一帧音频的行进过程,依次查看音源、备用切换规则和时钟,就能理解系统如何维持电台的播出。[1][3]

理解这套架构,可以从分工入手。在常见的网络广播配置中,Liquidsoap 负责编排节目并编码,Icecast 负责将音频流分发给听众,听众的播放器再把收到的数据变成声音。听众增加,主要增加的是分发环节的工作量;决定他们听到什么,则是上游的职责。[1] 本文示例依据 Liquidsoap 的 2.4.5 版文档,法国广播电台(Radio France)的公开部署则作为单独的运维实例。

输出端请求下一帧

Liquidsoap 脚本会把多个音源(source)连接成一张网络。音源逐帧供应媒体数据,并按需要附带元数据和曲目边界。因此,播放列表、直播输入,以及组合其他音源的算子,都能参与同一套系统。[3]

时钟每跳动一次,输出端就向自己的音源请求数据。请求沿着相连的算子传递,直到抵达能够供应采样数据的环节。例如,output.icecast 可以从 fallback 获取数据,再由后者选中一个播放列表。脚本描述了这些连接关系,播出期间,数据请求会反复沿着它们传递。[3]

有些输入即使尚未播出,也要持续运行。音源文档将用于接收传入直播流的 input.harbor 列为主动音源:即使当前选中了另一个音源,它仍须接收数据。[3] 因而,备用输入也有自己的运行过程,在听众听到它之前,就已经开始工作。

文件名还要经过处理才能变成声音

录制素材经由另一层抽象进入系统:请求(request)request.create 接受一个 URI,创建请求之后,还要由 playlistsingle 这类基于请求的音源解析它,取得能够解码的素材,才能播放。[4]

解析过程可以包含多个步骤。自定义协议先把媒体库中的标识符转换成 URL,HTTP 处理器再下载文件,随后还要有解码器能够读取它。即使已经取得本地文件,内容不合要求也会阻碍后续处理。[4] 节目单上有一条记录,与音源已经准备好播出,是两种不同的状态。

元数据同样有到达时限。Liquidsoap 的 annotate: 协议可以在请求解析期间传入 cue_incue_out。这些指令必须在播放前抵达解码器;到了更下游才附加,便无法追溯改变解码器已经读取的内容。[4] 这里体现了一条有用的架构原则:信息应当在仍能影响处理结果的环节到位。

可用的音频也会是一片静音

Liquidsoap 会区分可失效音源与预期持续可用的音源。普通播放列表属于可失效音源,因为其中的文件会有无效或无法访问的情况。默认情况下,输出端要求输入音源持续可用。如果 fallback 的最后一项是 single("standby.ogg"),且它指向一段有效的本地录音,就能用来保证音频持续供应。另一种做法是使用 mksafe,在输入失效时供应静音。[1]

这里的 infallible(持续可用)有意限定在很窄的范围内,描述的是流媒体模型中的音源可用性。至于节目内容是否有用,或机器断电后还能否播出,都超出了这个词所能保证的范围。

演播室的连接可以一直保持着,同时持续传来静音。Liquidsoap 用另一个算子 blank.strip 处理这种情况:静音持续过久,就把该输入标记为不可用,外层的备用切换算子随后可以选用其他音源。文档将 max_blank=5.track_sensitive=false 配合使用:输入静音达到五秒后,插播内容接替播出;声音恢复时,即使插播内容尚未到达曲目边界,也可以切回直播音源。[5]

这项设置也表达了一项编辑决定。长时间停顿,既有技术故障的情形,也有戏剧朗诵或作品有意收尾的情形。检测器测量的是音频状态,电台则决定这种状态持续到何时应当介入。规则写得清楚,就能在真正播出之前讨论并演练这次中断与切换。

交叉淡化需要提前取得音频

音源选择决定音频从哪里来,时钟决定系统以多快的速度消耗它。每个音源都归属于一个时钟,Liquidsoap 通常会自动确定这种归属。[6]

录制好的音乐可以提前读取。crossfade(交叉淡化)需要这种余地,因为两首曲目重叠时,系统须暂时以高于输出流播放速度的速率消耗素材。直播输入若按自身时序运行,就未必有同样的余地。时钟文档给出一个例子:SRT 输入与需要掌握处理节奏的交叉淡化算子相连时,系统拒绝了这项连接。[6]

buffer() 可以在不同的时钟域之间建立缓冲队列,让媒体数据从一个时钟域流向另一个。队列容量有限,速率差异足够大,就会耗尽或填满队列。因此,缓冲也带来了容量与时序上的取舍,对设备间节奏差异的调节能力有其限度。[6] 对负责接入演播室信号的人来说,实际要弄清的是哪个组件掌握节奏,以及其他组件各自能够容忍多长的等待。

广播机构在音源网络之外增加了什么

法国广播电台公开的配置,让这些抽象概念有了具体形态。其 README 描述了多路 SRT 输入:它们经由不同的网络路径传送同一电台的音频。一个 Liquidsoap 进程从中选择,生成 radio_prod,随后按多组参数编码,再经 Icecast 和 HLS 分发。[7]

配置还公开了 preferred_outputreal_outputis_output_blank。三者分别表示配置设定或手动指定的首选输出、备用切换系统实际选中的输出,以及当前选中项是否正在输出静音。监测项目还包括输入是否就绪、音频电平和缓冲区状态。[7] 进程正在运行,只是判断播出是否正常的初步依据。

Liquidsoap 在更大的电台系统中承担这类职责,已有很长一段历史。Nathan Willis 在 2012 年发表于 LWN 的 Airtime 报道中,将它描述为广播管理应用底层的音频流生成器。[8] 这份独立报道也解释了,一门小型语言为何能影响到编写脚本的人之外:媒体处理组件之上,还可以搭建排期与节目呈现界面。

依我的理解,这套设计的长处在于让持续播出的安排有据可查。对小型电台来说,这仍然要求有人维护脚本,并测试文件失效、主持人断线、输入静音及恢复播出等情况。对于规模更大的机构,法国广播电台的实践展示了另一层价值:观察实际选中的音源及其状态。[7] 备用录音响起时,让人满意的还有对整个过程的理解:它为何启动,此刻正在播出什么,以及满足哪些条件后直播节目会回来。

来源

  1. Liquidsoap 2.4.5 文档,“Quickstart”——音频流的生成与分发、音源失效、本地备用录音及静音后备方案。
  2. Edison McCullen,“Maison de la Radio & Pont Rouelle”,2018 年 5 月 17 日,Wikimedia Commons——原始照片及 CC BY-SA 4.0 署名信息。
  3. Liquidsoap 2.4.5 文档,“Understanding Sources in Liquidsoap”——帧、音源组合、由输出端驱动的执行过程及主动输入。
  4. Liquidsoap 2.4.5 文档,“Understanding Requests”——URI 解析、解码,以及播放起止点元数据应当传入的时机。
  5. Liquidsoap 2.4.5 文档,“Blank detection”——将静音输入标记为不可用,以及声音恢复后的切回操作。
  6. Liquidsoap 2.4.5 文档,“Clocks in Liquidsoap”——时钟域、交叉淡化的约束、SRT 时序及缓冲区。
  7. 法国广播电台,“Radio France's Liquidsoap scripts”,公开仓库 README——冗余输入路径、输出编码参数、选择状态及监测。
  8. Nathan Willis,“Radio station management with Airtime”,LWN,2012 年 2 月 15 日——关于 Liquidsoap 在电台自动化系统中所处位置的独立历史报道。
Previous Open Food Network 让食品集配中心按同一张时间表运转

Recommended In oss

Matched by subject and format