Better and Cheaper Than IPTV

Better and Cheaper Than IPTV

比 IPTV 更好、更便宜

Castor Smart TVs won’t cast arbitrary web video, and screen mirroring is laggy and drops resolution. Castor casts the real stream instead, at full quality, from your terminal. Point Castor at a web page you are watching, or at a direct stream URL, and it finds the video, extracts the stream, transcodes it for your TV, and casts in real time. Castor 智能电视无法投屏任意网页视频,而屏幕镜像不仅延迟高,还会降低分辨率。Castor 则直接从你的终端以全画质投射真实的流媒体。只需将 Castor 指向你正在观看的网页或直接的流媒体 URL,它就能找到视频、提取流、为你的电视进行转码,并实时投屏。

It can also resolve an IMDB/TMDB id against sources you configure yourself, and burn in auto-generated subtitles. To extract, it launches headless Chrome and watches network traffic over the Chrome DevTools Protocol, then runs a short action pipeline to start playback: click the page, navigate into the largest iframe, and click again as a fallback. This works on pages that allow automated playback, and won’t work everywhere. A general-purpose casting tool: it casts only what you point it at. See Purpose and disclaimer. Run castor cast to browse titles and cast, without leaving the terminal. 它还可以根据你自行配置的源解析 IMDB/TMDB ID,并烧录自动生成的字幕。为了提取视频,它会启动无头 Chrome 并通过 Chrome DevTools 协议监控网络流量,然后运行一个简短的操作流水线来启动播放:点击页面,导航到最大的 iframe,并点击作为备选方案。这适用于允许自动播放的页面,但并非在所有地方都有效。这是一个通用的投屏工具:它只投射你指定的内容。请参阅“目的与免责声明”。运行 castor cast 即可在终端内浏览标题并进行投屏。

Installation

安装

The recommended way to run Castor is the native binary. It runs directly on your machine, so it shares your TV’s network (required for device discovery). It requires Chrome/Chromium (headless extraction), ffmpeg (transcoding), and ffprobe (format detection) on your PATH. A Linux-only Docker image that bundles all three is also available. 推荐运行 Castor 的方式是使用原生二进制文件。它直接在你的机器上运行,因此与你的电视共享网络(设备发现所必需)。它要求你的 PATH 中包含 Chrome/Chromium(用于无头提取)、ffmpeg(用于转码)和 ffprobe(用于格式检测)。此外,还提供了一个集成了这三者的 Linux 专用 Docker 镜像。

Homebrew (macOS) brew install --cask stupside/tap/castor

From source Needs Go 1.26+ and cmake (the whisper.cpp bindings are cgo and link a locally built libwhisper.a): 从源码安装 需要 Go 1.26+ 和 cmake(whisper.cpp 绑定是 cgo,并链接本地构建的 libwhisper.a):

git clone --recurse-submodules https://github.com/stupside/castor.git
cd castor
make # builds libwhisper.a, then the castor binary

go install won’t work: the vendored whisper.cpp bindings come in through a local replace and need that prebuilt static lib. go install 将无法工作:vendored 的 whisper.cpp 绑定是通过本地替换引入的,需要预先构建的静态库。

Quick start

快速入门

Tell Castor which TV to use: find its name with castor scan and put it in config.yaml. 告诉 Castor 使用哪台电视:使用 castor scan 找到其名称,并将其放入 config.yaml

device:
  name: "Living Room TV" # exact name from `castor scan`
  type: dlna

Now cast a page you are watching, or a stream URL you have: 现在,投射你正在观看的页面或你拥有的流媒体 URL:

castor cast player https://example.com/watch/some-video

For the interactive browser, which searches titles and casts them for you, add a TMDB key and a source (see Configuration), then run castor cast: 对于交互式浏览器(它会为你搜索标题并投屏),请添加 TMDB 密钥和源(参见“配置”),然后运行 castor cast

Run castor --help for every command and its flags. 运行 castor --help 查看所有命令及其标志。

Configuration

配置

Castor reads config.yaml from the current directory, or the path passed to --config. The only required key is the device to cast to (shown in Quick start); everything mechanical (timeouts, probing, capture, transcoding, network interface, Chrome discovery) has working defaults. Keep secrets out of the committed file: put them in a git-ignored config.local.yaml that overlays it, or in CASTOR_SECTION__FIELD environment variables. See SECURITY.md. Castor 会从当前目录读取 config.yaml,或者从传递给 --config 的路径读取。唯一必需的键是投屏设备(如“快速入门”所示);所有机械性设置(超时、探测、捕获、转码、网络接口、Chrome 发现)都有默认值。请勿将密钥提交到文件中:将其放入 git 忽略的 config.local.yaml 中进行覆盖,或使用 CASTOR_SECTION__FIELD 环境变量。请参阅 SECURITY.md

Sources

cast movie, cast episode, and the interactive browser resolve a title id against sources you configure. Castor bundles none, so add your own (sites you are authorized to use). There is no catalog and no lookup: Castor substitutes the id into the templates you write, prefixes each of your proxies, and opens the resulting page, then extracts the stream exactly like cast player. cast moviecast episode 和交互式浏览器会根据你配置的源解析标题 ID。Castor 不捆绑任何源,因此请添加你自己的源(你被授权使用的网站)。这里没有目录和查找功能:Castor 会将 ID 替换为你编写的模板中,为每个代理添加前缀,打开生成的页面,然后像 cast player 一样提取流。

For example, castor cast movie tt12300742 opens https://your-source.example/embed/movie/tt12300742. 例如,castor cast movie tt12300742 会打开 https://your-source.example/embed/movie/tt12300742

sources:
  - proxies: ["https://your-source.example"] # base URLs, tried in order
    templates:
      movie: "/embed/movie/{itemID}"
      episode: "/embed/tv/{itemID}/{season}-{episode}"

TMDB

TMDB

The interactive browser (castor cast) uses a TMDB API key to search titles; direct commands like cast movie <id> do not need it. Get a free key from themoviedb.org and keep it in config.local.yaml: 交互式浏览器 (castor cast) 使用 TMDB API 密钥来搜索标题;像 cast movie <id> 这样的直接命令不需要它。从 themoviedb.org 获取免费密钥并将其保存在 config.local.yaml 中:

tmdb:
  api_key: "<KEY>"

Subtitles

字幕

Auto-generated subtitles, transcribed with whisper and burned into the video. Off by default: 自动生成的字幕,使用 whisper 转录并烧录到视频中。默认关闭:

whisper:
  enable: true # off by default
  # language: "fr" # default: English
  # model_path: "" # default: ggml-tiny.en (~75 MB, auto-downloaded)

Supported devices

支持的设备

DLNA / UPnP Any TV implementing the DLNA/UPnP MediaRenderer:1 profile works, which covers virtually every smart TV sold in the last decade: Samsung (tested), LG, Sony Bravia, Panasonic Viera, Philips, Hisense, TCL, VIZIO, Sharp. Networked players like Kodi, VLC, and Plex also work. Run castor scan to list what is on your network. 任何实现 DLNA/UPnP MediaRenderer:1 配置文件的电视都可以工作,这涵盖了过去十年销售的几乎所有智能电视:三星(已测试)、LG、索尼 Bravia、松下 Viera、飞利浦、海信、TCL、VIZIO、夏普。像 Kodi、VLC 和 Plex 这样的网络播放器也可以工作。运行 castor scan 列出你网络上的设备。

Chromecast Experimental: implemented but untested. Contributions welcome. 实验性功能:已实现但未经测试。欢迎贡献。

Docker (optional)

Docker(可选)

A Linux-only alternative that bundles Chrome, ffmpeg, and ffprobe. 一个仅限 Linux 的替代方案,集成了 Chrome、ffmpeg 和 ffprobe。

Warning: Docker can only reach your TV from a Linux host on the same LAN. Discovery uses SSDP multicast and the TV streams back from Castor’s replay server, and neither survives Docker’s bridge network, so --network host is required. 警告: Docker 只能从同一局域网内的 Linux 主机访问你的电视。发现功能使用 SSDP 多播,电视从 Castor 的重放服务器回传流,这两者都无法在 Docker 的桥接网络中存活,因此必须使用 --network host

On Docker Desktop (macOS/Windows) that flag is a silent no-op: the container lands on Docker Desktop’s internal VM subnet (e.g. 192.168.65.x) instead of your LAN, so scan finds nothing and cast fails with device "…" (type dlna) not found. Run the native binary on macOS/Windows instead, or bridge a Linux VM onto your LAN (e.g. Lima + socket_vmnet). 在 Docker Desktop (macOS/Windows) 上,该标志会静默失效:容器会进入 Docker Desktop 的内部 VM 子网(例如 192.168.65.x)而不是你的局域网,因此 scan 找不到任何东西,cast 会报错 device "…" (type dlna) not found。请改在 macOS/Windows 上运行原生二进制文件,或将 Linux VM 桥接到你的局域网(例如 Lima + socket_vmnet)。

On a Linux box or NAS on the same network as the TV, the prebuilt ghcr.io/stupside/castor image saves you installing the dependencies by hand: 在与电视处于同一网络的 Linux 主机或 NAS 上,预构建的 ghcr.io/stupside/castor 镜像可以让你免于手动安装依赖:

# Discover devices (no config required)
docker run --rm --network host ghcr.io/stupside/castor:latest scan

# Cast, mounting config.yaml and a persistent model cache
docker run --rm --network host \
  -v "$PWD/config.yaml:/config.yaml" \
  -v castor-cache:/root/.cache \
  ghcr.io/stupside/castor:latest \
  cast player https://example.com/watch/some-video

The container reads config from config.yaml at /config.yaml, so run every command from the directory holding it. The castor-cache volume keeps the auto-downloaded whisper models between runs; swap :latest for any release tag to pin a version. 容器从 /config.yaml 读取配置,因此请在包含该文件的目录中运行每个命令。castor-cache 卷可以在运行之间保留自动下载的 whisper 模型;将 :latest 替换为任何发布标签以固定版本。

Purpose and disclaimer

目的与免责声明

Castor is a general-purpose caster, not a service tied to any particular site. It hosts nothing. No bundled video, catalog, or sources: Castor casts only a page, stream URL, or source you supply and are authorized to use, much like a Chromecast. It does not touch DRM. Castor does not decrypt or circumvent DRM, and cannot cast DRM-protected services. Castor 是一个通用投屏器,而不是绑定到任何特定网站的服务。它不托管任何内容。没有捆绑视频、目录或源:Castor 只投射你提供并授权使用的页面、流媒体 URL 或源,就像 Chromecast 一样。它不涉及 DRM。Castor 不会解密或规避 DRM,也无法投射受 DRM 保护的服务。