Add streamlink command fallback and improve ENOENT errors (v3.7.9)
Resolve streamlink execution more robustly by trying direct binary and Python module launchers, then return actionable error messages when streamlink is missing on server environments.
This commit is contained in:
parent
78378b9812
commit
a3c3c6d225
4
typescript-version/package-lock.json
generated
4
typescript-version/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "twitch-vod-manager",
|
||||
"version": "3.7.8",
|
||||
"version": "3.7.9",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "twitch-vod-manager",
|
||||
"version": "3.7.8",
|
||||
"version": "3.7.9",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twitch-vod-manager",
|
||||
"version": "3.7.8",
|
||||
"version": "3.7.9",
|
||||
"description": "Twitch VOD Manager - Download Twitch VODs easily",
|
||||
"main": "dist/main.js",
|
||||
"author": "xRangerDE",
|
||||
|
||||
@ -335,7 +335,7 @@
|
||||
|
||||
<div class="settings-card">
|
||||
<h3>Updates</h3>
|
||||
<p id="versionInfo" style="margin-bottom: 10px; color: var(--text-secondary);">Version: v3.7.8</p>
|
||||
<p id="versionInfo" style="margin-bottom: 10px; color: var(--text-secondary);">Version: v3.7.9</p>
|
||||
<button class="btn-secondary" onclick="checkUpdate()">Nach Updates suchen</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -346,7 +346,7 @@
|
||||
<div class="status-dot" id="statusDot"></div>
|
||||
<span id="statusText">Nicht verbunden</span>
|
||||
</div>
|
||||
<span id="versionText">v3.7.8</span>
|
||||
<span id="versionText">v3.7.9</span>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@ -8,7 +8,7 @@ import { autoUpdater } from 'electron-updater';
|
||||
// ==========================================
|
||||
// CONFIG & CONSTANTS
|
||||
// ==========================================
|
||||
const APP_VERSION = '3.7.8';
|
||||
const APP_VERSION = '3.7.9';
|
||||
const UPDATE_CHECK_URL = 'http://24-music.de/version.json';
|
||||
|
||||
// Paths
|
||||
@ -172,6 +172,7 @@ let currentDownloadCancelled = false;
|
||||
let downloadStartTime = 0;
|
||||
let downloadedBytes = 0;
|
||||
const userIdLoginCache = new Map<string, string>();
|
||||
let streamlinkCommandCache: { command: string; prefixArgs: string[] } | null = null;
|
||||
|
||||
// ==========================================
|
||||
// TOOL PATHS
|
||||
@ -201,6 +202,52 @@ function getStreamlinkPath(): string {
|
||||
return 'streamlink';
|
||||
}
|
||||
|
||||
function canExecute(cmd: string): boolean {
|
||||
try {
|
||||
execSync(cmd, { stdio: 'ignore', windowsHide: true });
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getStreamlinkCommand(): { command: string; prefixArgs: string[] } {
|
||||
if (streamlinkCommandCache) {
|
||||
return streamlinkCommandCache;
|
||||
}
|
||||
|
||||
const directPath = getStreamlinkPath();
|
||||
if (directPath !== 'streamlink' || canExecute('streamlink --version')) {
|
||||
streamlinkCommandCache = { command: directPath, prefixArgs: [] };
|
||||
return streamlinkCommandCache;
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
if (canExecute('py -3 -m streamlink --version')) {
|
||||
streamlinkCommandCache = { command: 'py', prefixArgs: ['-3', '-m', 'streamlink'] };
|
||||
return streamlinkCommandCache;
|
||||
}
|
||||
|
||||
if (canExecute('python -m streamlink --version')) {
|
||||
streamlinkCommandCache = { command: 'python', prefixArgs: ['-m', 'streamlink'] };
|
||||
return streamlinkCommandCache;
|
||||
}
|
||||
} else {
|
||||
if (canExecute('python3 -m streamlink --version')) {
|
||||
streamlinkCommandCache = { command: 'python3', prefixArgs: ['-m', 'streamlink'] };
|
||||
return streamlinkCommandCache;
|
||||
}
|
||||
|
||||
if (canExecute('python -m streamlink --version')) {
|
||||
streamlinkCommandCache = { command: 'python', prefixArgs: ['-m', 'streamlink'] };
|
||||
return streamlinkCommandCache;
|
||||
}
|
||||
}
|
||||
|
||||
streamlinkCommandCache = { command: directPath, prefixArgs: [] };
|
||||
return streamlinkCommandCache;
|
||||
}
|
||||
|
||||
function getFFmpegPath(): string {
|
||||
try {
|
||||
if (process.platform === 'win32') {
|
||||
@ -777,8 +824,8 @@ function downloadVODPart(
|
||||
totalParts: number
|
||||
): Promise<DownloadResult> {
|
||||
return new Promise((resolve) => {
|
||||
const streamlinkPath = getStreamlinkPath();
|
||||
const args = [url, 'best', '-o', filename, '--force'];
|
||||
const streamlinkCmd = getStreamlinkCommand();
|
||||
const args = [...streamlinkCmd.prefixArgs, url, 'best', '-o', filename, '--force'];
|
||||
let lastErrorLine = '';
|
||||
|
||||
if (startTime) {
|
||||
@ -788,10 +835,10 @@ function downloadVODPart(
|
||||
args.push('--hls-duration', endTime);
|
||||
}
|
||||
|
||||
console.log('Starting download:', streamlinkPath, args);
|
||||
appendDebugLog('download-part-start', { itemId, streamlinkPath, filename, args });
|
||||
console.log('Starting download:', streamlinkCmd.command, args);
|
||||
appendDebugLog('download-part-start', { itemId, command: streamlinkCmd.command, filename, args });
|
||||
|
||||
const proc = spawn(streamlinkPath, args, { windowsHide: true });
|
||||
const proc = spawn(streamlinkCmd.command, args, { windowsHide: true });
|
||||
currentProcess = proc;
|
||||
|
||||
downloadStartTime = Date.now();
|
||||
@ -890,8 +937,12 @@ function downloadVODPart(
|
||||
clearInterval(progressInterval);
|
||||
console.error('Process error:', err);
|
||||
currentProcess = null;
|
||||
appendDebugLog('download-part-process-error', { itemId, error: String(err) });
|
||||
resolve({ success: false, error: String(err) });
|
||||
const rawError = String(err);
|
||||
const errorMessage = rawError.includes('ENOENT')
|
||||
? 'Streamlink nicht gefunden. Installiere Streamlink oder Python+streamlink (py -3 -m pip install streamlink).'
|
||||
: rawError;
|
||||
appendDebugLog('download-part-process-error', { itemId, error: errorMessage, rawError });
|
||||
resolve({ success: false, error: errorMessage });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user