v3: youtube embeds now honour the timestamp in the source url, with a migration backfilling existing dumps
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 50s
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 50s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,30 @@ function extractPlaylistId(url: string): string | null {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the playback offset in seconds from a YouTube URL.
|
||||
* Accepts `t` (plain seconds, `90s`, or `1h2m3s` / `20m5s` forms) and `start`
|
||||
* (plain seconds). Returns null when absent or unparseable.
|
||||
*/
|
||||
function extractStartSeconds(url: string): number | null {
|
||||
let raw: string | null;
|
||||
try {
|
||||
const u = new URL(url);
|
||||
raw = u.searchParams.get("t") ?? u.searchParams.get("start");
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
if (!raw) return null;
|
||||
|
||||
const plain = /^\d+$/.exec(raw);
|
||||
if (plain) return Number(raw);
|
||||
|
||||
const hms = /^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/i.exec(raw);
|
||||
if (!hms || (!hms[1] && !hms[2] && !hms[3])) return null;
|
||||
return Number(hms[1] ?? 0) * 3600 + Number(hms[2] ?? 0) * 60 +
|
||||
Number(hms[3] ?? 0);
|
||||
}
|
||||
|
||||
/** Matches /channel/UC…, /@handle, /c/name, /user/name */
|
||||
function extractChannelPath(url: string): string | null {
|
||||
try {
|
||||
@@ -134,6 +158,8 @@ export const youtubeProvider: RichContentProvider = {
|
||||
|
||||
const embedParams = new URLSearchParams({ rel: "0" });
|
||||
if (listId) embedParams.set("list", listId);
|
||||
const start = extractStartSeconds(url);
|
||||
if (start) embedParams.set("start", String(start));
|
||||
|
||||
return {
|
||||
type: "youtube",
|
||||
|
||||
Reference in New Issue
Block a user