Skip to content

Commit

Permalink
Improve to use Config.json instead of enviorment vars and also packag…
Browse files Browse the repository at this point in the history
…e it
  • Loading branch information
SNRSE committed Jan 16, 2025
1 parent b5d5439 commit da17246
Show file tree
Hide file tree
Showing 5 changed files with 1,529 additions and 42 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

/media
/node_modules
/dist
6 changes: 6 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"folderToWatch": "./media",
"vmixUrl": "http://localhost:8088",
"playlistName": "List",
"supportedExtensions": [".mp4", ".mov", ".wmv", ".avi", ".mpg", ".mpeg"]
}
77 changes: 36 additions & 41 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,43 @@
const chokidar = require('chokidar');
const axios = require('axios');
const path = require('path');
const dotenv = require('dotenv');
const fs = require('fs');

// Load environment variables
dotenv.config();

// Configuration
const config = {
folderToWatch: process.env.WATCH_FOLDER || './media',
vmixUrl: process.env.VMIX_URL || 'http://localhost:8088',
playlistName: process.env.VMIX_PLAYLIST_NAME || 'List',
supportedExtensions: ['.mp4', '.mov', '.wmv', '.avi', '.mpg', '.mpeg']
// Get the directory where the executable is located
const getExeDir = () => {
// When packaged with pkg, process.pkg is defined
if (process.pkg) {
return path.dirname(process.execPath);
}
return __dirname;
};

// Load configuration
let config;
try {
const configPath = path.join(getExeDir(), 'config.json');
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
} catch (error) {
// Default configuration if config.json is not found
config = {
folderToWatch: './media',
vmixUrl: 'http://localhost:8088',
playlistName: 'List',
supportedExtensions: ['.mp4', '.mov', '.wmv', '.avi', '.mpg', '.mpeg']
};

// Create default config file if it doesn't exist
try {
fs.writeFileSync(
path.join(getExeDir(), 'config.json'),
JSON.stringify(config, null, 2)
);
console.log('Created default config.json');
} catch (writeError) {
console.error('Failed to create default config.json:', writeError.message);
}
}

// Initialize watcher
const watcher = chokidar.watch(config.folderToWatch, {
ignored: /(^|[\/\\])\../, // ignore hidden files
Expand All @@ -24,34 +48,11 @@ const watcher = chokidar.watch(config.folderToWatch, {
}
});

// Helper function to add file to vMix playlist
async function addToVmixPlaylist(filePath) {
const extension = path.extname(filePath).toLowerCase();

if (!config.supportedExtensions.includes(extension)) {
console.log(`Ignoring file ${filePath} - unsupported format`);
return;
}

try {
// Convert to absolute path if it isn't already
const absolutePath = path.resolve(filePath);
const encodedPath = encodeURIComponent(absolutePath);
const url = `${config.vmixUrl}/api/?Function=ListAdd&Input=${config.playlistName}&Value=${encodedPath}`;
await axios.get(url);
console.log(`Added ${absolutePath} to vMix playlist`);
} catch (error) {
console.error(`Error adding file to vMix: ${error.message}`);
}
}

// Helper function to parse XML response
async function getVmixState() {
try {
const response = await axios.get(`${config.vmixUrl}/api`);
// Response is XML, we'll use a simple way to parse it for now
const xmlText = response.data;
return xmlText;
return response.data;
} catch (error) {
console.error(`Error getting vMix state: ${error.message}`);
return null;
Expand All @@ -61,18 +62,14 @@ async function getVmixState() {
// Helper function to find list items for a specific input
function findListItems(xmlText, absolutePath) {
try {
// Find the VideoList input that contains our file
const listMatch = xmlText.match(/<input[^>]*type="VideoList"[^>]*>[\s\S]*?<list>([\s\S]*?)<\/list>/g);

if (listMatch) {
for (const list of listMatch) {
// Extract items from the list
const items = list.match(/<item[^>]*>(.*?)<\/item>/g);
if (items) {
// Find the index of our file (1-based for vMix)
const index = items.findIndex(item => item.includes(absolutePath)) + 1;
if (index > 0) {
// Find the input title/name
const titleMatch = list.match(/title="([^"]*?)"/);
const inputName = titleMatch ? titleMatch[1] : 'List';
return { index, inputName };
Expand Down Expand Up @@ -112,11 +109,9 @@ async function removeFromVmixPlaylist(filePath) {
try {
const absolutePath = path.resolve(filePath);

// Get current vMix state
const xmlState = await getVmixState();
if (!xmlState) return;

// Find the file in the lists
const fileInfo = findListItems(xmlState, absolutePath);

if (fileInfo) {
Expand All @@ -143,7 +138,6 @@ watcher
})
.on('change', path => {
console.log(`File ${path} has been changed`);
// Re-add the file to update it in vMix
addToVmixPlaylist(path);
})
.on('rename', (oldPath, newPath) => {
Expand All @@ -156,6 +150,7 @@ watcher
});

// Log that we're running
console.log('Configuration:', config);
console.log(`Watching ${config.folderToWatch} for changes...`);
console.log(`vMix API URL: ${config.vmixUrl}`);
console.log(`Supported file types: ${config.supportedExtensions.join(', ')}`);
Loading

0 comments on commit da17246

Please sign in to comment.