精简线路
This commit is contained in:
+12
-8
@@ -42,8 +42,6 @@ return {
|
|||||||
{
|
{
|
||||||
sourceId,
|
sourceId,
|
||||||
sourceName: '默认源',
|
sourceName: '默认源',
|
||||||
lineId: 'default',
|
|
||||||
lineName: '默认线路',
|
|
||||||
episodes: [],
|
episodes: [],
|
||||||
episodes_titles: []
|
episodes_titles: []
|
||||||
}
|
}
|
||||||
@@ -51,7 +49,7 @@ return {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
async resolvePlayUrl(ctx, { playUrl, sourceId, lineId, episodeIndex }) {
|
async resolvePlayUrl(ctx, { playUrl, sourceId, episodeIndex }) {
|
||||||
return {
|
return {
|
||||||
url: playUrl,
|
url: playUrl,
|
||||||
type: 'auto',
|
type: 'auto',
|
||||||
@@ -71,7 +69,7 @@ return {
|
|||||||
推荐
|
推荐
|
||||||
4. `detail({ id, sourceId })`
|
4. `detail({ id, sourceId })`
|
||||||
详情
|
详情
|
||||||
5. `resolvePlayUrl({ playUrl, sourceId, lineId, episodeIndex })`
|
5. `resolvePlayUrl({ playUrl, sourceId, episodeIndex })`
|
||||||
播放前解析最终地址
|
播放前解析最终地址
|
||||||
|
|
||||||
## `ctx` 里能用什么
|
## `ctx` 里能用什么
|
||||||
@@ -128,11 +126,12 @@ return {
|
|||||||
{
|
{
|
||||||
sourceId: 'default',
|
sourceId: 'default',
|
||||||
sourceName: '默认源',
|
sourceName: '默认源',
|
||||||
lineId: 'line1',
|
|
||||||
lineName: '线路1',
|
|
||||||
episodes: [
|
episodes: [
|
||||||
'https://example.com/play/1',
|
'https://example.com/play/1',
|
||||||
'https://example.com/play/2'
|
{
|
||||||
|
playUrl: 'https://example.com/play/2',
|
||||||
|
needResolve: false
|
||||||
|
}
|
||||||
],
|
],
|
||||||
episodes_titles: ['第1集', '第2集']
|
episodes_titles: ['第1集', '第2集']
|
||||||
}
|
}
|
||||||
@@ -140,6 +139,12 @@ return {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- `episodes` 可以是字符串,默认等价于 `{ playUrl: '...', needResolve: true }`
|
||||||
|
- `needResolve` 默认为 `true`
|
||||||
|
- 显式写 `needResolve: false` 时,播放页会直接使用该地址,不再调用 `resolvePlayUrl`
|
||||||
|
|
||||||
## `resolvePlayUrl` 返回格式
|
## `resolvePlayUrl` 返回格式
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@@ -196,4 +201,3 @@ async resolvePlayUrl(ctx, { playUrl }) {
|
|||||||
"code": "return { ... }"
|
"code": "return { ... }"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -6278,7 +6278,6 @@ const VideoSourceScriptLab = () => {
|
|||||||
: JSON.stringify(
|
: JSON.stringify(
|
||||||
{
|
{
|
||||||
sourceId: 'main',
|
sourceId: 'main',
|
||||||
lineId: 'default',
|
|
||||||
playUrl: 'https://example.com/video.m3u8',
|
playUrl: 'https://example.com/video.m3u8',
|
||||||
episodeIndex: 0,
|
episodeIndex: 0,
|
||||||
},
|
},
|
||||||
@@ -6469,7 +6468,7 @@ const VideoSourceScriptLab = () => {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<p className='text-xs text-gray-500 dark:text-gray-400'>
|
<p className='text-xs text-gray-500 dark:text-gray-400'>
|
||||||
现在脚本可以自己管理多个源和线路,测试入参可传 `sourceId`、`lineId`。
|
现在脚本可以自己管理多个源,测试入参可传 `sourceId`。
|
||||||
</p>
|
</p>
|
||||||
<textarea
|
<textarea
|
||||||
value={testPayload}
|
value={testPayload}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
export const runtime = 'nodejs';
|
export const runtime = 'nodejs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /api/source-script/play?key=xxx&sourceId=xxx&lineId=xxx&episodeIndex=0&playUrl=base64url&format=json
|
* GET /api/source-script/play?key=xxx&sourceId=xxx&episodeIndex=0&playUrl=base64url&format=json
|
||||||
* format=json: 返回 JSON 格式(用于 play 页面)
|
* format=json: 返回 JSON 格式(用于 play 页面)
|
||||||
* 默认: 返回重定向(用于播放器或外部调用)
|
* 默认: 返回重定向(用于播放器或外部调用)
|
||||||
*/
|
*/
|
||||||
@@ -23,7 +23,6 @@ export async function GET(request: NextRequest) {
|
|||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
const key = searchParams.get('key');
|
const key = searchParams.get('key');
|
||||||
const sourceId = searchParams.get('sourceId');
|
const sourceId = searchParams.get('sourceId');
|
||||||
const lineId = searchParams.get('lineId') || 'default';
|
|
||||||
const episodeIndexRaw = searchParams.get('episodeIndex');
|
const episodeIndexRaw = searchParams.get('episodeIndex');
|
||||||
const playUrlEncoded = searchParams.get('playUrl');
|
const playUrlEncoded = searchParams.get('playUrl');
|
||||||
const format = searchParams.get('format');
|
const format = searchParams.get('format');
|
||||||
@@ -45,7 +44,6 @@ export async function GET(request: NextRequest) {
|
|||||||
const result = await resolveSavedScriptPlayUrl({
|
const result = await resolveSavedScriptPlayUrl({
|
||||||
key,
|
key,
|
||||||
sourceId,
|
sourceId,
|
||||||
lineId,
|
|
||||||
episodeIndex,
|
episodeIndex,
|
||||||
playUrl,
|
playUrl,
|
||||||
});
|
});
|
||||||
|
|||||||
+28
-31
@@ -122,8 +122,6 @@ const DEFAULT_SCRIPT_TEMPLATE = `return {
|
|||||||
{
|
{
|
||||||
sourceId: sourceId || 'main',
|
sourceId: sourceId || 'main',
|
||||||
sourceName: '主站',
|
sourceName: '主站',
|
||||||
lineId: 'default',
|
|
||||||
lineName: '默认线路',
|
|
||||||
episodes: [],
|
episodes: [],
|
||||||
episodes_titles: []
|
episodes_titles: []
|
||||||
}
|
}
|
||||||
@@ -131,8 +129,8 @@ const DEFAULT_SCRIPT_TEMPLATE = `return {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
async resolvePlayUrl(ctx, { playUrl, sourceId, lineId, episodeIndex }) {
|
async resolvePlayUrl(ctx, { playUrl, sourceId, episodeIndex }) {
|
||||||
ctx.log.info('resolvePlayUrl', sourceId, lineId, episodeIndex, playUrl);
|
ctx.log.info('resolvePlayUrl', sourceId, episodeIndex, playUrl);
|
||||||
return {
|
return {
|
||||||
url: playUrl,
|
url: playUrl,
|
||||||
type: 'auto',
|
type: 'auto',
|
||||||
@@ -746,13 +744,19 @@ export function normalizeScriptSearchResults(input: {
|
|||||||
typeof episode === 'string'
|
typeof episode === 'string'
|
||||||
? episode
|
? episode
|
||||||
: String(episode?.playUrl || episode?.url || '');
|
: String(episode?.playUrl || episode?.url || '');
|
||||||
return buildScriptPlayUrl({
|
const needResolve =
|
||||||
scriptKey: input.scriptKey,
|
typeof episode === 'object' && episode
|
||||||
sourceId: input.sourceId,
|
? episode.needResolve !== false
|
||||||
lineId: String(episode?.lineId || item?.lineId || 'default'),
|
: true;
|
||||||
episodeIndex: index,
|
|
||||||
playUrl,
|
return needResolve
|
||||||
});
|
? buildScriptPlayUrl({
|
||||||
|
scriptKey: input.scriptKey,
|
||||||
|
sourceId: input.sourceId,
|
||||||
|
episodeIndex: index,
|
||||||
|
playUrl,
|
||||||
|
})
|
||||||
|
: playUrl;
|
||||||
})
|
})
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
@@ -788,8 +792,6 @@ export function normalizeScriptDetailResult(input: {
|
|||||||
{
|
{
|
||||||
sourceId: input.sourceId,
|
sourceId: input.sourceId,
|
||||||
sourceName: input.sourceName,
|
sourceName: input.sourceName,
|
||||||
lineId: 'default',
|
|
||||||
lineName: '默认线路',
|
|
||||||
episodes: input.result?.episodes || [],
|
episodes: input.result?.episodes || [],
|
||||||
episodes_titles: input.result?.episodes_titles || [],
|
episodes_titles: input.result?.episodes_titles || [],
|
||||||
},
|
},
|
||||||
@@ -800,7 +802,6 @@ export function normalizeScriptDetailResult(input: {
|
|||||||
|
|
||||||
playbacks.forEach((playback: any) => {
|
playbacks.forEach((playback: any) => {
|
||||||
const playbackSourceName = String(playback.sourceName || input.sourceName);
|
const playbackSourceName = String(playback.sourceName || input.sourceName);
|
||||||
const lineName = String(playback.lineName || '默认线路');
|
|
||||||
const titles = Array.isArray(playback.episodes_titles)
|
const titles = Array.isArray(playback.episodes_titles)
|
||||||
? playback.episodes_titles
|
? playback.episodes_titles
|
||||||
: [];
|
: [];
|
||||||
@@ -817,17 +818,21 @@ export function normalizeScriptDetailResult(input: {
|
|||||||
: String(titles[index] || `第${index + 1}集`);
|
: String(titles[index] || `第${index + 1}集`);
|
||||||
|
|
||||||
const playbackSourceId = String(playback.sourceId || input.sourceId);
|
const playbackSourceId = String(playback.sourceId || input.sourceId);
|
||||||
const lineId = String(playback.lineId || 'default');
|
const needResolve =
|
||||||
const playUrl = buildScriptPlayUrl({
|
typeof episode === 'object' && episode
|
||||||
scriptKey: input.scriptKey,
|
? episode.needResolve !== false
|
||||||
sourceId: playbackSourceId,
|
: true;
|
||||||
lineId,
|
const playUrl = needResolve
|
||||||
episodeIndex: index,
|
? buildScriptPlayUrl({
|
||||||
playUrl: rawPlayUrl,
|
scriptKey: input.scriptKey,
|
||||||
});
|
sourceId: playbackSourceId,
|
||||||
|
episodeIndex: index,
|
||||||
|
playUrl: rawPlayUrl,
|
||||||
|
})
|
||||||
|
: rawPlayUrl;
|
||||||
|
|
||||||
flattenedEpisodes.push(playUrl);
|
flattenedEpisodes.push(playUrl);
|
||||||
flattenedTitles.push(`${playbackSourceName} / ${lineName} / ${episodeTitle}`);
|
flattenedTitles.push(`${playbackSourceName} / ${episodeTitle}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -861,8 +866,6 @@ export async function resolveScriptDetailPlaybacks(input: {
|
|||||||
{
|
{
|
||||||
sourceId: input.sourceId,
|
sourceId: input.sourceId,
|
||||||
sourceName: input.sourceId,
|
sourceName: input.sourceId,
|
||||||
lineId: 'default',
|
|
||||||
lineName: '默认线路',
|
|
||||||
episodes: input.result?.episodes || [],
|
episodes: input.result?.episodes || [],
|
||||||
episodes_titles: input.result?.episodes_titles || [],
|
episodes_titles: input.result?.episodes_titles || [],
|
||||||
},
|
},
|
||||||
@@ -882,7 +885,6 @@ export async function resolveScriptDetailPlaybacks(input: {
|
|||||||
const resolvedPlaybacks = await Promise.all(
|
const resolvedPlaybacks = await Promise.all(
|
||||||
playbacks.map(async (playback: any) => {
|
playbacks.map(async (playback: any) => {
|
||||||
const playbackSourceId = String(playback.sourceId || input.sourceId);
|
const playbackSourceId = String(playback.sourceId || input.sourceId);
|
||||||
const lineId = String(playback.lineId || 'default');
|
|
||||||
const episodes = Array.isArray(playback.episodes) ? playback.episodes : [];
|
const episodes = Array.isArray(playback.episodes) ? playback.episodes : [];
|
||||||
|
|
||||||
const resolvedEpisodes = await Promise.all(
|
const resolvedEpisodes = await Promise.all(
|
||||||
@@ -898,7 +900,6 @@ export async function resolveScriptDetailPlaybacks(input: {
|
|||||||
compiled.resolvePlayUrl(ctx, {
|
compiled.resolvePlayUrl(ctx, {
|
||||||
playUrl,
|
playUrl,
|
||||||
sourceId: playbackSourceId,
|
sourceId: playbackSourceId,
|
||||||
lineId,
|
|
||||||
episodeIndex: index,
|
episodeIndex: index,
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
@@ -941,14 +942,12 @@ function decodeBase64Url(value: string) {
|
|||||||
export function buildScriptPlayUrl(input: {
|
export function buildScriptPlayUrl(input: {
|
||||||
scriptKey: string;
|
scriptKey: string;
|
||||||
sourceId: string;
|
sourceId: string;
|
||||||
lineId: string;
|
|
||||||
episodeIndex: number;
|
episodeIndex: number;
|
||||||
playUrl: string;
|
playUrl: string;
|
||||||
}) {
|
}) {
|
||||||
const searchParams = new URLSearchParams({
|
const searchParams = new URLSearchParams({
|
||||||
key: input.scriptKey,
|
key: input.scriptKey,
|
||||||
sourceId: input.sourceId,
|
sourceId: input.sourceId,
|
||||||
lineId: input.lineId,
|
|
||||||
episodeIndex: String(input.episodeIndex),
|
episodeIndex: String(input.episodeIndex),
|
||||||
playUrl: encodeBase64Url(input.playUrl),
|
playUrl: encodeBase64Url(input.playUrl),
|
||||||
});
|
});
|
||||||
@@ -962,7 +961,6 @@ export function parseScriptPlayUrlValue(value: string) {
|
|||||||
export async function resolveSavedScriptPlayUrl(input: {
|
export async function resolveSavedScriptPlayUrl(input: {
|
||||||
key: string;
|
key: string;
|
||||||
sourceId: string;
|
sourceId: string;
|
||||||
lineId: string;
|
|
||||||
episodeIndex: number;
|
episodeIndex: number;
|
||||||
playUrl: string;
|
playUrl: string;
|
||||||
configValues?: Record<string, string>;
|
configValues?: Record<string, string>;
|
||||||
@@ -983,7 +981,6 @@ export async function resolveSavedScriptPlayUrl(input: {
|
|||||||
compiled.resolvePlayUrl(ctx, {
|
compiled.resolvePlayUrl(ctx, {
|
||||||
playUrl: input.playUrl,
|
playUrl: input.playUrl,
|
||||||
sourceId: input.sourceId,
|
sourceId: input.sourceId,
|
||||||
lineId: input.lineId,
|
|
||||||
episodeIndex: input.episodeIndex,
|
episodeIndex: input.episodeIndex,
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user