---
url: /guide/web-player.md
---
# 内置 Web 播放器

rtp2httpd 内置了一个基于 Web 的现代化播放器，可以直接在浏览器中观看已配置的 M3U 频道列表，无需安装任何客户端。

## 功能特性

* **频道列表**：自动加载配置的 M3U 频道列表
* **在线直播**：在浏览器中直接观看直播
* **时移回看**：支持 EPG 电子节目单和时移回看（需要有回看源）
* **快速起播**：搭配 FCC 可实现毫秒级换台速度
* **无缝换台**：换台时预加载新流，减少黑屏
* **响应式设计**：桌面和移动端 UI 自适应
* **PWA 支持**：可添加到手机、平板、桌面或 LG webOS 电视主屏幕，像原生应用一样快捷打开
* **零开销**：纯 Web 前端实现，对 rtp2httpd 运行几乎没有资源占用（无解码转码开销）

> \[!IMPORTANT]
> 播放器依赖浏览器的原生解码能力，部分编码格式（如 E-AC3）可能在某些浏览器中无法播放（表现为无音频、画面黑屏）。推荐使用最新版本的 Chrome、Edge 或 Safari。

## 访问方式

配置好 M3U 播放列表后，通过浏览器访问：

```url
http://服务器地址:端口/player
```

**示例**：

```url
http://192.168.1.1:5140/player
```

播放器页面路径可以通过配置项 `player-page-path` 自定义。设置为 `/` 可以实现不带任何路径直接访问。

## 链接直达频道

可以在播放器地址后附加 `#频道序号` 或 `#频道名称`，直接打开指定频道，适合收藏或分享给他人：

```url
http://服务器地址:端口/player#5
http://服务器地址:端口/player#CCTV-1
```

播放器在切换频道时会自动更新地址栏，随时复制即可分享当前正在播放的频道。

## 复制媒体直链

在频道列表中键点击频道，可复制该频道当前线路的直播地址。在节目单中键点击节目，可复制该节目的回看地址（需要频道配置了 `catchup-source`）。复制成功后页面会弹出提示。

复制得到的是可直接请求的 HTTP 媒体地址，可用于 FFmpeg、N\_m3u8DL-RE、IDM 等工具下载或在第三方播放器中打开。多线路频道会复制最近一次使用的线路；若当前页面带有 `r2h-token`，复制的链接也会带上该参数。

组播和 RTSP 直链还会带上 `r2h-filename` 查询参数，值为频道名、线路标签、节目名和时间范围组成的 `.ts` 文件名。用浏览器打开并触发下载时，会按该文件名保存。详见 [URL 格式说明](./url-formats.md#下载文件名)。

> \[!NOTE]
> 正在播出且没有回看源的节目会复制直播地址。尚未开始且没有回看源的节目无法复制。

## PWA 支持与添加到主屏幕

内置 Web 播放器支持 PWA（Progressive Web App）。你可以将播放器页面添加到设备主屏幕（包括手机、平板、电脑，以及 LG webOS 智能电视），像打开原生应用一样一键进入，获得全屏、沉浸式的观看体验。

添加到主屏幕后，桌面图标名称默认为 **R2H 播放器**，并会使用内置的应用图标。播放器会保留主题等本地设置。

### iOS / iPadOS（Safari）

1. 在 Safari 中打开播放器页面（例如 `http://192.168.1.1:5140/player`）
2. 点击地址栏左侧扩展按钮中的 **分享**
3. 在分享菜单中下滑，选择 **添加到主屏幕**
4. 确认名称后点击 **添加**

### Android（Chrome、Edge 等）

1. 在浏览器中打开播放器页面
2. 点击浏览器右上角的 **菜单**（⋮）
3. 选择 **添加到主屏幕** 或 **安装应用**
4. 按提示确认安装

部分浏览器还会在地址栏或页面底部显示安装横幅，点击 **安装** 或 **添加** 即可完成。

### 桌面端（Chrome、Edge）

1. 在浏览器中打开播放器页面
2. 点击地址栏右侧的 **安装** 图标（如有），或从浏览器菜单中选择 **投放、保存和分享** → **创建快捷方式**
3. 按提示确认

安装后，播放器会以独立窗口运行，可从系统应用列表或 Dock / 任务栏快速启动。

### LG 电视（webOS）

LG webOS 智能电视同样支持通过内置浏览器使用播放器，并将页面固定到电视桌面：

1. 在电视上打开 **Web Browser** 应用
2. 在地址栏输入播放器页面地址（例如 `http://192.168.1.1:5140/player`）
3. 打开浏览器菜单，选择 **添加到主屏幕**（Add shortcut to the Home screen）
4. 返回电视主界面，即可从桌面快捷方式启动播放器

> \[!NOTE]
> 若通过 `player-page-path` 自定义了播放器路径，请使用实际路径访问后再添加到主屏幕。添加到主屏幕的快捷方式会固定指向添加时的 URL，包括其中的 `r2h-token` 等查询参数（如有）。
> 也可以在 URL 末尾附加 `#频道名称` 或 `#频道序号`，将快捷方式固定到指定频道。

## 频道聚合

在 M3U 中，一行 `#EXTINF` 后面紧跟多行 URL，即表示该频道拥有多条线路。播放器会将它们聚合为一个频道，在频道列表中只显示一次，用户可以通过线路选择器切换不同线路（如不同清晰度）：

![频道源选择器](../images/channel-source-selector.png)

```m3u
#EXTINF:-1 group-title="卫视",广东卫视
http://192.168.1.1:5140/rtp/239.253.64.96:5140$超高清
http://192.168.1.1:5140/rtp/239.253.64.200:5140$高清
```

如果源 URL 带有 `$标签` 后缀，播放器会将其提取为源的显示标签（如「超高清」「高清」「标清」）。没有 `$标签` 的源则按序号显示（如「线路 1」「线路 2」）。

> \[!NOTE]
> 频道聚合是 **内置 Web 播放器** 的前端功能，并非 rtp2httpd 服务端行为。第三方播放器（如 APTV、TiviMate 等）是否支持类似的聚合显示取决于其自身实现。rtp2httpd 服务端仅负责解析 `$标签`、生成独立的服务路径，以及在转换后的 M3U 中保留 `$标签`。

关于线路标签的 M3U 配置方式，详见 [M3U 播放列表集成](./m3u-integration.md#线路标签)。

## 无缝换台

内置 Web 播放器默认开启 **无缝换台** 。换台或切换线路时，播放器会在后台预先加载新频道的视频流，待新流准备就绪后再切换画面，减少黑屏和等待时间，配合 [FCC 快速换台](./fcc-setup.md) 可获得更流畅的换台体验。

该功能通过双槽位预加载实现。由于在换台过程中短暂存在两路视频同时拉流的情况，如果你的带宽比较小（公网访问时），或是上游只支持单路组播，导致换台出现卡顿，可以手动关闭这个选项——在播放器页面右上角的 **设置**（齿轮图标）中关闭 **无缝换台** 即可。关闭后换台会先断开当前流再加载新流，占用带宽更低，但切换时可能出现短暂黑屏。

## 时间占位符

内置 Web 播放器支持以下时间占位符格式，可在 M3U `catchup-source` URL 中使用：

### `${}` 格式（使用 long format）

| 占位符                        | 说明                                    | 示例输出                 |
| ----------------------------- | --------------------------------------- | ------------------------ |
| `${utc}`                      | 节目开始时间（UTC，ISO8601 格式）       | 2025-01-15T10:30:45.000Z |
| `${utc:yyyyMMddHHmmss}`       | 节目开始时间（UTC，自定义 long format） | 20250115103045           |
| `${utcend}`                   | 节目结束时间（UTC，ISO8601 格式）       | 2025-01-15T12:30:45.000Z |
| `${utcend:yyyyMMddHHmmss}`    | 节目结束时间（UTC，自定义 long format） | 20250115123045           |
| `${start}`                    | 同 `${utc}`                             | 2025-01-15T10:30:45.000Z |
| `${start:yyyyMMddHHmmss}`     | 同 `${utc:yyyyMMddHHmmss}`              | 20250115103045           |
| `${end}`                      | 同 `${utcend}`                          | 2025-01-15T12:30:45.000Z |
| `${end:yyyyMMddHHmmss}`       | 同 `${utcend:yyyyMMddHHmmss}`           | 20250115123045           |
| `${lutc}`                     | 当前时间（UTC，ISO8601 格式）           | 2025-01-15T14:00:00.000Z |
| `${lutc:yyyyMMddHHmmss}`      | 当前时间（UTC，自定义 long format）     | 20250115140000           |
| `${now}`                      | 同 `${lutc}`                            | 2025-01-15T14:00:00.000Z |
| `${now:yyyyMMddHHmmss}`       | 同 `${lutc:yyyyMMddHHmmss}`             | 20250115140000           |
| `${timestamp}`                | 当前 Unix 时间戳（秒）                  | 1736949600               |
| `${timestamp:yyyyMMddHHmmss}` | 同 `${lutc:yyyyMMddHHmmss}`             | 20250115140000           |
| `${(b)yyyyMMddHHmmss}`        | 节目开始时间（本地时间，long format）   | 20250115183045           |
| `${(e)yyyyMMddHHmmss}`        | 节目结束时间（本地时间，long format）   | 20250115203045           |
| `${(b)yyyyMMdd\|UTC}`         | 节目开始时间（UTC，long format）        | 20250115103045           |
| `${(e)yyyyMMdd\|UTC}`         | 节目结束时间（UTC，long format）        | 20250115123045           |
| `${(b)timestamp}`             | 节目开始时间的 Unix 时间戳（秒）        | 1736937045               |
| `${(e)timestamp}`             | 节目结束时间的 Unix 时间戳（秒）        | 1736944245               |
| `${yyyy}`                     | 节目开始时间：4 位年份（本地时间）      | 2025                     |
| `${MM}`                       | 节目开始时间：月份 01-12（本地时间）    | 01                       |
| `${dd}`                       | 节目开始时间：日期 01-31（本地时间）    | 15                       |
| `${HH}`                       | 节目开始时间：小时 00-23（本地时间）    | 18                       |
| `${mm}`                       | 节目开始时间：分钟 00-59（本地时间）    | 30                       |
| `${ss}`                       | 节目开始时间：秒数 00-59（本地时间）    | 45                       |
| `${duration}`                 | 节目时长（秒）                          | 7200                     |
| `${offset}`                   | 当前时间距节目开始的秒数                | 12600                    |

### `{}` 格式（使用 short format）

| 占位符               | 说明                                     | 示例输出                 |
| -------------------- | ---------------------------------------- | ------------------------ |
| `{utc}`              | 节目开始时间（UTC，ISO8601 格式）        | 2025-01-15T10:30:45.000Z |
| `{utc:YmdHMS}`       | 节目开始时间（UTC，自定义 short format） | 20250115103045           |
| `{utcend}`           | 节目结束时间（UTC，ISO8601 格式）        | 2025-01-15T12:30:45.000Z |
| `{utcend:YmdHMS}`    | 节目结束时间（UTC，自定义 short format） | 20250115123045           |
| `{start}`            | 同 `{utc}`                               | 2025-01-15T10:30:45.000Z |
| `{start:YmdHMS}`     | 同 `{utc:YmdHMS}`                        | 20250115103045           |
| `{end}`              | 同 `{utcend}`                            | 2025-01-15T12:30:45.000Z |
| `{end:YmdHMS}`       | 同 `{utcend:YmdHMS}`                     | 20250115123045           |
| `{lutc}`             | 当前时间（UTC，ISO8601 格式）            | 2025-01-15T14:00:00.000Z |
| `{lutc:YmdHMS}`      | 当前时间（UTC，自定义 short format）     | 20250115140000           |
| `{now}`              | 同 `{lutc}`                              | 2025-01-15T14:00:00.000Z |
| `{now:YmdHMS}`       | 同 `{lutc:YmdHMS}`                       | 20250115140000           |
| `{timestamp}`        | 当前 Unix 时间戳（秒）                   | 1736949600               |
| `{timestamp:YmdHMS}` | 同 `{lutc:YmdHMS}`                       | 20250115140000           |
| `{(b)YmdHMS}`        | 节目开始时间（本地时间，short format）   | 20250115183045           |
| `{(e)YmdHMS}`        | 节目结束时间（本地时间，short format）   | 20250115203045           |
| `{(b)YmdHMS\|UTC}`   | 节目开始时间（UTC，short format）        | 20250115103045           |
| `{(e)YmdHMS\|UTC}`   | 节目结束时间（UTC，short format）        | 20250115123045           |
| `{(b)timestamp}`     | 节目开始时间的 Unix 时间戳（秒）         | 1736937045               |
| `{(e)timestamp}`     | 节目结束时间的 Unix 时间戳（秒）         | 1736944245               |
| `{Y}`                | 节目开始时间：4 位年份（本地时间）       | 2025                     |
| `{m}`                | 节目开始时间：月份 01-12（本地时间）     | 01                       |
| `{d}`                | 节目开始时间：日期 01-31（本地时间）     | 15                       |
| `{H}`                | 节目开始时间：小时 00-23（本地时间）     | 18                       |
| `{M}`                | 节目开始时间：分钟 00-59（本地时间）     | 30                       |
| `{S}`                | 节目开始时间：秒数 00-59（本地时间）     | 45                       |
| `{duration}`         | 节目时长（秒）                           | 7200                     |
| `{offset}`           | 当前时间距节目开始的秒数                 | 12600                    |

### 格式说明

**Long Format（长格式）**：用于 `${}` 括号中的自定义格式

* `yyyy` - 4 位年份
* `MM` - 2 位月份（01-12）
* `dd` - 2 位日期（01-31）
* `HH` - 2 位小时（00-23）
* `mm` - 2 位分钟（00-59）
* `ss` - 2 位秒数（00-59）

示例：`${utc:yyyyMMddHHmmss}` → `20250115103045`

**Short Format（短格式）**：用于 `{}` 括号中的自定义格式

* `Y` - 4 位年份
* `m` - 2 位月份（01-12）
* `d` - 2 位日期（01-31）
* `H` - 2 位小时（00-23）
* `M` - 2 位分钟（00-59）
* `S` - 2 位秒数（00-59）

示例：`{utc:YmdHMS}` → `20250115103045`

## 相关文档

* [M3U 播放列表集成](./m3u-integration.md)：M3U 配置和线路标签
* [FCC 快速换台配置](./fcc-setup.md)：启用毫秒级换台功能
* [配置参数详解](../reference/configuration.md)：播放器相关配置参数
