mirror of
https://github.com/imputnet/cobalt.git
synced 2026-10-24 02:52:18 +00:00
api/loom: add transcript-only downloads
This commit is contained in:
parent
2d630d11a5
commit
609ee6cd3c
6 changed files with 84 additions and 27 deletions
|
|
@ -22,7 +22,7 @@ if the desired service isn't supported yet, feel free to create an appropriate i
|
|||
| dailymotion | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
|
||||
| instagram | ✅ | ✅ | ✅ | ❌ | ➖ | ➖ |
|
||||
| facebook | ✅ | ❌ | ✅ | ❌ | ➖ | ➖ |
|
||||
| loom | ✅ | ❌ | ✅ | ❌ | ✅ | ➖ |
|
||||
| loom | ✅ | ❌ | ✅ | ✅ | ✅ | ➖ |
|
||||
| newgrounds | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
|
||||
| ok.ru | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ |
|
||||
| pinterest | ✅ | ✅ | ✅ | ❌ | ➖ | ➖ |
|
||||
|
|
@ -45,7 +45,7 @@ if the desired service isn't supported yet, feel free to create an appropriate i
|
|||
| ➖ | unreasonable/impossible |
|
||||
| ❌ | not supported |
|
||||
|
||||
standalone transcript downloads are supported for youtube with `downloadMode: "captions"`.
|
||||
standalone transcript downloads are supported for marked services with `downloadMode: "captions"`.
|
||||
|
||||
### additional notes or features (per service)
|
||||
| service | notes or features |
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
const normalizedLanguage = language => language?.toLowerCase().replace("_", "-");
|
||||
|
||||
export const matchesCaptionLanguage = (language, requested) => {
|
||||
if (!requested || !language) return true;
|
||||
|
||||
const normalized = normalizedLanguage(language);
|
||||
const normalizedRequested = normalizedLanguage(requested);
|
||||
return normalized === normalizedRequested
|
||||
|| normalized?.split("-")[0] === normalizedRequested?.split("-")[0];
|
||||
};
|
||||
|
||||
export const createCaptionResponse = ({
|
||||
url,
|
||||
format,
|
||||
|
|
@ -10,26 +19,29 @@ export const createCaptionResponse = ({
|
|||
author,
|
||||
source,
|
||||
headers,
|
||||
}) => ({
|
||||
type: "captions",
|
||||
isCaptionOnly: true,
|
||||
urls: url,
|
||||
headers,
|
||||
captionFormat: format,
|
||||
captionLanguage: language,
|
||||
filenameAttributes: {
|
||||
service,
|
||||
id,
|
||||
title: title || `${service}_${id}`,
|
||||
author,
|
||||
},
|
||||
captionMetadata: {
|
||||
title,
|
||||
author,
|
||||
language,
|
||||
source,
|
||||
},
|
||||
});
|
||||
}) => {
|
||||
const resolvedTitle = title || `${service}_${id}`;
|
||||
return {
|
||||
type: "captions",
|
||||
isCaptionOnly: true,
|
||||
urls: url,
|
||||
headers,
|
||||
captionFormat: format,
|
||||
captionLanguage: language || "unknown",
|
||||
filenameAttributes: {
|
||||
service,
|
||||
id,
|
||||
title: resolvedTitle,
|
||||
author,
|
||||
},
|
||||
captionMetadata: {
|
||||
title: resolvedTitle,
|
||||
author,
|
||||
language,
|
||||
source,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const selectCaptionTrack = (tracks, subtitleLang, allowAutomatic = false) => {
|
||||
const allowed = tracks.filter(track => allowAutomatic || track.kind !== "asr");
|
||||
|
|
|
|||
|
|
@ -252,6 +252,9 @@ export default async function({ host, patternMatch, params, authType }) {
|
|||
r = await loom({
|
||||
id: patternMatch.id,
|
||||
subtitleLang,
|
||||
isCaptionOnly,
|
||||
captionLanguage: params.captionLanguage || subtitleLang,
|
||||
captionFormat: params.captionFormat,
|
||||
});
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import UrlPattern from "url-pattern";
|
||||
|
||||
export const audioIgnore = new Set(["vk", "ok", "loom"]);
|
||||
export const captionOnlyServices = new Set(["youtube"]);
|
||||
export const captionOnlyServices = new Set(["loom", "youtube"]);
|
||||
export const hlsExceptions = new Set(["dailymotion", "vimeo", "rutube", "bsky", "youtube"]);
|
||||
|
||||
export const services = {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
import { genericUserAgent } from "../../config.js";
|
||||
import {
|
||||
createCaptionResponse,
|
||||
matchesCaptionLanguage,
|
||||
} from "../helpers/captions.js";
|
||||
|
||||
const craftHeaders = id => ({
|
||||
"user-agent": genericUserAgent,
|
||||
|
|
@ -80,12 +84,38 @@ async function getTranscript(id) {
|
|||
.then(r => r.status === 200 && r.json())
|
||||
.catch(() => {});
|
||||
|
||||
if (gql?.data?.fetchVideoTranscript?.captions_source_url?.includes('.vtt?')) {
|
||||
return gql.data.fetchVideoTranscript.captions_source_url;
|
||||
const transcript = gql?.data?.fetchVideoTranscript;
|
||||
if (transcript?.captions_source_url?.includes('.vtt?')) {
|
||||
return {
|
||||
url: transcript.captions_source_url,
|
||||
language: transcript.language,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default async function({ id, subtitleLang }) {
|
||||
export default async function({
|
||||
id,
|
||||
subtitleLang,
|
||||
isCaptionOnly,
|
||||
captionLanguage,
|
||||
captionFormat,
|
||||
}) {
|
||||
if (isCaptionOnly) {
|
||||
const transcript = await getTranscript(id);
|
||||
if (!transcript || !matchesCaptionLanguage(transcript.language, captionLanguage)) {
|
||||
return { error: "fetch.empty" };
|
||||
}
|
||||
|
||||
return createCaptionResponse({
|
||||
url: transcript.url,
|
||||
format: captionFormat,
|
||||
language: transcript.language,
|
||||
service: "loom",
|
||||
id,
|
||||
source: `https://www.loom.com/share/${id}`,
|
||||
});
|
||||
}
|
||||
|
||||
let url = await fromTranscodedURL(id);
|
||||
url ??= await fromRawURL(id);
|
||||
|
||||
|
|
@ -96,7 +126,7 @@ export default async function({ id, subtitleLang }) {
|
|||
let subtitles;
|
||||
if (subtitleLang) {
|
||||
const transcript = await getTranscript(id);
|
||||
if (transcript) subtitles = transcript;
|
||||
if (transcript) subtitles = transcript.url;
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,18 @@
|
|||
"status": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "standalone transcript",
|
||||
"url": "https://www.loom.com/share/aa3d8b08bee74d05af5b42989e9f33e9",
|
||||
"params": {
|
||||
"downloadMode": "captions",
|
||||
"captionFormat": "txt"
|
||||
},
|
||||
"expected": {
|
||||
"code": 200,
|
||||
"status": "tunnel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "video with no transcodedUrl",
|
||||
"url": "https://www.loom.com/share/aa3d8b08bee74d05af5b42989e9f33e9",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue