diff --git a/server/helpers.js b/server/helpers.js
index 33cc2a0..9544023 100644
--- a/server/helpers.js
+++ b/server/helpers.js
@@ -20,7 +20,7 @@ function parseMarkdown(parsed) {
parsed = parsed.replace(italicRegex, '$1');
var linkRegex = /\[([^\]]+)]\(([^)]+)\)/g;
- parsed = parsed.replace(linkRegex, '$1');
+ parsed = parsed.replace(linkRegex, '$1');
parsed = parsed.replace(/\n/g, '
');
diff --git a/server/stream/parser.js b/server/stream/parser.js
index 48299f1..d0142bc 100644
--- a/server/stream/parser.js
+++ b/server/stream/parser.js
@@ -1,7 +1,7 @@
'use strict';
const exec = require('child_process').exec;
-const fs = require('fs');
+const fs = require('fs').promises; // Use the Promise-based fs API
const ffmpeg = require('ffmpeg-static');
const filePath = '/proc/asound/cards';
const platform = process.platform;
@@ -16,106 +16,97 @@ function parseAudioDevice(options, callback) {
options = null;
}
options = options || {};
- const ffmpegPath = "\"" + ffmpeg.replace(/\\/g, '\\\\') + "\"";
+ const ffmpegPath = `"${ffmpeg.replace(/\\/g, '\\\\')}"`;
const callbackExists = typeof callback === 'function';
-
- let inputDevice, prefix, audioSeparator, alternativeName, deviceParams;
- switch (platform) {
- case 'win32':
- inputDevice = 'dshow';
- prefix = /\[dshow/;
- audioSeparator = /DirectShow\saudio\sdevices/;
- alternativeName = /Alternative\sname\s*?\"(.*?)\"/;
- deviceParams = /\"(.*?)\"/;
- break;
- case 'darwin':
- inputDevice = 'avfoundation';
- prefix = /^\[AVFoundation/;
- audioSeparator = /AVFoundation\saudio\sdevices/;
- deviceParams = /^\[AVFoundation.*?\]\s\[(\d*?)\]\s(.*)$/;
- break;
- case 'linux':
- fs.readFile(filePath, 'utf8', (err, data) => {
- if (err) {
- console.error(`Error reading file: ${err.message}`);
- return;
- }
-
- // Extract values between square brackets, trim whitespace, and prefix with 'hw:'
- const regex = /\[([^\]]+)\]/g;
- const matches = (data.match(regex) || []).map(match => 'hw:' + match.replace(/\s+/g, '').slice(1, -1));
-
- if (matches.length > 0) {
- // Process the extracted values
- matches.forEach(function(match) {
- if (typeof match === 'string') {
- audioDevices.push({ name: match });
- } else if (typeof match === 'object' && match.name) {
- audioDevices.push(match);
- }
- });
- } else {
- logWarn('No audio devices have been found.');
- }
- });
- break;
- }
-
-
- const searchPrefix = (line) => (line.search(prefix) > -1);
- const searchAudioSeparator = (line) => isVideo && (line.search(audioSeparator) > -1);
- const searchAlternativeName = (line) => (platform === 'win32') && (line.search(/Alternative\sname/) > -1);
-
- const execute = (fulfill, reject) => {
- exec(`${ffmpegPath} -f ${inputDevice} -list_devices true -i ""`, (err, stdout, stderr) => {
- stderr.split("\n")
- .filter(searchPrefix)
- .forEach((line) => {
- const deviceList = isVideo ? videoDevices : audioDevices;
- if (searchAudioSeparator(line)) {
- isVideo = false;
- return;
+ const execute = async (fulfill, reject) => {
+ try {
+ if (platform === 'linux') {
+ try {
+ const data = await fs.readFile(filePath, 'utf8');
+ const regex = /\[([^\]]+)\]/g;
+ const matches = (data.match(regex) || []).map(match => 'hw:' + match.replace(/\s+/g, '').slice(1, -1));
+
+ matches.forEach(match => {
+ if (typeof match === 'string') {
+ audioDevices.push({ name: match });
+ }
+ });
+ } catch (err) {
+ console.error(`Error reading file: ${err.message}`);
}
- if (searchAlternativeName(line)) {
- const lastDevice = deviceList[deviceList.length - 1];
- lastDevice.alternativeName = line.match(alternativeName)[1];
- return;
- }
- const params = line.match(deviceParams);
- if (params) {
- let device;
- switch (platform) {
- case 'win32':
- device = {
- name: params[1]
- };
- break;
- case 'darwin':
- device = {
- id: parseInt(params[1]),
- name: params[2]
- };
- break;
- case 'linux':
- device = {
- name: params[1]
- };
- break;
- }
- deviceList.push(device);
- }
- });
- audioDevices = audioDevices.filter(device => device.name !== undefined);
- const result = { videoDevices, audioDevices };
- if (callbackExists) {
- callback(result);
- } else {
- fulfill(result);
+
+ // Linux doesn't support the `-list_devices` ffmpeg command like macOS/Windows,
+ // so skip the ffmpeg exec for Linux
+ const result = { videoDevices: [], audioDevices };
+ if (callbackExists) return callback(result);
+ return fulfill(result);
}
- });
+
+ let inputDevice, prefix, audioSeparator, alternativeName, deviceParams;
+
+ switch (platform) {
+ case 'win32':
+ inputDevice = 'dshow';
+ prefix = /\[dshow/;
+ audioSeparator = /DirectShow\saudio\sdevices/;
+ alternativeName = /Alternative\sname\s*?"(.*?)"/;
+ deviceParams = /"(.*?)"/;
+ break;
+ case 'darwin':
+ inputDevice = 'avfoundation';
+ prefix = /^\[AVFoundation/;
+ audioSeparator = /AVFoundation\saudio\sdevices/;
+ deviceParams = /^\[AVFoundation.*?]\s\[(\d+)]\s(.*)$/;
+ break;
+ }
+
+ exec(`${ffmpegPath} -f ${inputDevice} -list_devices true -i ""`, (err, stdout, stderr) => {
+ stderr.split("\n")
+ .filter(line => line.search(prefix) > -1)
+ .forEach(line => {
+ const deviceList = isVideo ? videoDevices : audioDevices;
+ if (line.search(audioSeparator) > -1) {
+ isVideo = false;
+ return;
+ }
+
+ if (platform === 'win32' && line.search(/Alternative\sname/) > -1) {
+ const lastDevice = deviceList[deviceList.length - 1];
+ const alt = line.match(alternativeName);
+ if (lastDevice && alt) {
+ lastDevice.alternativeName = alt[1];
+ }
+ return;
+ }
+
+ const params = line.match(deviceParams);
+ if (params) {
+ let device;
+ switch (platform) {
+ case 'win32':
+ device = { name: params[1] };
+ break;
+ case 'darwin':
+ device = { id: parseInt(params[1]), name: params[2] };
+ break;
+ }
+ deviceList.push(device);
+ }
+ });
+
+ audioDevices = audioDevices.filter(device => device.name !== undefined);
+ const result = { videoDevices, audioDevices };
+ if (callbackExists) return callback(result);
+ return fulfill(result);
+ });
+ } catch (err) {
+ console.error('Unexpected error:', err);
+ if (callbackExists) callback({ videoDevices: [], audioDevices: [] });
+ else reject(err);
+ }
};
-
+
if (callbackExists) {
execute();
} else {
diff --git a/web/index.ejs b/web/index.ejs
index 5cce173..49a5da4 100644
--- a/web/index.ejs
+++ b/web/index.ejs
@@ -23,8 +23,6 @@
-
-
@@ -267,6 +265,19 @@
Filters
@@ -409,10 +409,10 @@Possible transmitters
+Other possible transmitters