From 27d5f46843f2c9db89fcafed173fd78707aa0265 Mon Sep 17 00:00:00 2001 From: WardPearce Date: Fri, 22 Mar 2024 17:34:37 +1300 Subject: [PATCH] Added chapter support --- materialious/src/lib/Api/model.ts | 11 ++ materialious/src/lib/Logo.svelte | 6 +- materialious/src/lib/Player.svelte | 14 ++- materialious/src/lib/misc.ts | 45 ++++++++ materialious/src/routes/+layout.svelte | 2 +- .../src/routes/watch/[slug]/+page.svelte | 105 +++++++++++------- materialious/src/routes/watch/[slug]/+page.ts | 4 +- 7 files changed, 144 insertions(+), 43 deletions(-) diff --git a/materialious/src/lib/Api/model.ts b/materialious/src/lib/Api/model.ts index c811a70e..3fa4aee6 100644 --- a/materialious/src/lib/Api/model.ts +++ b/materialious/src/lib/Api/model.ts @@ -91,6 +91,17 @@ export interface VideoPlay extends Video { recommendedVideos: VideoBase[]; authorThumbnails: Image[]; captions: Captions[]; + storyboards?: { + url: string; + templateUrl: string; + width: number; + height: number; + count: number; + interval: number; + storyboardWidth: number; + storyboardHeight: number; + storyboardCount: number; + }[]; } export interface ReturnYTDislikes { diff --git a/materialious/src/lib/Logo.svelte b/materialious/src/lib/Logo.svelte index d0d0f482..fc019de5 100644 --- a/materialious/src/lib/Logo.svelte +++ b/materialious/src/lib/Logo.svelte @@ -1,5 +1,9 @@ + + { + currentTime = event.detail.plyr.currentTime; + }); + player.autoplay = get(playerAutoPlay); player.loop = get(playerAlwaysLoop); diff --git a/materialious/src/lib/misc.ts b/materialious/src/lib/misc.ts index a7a6f0ed..2e37f8d3 100644 --- a/materialious/src/lib/misc.ts +++ b/materialious/src/lib/misc.ts @@ -11,4 +11,49 @@ export function numberWithCommas(number: number) { export function cleanNumber(number: number): string { return humanNumber(number, (number: number) => Number.parseFloat(number.toString()).toFixed(1)); +} + +export function phaseDescription(content: string): { + description: string, timestamps: { title: string; time: number; timePretty: string; }[]; +} { + const timestamps: { title: string; time: number; timePretty: string; }[] = []; + const lines = content.split('\n'); + + const regex = /(\d+:\d+(?::\d+)?)(?:\s(.+))?/; + const filteredLines = lines.filter(line => { + const match = regex.exec(line); + + if (match !== null) { + const timestamp = match[1]; + const title = match[2] || ''; + timestamps.push({ + time: convertToSeconds(timestamp), + title: title, + timePretty: timestamp + }); + return false; + } + + return true; + }); + + const filteredContent = filteredLines.join('\n'); + + return { description: filteredContent, timestamps: timestamps }; +} + +function convertToSeconds(time: string): number { + const parts = time.split(':').map(part => parseInt(part)); + let seconds = 0; + if (parts.length === 3) { + // hh:mm:ss + seconds = parts[0] * 3600 + parts[1] * 60 + parts[2]; + } else if (parts.length === 2) { + // hh:ss or m:ss + seconds = parts[0] * 60 + parts[1]; + } else if (parts.length === 1) { + // s + seconds = parts[0]; + } + return seconds; } \ No newline at end of file diff --git a/materialious/src/routes/+layout.svelte b/materialious/src/routes/+layout.svelte index 5d9f3c48..5ac210ac 100644 --- a/materialious/src/routes/+layout.svelte +++ b/materialious/src/routes/+layout.svelte @@ -219,7 +219,7 @@ >menu - +
Materialious
diff --git a/materialious/src/routes/watch/[slug]/+page.svelte b/materialious/src/routes/watch/[slug]/+page.svelte index 8d910da5..2835038f 100644 --- a/materialious/src/routes/watch/[slug]/+page.svelte +++ b/materialious/src/routes/watch/[slug]/+page.svelte @@ -4,10 +4,13 @@ import Player from '$lib/Player.svelte'; import Thumbnail from '$lib/Thumbnail.svelte'; import { cleanNumber, numberWithCommas } from '$lib/misc.js'; + import type Plyr from 'plyr'; import { activePage } from '../../../store.js'; export let data; + let player: Plyr | undefined; + activePage.set(null); async function toggleSubscribed() { @@ -19,13 +22,16 @@ data.subscribed = !data.subscribed; } + + let currentTime: number; + let seekTo: (time: number) => void; {#if data}
{#key data.video.videoId} - + {/key}
{data.video.title}
@@ -116,11 +122,22 @@

{numberWithCommas(data.video.viewCount)} views • {data.video.publishedText}

-

{data.video.description}

+

{data.content.description}

+ {#if data.content} +
Chapters
+ {#each data.content.timestamps as timestamp} + + {/each} + {/if}
- {#if data.comments && data.comments.comments.length > 0} + {#if data.comments && typeof data.comments.comments !== 'undefined' && data.comments.comments.length > 0}
{numberWithCommas(data.comments.commentCount)} comments
{#each data.comments.comments as comment}
@@ -169,44 +186,54 @@ {/if}
- {#each data.video.recommendedVideos as recommendedVideo} -
- -
- {/each} + {#if data.video.recommendedVideos} + {#each data.video.recommendedVideos as recommendedVideo} +
+ +
+ {/each} + {/if}
- - {:else} {/if} + + diff --git a/materialious/src/routes/watch/[slug]/+page.ts b/materialious/src/routes/watch/[slug]/+page.ts index b3f730dd..fb8c33fb 100644 --- a/materialious/src/routes/watch/[slug]/+page.ts +++ b/materialious/src/routes/watch/[slug]/+page.ts @@ -1,4 +1,5 @@ import { amSubscribed, getComments, getDislikes, getVideo, postHistory } from '$lib/Api/index.js'; +import { phaseDescription } from '$lib/misc'; import { get } from 'svelte/store'; import { auth, playerProxyVideos } from '../../../store'; @@ -11,6 +12,7 @@ export async function load({ params }) { video: video, returnYTDislikes: await getDislikes(params.slug), comments: video.liveNow ? null : await getComments(params.slug, { sort_by: "top", source: "youtube" }), - subscribed: await amSubscribed(video.authorId) + subscribed: await amSubscribed(video.authorId), + content: phaseDescription(video.description) }; };