agentleFS
ZLMediaKitZLMediaKit/pymkui/.github/instructions/copilot-instructions.md

pymkui / instructions

Copilot instructions206 starsChanged 8 months agoMITView on GitHub

本文件作为 GitHub Copilot 及其他 AI 辅助工具的上下文指令文件,同时也是本项目的开发规范文档。 最后更新:2026-03-18(补充 ZLM API 访问规范:getzlmbaseurl / getforward_headers) PyMKUI 是 ZLMediaKit 的业务管理前端工程,采用前后端分离架构: 所有 Python API 必须与 ZLMediaKit 的响应格式保持一致: code 取值约定(与 ZLMediaKit 对齐):

Files
copilot-instructions.md

PyMKUI 项目开发规范与 AI 辅助指令

本文件作为 GitHub Copilot 及其他 AI 辅助工具的上下文指令文件,同时也是本项目的开发规范文档。
最后更新:2026-03-18(补充 ZLM API 访问规范:get_zlm_base_url / get_forward_headers)


一、项目概述

PyMKUI 是 ZLMediaKit 的业务管理前端工程,采用前后端分离架构:

层次目录技术栈说明
前端frontend/原生 HTML + Tailwind CSS + 原生 JSSPA 风格,iframe 子页面组织
后端backend/Python 3.12 + FastAPI + SQLiteZLMediaKit Python 插件模式运行
媒体服务外部进程ZLMediaKit (C++)通过 HTTP API 交互
数据库data/SQLite (pymkui.db)业务数据持久化

运行架构

浏览器
  └─ ZLMediaKit 内置 HTTP 服务 (port 8080)
        ├─ 静态文件服务 → frontend/ 目录
        ├─ /index/api/* → ZLMediaKit 原生 C++ HTTP API
        └─ /index/pyapi/* → Python FastAPI (通过 mk_plugin 注入到 ZLMediaKit)
                                └─ SQLite 数据库

端口规划

端口协议服务
8080TCPZLMediaKit HTTP / WS / HLS / FLV / FMP4
8443TCPZLMediaKit HTTPS / WSS
1935TCPRTMP 推拉流
8554TCPRTSP
10000TCP/UDPRTP/RTCP (GB28181)
8000UDPWebRTC ICE/STUN

二、目录结构规范

pymkui/
├── .github/
│   └── copilot-instructions.md   # 本文件(AI 指令 + 开发规范)
├── frontend/
│   ├── index.html                # 主框架页(导航 + iframe 容器)
│   ├── login.html                # 登录页
│   ├── css/
│   │   ├── common.css            # 全局公共样式
│   │   ├── index.css             # 主框架样式
│   │   └── login.css             # 登录页样式
│   ├── js/
│   │   ├── api.js                # ★ 全局 API 封装对象(Api.*)
│   │   ├── dashboard.js          # 仪表板逻辑
│   │   ├── streams.js            # 流管理逻辑
│   │   ├── network.js            # 网络连接管理
│   │   ├── pull-proxy.js         # 拉流代理管理
│   │   ├── settings.js           # 服务器配置
│   │   ├── protocol-options.js   # 转协议预设管理
│   │   ├── whip.js               # WHIP 推流
│   │   ├── config_comments.js    # 配置项注释说明
│   │   └── lib/                  # 第三方库(jessibuca 等)
│   └── pages/                    # iframe 子页面
│       ├── dashboard.html
│       ├── streams.html
│       ├── network.html
│       ├── pull-proxy.html
│       ├── push-proxy.html
│       ├── settings.html
│       ├── protocol-options.html
│       ├── whip.html
│       └── auth.html
├── backend/
│   ├── config.py                 # 路径配置
│   ├── database.py               # SQLite 数据库操作类
│   ├── mk_logger.py              # 日志模块(适配 mk_loader/print 两种模式)
│   ├── mk_plugin.py              # ★ ZLMediaKit Python 插件入口
│   ├── py_http_api.py            # ★ FastAPI HTTP API 定义
│   ├── shared_loop.py            # 全局 asyncio 事件循环
│   └── requirements.txt
├── data/
│   └── pymkui.db                 # SQLite 数据库文件
└── README.md

三、后端开发规范(Python / FastAPI)

3.1 Python 版本与依赖

  • Python 版本:3.12+
  • 核心依赖(requirements.txt):
    psutil>=5.9.0
    httpx>=0.24.0
    fastapi>=0.100.0
    starlette>=0.30.0
    uvicorn[standard]>=0.22.0
    uvloop>=0.17.0

3.2 模块职责

模块职责注意事项
config.py项目路径常量只放路径配置,不放业务逻辑
database.pySQLite CRUD所有数据库操作集中此处,禁止在其他模块直接操作 SQLite
mk_logger.py统一日志使用 log_info/log_warn/log_error,禁止直接 print()
mk_plugin.pyZLM 插件入口实现 on_start/on_exit/on_publish/on_play 等回调
py_http_api.pyFastAPI 路由所有 Python 侧 HTTP API 定义在此
shared_loop.py异步事件循环全局唯一 asyncio loop,供跨线程协程使用

3.3 API 路由命名规范

  • Python API 路径前缀:/index/pyapi/(区别于 ZLM 原生的 /index/api/)
  • 命名风格:小写 + 下划线(snake_case),例如:
    • GET /index/pyapi/get_protocol_options_list
    • POST /index/pyapi/add_protocol_options
    • POST /index/pyapi/update_protocol_options
    • POST /index/pyapi/delete_protocol_options

3.4 API 响应格式规范

所有 Python API 必须与 ZLMediaKit 的响应格式保持一致:

# 成功
{"code": 0, "msg": "操作成功", "data": {...}}

# 失败  
{"code": -1, "msg": "失败原因描述"}

code 取值约定(与 ZLMediaKit 对齐):

code含义
0成功
-1业务失败(OtherFailed)
-100鉴权失败(AuthFailed)
-200SQL 执行失败(SqlFailed)
-300参数非法(InvalidArgs)
-400代码抛异常(Exception)

3.5 请求参数解析规范

FastAPI 路由必须同时支持 JSON body、form-urlencoded、GET query 三种传参方式。
使用已有的 get_param_from_request() 工具函数,或按以下顺序解析:

  1. Query 参数
  2. Body(JSON / form)
  3. Header
async def my_api(request: Request):
    body_bytes = await request.body()
    content_type = request.headers.get("content-type", "")
    
    if "application/json" in content_type or not content_type:
        data = json.loads(body_bytes.decode("utf-8"))
    elif "application/x-www-form-urlencoded" in content_type:
        parsed = urllib.parse.parse_qs(body_bytes.decode("utf-8"), keep_blank_values=True)
        data = {k: v[0] if len(v) == 1 else v for k, v in parsed.items()}
    # ...

3.6 调用 ZLMediaKit HTTP API 规范

Python 后端转发请求给 ZLMediaKit 时,必须使用以下两个统一工具函数,禁止手动拼接 URL 或手动透传 cookie:

get_zlm_base_url() — 获取 ZLM 内部访问地址

def get_zlm_base_url() -> str:
    """
    获取 ZLMediaKit 内部访问的 base URL。
    - http.port != 0  → http://127.0.0.1:{http.port}
    - http.port == 0  → https://127.0.0.1:{http.ssl_port}
    """
    http_port = mk_loader.get_config("http.port")
    try:
        http_port = int(http_port)
    except (TypeError, ValueError):
        http_port = 0

    if http_port != 0:
        return f"http://127.0.0.1:{http_port}"
    else:
        ssl_port = mk_loader.get_config("http.ssl_port")
        return f"https://127.0.0.1:{ssl_port}"
  • http.port 非 0 时使用 HTTP;为 0 时表示 HTTP 被禁用,自动切换 HTTPS + http.ssl_port
  • 禁止硬编码 http://127.0.0.1:8080 等端口

get_forward_headers(request) — 透传客户端 Cookie

def get_forward_headers(request: Request) -> dict:
    """从入站请求中提取需要透传给 ZLMediaKit 的 headers(目前仅 cookie)。"""
    headers: dict = {}
    cookie = request.headers.get("cookie")
    if cookie:
        headers["cookie"] = cookie
    return headers
  • 所有转发到 ZLM 的请求必须透传 cookie,否则会触发 ZLM 鉴权失败(code=-100)

标准调用示例

# ✅ 正确写法
zlm_url = f"{get_zlm_base_url()}/index/api/addStreamProxy"
zlm_params = {
    "vhost": vhost,
    "app": app,
    "stream": stream,
    "url": url,
}
response = await client.post(zlm_url, data=zlm_params, headers=get_forward_headers(request))
result = response.json()

# ❌ 错误写法(不允许)
zlm_url = f"http://127.0.0.1:{mk_loader.get_config('http.port')}/index/api/addStreamProxy"
response = await client.post(zlm_url, data=zlm_params)   # 缺少 cookie 透传
  • client 使用模块级全局 httpx.AsyncClient 单例,不要在每次请求中 async with httpx.AsyncClient()
  • ZLM API 参数使用 form-data(data=),不是 JSON(json=)

3.7 数据库规范

  • 数据库文件路径从 config.DATABASE_PATH 获取,不硬编码
  • 全局唯一 Database 实例(db = Database()),在 py_http_api.py 模块级初始化
  • 字段更新使用动态 SET 子句,更新时必须同步更新 updated_at
  • 流的唯一键由 (vhost, app, stream) 三元组组成,数据库层做 UNIQUE 约束
  • JSON 类型数据(如 custom_params)存储为 JSON 字符串

3.8 FastAPI 路由文档规范

每个路由必须有:

  • tags(按业务模块分组,如 ["拉流代理"]、["转协议预设"])
  • summary(中文简短说明)
  • docstring(详细参数说明)
@app.post(
    "/index/pyapi/addStreamProxy",
    tags=["拉流代理"],
    summary="添加拉流代理",
)
async def add_stream_proxy(request: Request):
    """
    添加拉流代理并同步到 ZLMediaKit
    
    参数:
    - vhost: 虚拟主机,默认 __defaultVhost__
    - app: 应用名(必选)
    - stream: 流ID(必选)
    - url: 拉流地址(必选)
    """

3.9 mk_plugin.py 回调规范

回调函数说明返回 True 含义
on_start()插件启动时调用,初始化配置-
on_exit()插件退出时调用-
on_publish(type, args, invoker, sender)推流鉴权事件被 Python 拦截
on_play(args, invoker, sender)播放鉴权事件被 Python 拦截
on_flow_report(...)流量上报事件被 Python 拦截
on_media_changed(is_register, sender)流注册/注销False = C++ 也处理
on_player_proxy_failed(url, ...)拉流代理失败False = C++ 也处理

on_start() 中必须执行:

mk_loader.set_config('api.legacyAuth', "0")       # 强制 cookie 登录
mk_loader.set_config('http.rootPath', frontend_path)  # 设置前端静态文件目录
mk_loader.update_config()
mk_loader.set_fastapi(check_route, submit_coro)   # 注册 FastAPI 到 ZLM

四、前端开发规范(HTML / CSS / JavaScript)

4.1 技术栈

技术引入方式说明
Tailwind CSSCDN(cdn.tailwindcss.com)主要 UI 框架
Font Awesome 4.7CDN图标库
Chart.js 4.xCDN图表
hls.jsCDNHLS 播放
Jessibucajs/lib/ 本地WebRTC/FLV 播放器

注意:不引入 Vue/React 等前端框架,保持原生 JS。

4.2 页面组织

  • index.html:主框架,包含侧边导航栏、顶部栏、iframe 容器
  • login.html:独立登录页
  • pages/*.html:各功能子页面,通过 <iframe> 嵌入主框架
  • 各子页面引入对应的 js/*.js 功能模块

4.3 主题与色彩规范

// Tailwind 主题配置(index.html 中定义)
colors: {
    primary: '#6366f1',    // 主色调(紫色)
    secondary: '#8b5cf6',  // 辅助色
    accent: '#ec4899',     // 强调色(粉色)
    dark: '#1e293b',       // 深色背景
    light: '#f8fafc',      // 浅色
}

常用 CSS 渐变类:

  • bg-gradient-primary:主色渐变按钮/卡片
  • bg-gradient-secondary:深色背景渐变
  • bg-gradient-accent:强调色渐变
  • text-gradient:渐变文字
  • hover:shadow-neon:霓虹光晕悬停效果

4.4 API 调用规范(前端)

所有 API 调用必须通过 api.js 中的 Api 对象,禁止直接 fetch:

// ✅ 正确
const result = await Api.getMediaList();
const result = await Api.request('/index/api/someApi', { body: {...} });

// ❌ 错误
const result = await fetch('/index/api/someApi', {...});

在 api.js 的 Api 对象中新增方法时遵循命名规范:

API 类型前端方法命名示例
ZLM 原生 GETget*getMediaList()
ZLM 原生操作动词+名词closeStream()
Python API GETget*getProtocolOptionsList()
Python API 增add*addStreamProxy()
Python API 改update*updateProtocolOptions()
Python API 删delete*deleteProtocolOptions()

Api.request() 默认参数:

// 默认 POST,JSON body,携带 cookie
Api.request(path, {
    method: 'POST',          // 可改为 'GET'
    body: { key: 'value' },  // 自动序列化为 JSON
})

4.5 认证机制

ZLMediaKit 使用 cookie + digest 认证(api.legacyAuth=0 模式):

  1. 调用 /index/api/getApiList → 获取 cookie(code=-100 时响应体携带)
  2. 计算 digest = MD5("zlmediakit:" + secret + ":" + cookie)
  3. 调用 /index/api/login?digest=xxx 完成登录
  4. 后续请求自动携带浏览器 session cookie(credentials: 'include')

认证状态检查使用 checkAuth()(在 api.js 中定义),所有子页面加载时调用。

4.6 页面功能模块规范

每个功能页面的 JS 文件应遵循以下结构:

// 1. 初始化函数(页面加载时调用)
function init<ModuleName>() {
    load<ModuleName>();
    // 绑定事件监听器
}

// 2. 加载数据函数
async function load<ModuleName>() {
    // 显示 loading 状态
    // 调用 API
    // 渲染数据到表格/列表
    // 处理错误
}

// 3. 操作函数(增删改)
async function add<Item>() {}
async function update<Item>() {}
async function delete<Item>() {}

// 4. 清理函数(页面切换时调用,释放播放器/定时器等资源)
function cleanup<ModuleName>() {}

4.7 Loading 状态规范

所有数据加载必须显示 loading 动画:

tbody.innerHTML = `
    <tr>
        <td colspan="8" class="p-10 text-center">
            <div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-primary mx-auto mb-4"></div>
            <span class="text-white/60 font-semibold">加载中...</span>
        </td>
    </tr>
`;

4.8 Toast 通知规范

使用 showToast(message, type, duration) 展示操作反馈:

showToast('操作成功', 'success');          // 成功(绿色)
showToast('操作失败: ' + result.msg, 'error');  // 失败(红色)
showToast('注意事项', 'warning');          // 警告(黄色)
showToast('提示信息', 'info');             // 信息(蓝色)

4.9 确认弹窗规范

危险操作(删除/停止/踢出等)必须使用 showConfirmModal() 二次确认:

showConfirmModal(
    '确认删除',
    '确定要删除该拉流代理吗?此操作不可恢复。',
    async function() {
        // 执行删除操作
    }
);

4.10 表格渲染规范

表格列对应字段不存在时统一显示 '-',不显示 undefined 或空字符串:

html += `<td class="p-4 text-white">${item.field || '-'}</td>`;

五、ZLMediaKit HTTP API 使用规范

5.1 API 分类速查

流管理

接口方法说明
/index/api/getMediaListGET/POST获取流列表,支持 schema/vhost/app/stream 过滤
/index/api/getMediaInfoGET/POST获取单路流信息(已过期,推荐用 getMediaList)
/index/api/close_streamsGET/POST关闭流(支持批量过滤)
/index/api/isMediaOnlineGET/POST判断流是否在线(已过期)

拉流代理

接口方法说明
/index/api/addStreamProxyGET/POST添加 RTSP/RTMP/HLS 拉流代理
/index/api/delStreamProxyGET/POST删除拉流代理(参数:key)
/index/api/listStreamProxyGET/POST获取拉流代理列表
/index/api/getProxyInfoGET/POST获取拉流代理详情(参数:key)

推流代理

接口方法说明
/index/api/addStreamPusherProxyGET/POST添加推流代理(转推)
/index/api/delStreamPusherProxyGET/POST删除推流代理
/index/api/listStreamPusherProxyGET/POST获取推流代理列表
/index/api/getProxyPusherInfoGET/POST获取推流代理详情

FFmpeg 代理

接口方法说明
/index/api/addFFmpegSourceGET/POST通过 FFmpeg 拉流代理(支持任意协议)
/index/api/delFFmpegSourceGET/POST删除 FFmpeg 拉流代理
/index/api/listFFmpegSourceGET/POST获取 FFmpeg 代理列表

录制管理

接口方法说明
/index/api/startRecordGET/POST开始录制(type: 0=HLS, 1=MP4)
/index/api/stopRecordGET/POST停止录制
/index/api/isRecordingGET/POST查询录制状态
/index/api/getMP4RecordFileGET/POST获取录像文件列表
/index/api/deleteRecordDirectoryGET/POST删除录像文件夹
/index/api/startRecordTaskGET/POST事件录制(支持回溯)

服务器管理

接口方法说明
/index/api/getServerConfigGET/POST获取服务器配置
/index/api/setServerConfigGET/POST修改服务器配置
/index/api/restartServerGET/POST重启服务器
/index/api/getStatisticGET/POST获取对象统计信息
/index/api/getThreadsLoadGET/POST获取 epoll 线程负载
/index/api/getWorkThreadsLoadGET/POST获取工作线程负载
/index/api/versionGET/POST获取版本信息

网络连接管理

接口方法说明
/index/api/getAllSessionGET/POST获取所有 TCP 连接
/index/api/kick_sessionGET/POST断开指定 TCP 连接(参数:id)
/index/api/kick_sessionsGET/POST批量断开 TCP 连接
/index/api/getMediaPlayerListGET/POST获取流观看者列表

截图

接口方法说明
/index/api/getSnapGET获取截图(返回 jpeg 图片)
/index/api/deleteSnapDirectoryGET/POST删除截图文件/文件夹

GB28181 / RTP

接口方法说明
/index/api/openRtpServerGET/POST创建 RTP 接收端口
/index/api/closeRtpServerGET/POST关闭 RTP 接收端口
/index/api/listRtpServerGET/POST列出所有 RTP 服务器
/index/api/startSendRtpGET/POST启动 PS-RTP 推流(GB28181 客户端)
/index/api/startSendRtpPassiveGET/POST启动 PS-RTP 被动推流
/index/api/stopSendRtpGET/POST停止 RTP 推流
/index/api/getRtpInfoGET/POST获取 RTP 流信息

WebRTC

接口方法说明
/index/api/webrtcPOSTWebRTC 播放/推流(SDP 交换)
/index/api/whipPOSTWHIP 标准推流接口
/index/api/whepPOSTWHEP 标准播放接口
/index/api/delete_webrtcDELETE删除 WebRTC 连接

多画面拼接

接口方法说明
/index/api/stack/startPOST启动多视频拼接(宫格)
/index/api/stack/resetPOST更新拼接参数
/index/api/stack/stopGET停止拼接

点播

接口方法说明
/index/api/loadMP4FileGET/POST点播 MP4 文件生成直播流
/index/api/setRecordSpeedGET/POST设置录像播放速度
/index/api/seekRecordStampGET/POST设置录像播放位置

认证

接口方法说明
/index/api/getApiListGET/POST获取 API 列表(同时用于获取 cookie)
/index/api/loginGET/POST登录(digest 认证)
/index/api/logoutGET/POST登出

5.2 关键参数说明

stream 标识规则

ZLMediaKit 中流的唯一标识(key)格式为:

{vhost}/{app}/{stream}
# 例如:__defaultVhost__/live/test

vhost 默认值:__defaultVhost__

originType 枚举:

值说明
0unknown
1rtmp_push(RTMP 推流)
2rtsp_push(RTSP 推流)
3rtp_push(RTP/GB28181 推流)
4pull(拉流代理)
5ffmpeg_pull(FFmpeg 拉流代理)
6mp4_vod(MP4 点播)
7device_chn(设备通道)

codec_id 枚举:

值编码
0H.264
1H.265
2AAC
3G.711A
4G.711U

addStreamProxy 转协议参数(同时适用于 Python 侧 protocol_options):

参数类型说明
enable_hlsbool转 HLS-MPEG-TS
enable_hls_fmp4bool转 HLS-FMP4
enable_mp4boolMP4 录制
enable_rtspbool转 RTSP/WebRTC
enable_rtmpbool转 RTMP/FLV
enable_tsbool转 HTTP-TS/WS-TS
enable_fmp4bool转 HTTP-FMP4/WS-FMP4
enable_audiobool转协议时是否携带音频
add_mute_audiobool无音频时添加静音 AAC
hls_demandboolHLS 按需生成
rtsp_demandboolRTSP 按需生成
rtmp_demandboolRTMP 按需生成
ts_demandboolHTTP-TS 按需生成
fmp4_demandboolHTTP-FMP4 按需生成
mp4_save_pathstringMP4 保存路径
mp4_max_secondintMP4 切片大小(秒)
mp4_as_playerboolMP4 录制是否计入观看人数
hls_save_pathstringHLS 保存路径
modify_stampint时间戳处理(0=绝对/1=系统/2=相对)
auto_closebool无人观看自动关闭
continue_push_msint推流断开后保留时间(毫秒)

六、Python API 说明(当前已实现)

6.1 系统性能

路径方法说明
/index/pyapi/host-statsGET获取 CPU/内存/磁盘/网络速率

响应示例:

{
    "code": 0,
    "data": {
        "time": "14:30:00",
        "cpu": 12.5,
        "memory": {"used": 2.1, "total": 8.0},
        "disk": {"used": 50.3, "total": 200.0},
        "network": {"sent": 1024.5, "recv": 2048.3, "sent_total": 10240, "recv_total": 20480}
    }
}

6.2 转协议预设管理

路径方法说明
/index/pyapi/add_protocol_optionsPOST添加预设
/index/pyapi/update_protocol_optionsPOST修改预设
/index/pyapi/delete_protocol_optionsPOST删除预设(参数:id)
/index/pyapi/get_protocol_options_listGET获取预设列表(id/name/created_at)
/index/pyapi/get_protocol_optionsGET获取预设详情(参数:id)

6.3 拉流代理管理

路径方法说明
/index/pyapi/addStreamProxyPOST添加拉流代理(同步到 ZLM + 写库)
/index/pyapi/delStreamProxyPOST删除拉流代理(同步到 ZLM + 写库,参数:key)
/index/pyapi/getStreamProxyListGET获取拉流代理列表(从数据库)
/index/pyapi/getStreamProxyGET获取拉流代理详情(参数:id)

七、数据库表结构说明

7.1 pull_proxies — 拉流代理

字段类型说明
idINTEGER PK自增主键
vhostTEXT虚拟主机,默认 __defaultVhost__
appTEXT应用名
streamTEXT流 ID
urlTEXT拉流地址
custom_paramsTEXT自定义参数(JSON 字符串)
protocol_paramsTEXT转协议参数(JSON 字符串)
enabledINTEGER是否启用(0/1)
created_atTIMESTAMP创建时间
updated_atTIMESTAMP更新时间

唯一约束:UNIQUE(vhost, app, stream)

7.2 push_tasks — 推流任务

字段类型说明
idINTEGER PK自增主键
nameTEXT任务名称
appTEXT应用名
streamTEXT流 ID
urlTEXT推流目标地址
enabledINTEGER是否启用(0/1)
created_atTIMESTAMP创建时间
updated_atTIMESTAMP更新时间

7.3 protocol_options — 转协议预设

存储用户自定义的转协议参数配置集,字段对应 ZLMediaKit [protocol] 配置节。
所有参数字段类型为 TEXT(NULL 代表使用 ZLM 默认配置)。

7.4 recordings — 录像记录

字段类型说明
idINTEGER PK自增主键
appTEXT应用名
streamTEXT流 ID
urlTEXT流 URL
file_pathTEXT录像文件路径
file_sizeINTEGER文件大小(字节)
created_atTIMESTAMP录像时间

八、已知问题与待修复事项

AI 辅助开发时请注意以下已知代码问题:

  1. database.py 部分方法中使用裸 print() 而非 mk_logger,后续统一替换为 mk_logger.log_warn()。
  2. py_http_api.py 部分 POST 接口:每个接口都重复实现了 body 解析逻辑,应重构为共享的 parse_request_body() 工具函数(get_param_from_request() 已有单字段版本,可参考扩展为整体 body 解析)。
  3. push_tasks 表已创建但暂无对应 API,待实现推流代理(转推)管理功能。

九、新功能开发指引

9.1 新增一个管理功能模块的完整步骤

  1. 数据库层(database.py):
    • 在 _create_tables() 中添加建表 SQL
    • 实现 add_*、get_*、get_all_*、update_*、delete_* 方法
  2. Python API 层(py_http_api.py):
    • 添加 @app.get/post 路由,路径格式 /index/pyapi/操作_资源
    • 如需联动 ZLMediaKit,通过 httpx 调用对应 /index/api/ 接口
  3. 前端 API 封装(js/api.js):
    • 在 Api 对象中添加对应方法
  4. 前端页面(pages/xxx.html + js/xxx.js):
    • 参照现有模块实现 init/load/add/update/delete 函数体
  5. 主框架导航(index.html):
    • 在侧边栏添加导航项和 iframe 切换逻辑

9.2 调用 ZLMediaKit 播放 URL 规则

# RTMP
rtmp://{host}:1935/{app}/{stream}

# HTTP-FLV
http://{host}:8080/{app}/{stream}.live.flv

# HLS
http://{host}:8080/{app}/{stream}/hls.m3u8

# HTTP-FMP4
http://{host}:8080/{app}/{stream}.live.mp4

# WebSocket-FLV
ws://{host}:8080/{app}/{stream}.live.flv

# RTSP
rtsp://{host}:8554/{app}/{stream}

# WebRTC (WHEP)
POST http://{host}:8080/index/api/whep?app={app}&stream={stream}

9.3 生成代码时的注意事项

  • 不要在 Python 代码中使用 print(),统一使用 mk_logger.log_info/warn/error()
  • 不要在前端代码中直接使用 fetch(),统一通过 Api.request()
  • 不要硬编码 ZLMediaKit 的 port 和 secret,从 mk_loader.get_config() 获取
  • 新增数据库表时,updated_at 字段通过 ON UPDATE 触发器或手动在代码中更新
  • 前端新页面使用 Tailwind CSS 时,遵循深色主题风格(bg-dark、text-white)
  • Python API 请求体解析须容忍 content-type 缺失的情况(默认当 JSON 处理)
  • ZLM API 中的布尔值参数:传 1/0 或 true/false 均可;数据库存储转协议参数时统一存为字符串

十、参考资源

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.