Fetch metadata when something is added to the playlist.

This commit is contained in:
2025-02-15 21:40:30 -08:00
parent a06bc3960e
commit d465dbf6fb
6 changed files with 297 additions and 5 deletions

View File

@@ -1,12 +1,19 @@
import { ChildProcess, spawn } from "child_process";
import { Socket } from "net";
import { WebSocket } from "ws";
import { getLinkPreview } from "link-preview-js";
interface PendingCommand {
resolve: (value: any) => void;
reject: (reason: any) => void;
}
interface LinkMetadata {
title?: string;
description?: string;
siteName?: string;
}
export class MediaPlayer {
private playerProcess: ChildProcess;
private socket: Socket;
@@ -15,6 +22,7 @@ export class MediaPlayer {
private pendingCommands: Map<number, PendingCommand> = new Map();
private requestId: number = 1;
private dataBuffer: string = '';
private metadata: Map<string, LinkMetadata> = new Map();
constructor() {
const socketFilename = Math.random().toString(36).substring(2, 10);
@@ -41,7 +49,12 @@ export class MediaPlayer {
public async getPlaylist(): Promise<any> {
return this.writeCommand("get_property", ["playlist"])
.then((response) => {
return response.data;
// Enhance playlist items with metadata
const playlist = response.data;
return playlist.map((item: any) => ({
...item,
metadata: this.metadata.get(item.filename) || {}
}));
});
}
@@ -81,7 +94,14 @@ export class MediaPlayer {
}
public async append(url: string) {
return this.modify(() => this.writeCommand("loadfile", [url, "append-play"]));
const result = await this.modify(() => this.writeCommand("loadfile", [url, "append-play"]));
// Asynchronously fetch the metadata for this after we update the playlist
this.fetchMetadataAndNotify(url).catch(error => {
console.warn(`Failed to fetch metadata for ${url}:`, error);
});
return result;
}
public async play() {
@@ -154,6 +174,25 @@ export class MediaPlayer {
});
}
private async fetchMetadataAndNotify(url: string) {
try {
const metadata = await getLinkPreview(url);
this.metadata.set(url, {
title: (metadata as any)?.title,
description: (metadata as any)?.description,
siteName: (metadata as any)?.siteName,
});
// Notify clients that metadata has been updated
this.handleEvent("metadata_update", {
url,
metadata: this.metadata.get(url)
});
} catch (error) {
throw error;
}
}
private connectToSocket(path: string) {
this.socket.connect(path);
this.socket.on("data", data => this.receiveData(data.toString()));