// Copyright 2014-2025 Jesper Larsson
//
// This file is part of Klipspringer, <https://klipspringer.avadeaux.net/>
//
// Klipspringer is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// Klipspringer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
// even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with Klipspringer. If
// not, see <https://www.gnu.org/licenses/>.
import * as net from 'net';
import { createPlayerCommon } from './player_common.js';
import { log } from './log.js';
export const createDevicePlayer = (opts, controlPath, inDevice, format) => {
const options = [...opts.java_opts];
options.push('net.avadeaux.klipspringer.DevicePlayer');
options.push('-recdir', opts.recdir);
options.push('-controlsock', controlPath);
if (inDevice) { options.push('-device', inDevice); }
if (format) {
let f = "", delim = "";
if (format.rate) { f += delim+"-r "+format.rate; delim = " " }
if (format.bits) { f += delim+"-b "+format.bits; delim = " " }
if (format.channels) { f += delim+"-c "+format.channels; delim = " " }
if (format.encoding) { f += delim+"-e "+format.encoding; delim = " " }
if (format.bigendian !== undefined) { f += delim+(format.bigendian ? "-B" : "-L") }
options.push("-format", f);
}
// Get superintf by createPlayerCommon.
const intf = createPlayerCommon("Device player", opts.java, options);
// Override pattern to check stdout for before ready.
intf.readyPattern = /^Ready control socket.*\n?/m;
// Sends command to player, returning a promise that resolves with answer
// object when it is done.
intf.command = (qstring) => intf.ready().then(() => new Promise((resolve, reject) => {
let ansString = '';
const sock = net.connect(controlPath, () => { sock.write(qstring+'\n') });
sock.on('data', msg => {
ansString += msg.toString();
}).on('end', () => {
ansString = ansString.trim();
try {
resolve(ansString.length ? JSON.parse(ansString) : { ok: "empty" });
} catch (jsonErr) {
resolve({ ok: ansString })
}
}).on('error', err => {
log.debug("Socket error: "+err);
reject(err);
});
})).catch(ans => ans && (ans.defunct || ans.err) ? { ...ans, defunct: true } : { defunct: true, err: ans.toString ? ans.toString() : ans });
// Commands passed on to Java process.
for (const cmd of ['start_record', 'stop_record', 'set_format', 'set_reclimit']) { intf.httpCallable[cmd] = intf.command }
// Quit only ends the stream, not the process.
intf.httpCallable.quit = (qstring, query) => intf.command(Object.entries({
...query,
cmd: 'end',
}).map(([p, v]) => p+'='+encodeURIComponent(v.toString())).join('&')+'\n');
return intf;
}
Version: v4.3.2.2 (2026-05-16T17:03:34+02:00)
Raw file
Source code overview
Klipspringer home