Owncast Plugin APIs
Owncast 插件运行时公开了一个全局的 owncast,并且可以调用宿主函数。 Most methods require the matching permission in your manifest. A call without it never reaches Owncast: the host logs the denial and the call does nothing. What your plugin sees depends on the method. Mutating calls that report an outcome raise an error (moderation, users.register, auth.grantSession, kv.set, videoConfig.write, actions.add, actions.clear, and every sql method), readers return an empty or zero value, and calls that return nothing become silent no-ops. fs.write, fs.delete, and storage.upload are the exceptions: they report failure in their return value rather than raising. A few methods are ambient and need no permission: logging, timers, reading bundled assets, and owncast.config.get.
Plugins require Owncast 0.3.0 or later.
调用会为两个 SDK 显示,请用选项卡选择您的语言。 有关设置,请参见 JavaScript 或 Python。 (JavaScript 方法名称为 camelCase,Python 使用 snake_case,所以 sendAction 变为 send_action,依此类推。)
Logging
owncast.log.info(message), .warning(message), and .error(message)
Write an operator-visible entry to Owncast's server log. Owncast records the calling plugin's slug and the matching info, warning, or error severity. It replaces control characters with spaces so each entry stays on one line, then truncates messages longer than 4 KiB.
- JavaScript
- Python
owncast.log.info('sync started');
owncast.log.warning('provider response is incomplete');
owncast.log.error('sync failed');
owncast.log.info("sync started")
owncast.log.warning("provider response is incomplete")
owncast.log.error("sync failed")
环境:无权限要求。 See the paired chat-logger examples for JavaScript and Python.
聊天
构建聊天机器人、管理工具或过滤器吗? 从 聊天插件 开始。
owncast.chat.send(text)
发布聊天消息。 作为您插件的机器人身份发送(来自 bot.displayName 或清单中的 name 的显示名称)。
- JavaScript
- Python
owncast.chat.send('hello chat');
owncast.chat.send("hello chat")
需要 chat.send。
owncast.chat.sendAction(text)
发布一种动作风格("/me")消息。
- JavaScript
- Python
owncast.chat.sendAction('is now live');
owncast.chat.send_action("is now live")
需要 chat.send。
owncast.chat.system(body)
发布一条服务器公告消息。 没有机器人身份附加。 正文以 HTML 内联呈现,因此用于短的、服务器归属的通知,例如“流在 5 分钟后开始”。 将正文视为不受信任的 HTML 输出:不要在未转义的情况下插入用户输入。
Requires chat.send.
owncast.chat.sendTo(clientId, text)
向单个连接的客户端发送私人消息。
Requires chat.send.
owncast.chat.replyTo(msg, text)
向发送聊天消息的人悄悄回复。 传递来自 onChatMessage/filterChatMessage 的聊天消息(或裸客户端 ID)。 如果发送者的连接未知(没有客户端 ID),则返回 false,因此您可以回退到公共 send。 在 sendTo(clientId, text) 上进行简化。
- JavaScript
- Python
onChatMessage(msg) {
if (!owncast.chat.replyTo(msg, "got it")) {
owncast.chat.send("got it");
}
}
@plugin.on_chat_message
def handle(msg):
if not owncast.chat.reply_to(msg, "got it"):
owncast.chat.send("got it")
需要 chat.send。
owncast.chat.history(limit?)
返回最近的聊天记录,每条记录包含 id、user、body 和 timestamp。 limit 默认为 50。
需要 chat.history。
owncast.chat.clients()
Return the list of currently-connected chat clients, each with id, userId?, displayName?, connectedAt?, userAgent?, ipAddress?, and messageCount. id 是用于 chat.kick 的每个连接的客户端 ID。
需要 chat.history。
owncast.chat.deleteMessage(messageId)
从观众那里隐藏一条聊天消息。
Requires chat.moderate.
owncast.chat.kick(clientId)
断开一个聊天客户端的连接。
Requires chat.moderate.
聊天身份
每个插件只有一个聊天身份,这是 Owncast 在安装插件时提供的机器人身份。 如果设置,则显示名称为您清单的 bot.displayName,否则为其 name,值为 IsBot: true。 send 和 sendAction 这两个方法以此身份发布,通过 Owncast 的正常聊天管道(过滤器、速率限制、审核)。 插件不能以任意名称发布或冒充真实用户。
机器人用户以插件的 slug 为关键字,因此身份在对 name 或 bot.displayName 的清单编辑中得以保存。 如果需要多个聊天角色,请发布多个插件。
用户
owncast.users.list() 和 owncast.users.get(id)
读取聊天用户列表或单个用户记录。
- JavaScript
- Python
const users = owncast.users.list();
const alice = owncast.users.get('u-alice');
users = owncast.users.list()
alice = owncast.users.get("u-alice")
需要 users.read。
owncast.users.setEnabled(id, enabled, reason?)
启用或禁用聊天用户。
- JavaScript
- Python
owncast.users.setEnabled('u-spammer', false, 'spam');
owncast.users.set_enabled("u-spammer", False, "spam")
需要 users.moderate。
owncast.users.banIP(ip)
禁止某个 IP 加入聊天。
- JavaScript
- Python
owncast.users.banIP('203.0.113.42');
owncast.users.ban_ip("203.0.113.42")
需要 users.moderate。
owncast.users.register({ authId, displayName?, scopes?, profileUrl?, handle?, public? })
Find or create an authenticated Owncast user for an external identity and return { userId }. Pass the provider's stable authId without adding your plugin slug. The host stores the slug separately as the identity provider, so plugins cannot collide with or spoof each other's users. displayName seeds a new user's name and is optional: omit it, or pass null, and Owncast generates a display name the same way it does for anonymous viewers. Non-empty scopes such as ["MODERATOR"] are applied on each call.
The optional profileUrl, handle, and public fields describe a verified external identity. profileUrl must be empty or an absolute HTTP(S) URL. handle is the provider's verified label, such as a GitHub login or fediverse handle. Set public to true only after the viewer opts into public display. It defaults to false. These profile fields are captured when the identity is first registered. Later calls with the same authId return the existing user but do not change the stored profile fields.
- JavaScript
- Python
const { userId } = owncast.users.register({
authId: 'github:583231',
displayName: 'octocat',
profileUrl: 'https://github.com/octocat',
handle: 'octocat',
public: false, // Set true only after the viewer opts in.
});
result = owncast.users.register(
"github:583231",
display_name="octocat",
profile_url="https://github.com/octocat",
handle="octocat",
public=False, # Set true only after the viewer opts in.
)
user_id = result.user_id
需要 users.register。
身份验证
这些提供了 观众身份验证门。 grantSession 和 endSession 仅在 onHttpRequest 处理程序内部工作,因为宿主会在飞行中的 HTTP 响应中附加会话 cookie。
owncast.auth.grantSession({ userId, ttl? })
为已注册用户(来自 owncast.users.register 的 userId)签发签名会话。 宿主生成、签名并将会话 cookie 附加到当前响应中;您的插件从不看到令牌,因此无法伪造或泄漏。 ttl 是一个可选的生存时间(以秒为单位)(0/省略使用宿主的默认值 24 小时)。
- JavaScript
- Python
const { userId } = owncast.users.register({ authId: 'shared', displayName: 'Guest' });
owncast.auth.grantSession({ userId });
return { status: 302, headers: { Location: returnTo } };
result = owncast.users.register("shared", display_name="Guest")
owncast.auth.grant_session(result.user_id)
return {"status": 302, "headers": {"Location": return_to}}
需要 auth.gate。
owncast.auth.endSession()
清除当前观众会话 cookie 以使其退出。 您的插件仍然控制重定向(并且可能会转到提供者的注销)。
- JavaScript
- Python
owncast.auth.endSession();
return { status: 302, headers: { Location: '/' } };
owncast.auth.end_session()
return {"status": 302, "headers": {"Location": "/"}}
需要 auth.gate。
存储
owncast.kv.get(key) 和 owncast.kv.set(key, value)
每个插件的键/值存储,由您插件的 slug 命名空间。 值为字符串。
对于更丰富的类型,使用 JSON 助手(getJSON / setJSON,Python 中使用 get_json / set_json)而不是自己解析和序列化。 JSON 获取器在键未设置或包含无效 JSON 时返回回退值。 插件无法读取彼此的键。
- JavaScript
- Python
owncast.kv.set('count', '1');
const n = Number(owncast.kv.get('count') ?? '0');
owncast.kv.setJSON('prefs', { theme: 'dark' });
const prefs = owncast.kv.getJSON('prefs', {});
owncast.kv.set("count", "1")
n = int(owncast.kv.get("count") or "0")
owncast.kv.set_json("prefs", {"theme": "dark"})
prefs = owncast.kv.get_json("prefs", {})
需要 storage.kv。
owncast.storage.upload(name, data)
上传文件到 Owncast 的公共文件区域。 JavaScript accepts a Uint8Array or string. Python accepts bytes or str. Raw bytes are preserved, while strings are encoded as UTF-8. JavaScript returns { url } or null. Python returns a dict accessed as result["url"], or None.
需要 storage.upload。
owncast.fs.*
A private, sandboxed filesystem at data/plugin-storage/\<your-slug>/files/. 与 owncast.storage.upload 不同,这些文件保持在服务器端:它们从不通过 HTTP 提供。 路径相对于您的沙盒根目录。 宿主将每个路径限制在自己的目录中(插件无法读取其他插件的文件,../ 或绝对路径会回滚到沙盒内部)。 所需的父目录在写入时会根据需要创建。
| JavaScript | Python | 返回值 |
|---|---|---|
fs.read(path) | fs.read(path) | Uint8Array / bytes, or null / None if missing |
fs.readText(path) | fs.read_text(path) | UTF-8 string / str, or null / None if missing |
fs.write(path, data) | fs.write(path, data) | { error? } |
fs.list(dir) | fs.list(dir) | 条目名称(缺失的目录为空) |
fs.delete(path) | fs.delete(path) | { error? } for a file or empty directory |
fs.exists(path) | fs.exists(path) | 布尔值 |
fs.read preserves the original bytes. fs.readText and fs.read_text decode UTF-8. Python replaces malformed byte sequences when decoding. fs.write preserves a JavaScript Uint8Array or Python bytes, and UTF-8 encodes strings. fs.write and fs.delete return {} on success. If the host rejects the operation, they return { error } with the reason.
- JavaScript
- Python
owncast.fs.write('notes/log.txt', 'hello');
const text = owncast.fs.readText('notes/log.txt');
const data = new Uint8Array([0xff, 0x00, 0x80]);
owncast.fs.write('cache/data.bin', data);
const stored = owncast.fs.read('cache/data.bin');
if (stored) owncast.storage.upload('data.bin', stored);
owncast.fs.write("notes/log.txt", "hello")
text = owncast.fs.read_text("notes/log.txt")
data = bytes((0xFF, 0x00, 0x80))
owncast.fs.write("cache/data.bin", data)
stored = owncast.fs.read("cache/data.bin")
if stored is not None:
owncast.storage.upload("data.bin", stored)
需要 storage.fs.
owncast.sql.*
One private SQLite database per plugin, at data/plugin-storage/\<your-slug>/db/plugin.db, separate from Owncast's own database and from the storage.fs sandbox. The sandbox is rooted at files/, so db/ is not a path owncast.fs.* refuses but one it cannot express, and the filesystem quota walk covers files/ only, so the two quotas stay independent. Reach for this over storage.kv when you need to sort, filter, or aggregate rather than just remember a value.
| Method | Returns |
|---|---|
sql.exec(sql, params?) | { rowsAffected, lastInsertId } |
sql.query(sql, params?) | rows as objects keyed by column name |
sql.queryRow(sql, params?) | the first row object, or null when nothing matched |
In Python queryRow is query_row, rows come back as dicts, and query_row returns None when nothing matched. An error throws in JavaScript and raises RuntimeError in Python. Parameters are null/None, booleans, numbers, or strings. Anything else is refused.
- JavaScript
- Python
owncast.sql.exec(`CREATE TABLE IF NOT EXISTS chatters (
user_id TEXT PRIMARY KEY,
messages INTEGER NOT NULL DEFAULT 0
)`);
owncast.sql.exec(
`INSERT INTO chatters (user_id, messages) VALUES (?, 1)
ON CONFLICT (user_id) DO UPDATE SET messages = messages + 1`,
[msg.user.id],
);
const top = owncast.sql.query(
'SELECT user_id, messages FROM chatters ORDER BY messages DESC LIMIT ?',
[5],
);
const mine = owncast.sql.queryRow('SELECT messages FROM chatters WHERE user_id = ?', [msg.user.id]);
owncast.sql.exec("""
CREATE TABLE IF NOT EXISTS chatters (
user_id TEXT PRIMARY KEY,
messages INTEGER NOT NULL DEFAULT 0
)
""")
owncast.sql.exec(
"""
INSERT INTO chatters (user_id, messages) VALUES (?, 1)
ON CONFLICT (user_id) DO UPDATE SET messages = messages + 1
""",
[msg.user.id],
)
top = owncast.sql.query(
"SELECT user_id, messages FROM chatters ORDER BY messages DESC LIMIT ?",
[5],
)
mine = owncast.sql.query_row("SELECT messages FROM chatters WHERE user_id = ?", [msg.user.id])
Each exec call runs as one host-owned transaction. A multi-statement batch commits whole or leaves the database untouched, so a schema migration can't half-apply. A plugin cannot leave a transaction open across calls, so there's nothing to clean up either.
query never hands back a silently short result. A query that overruns the row cap or the result budget is an error telling you to add a LIMIT, so write the bound you actually want when a table grows with your audience. queryRow reads a single row, which keeps it cheap on a table query is too big for.
| Limit | Value |
|---|---|
| Encoded request | 64 KiB total JSON |
| Bound parameters | 64 per call |
| Returned column value | 1 MiB |
| Encoded query result | 1 MiB |
| Rows returned | 10000 |
| Call duration | 2 seconds |
| Database size | 128 MiB |
Ordinary SQL is unaffected: DDL, DML, indexes, views, triggers, ORDER BY, recursive CTEs, subqueries, UNION, and the json1 functions all work. Refused in every host: ATTACH, DETACH, every PRAGMA (reads included), temporary-schema DDL both as keywords (CREATE TEMP TABLE / INDEX / TRIGGER / VIEW) and schema-qualified (CREATE TABLE temp.x), load_extension(), VACUUM and VACUUM INTO, and transaction controls (BEGIN, COMMIT, END, ROLLBACK, SAVEPOINT, and RELEASE). exec already owns the transaction around the whole batch.
Parameters and results cross the host boundary as JSON. Python can bind and read exact 64-bit SQLite integers. JavaScript loses unsafe integers before JSON.stringify on writes and during JSON.parse on reads. Store values above Number.MAX_SAFE_INTEGER (2^53 - 1) as TEXT when a JavaScript plugin needs them to remain exact.
Requires storage.sql. For a worked example, the chat-leaderboard plugin covers schema creation in one atomic exec, an ON CONFLICT upsert, a bounded ranked query, and a single-row read, in both JavaScript and Python. It contrasts with message-counter, which keeps the same counts in storage.kv and cannot rank.
配置
owncast.config.get(key, fallback?)
读取你插件的一个声明的config设置。 当存在时返回管理员设置的值,否则返回声明的默认值,已经解析为其声明的类型。 对于一个未知的键(或没有值的键)将返回fallback。
- JavaScript
- Python
const cooldownMs = owncast.config.get('cooldownMs', 2000);
cooldown_ms = owncast.config.get("cooldownMs", 2000)
Ambient: no permission required. 优先选择此选项,而不是为简单的旋钮构建自定义设置页面和键/值管道。 (配置键是你在手动中命名的名称,并且不按照语言翻译。)
网络
owncast.http.fetch(url, opts?)
同步的出站 HTTP 请求。 opts 包含 method,headers 和 body。 结果是 { status, headers, body }. 只有在你的手动中列出的 network.allowedHosts 的主机是可达的。 其余一切返回错误。
- JavaScript
- Python
const res = owncast.http.fetch('https://api.example.com/status');
if (res.status === 200) {
const data = JSON.parse(res.body);
}
import json
res = owncast.http.fetch("https://api.example.com/status")
if res.status == 200:
data = json.loads(res.body)
需要 network.fetch 和在 network.allowedHosts 中匹配的条目。 使用这个进行出站 HTTP 而不是你语言自己的 HTTP 客户端(在 Python 中,不要使用 requests:它不会编译成插件)。
请参见手动参考:网络以获取允许列表语法。
插件到插件事件
owncast.events.emit(eventType, payload)
Emit to a custom hook owned by another plugin. eventType is the fully
qualified \<recipient-slug>.\<hook> target. The host dispatches that exact name
and does not add the emitter's slug. The receiving plugin declares only its
local hook name. See the
handlers reference.
- JavaScript
- Python
owncast.events.emit('announcer.announcement.broadcast', { text: 'We are live' });
owncast.events.emit("announcer.announcement.broadcast", {"text": "We are live"})
需要 events.emit。
流和服务器状态
owncast.stream.current()
The current live stream state: { online, title?, summary?, viewers, startedAt?, latencyLevel? }.
Requires server.read.
owncast.stream.broadcaster()
Inbound encode telemetry for the current connection: { remoteAddr?, codecs?, resolution?, framerate?, bitrates? }. 只读,当没有连接广播时为零值。 要更改视频输出,请参见下方的视频配置组。
需要 server.read。
owncast.server.info()
Static server info: { name?, url?, summary?, welcomeMessage?, version? }.
- JavaScript
- Python
const name = owncast.server.info().name;
name = owncast.server.info().name
需要 server.read。
owncast.server.socials()
The streamer's configured social links, each { platform, url, icon? }.
Requires server.read.
owncast.server.emotes()
服务器的自定义聊天表情:与公共/api/emoji端点提供的相同集合,每个{ name, url }。 用于服务器端渲染或过滤:code:表情。
需要 server.read。
owncast.server.federation()
Whether fediverse federation is enabled and under what handle: { enabled, username?, isPrivate? }. username is omitted when unset, and isPrivate is present only when true.
需要 server.read。
owncast.server.tags()
流媒体配置的标签,作为字符串列表。
需要 server.read。
视频和转码配置
owncast.videoConfig.read()
Returns the current VideoConfig.
| Field | Type | Values |
|---|---|---|
latencyLevel | number | 0 through 4 |
codec | string | Configured ffmpeg encoder name |
autoplay | string | off, always, or sound-only |
variants | StreamVariant[] | Configured output renditions |
codec reads can report a legacy value or an encoder added by a newer host. Writes accept libx264, h264_omx, h264_vaapi, h264_qsv, h264_nvenc, h264_v4l2m2m, or h264_videotoolbox. Hardware codecs require the matching encoder in the host's ffmpeg build.
Autoplay off requires the viewer to press play. always starts automatically and may fall back to muted playback. sound-only starts automatically only when the browser allows sound.
Each StreamVariant has these fields:
| Field | Type | Description |
|---|---|---|
width | number | Scaled output width |
height | number | Scaled output height |
framerate | number | Output frames per second |
videoBitrate | number | Video bitrate in kbps |
cpuUsageLevel | number | Processing usage from 0 (lowest) through 4 (highest) |
isPassthrough | boolean | Pass video through without transcoding |
Audio settings are not exposed to plugins. Owncast preserves the existing audio configuration for each variant a plugin updates.
- JavaScript
- Python
const cfg = owncast.videoConfig.read();
cfg = owncast.video_config.read()
需要 videoconfig.read。
owncast.videoConfig.write(partial)
Update any of the VideoConfig fields above. 传递部分对象。 只有包含的字段才会被更改。 更改在下次流开始时应用:主机不会重新启动正在进行的广播。
- JavaScript
- Python
owncast.videoConfig.write({ latencyLevel: 2, autoplay: "sound-only" });
owncast.video_config.write({"latencyLevel": 2, "autoplay": "sound-only"})
需要 videoconfig.write。 这是高信任的。 管理员应该谨慎授予。
通知
owncast.notifications.discord(text)
通过流媒体的配置网页发送 Discord 通知。
需要 notifications.send。
owncast.notifications.browserPush({ title, body, url? })
推送到订阅的浏览器。
- JavaScript
- Python
owncast.notifications.browserPush({ title: 'Live now', body: 'Come say hi', url: '/' });
owncast.notifications.browser_push({"title": "Live now", "body": "Come say hi", "url": "/"})
需要 notifications.send。
owncast.notifications.fediverse({ type, body, image?, link? })
发送格式化为联邦宇宙的通知(呈现为对关注者的帖子)。
需要 notifications.send。
联邦宇宙
owncast.fediverse.post(text)
从 Owncast 账户向联邦宇宙发布公共帖子。
Returns { url } on success (currently with an empty url: Owncast publishes the note but does not yet return its URL), or null when the host rejects the call.
需要 fediverse.post。 高信任:联邦宇宙的帖子以流媒体的自主句柄发布,无法静默撤销。 管理员应该谨慎授予。
操作按钮(运行时)
owncast.actions.add(button | buttons[])
在不重新加载的情况下,将一个或多个操作按钮附加到你的插件手动集中。 每个按钮都需要与 manifest.actions 条目相同的字段(title,以及 url/openExternally 或内联的 html)。 主机使用与 manifest.actions 相同的规则验证每个条目,并持久化结果以便于添加生存超载。 A rejected entry throws an error naming the entry and the rule it broke, and the whole batch is rejected, so nothing is added when any entry is invalid.
- JavaScript
- Python
owncast.actions.add({ title: 'Donate', url: '/plugins/my-plugin/donate', openExternally: true });
owncast.actions.add({"title": "Donate", "url": "/plugins/my-plugin/donate", "openExternally": True})
需要 ui.modify。
owncast.actions.clear()
删除所有运行时添加的操作按钮。 声明的操作仍然存在。
需要 ui.modify。
在用户界面:操作按钮中有完整的说明。
实时推送(服务器发送的事件)
owncast.sse.send(channel, event, data)
推送服务器发送的事件到每个连接到你插件的 /_sse/\<channel> 端点的浏览器。
channel:推送到哪个流。 使用""表示默认通道。event:浏览器监听的事件名称。 使用""表示默认的message事件。data:有效负载。 字符串原样发送。 其他任何内容都将为你 JSON 编码。
- JavaScript
- Python
owncast.sse.send('alerts', 'donation', { from: 'alice', amount: 5 });
owncast.sse.send("alerts", "donation", {"from": "alice", "amount": 5})
火并遗忘。 调用会立即返回,并且不会阻塞。 慢速客户端会丢帧,而不是使您的插件停顿。
需要 http.sse。
在 提供 HTTP:实时更新 中的完整覆盖。
计时器
安排延迟和重复的工作。 计时器是 环境,不需要权限,并在您的插件被禁用时自动清除。 (Python: set_timeout, set_interval, clear。)
owncast.timer.setTimeout(fn, ms)
在 ms 毫秒后运行一次 fn。 返回一个 id。
owncast.timer.setInterval(fn, ms)
每 ms 毫秒重复运行 fn。 返回一个 id。
owncast.timer.clear(id)
通过调用返回的 id 取消一个待处理的超时或间隔。
捆绑的资源
读取您在插件的 assets/ 目录中发送的文件。 环境: 不需要权限。 (Python: read, read_text。)
owncast.assets.read(path) and owncast.assets.readText(path)
Read a file bundled under assets/, relative to that directory. read returns the original bytes as a JavaScript Uint8Array or Python bytes. readText and Python's read_text decode the bytes as UTF-8. Python replaces malformed byte sequences when decoding. Missing files return null in JavaScript or None in Python.
- JavaScript
- Python
const image = owncast.assets.read('badge.png');
const template = owncast.assets.readText('template.html');
image = owncast.assets.read("badge.png")
template = owncast.assets.read_text("template.html")
完整的 API 参考
下面的方法名称为 JavaScript(驼峰命名)形式。 Python 等价物为 snake_case(sendAction → send_action, banIP → ban_ip, videoConfig → video_config,依此类推)。
| API | 权限 |
|---|---|
owncast.log.info / .warning / .error | 无(环境) |
owncast.chat.send | chat.send |
owncast.chat.sendAction | chat.send |
owncast.chat.sendTo | chat.send |
owncast.chat.system | chat.send |
owncast.chat.replyTo | chat.send |
owncast.chat.history | chat.history |
owncast.chat.clients | chat.history |
owncast.chat.deleteMessage | chat.moderate |
owncast.chat.kick | chat.moderate |
owncast.users.list / .get | users.read |
owncast.users.setEnabled / .banIP | users.moderate |
owncast.users.register | users.register |
owncast.auth.grantSession / .endSession | auth.gate |
owncast.kv.get / .set / .getJSON / .setJSON | storage.kv |
owncast.storage.upload | storage.upload |
owncast.fs.read / .readText / .write / .list / .delete / .exists | storage.fs |
owncast.sql.exec / .query / .queryRow | storage.sql |
owncast.http.fetch | network.fetch |
owncast.events.emit | events.emit |
owncast.stream.current | server.read |
owncast.stream.broadcaster | server.read |
owncast.server.info / .socials / .emotes / .federation / .tags | server.read |
owncast.videoConfig.read | videoconfig.read |
owncast.videoConfig.write | videoconfig.write |
owncast.notifications.discord / .browserPush / .fediverse | notifications.send |
owncast.fediverse.post | fediverse.post |
owncast.actions.add / .clear | ui.modify |
owncast.timer.setTimeout / .setInterval / .clear | 无(环境) |
owncast.assets.read / .readText | 无(环境) |
owncast.config.get | none (ambient) |
owncast.sse.send | http.sse |
Improve this page
See something missing or incorrect? Edit this page and improve the documentation for everyone.
Gabe Kangas