diff --git a/CHANGELOG.md b/CHANGELOG.md index b7514550..fcd44461 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- Support for casting clips from web app + ## [0.25.6] - 2024-09-12 ### Added diff --git a/playlet-web/src/lib/Api/InvidiousApi.ts b/playlet-web/src/lib/Api/InvidiousApi.ts index 82bb9454..cdc1b7e1 100644 --- a/playlet-web/src/lib/Api/InvidiousApi.ts +++ b/playlet-web/src/lib/Api/InvidiousApi.ts @@ -52,6 +52,11 @@ export class InvidiousApi { return await response.json(); } + public async getClipMetadata(clipId: string) { + const response = await fetch(`${this.instance}/api/v1/clips/${clipId}`); + return await response.json(); + } + public async getChannelMetadata(ucid: string) { const response = await fetch(`${this.instance}/api/v1/channels/${ucid}`); return await response.json(); diff --git a/playlet-web/src/lib/LinkDragDrop.svelte b/playlet-web/src/lib/LinkDragDrop.svelte index dcb6d112..6ff788e5 100644 --- a/playlet-web/src/lib/LinkDragDrop.svelte +++ b/playlet-web/src/lib/LinkDragDrop.svelte @@ -67,6 +67,9 @@ if (videoInfo.videoId) { searchForVideoById(videoInfo.videoId, videoInfo.timestamp); return; + } else if (videoInfo.clipId) { + searchVideoByClipId(videoInfo.clipId); + return; } else { // TODO:P2 make a HEAD request and check for a redirect, then // resolve the redirect url. @@ -82,6 +85,26 @@ } } + async function searchVideoByClipId(clipId) { + try { + isLoading = true; + + const clipInfo = await invidiousApi.getClipMetadata(clipId); + const video = clipInfo.video; + if (clipInfo.clipTitle) { + video.title = `${clipInfo.clipTitle} (${video.title})`; + } + videoMetadata = video; + videoStartAtChecked = !!clipInfo.startTime; + if (videoStartAtChecked) { + videoStartAtTimestamp = clipInfo.startTime; + } + videoModal.show(); + } finally { + isLoading = false; + } + } + async function searchForVideoById(videoId, timestamp) { try { isLoading = true; @@ -149,6 +172,13 @@ } } + if (url.startsWith("https://www.youtube.com/clip/")) { + const clipId = url.substring("https://www.youtube.com/clip/".length); + return { + clipId, + }; + } + // Share/Short url const YoutubeUrls = [ "https://youtu.be/",