return {
meta: {
name: '示例脚本',
author: 'admin'
},
async getSources(ctx) {
return [{ id: 'default', name: '默认源' }];
},
async search(ctx, { keyword, page, sourceId }) {
return {
list: [],
page,
pageCount: 1,
total: 0
};
},
async recommend(ctx, { page }) {
return {
list: [],
page: page || 1,
pageCount: 1,
total: 0
};
},
async detail(ctx, { id, sourceId }) {
return {
id,
title: '',
poster: '',
year: '',
desc: '',
playbacks: [
{
sourceId,
sourceName: '默认源',
episodes: [],
episodes_titles: []
}
]
};
},
async resolvePlayUrl(ctx, { playUrl, sourceId, episodeIndex }) {
return {
url: playUrl,
type: 'auto',
headers: {}
};
}
};getSources()返回脚本管理的子源列表search({ keyword, page, sourceId })搜索recommend({ page })推荐detail({ id, sourceId })详情resolvePlayUrl({ playUrl, sourceId, episodeIndex })播放前解析最终地址
ctx.fetch(...)发请求ctx.request.get/getJson/getHtml/post快捷请求ctx.html.load(html)cheerio风格解析ctx.cache.get/set/del脚本缓存ctx.log.info/warn/error输出测试日志ctx.utils.buildUrl/joinUrl/randomUA/sleep/base64Encode/base64Decode/now常用工具ctx.config.get/require/all读脚本配置ctx.runtime当前脚本信息
{
list: [
{
id: '123',
title: '凡人修仙传',
poster: 'https://...',
year: '2025',
desc: '简介',
type_name: '动漫',
douban_id: 0,
vod_remarks: '更新至10集'
}
],
page: 1,
pageCount: 1,
total: 1
}{
id: '123',
title: '凡人修仙传',
poster: 'https://...',
year: '2025',
desc: '简介',
playbacks: [
{
sourceId: 'default',
sourceName: '默认源',
episodes: [
'https://example.com/play/1',
{
playUrl: 'https://example.com/play/2',
needResolve: false
}
],
episodes_titles: ['第1集', '第2集']
}
]
}说明:
episodes可以是字符串,默认等价于{ playUrl: '...', needResolve: true }needResolve默认为true- 显式写
needResolve: false时,播放页会直接使用该地址,不再调用resolvePlayUrl
{
url: 'https://real-url.m3u8',
type: 'auto',
headers: {}
}async search(ctx, { keyword, page, sourceId }) {
const data = await ctx.request.getJson('https://example.com/api/search', {
query: { wd: keyword, pg: page }
});
return {
list: (data.list || []).map((item) => ({
id: String(item.id),
title: item.title,
poster: item.pic || '',
year: item.year || '',
desc: item.desc || ''
})),
page,
pageCount: data.pagecount || 1,
total: data.total || 0
};
}async resolvePlayUrl(ctx, { playUrl }) {
return {
url: playUrl,
type: 'auto',
headers: {}
};
}{
"key": "demo",
"name": "演示脚本",
"description": "test",
"enabled": true,
"code": "return { ... }"
}