Experiment to rebuild Diffuse using web applets.
at main 2.3 kB view raw
1import { parseBlob, parseFromTokenizer, parseWebStream } from "music-metadata"; 2import * as URI from "uri-js"; 3import * as HTTP_TOKENIZER from "@tokenizer/http"; 4import * as RANGE_TOKENIZER from "@tokenizer/range"; 5 6import type { TrackStats, TrackTags } from "@applets/core/types"; 7import type { Extraction, Urls } from "./types"; 8 9// 🛠️ 10 11export async function musicMetadataTags({ 12 includeArtwork, 13 mimeType, 14 stream, 15 urls, 16}: { 17 includeArtwork?: boolean; 18 mimeType?: string; 19 stream?: ReadableStream; 20 urls?: Urls; 21}): Promise<Extraction> { 22 const uri = urls ? URI.parse(urls.get) : undefined; 23 const pathParts = uri?.path?.split("/"); 24 const filename = pathParts?.[pathParts.length - 1]; 25 26 let meta; 27 28 if (urls?.get.startsWith("blob:")) { 29 const blob = await fetch(urls.get).then((r) => r.blob()); 30 meta = await parseBlob(blob, { skipCovers: !includeArtwork }); 31 } else if (urls) { 32 const httpClient = new HTTP_TOKENIZER.HttpClient(urls.head, { resolveUrl: false }); 33 httpClient.resolvedUrl = urls.get; 34 const getHeadInfo = httpClient.getHeadInfo; 35 36 // FUCKAROUND: Not sure of the downsides of this 37 httpClient.getHeadInfo = async () => { 38 const info = await getHeadInfo.call(httpClient); 39 return { ...info, acceptPartialRequests: true }; 40 }; 41 42 const tokenizer = await RANGE_TOKENIZER.tokenizer(httpClient); 43 44 meta = await parseFromTokenizer(tokenizer, { skipCovers: !includeArtwork }); 45 } else if (stream) { 46 meta = await parseWebStream(stream, { mimeType }, { skipCovers: !includeArtwork }); 47 } else { 48 throw new Error("Missing args, need either some urls or a stream."); 49 } 50 51 const stats: TrackStats = { 52 duration: meta.format.duration, 53 }; 54 55 const tags: TrackTags = { 56 album: meta.common.album, 57 artist: meta.common.artist, 58 disc: { no: meta.common.disk.no || 1, of: meta.common.disk.of ?? undefined }, 59 genre: Array.isArray(meta.common.genre) ? meta.common.genre[0] : meta.common.genre, 60 title: meta.common.title || filename || urls?.head || "Unknown", 61 track: { no: meta.common.track.no || 1, of: meta.common.track.of ?? undefined }, 62 year: meta.common.year, 63 }; 64 65 return { 66 artwork: includeArtwork ? meta.common.picture : undefined, 67 stats, 68 tags, 69 }; 70}