Experiment to rebuild Diffuse using web applets.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: allow passing streams to the metadata processor (not sure this actually works)

+22 -13
+1 -1
src/pages/orchestrator/input-cache/_applet.astro
··· 1 1 <script> 2 2 import { applets } from "@web-applets/sdk"; 3 3 4 - import type { Output, Track, TrackStats, TrackTags } from "@applets/core/types.d.ts"; 4 + import type { Output, Track } from "@applets/core/types.d.ts"; 5 5 import { applet, waitUntilAppletIsReady } from "@scripts/theme"; 6 6 7 7 ////////////////////////////////////////////
+17 -10
src/pages/processor/metadata-fetcher/_applet.astro
··· 21 21 //////////////////////////////////////////// 22 22 context.setActionHandler("extract", extract); 23 23 24 - async function extract({ urls }: { urls: Urls }) { 24 + async function extract(args: { mimeType?: string; stream?: ReadableStream; urls?: Urls }) { 25 25 // Construct records 26 26 // TODO: Use other metadata lib as fallback: https://github.com/buzz/mediainfo.js 27 - const { stats, tags } = await musicMetadataTags(urls, false); 27 + const { stats, tags } = await musicMetadataTags(args, false); 28 28 29 29 // Fin 30 30 return { stats, tags }; 31 31 } 32 32 33 33 // 🛠️ 34 - async function musicMetadataTags(urls: Urls, covers: boolean = false): Promise<Extraction> { 35 - const uri = URI.parse(urls.get); 36 - const pathParts = uri.path?.split("/"); 34 + async function musicMetadataTags( 35 + { mimeType, stream, urls }: { mimeType?: string; stream?: ReadableStream; urls?: Urls }, 36 + covers: boolean = false, 37 + ): Promise<Extraction> { 38 + const uri = urls ? URI.parse(urls.get) : undefined; 39 + const pathParts = uri?.path?.split("/"); 37 40 const filename = pathParts?.[pathParts.length - 1]; 38 41 39 42 let meta; 40 43 41 - if (urls.get.startsWith("blob:")) { 42 - const mimeType = filename?.includes(".") 44 + if (urls?.get.startsWith("blob:")) { 45 + const mimeFallback = filename?.includes(".") 43 46 ? contentType(filename.split(".").reverse()[0]) 44 47 : undefined; 45 48 46 49 const resp = await fetch(urls.get); 47 50 const stream = resp.body; 48 51 49 - meta = await parseWebStream(stream, { mimeType }); 50 - } else { 52 + meta = await parseWebStream(stream, { mimeType: mimeType || mimeFallback }); 53 + } else if (urls) { 51 54 const httpClient = new HTTP_TOKENIZER.HttpClient(urls.head, { resolveUrl: false }); 52 55 httpClient.resolvedUrl = urls.get; 53 56 54 57 const tokenizer = await RANGE_TOKENIZER.tokenizer(httpClient); 55 58 56 59 meta = await parseFromTokenizer(tokenizer, { skipCovers: covers }); 60 + } else if (stream) { 61 + meta = await parseWebStream(stream, { mimeType }); 62 + } else { 63 + throw new Error("Missing args, need either some urls or a stream."); 57 64 } 58 65 59 66 const stats: TrackStats = { ··· 65 72 artist: meta.common.artist, 66 73 disc: { no: meta.common.disk.no || 1, of: meta.common.disk.of ?? undefined }, 67 74 genre: Array.isArray(meta.common.genre) ? meta.common.genre[0] : meta.common.genre, 68 - title: meta.common.title || filename || urls.head, 75 + title: meta.common.title || filename || urls?.head || "Unknown", 69 76 track: { no: meta.common.track.no || 1, of: meta.common.track.of ?? undefined }, 70 77 year: meta.common.year, 71 78 };
+4 -2
src/pages/processor/metadata-fetcher/_manifest.json
··· 9 9 "params_schema": { 10 10 "type": "object", 11 11 "properties": { 12 + "stream": { 13 + "type": "object" 14 + }, 12 15 "urls": { 13 16 "type": "object", 14 17 "properties": { ··· 17 20 }, 18 21 "required": ["get", "head"] 19 22 } 20 - }, 21 - "required": ["urls"] 23 + } 22 24 } 23 25 } 24 26 }