超级直播海外版

JS 解析规则 · 开发文档

需超级直播海外版 3.2.0 及以上。在频道地址里用 js:// 调用本机或 HTTP(S) 上的 JavaScript 脚本,把网页/接口解析成可播放地址。运行时为内置 QuickJS;脚本里可用 ms、ku9(与 cjs 同一对象)。

版本要求:js:// 解析规则自超级直播海外版 3.2.0(versionCode 360)起支持;更早版本不可用。请先到 下载页 安装最新 APK。
适用客户端:超级直播海外版(包名 com.hd.zhibo)需开启「扩展支持库 / JS」能力后,才可跑用户脚本。支持本机文件(外部存储 cjzb/js/,路径由系统现取,勿写死 /storage/emulated/0),以及远程 js://http(s)://…/xxx.js?id=;也可简写为 js_http://… / js_https://…(等价)。

1. 脚本怎么跑

频道地址写法入口
js:///绝对路径.js
或 js://http(s)://某脚本.js?id=
或简写 js_http:// / js_https://某脚本.js?id=
全局 main(item)。远程简写会归一成 js://http(s)://…;远程时 item.url 为真实 http(s)://…(含查询)
局域网 http://盒子IP:9188/ms/js/文件名.js?id= 同一份 main(item)(手机助手可访问盒子上的脚本)
/sdcard/cjzb/http.js http_dispatch(method, path, query, body),仅当内置 Lua 没有这条路由时

item 常用字段:

  • item.url:整段频道地址(含 js://… 与查询)
  • item.pageUrl:查询参数 page= 的值(若有)
  • item.name:频道 id / 名称侧传入的标识

推荐返回对象(也可用字符串直接返回可播 URL):

function main(item) {
  // …
  return {
    url: "https://cdn.example/live.m3u8",
    referer: "https://www.example.com/",
    userAgent: "Mozilla/5.0"
  };
}

url 必填。也可用 playUrl / playurl,或 { urls: [{ url: "…" }] }。referer、userAgent(或 ua)以及 headers 对象会写入播放请求头。

2. 运行限制

  • 脚本最长约 1MB;运行内存上限约 16MB;单次执行超过约 20 秒会被打断。
  • 脚本里发起的 HTTP 只允许 http:// / https://,单次回包上限约 2MB。
  • 最终播放地址协议须为:http(s) / rtmp / rtsp / udp / rtp / file。
  • 调试:脚本里 ku9.log(...) 或 ms.log("i", "…"),logcat 标签多为 Qjs。

返回的播放地址前面可加解码前缀(可选)。宿主在真正起播前会剥掉前缀,再把剩下的 URL 交给对应解码路径;脚本里读到的 item.url 一般已是剥过的干净地址,不要自己再解析或叠两层(如 sys:sys:…)。规范写法是单冒号;写成 sys:// / soft:// / soft_hw:// 也等价(宿主会连同紧随的 // 一并去掉)。

前缀含义例子
sys: 强制走系统播放器(Android MediaPlayer / 厂商播放器),不走 App 内置解码。 sys:http://cdn.example/live.m3u8
soft: 强制走 App 内置软解(软件解码路径)。 soft:http://cdn.example/live.ts
soft_hw: 强制走 App 内置硬解(MediaCodec 等硬件解码,仍由内置播放器接管,不是系统播放器)。 soft_hw:udp://239.1.1.1:1234

未加前缀时,按用户在菜单里选的解码方式起播。脚本返回址若带了前缀,优先于频道下发地址上的前缀。

3. 函数返回值约定

  • string:文本(hex、Base64、JSON 文本等)。
  • 字节:原始字节。若内容是合法 UTF-8,宿主常做成 string;否则为 ArrayBuffer。失败时加密类函数多返回 null。
  • 每个函数通常有蛇形与驼峰两个名字,例如 xxtea_decrypt 与 xxteaDecrypt。下表只写一个。

4. ku9 网络(仅 JS)

ku9 与 cjs 是同一对象。ku9.get / post / request 不带 App 登录 Bearer;需要鉴权时请自己在 headers 里加。

函数参数返回
get(url, headers)headers 可省,对象或 "Name: value\r\n"字节(响应正文)。失败多为 ""
post(url, body, headers)同上
request(url, method, headers, body, followRedirects)followRedirects === false 时不跟随跳转对象:code 数字,body 字节,url/error 字符串,headers 值为字符串
request(url, opts)opts.method / headers / body|data / followRedirects同上
getQuery(url, key)string;没有则 ""
getCache(key) / setCache(key, value, ttlMs)ttlMs 可省(毫秒);过期后取不到get 为字节;set 无返回
log(...)若干参数拼成一行无
var r = ku9.request("https://example/api", "POST", {
  "Content-Type": "application/json",
  "Referer": "https://example/"
}, JSON.stringify({ a: 1 }));
if (!r || r.code !== 200) throw new Error("http " + (r && r.code));
var data = JSON.parse(r.body);

5. 加密与摘要

ms 与 ku9 上都有。字符串参数按 UTF-8 字节参与运算。

函数说明
md5 / sha1 / sha256返回小写 hex string
sha512返回 64 字节原文,不是 hex 文本
hash(algo, data, raw) / hash_hmac(algo, data, key, raw)algo 如 "md5"、"sha384";raw 为真返回字节
crc32(data)数字
xxtea_decrypt / xxtea_encrypt与常见 PHP XXTEA(末尾长度字)一致;失败 null
aes_cbc_decrypt/encrypt、aes_ecb_decrypt、sm4_ecb_decryptPKCS7;失败 null
cipher(name, mode, data, key, iv, opts)如 "aes-128-ctr";mode 以 e 开头为加密
rsa_public_encrypt / rsa_sign / rsa_verifyPEM 或裸 base64;失败见上表约定
gzip / gunzip字节;失败 null
hex_encode/decode、b64_encode/decode、urlencode/urldecode编解码工具;失败多为 null
random_bytes(n)最多 1MB;返回字节;失败 null

若接口给的是 Base64 密文,可先 b64_decode(或 atob)再 xxtea_decrypt。

6. 设备与时间

函数返回
mac() / mac_address(iface)网卡 MAC string;没有则 ""
uuid() / device_id()设备码 string
time() / current_time_sec()秒(数字)
current_time_millis() / now_ms()毫秒(数字)
microtime(asFloat)不传:string,形如 "0.微秒 秒";asFloat 为真:数字(秒的小数)
uniqid(prefix, moreEntropy)string;moreEntropy 为真时末尾再加随机 hex

播放器还会在最终地址上替换 [mac]、[uuid]、[port]、[httpport]。脚本里也可用 ms.proxy_port() 自行拼端口。

7. 只在 ms 上

下列能力挂在 ms;其中 HTTP 变体可能自动带上 App 侧鉴权头(与 ku9.* 不同)。

函数返回
http_get(url) / download(url)字节(GET 正文)。HTTP 4xx/5xx 或失败为 null
http_request(method, url, headers, body)成功:字节。失败 null
http_ex(method, url, headers, body, opts)对象:status 数字,body 字节,headers 值为 string。opts.redirect === false 时不跟随跳转
http_status(url)数字(状态码)。失败 -1
ws_text(url, headers, body, opts)字节。opts.binary 为真时按二进制帧收取
download_to_file(url, path, md5)布尔。md5 可省,有则按文件内容核对
read_file(path)字节。打不开为 null
write_file(path, data)布尔。父目录不存在则失败(不会自动建目录)
isfile(path)数字:普通文件为 1,否则 0
isdir(path)数字:目录为 1,否则 0
mkdir(path)数字:建好或本来就是目录为 0,失败为 1(中间缺的目录会一并建出)
md5_file(path)string,32 位小写 hex。打不开为 ""
appname()string,应用显示名;没有则 ""
vername()string,versionName,如 3.2.0
appver()string,versionCode 的十进制数字
pkname()string,包名(超级直播 com.hd.zhibo)
abi()数字
api_base() / auth_token()string
proxy_port()数字,本机代理端口;没有则 null
json_decode(text)对象或数组;失败 null
json_encode(value)string;失败 null
log(level, msg)无。level 以 w / e 开头分别为警告和错误
stop_play()无
set_dns_rules(text) / set_engine_params(text)无。参数为 string
crypto_selftest()数字。0 为通过

常量:ms.ACTION_LIVE = 0,ACTION_CATCHUP = 1,ACTION_VOD = 2,ACTION_TIMESHIFT = 3。

8. 全局函数

  • atob(s):Base64 → 0–255 字符 string(可用 charCodeAt 取字节)
  • btoa(s):接受上述 string 或 Uint8Array / ArrayBuffer,返回 Base64 string

9. 本机 http_dispatch

文件:/sdcard/cjzb/http.js(须返回 string):

function http_dispatch(method, path, query, body) {
  // method、path、query 均为 string;query 是 JSON 文本
  // body:合法 UTF-8 为 string;否则可能是 Uint8Array
  return "{\"code\":0}";
}

10. 最小可用示例

把下面保存为外部存储 cjzb/js/demo.js,频道地址写成:

js:///sdcard/cjzb/js/demo.js?page=https://example.com/live

function main(item) {
  ku9.log("page=", item.pageUrl || "");
  var page = item.pageUrl || ku9.getQuery(item.url, "page");
  if (!page) throw new Error("missing page");

  var html = ku9.get(page, {
    "User-Agent": "Mozilla/5.0",
    "Referer": "https://example.com/"
  });
  if (!html) throw new Error("empty body");

  // 按站点自己改:这里只是示意
  var m = String(html).match(/https?:\/\/[^"'\s]+\.m3u8[^"'\s]*/i);
  if (!m) throw new Error("m3u8 not found");

  return {
    url: m[0],
    referer: "https://example.com/",
    userAgent: "Mozilla/5.0"
  };
}
合规提醒:解析脚本仅供对接你有权使用的自建或已获授权的节目源。频道内容、版权与当地法规由部署方负责。请勿用于未获授权的转播或破解。