fix: improve VLC property parsing with defensive handling

- Add resolved flag to prevent double resolution race condition
- Use regex to parse numeric values instead of fragile line filtering
- Centralize cleanup in done() helper for consistent handling
- Increase timeout to 2000ms to match MPV

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 4.5 committed 2026-01-22 13:43:36 +01:00
1 parent 1df371b163
commit 85225c03d2
1 file changed
+16 -21
@@ -195,6 +195,17 @@ async function getVlcProperty(port: number, command: string): Promise<string> {
return new Promise((resolve) => {
const client = createConnection({ port, host: '127.0.0.1' });
let data = '';
let resolved = false;
const done = (result: string) => {
if (resolved) return;
resolved = true;
clearTimeout(timeoutHandle);
if (!client.destroyed) client.destroy();
resolve(result);
};
const timeoutHandle = setTimeout(() => done(''), 2000);
client.on('connect', () => {
client.write(command + '\n');
@@ -202,31 +213,15 @@ async function getVlcProperty(port: number, command: string): Promise<string> {
client.on('data', (chunk) => {
data += chunk.toString();
// VLC prompt '>' means command finished
if (data.includes('>')) {
// VLC prompt means command finished
client.destroy();
// Parse: find numeric value (for get_time/get_length)
const match = data.match(/^(\d+(\.\d+)?)\s*$/m);
done(match ? match[1] : '');
}
});
client.on('close', () => {
// Parse data
const lines = data
.split('\n')
.map((l) => l.trim())
.filter(
(l) => l && !l.includes('>') && !l.startsWith(command)
);
// The result should be one of the lines
const result = lines.length > 0 ? lines[0] : '';
resolve(result);
});
client.on('error', () => resolve(''));
setTimeout(() => {
if (!client.destroyed) client.destroy();
resolve('');
}, 1000);
client.on('error', () => done(''));
});
}