You've already forked fm-dx-webserver
mirror of
https://github.com/KubaPro010/fm-dx-webserver.git
synced 2026-02-26 22:13:53 +01:00
bugfixes, refactor, code removal
This commit is contained in:
@@ -34,7 +34,7 @@ console.log(`\x1b[32m
|
||||
|_| |_| |_| |____/_/\\_\\ \\_/\\_/ \\___|_.__/|___/\\___|_| \\_/ \\___|_|
|
||||
`);
|
||||
console.log('\x1b[0mFM-DX-Webserver', pjson.version);
|
||||
console.log('\x1b[90m======================================================');
|
||||
console.log('\x1b[90m―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――');
|
||||
|
||||
// Start ffmpeg
|
||||
require('./stream/index');
|
||||
@@ -83,7 +83,7 @@ function connectToSerial() {
|
||||
serialport.write('C0\n');
|
||||
serialport.write('I0,0\n');
|
||||
|
||||
if(serverConfig.defaultFreq) {
|
||||
if(serverConfig.defaultFreq && serverConfig.enableDefaultFreq === true) {
|
||||
serialport.write('T' + Math.round(serverConfig.defaultFreq * 1000) +'\n');
|
||||
dataHandler.initialData.freq = Number(serverConfig.defaultFreq).toFixed(3);
|
||||
dataHandler.dataToSend.freq = Number(serverConfig.defaultFreq).toFixed(3);
|
||||
@@ -160,7 +160,9 @@ function connectToXdrd() {
|
||||
|
||||
if (authFlags.authMsg && authFlags.firstClient) {
|
||||
client.write('x\n');
|
||||
client.write(serverConfig.defaultFreq ? 'T' + Math.round(serverConfig.defaultFreq * 1000) + '\n' : 'T87500\n');
|
||||
client.write(serverConfig.defaultFreq && serverConfig.enableDefaultFreq === true ? 'T' + Math.round(serverConfig.defaultFreq * 1000) + '\n' : 'T87500\n');
|
||||
dataHandler.initialData.freq = serverConfig.defaultFreq && serverConfig.enableDefaultFreq === true ? (serverConfig.defaultFreq).toFixed(3) : (87.5).toFixed(3);
|
||||
dataHandler.dataToSend.freq = serverConfig.defaultFreq && serverConfig.enableDefaultFreq === true ? (serverConfig.defaultFreq).toFixed(3) : (87.5).toFixed(3);
|
||||
client.write('A0\n');
|
||||
client.write(serverConfig.audio.startupVolume ? 'Y' + (serverConfig.audio.startupVolume * 100).toFixed(0) + '\n' : 'Y100\n');
|
||||
client.off('data', authDataHandler);
|
||||
|
||||
@@ -39,54 +39,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs_1 = require("fs");
|
||||
const child_process_1 = require("child_process");
|
||||
const ws = __importStar(require("ws"));
|
||||
const wrtc = require('wrtc');
|
||||
const Settings = JSON.parse((0, fs_1.readFileSync)('server/stream/settings.json', 'utf-8'));
|
||||
const FFmpeg_command = ffmpegStaticPath;
|
||||
class RtcProvider {
|
||||
constructor() {
|
||||
this.RtcDistributePeer = new wrtc.RTCPeerConnection(Settings.RtcConfig);
|
||||
this.RtcDistributePeer.addTransceiver('audio');
|
||||
this.RtcDistributePeer.ontrack = this.OnTrack.bind(this);
|
||||
this.RtcDistributePeer.onicecandidate = this.OnIceCandidate_Distribute.bind(this);
|
||||
this.RtcSourcePeer = new wrtc.RTCPeerConnection(Settings.RtcConfig);
|
||||
this.RtcSourceMediaSource = new wrtc.nonstandard.RTCAudioSource();
|
||||
this.RtcSourceTrack = this.RtcSourceMediaSource.createTrack();
|
||||
this.RtcSourcePeer.addTrack(this.RtcSourceTrack);
|
||||
this.RtcSourcePeer.onicecandidate = this.OnIceCandidate_Source.bind(this);
|
||||
this.Init();
|
||||
}
|
||||
Init() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let offer = yield this.RtcSourcePeer.createOffer();
|
||||
yield this.RtcSourcePeer.setLocalDescription(new wrtc.RTCSessionDescription(offer));
|
||||
yield this.RtcDistributePeer.setRemoteDescription(offer);
|
||||
let answer = yield this.RtcDistributePeer.createAnswer();
|
||||
yield this.RtcDistributePeer.setLocalDescription(new wrtc.RTCSessionDescription(answer));
|
||||
yield this.RtcSourcePeer.setRemoteDescription(new wrtc.RTCSessionDescription(answer));
|
||||
});
|
||||
}
|
||||
OnTrack(event) {
|
||||
this.RtcDistributeTrack = event.track;
|
||||
}
|
||||
OnIceCandidate_Distribute(e) {
|
||||
if (!e.candidate)
|
||||
return;
|
||||
(() => __awaiter(this, void 0, void 0, function* () { return yield this.RtcSourcePeer.addIceCandidate(e.candidate); }))();
|
||||
}
|
||||
OnIceCandidate_Source(e) {
|
||||
if (!e.candidate)
|
||||
return;
|
||||
(() => __awaiter(this, void 0, void 0, function* () { return yield this.RtcDistributePeer.addIceCandidate(e.candidate); }))();
|
||||
}
|
||||
InsertMediaData(data) {
|
||||
if (!this.RtcSourceMediaSource)
|
||||
return;
|
||||
this.RtcSourceMediaSource.onData(data);
|
||||
}
|
||||
GetTrack() {
|
||||
return this.RtcDistributeTrack;
|
||||
}
|
||||
}
|
||||
class StreamClient {
|
||||
constructor(server, socket) {
|
||||
this.Server = server;
|
||||
@@ -102,10 +56,7 @@ class StreamClient {
|
||||
try {
|
||||
let request = JSON.parse(message.toString());
|
||||
if (request.type == "answer") {
|
||||
(() => __awaiter(this, void 0, void 0, function* () { return yield this.RtcPeer.setRemoteDescription(new wrtc.RTCSessionDescription(request.data)); }))();
|
||||
}
|
||||
else if (request.type == "webrtc") {
|
||||
this.Server.SetWebRtc(this);
|
||||
|
||||
}
|
||||
else if (request.type == "fallback") {
|
||||
this.Server.SetFallback(this, request.data);
|
||||
@@ -137,17 +88,6 @@ class StreamClient {
|
||||
}
|
||||
catch (ex) {
|
||||
}
|
||||
if (this.RtcSender && this.RtcPeer)
|
||||
this.RtcPeer.removeTrack(this.RtcSender);
|
||||
if (this.RtcSender)
|
||||
this.RtcSender = null;
|
||||
if (this.RtcTrack)
|
||||
this.RtcTrack = null;
|
||||
if (this.RtcPeer) {
|
||||
this.RtcPeer.close();
|
||||
delete this.RtcPeer;
|
||||
this.RtcPeer = null;
|
||||
}
|
||||
}
|
||||
SendBinary(buffer) {
|
||||
if (this.Socket.readyState != ws.OPEN) {
|
||||
@@ -163,28 +103,6 @@ class StreamClient {
|
||||
}
|
||||
this.Socket.send(text);
|
||||
}
|
||||
StartRtc(track) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
this.RtcPeer = new wrtc.RTCPeerConnection(Settings.RtcConfig);
|
||||
this.RtcTrack = track;
|
||||
this.RtcSender = this.RtcPeer.addTrack(this.RtcTrack);
|
||||
this.RtcPeer.onconnectionstatechange = this.OnConnectionStateChange.bind(this);
|
||||
this.RtcPeer.onicecandidate = this.OnIceCandidate.bind(this);
|
||||
let offer = yield this.RtcPeer.createOffer();
|
||||
yield this.RtcPeer.setLocalDescription(new wrtc.RTCSessionDescription(offer));
|
||||
this.SendText(JSON.stringify({
|
||||
"type": "offer",
|
||||
"data": offer
|
||||
}));
|
||||
});
|
||||
}
|
||||
OnConnectionStateChange(e) {
|
||||
if (!this.RtcPeer)
|
||||
return;
|
||||
let state = this.RtcPeer.connectionState;
|
||||
if (state != "new" && state != "connecting" && state != "connected")
|
||||
this.OnError(null);
|
||||
}
|
||||
OnIceCandidate(e) {
|
||||
if (e.candidate) {
|
||||
this.SendText(JSON.stringify({
|
||||
@@ -199,9 +117,7 @@ class StreamServer {
|
||||
this.Port = port;
|
||||
this.Channels = channels;
|
||||
this.SampleRate = sampleRate;
|
||||
this.RtcProvider = new RtcProvider();
|
||||
this.Clients = new Set();
|
||||
this.RtcClients = new Set();
|
||||
this.FallbackClients = {
|
||||
"wav": new Set(),
|
||||
"mp3": new Set()
|
||||
@@ -246,7 +162,6 @@ class StreamServer {
|
||||
"channelCount": this.Channels,
|
||||
"numberOfFrames": this.SamplesCount,
|
||||
};
|
||||
this.RtcProvider.InsertMediaData(data);
|
||||
this.Samples = new Int16Array(this.Channels * this.SamplesCount);
|
||||
this.SamplesPosition = 0;
|
||||
}
|
||||
@@ -266,30 +181,22 @@ class StreamServer {
|
||||
this.FallbackClients[format].add(client);
|
||||
this.FallbackProvider[format].PrimeClient(client);
|
||||
}
|
||||
SetWebRtc(client) {
|
||||
this.RtcClients.add(client);
|
||||
client.StartRtc(this.RtcProvider.GetTrack());
|
||||
}
|
||||
DestroyClient(client) {
|
||||
this.FallbackClients["mp3"].delete(client);
|
||||
this.FallbackClients["wav"].delete(client);
|
||||
this.RtcClients.delete(client);
|
||||
this.Clients.delete(client);
|
||||
client.Destroy();
|
||||
}
|
||||
GetStats() {
|
||||
let rtc = this.RtcClients.size;
|
||||
let fallback = {
|
||||
"wav": (this.FallbackClients["wav"] ? this.FallbackClients["wav"].size : 0),
|
||||
"mp3": (this.FallbackClients["mp3"] ? this.FallbackClients["mp3"].size : 0),
|
||||
};
|
||||
let total = rtc;
|
||||
for (let format in fallback) {
|
||||
total += fallback[format];
|
||||
}
|
||||
return {
|
||||
"Total": total,
|
||||
"Rtc": rtc,
|
||||
"Fallback": fallback,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ function enableAudioStream() {
|
||||
var ffmpegParams;
|
||||
var ffmpegCommand;
|
||||
serverConfig.webserver.webserverPort = Number(serverConfig.webserver.webserverPort);
|
||||
const ffmpegPath = "\"" + ffmpeg.replace(/\\/g, '\\\\') + "\"";
|
||||
|
||||
const flags = `-fflags +nobuffer+flush_packets -flags low_delay -rtbufsize 6192 -probesize 32`;
|
||||
const codec = `-acodec pcm_s16le -ar 48000 -ac ${serverConfig.audio.audioChannels}`;
|
||||
const output = `-f s16le -fflags +nobuffer+flush_packets -packetsize 384 -flush_packets 1 -bufsize 960`;
|
||||
@@ -23,11 +23,12 @@ const ffmpegPath = "\"" + ffmpeg.replace(/\\/g, '\\\\') + "\"";
|
||||
ffmpegParams = `${flags} -f alsa -i "${serverConfig.audio.softwareMode && serverConfig.audio.softwareMode == true ? 'plug' : ''}${serverConfig.audio.audioDevice}" ${codec} ${output} pipe:1 | node server/stream/3las.server.js -port ${serverConfig.webserver.webserverPort + 10} -samplerate 48000 -channels ${serverConfig.audio.audioChannels}`;
|
||||
}
|
||||
|
||||
consoleCmd.logInfo("Using audio device: " + serverConfig.audio.audioDevice);
|
||||
consoleCmd.logInfo(`Launching audio stream on internal port ${serverConfig.webserver.webserverPort + 10}.`);
|
||||
logInfo("Trying to start audio stream on device: \x1b[35m" + serverConfig.audio.audioDevice);
|
||||
logInfo(`Using internal audio network port ${serverConfig.webserver.webserverPort + 10}.`);
|
||||
|
||||
// If an audio device is configured, start the stream
|
||||
if(serverConfig.audio.audioDevice.length > 2) {
|
||||
let startupSuccess = false;
|
||||
const childProcess = spawn(ffmpegCommand, [ffmpegParams], { shell: true });
|
||||
|
||||
childProcess.stdout.on('data', (data) => {
|
||||
@@ -36,6 +37,13 @@ const ffmpegPath = "\"" + ffmpeg.replace(/\\/g, '\\\\') + "\"";
|
||||
|
||||
childProcess.stderr.on('data', (data) => {
|
||||
logFfmpeg(`stderr: ${data}`);
|
||||
if(data.includes('I/O error')) {
|
||||
logError('Audio device \x1b[35m' + serverConfig.audio.audioDevice + '\x1b[0m failed to start. Start server with the command \x1b[33mnode . --ffmpegdebug \x1b[0mfor more info.')
|
||||
}
|
||||
if(data.includes('size=') && startupSuccess === false) {
|
||||
logInfo('Audio stream started up successfully.');
|
||||
startupSuccess = true;
|
||||
}
|
||||
});
|
||||
|
||||
childProcess.on('close', (code) => {
|
||||
|
||||
Reference in New Issue
Block a user