Newest 'ffmpeg' Questions - Stack Overflow
Les articles publiés sur le site
-
Write EPIPE after upgrade Node.js
30 juillet, par RougherI am using this code for detecting audio replay gain. It was working well with Node.js 16, but after upgrading to Node.js 22, it started crashing a few times in an hour with this error:
write EPIPE at WriteWrap.onWriteComplete [as oncomplete] (node:internal/stream_base_commons:87:19) { errno: -32, code: 'EPIPE', syscall: 'write' }
My original code was
static getReplayGainVolume(audioData: Buffer) { // Calculate the mean volume of the audio file at the given filePath var ffmpeg = spawn('ffmpeg', [ '-i', '-', '-af', 'replaygain', '-f', 'null', '/dev/null', '-hide_banner', '-nostats' ]); var output = ''; ffmpeg.stdin.write(audioData); ffmpeg.stdin.end(); return new Promise((resolve,reject)=>{ ffmpeg.on('error', function (err: any) { reject(err); }); ffmpeg.on('close', function (_code: any) { // [Parsed_replaygain_0 @ 0000000002a2b5c0] track_gain = +6.53 dB if (!output.includes("track_gain")) { reject(output); return; } const gainWithDb = output.split("track_gain = ")[1]; if (!gainWithDb) { reject(output); return; } const gain = gainWithDb.split(" dB")[0]; if (!gain) { reject(output); return; } resolve(parseFloat(gain)); }); ffmpeg.stderr.on('data', function (data: any) { // ffmpeg sends all output to stderr. It is not a bug, it is a feature :) var tData = data.toString('utf8'); output += tData; }); }); }
Then after search in forums and Google, I improved (I hope I improved it with cleanups)
static getReplayGainVolume(audioData: Buffer): Promise
{ return new Promise((resolve, reject) => { const FFMPEG_PATH = 'ffmpeg'; // Adjust this if ffmpeg is not in system PATH const FFMPEG_TIMEOUT_MS = 30 * 1000; // 30 seconds timeout for FFmpeg execution let ffmpeg: ChildProcessWithoutNullStreams; let output = ''; // Accumulate all stderr output // Timeout for the FFmpeg process itself const ffmpegTimeout = setTimeout(() => { log.error(`[FFmpeg] FFmpeg process timed out after ${FFMPEG_TIMEOUT_MS / 1000} seconds. Killing process.`); if (ffmpeg && !ffmpeg.killed) { ffmpeg.kill('SIGKILL'); // Force kill reject(new Error(`FFmpeg process timed out and was killed.`)); } }, FFMPEG_TIMEOUT_MS); // --- Define cleanup function to be called on process exit/error --- const cleanup = (shouldReject = false, error?: Error | string) => { clearTimeout(ffmpegTimeout); // Ensure timeout is cleared // Remove all listeners to prevent leaks // This is CRITICAL for long-running bots that spawn many child processes ffmpeg.stdin.removeAllListeners(); ffmpeg.stdout.removeAllListeners(); ffmpeg.stderr.removeAllListeners(); ffmpeg.removeAllListeners(); // Remove process listeners if (ffmpeg && !ffmpeg.killed) { // Ensure ffmpeg process is killed if still alive ffmpeg.kill(); // Graceful kill (SIGTERM), then wait for exit. If not, then SIGKILL. } if (shouldReject) { reject(error instanceof Error ? error : new Error(String(error))); } }; try { ffmpeg = spawn(FFMPEG_PATH, [ '-i', 'pipe:0', // Read input from stdin (pipe:0) '-af', 'replaygain', '-f', 'null', '/dev/null', // Write output to null device (discard audio output) '-hide_banner', '-nostats' // Suppress ffmpeg's initial info and progress stats ], { stdio: ['pipe', 'pipe', 'pipe'] }); // Explicitly pipe stdin, stdout, stderr // --- CRITICAL: Event Handlers for ffmpeg process --- // 1. Handle errors during spawning or execution (e.g., ffmpeg not found) ffmpeg.on('error', (err: any) => { log.error(`[FFmpeg] Failed to spawn or execute FFmpeg process:`, err); cleanup(true, new Error(`FFmpeg process error: ${err.message}`)); }); // 2. Accumulate stderr output (where replaygain results and ffmpeg errors are printed) ffmpeg.stderr.on('data', (data: Buffer) => { output += data.toString('utf8'); }); // 3. Handle process exit (success or failure) ffmpeg.on('close', (code: number) => { // 'close' indicates process has exited log.debug(`[FFmpeg] FFmpeg process exited with code: ${code}.`); if (code !== 0) { // Non-zero exit code means failure log.error(`[FFmpeg] FFmpeg process exited with non-zero code ${code}. Output:\n${output}`); cleanup(true, new Error(`FFmpeg process failed with exit code ${code}. Output: ${output}`)); return; } // If successful exit (code 0), parse the output if (!output.includes("track_gain")) { log.error(`[FFmpeg] 'track_gain' not found in FFmpeg output (exit code 0). Output:\n${output}`); cleanup(true, new Error(`'track_gain' not found in FFmpeg output. Output: ${output}`)); return; } try { // Regex to parse track_gain (e.g., "+6.53 dB" or "-12.00 dB") const gainMatch = output.match(/track_gain\s*=\s*([+-]?\d+\.?\d*)\s*dB/); if (gainMatch && gainMatch[1]) { const gain = parseFloat(gainMatch[1]); log.debug(`[FFmpeg] Replay gain volume: ${gain} dB.`); cleanup(); // Clean up on success resolve(gain); } else { log.error(`[FFmpeg] Failed to parse gain from FFmpeg output. Output:\n${output}`); cleanup(true, new Error(`Failed to parse gain from FFmpeg output. Output: ${output}`)); } } catch (parseError: any) { log.error(`[FFmpeg] Error parsing FFmpeg replay gain output:`, parseError); cleanup(true, new Error(`Error parsing FFmpeg output: ${parseError.message}. Output: ${output}`)); } }); // 4. Write audio data to ffmpeg's stdin // This is the only write operation that could throw EPIPE in this function. try { ffmpeg.stdin.write(audioData); ffmpeg.stdin.end(); // Close stdin to signal end of input } catch (stdinError: any) { log.error(`[FFmpeg] Error writing audioData to FFmpeg stdin:`, stdinError); // This error means ffmpeg's stdin pipe closed unexpectedly. // This is the direct equivalent of an EPIPE (Broken Pipe) at the child process level. cleanup(true, new Error(`Failed to pipe audio data to FFmpeg stdin: ${stdinError.message}`)); } } catch (spawnError: any) { // Catch errors from the spawn call itself (e.g., FFMPEG_PATH is invalid) log.error(`[FFmpeg] Error spawning FFmpeg:`, spawnError); cleanup(true, new Error(`Failed to spawn FFmpeg process: ${spawnError.message}`)); } }); } But unfortunately I still get the same error. Has anyone encountered this problem? How can I solve it?
I use ffmpeg version 4.2.7-0ubuntu0.1
-
How can I decode MegaRace (93/94) .HNM videos ? — FFmpeg fails and legacy tools are missing [closed]
29 juillet, par L PGoal
- I want to convert the original full‑motion videos shipped with MegaRace (DOS, 1993/94) from Cryo’s proprietary HNM format into a modern, playable container (e.g. lossless AVI/PNG sequence).
- Capturing the screen while the game runs is not an option: the target is the pure background animation (no sprites, no overlays, no DOSBox scaling filters, no subtitles).
What I already have
- Extracted all
*.HNM
files out ofMEGARACE.DAT
with Game Extractor.
(Directory listing: 100+ files fromAZUR.HNM
toVWBT5.HNM
.) - Verified that they are indeed Cryo HNM: the wiki pages [1] and [2] say MegaRace uses an early variant (v1/v2) written by Pascal Urro (might also used in 92's Dune, 95's Lost Eden etc.).
- Tried FFmpeg (from latest to earliest) with
ffplay -f hnm -i EXPLO.HNM
, but every file aborts withinvalid resolution
andinvalid data found when processing input
. Same for ffprobe and ffmpeg -i. - Searched for legacy tools:
- hnmdec / hnm2avi — no longer included in modern ScummVM‑Tools; seems to have been present at some point.
- extract_cryo — source vanished.
- Game Media Formats DirectShow Filters, by Valery Anisimovsky could, in theory, load the vendor codecs (
CM6_*.dll
) and expose them to DirectShow, but I haven't found the necessary Cryo DLLs shipped with MegaRace.
- Looked at the DOSBox “Video Codec” folder – it only contains ZMBV (
zmbv.dll
,zmbv.inf
), which is unrelated (that’s the codec DOSBox uses for screen‑capture).
Environment
- macOS Sequoia 15.5 on Apple Silicon (but I can boot Windows 11 ARM or use x86_64 VMs if the solution requires them).
- No need for audio; video stream alone is fine.
Why this matters
- Archiving early
FMV
assets is part of game preservation. MegaRace’s CG backgrounds are unique and currently inaccessible without running the whole DOS game.
What I’m looking for
- Specifications or source code for the
HNM
v1/v2 codec. - A working decoder (CLI or library) for any platform so I can batch‑convert all files.
- Pointers on how to patch FFmpeg’s current
libavcodec
/hnm4video.c
to support the older variant. - Alternatively, hints on extracting the player’s built‑in decoder from
MEGARACE.EXE
(or ScummVM’s internal implementation, if any) and wrapping it. - Any lead, paper, or old DOS utility is appreciated!
-
How to compile latest FFmpeg Library for Android ?
29 juillet, par Timo SchuckStruggling to put together a working and generally best practice build of current FFmpeg. There seems to be no up-to-date documents or tutorials. What does exist is full of outdated links or build-scripts that do not work.
-
Input path errors while running FFMPEG and keeping subdirectory structure [closed]
29 juillet, par piet koosMy goal is to reduce the size of all .ogg files found under the parent directory "Formatted", while keeping the sub-directories and files structure the same.
Example
.../Formatted/"test1, test2, test3 and so on"/"files.ogg"
to
.../Contributors/"test1, test2, test3 and so on"/"reduced_files.ogg"
However. While the script runs ffmpeg it seems that the some input file paths gives "Error opening input: No such file or directory". eg. It either cuts off the 'h' of home or adds a '.' to the end of the file extension.
"ome/user1/Downloads/Encoding/Formatted/test1/"file""
or
Parse error, at least 3 arguments were expected, only 1 given in string "oding/Formatted/test1/"file"
Resulting in
.../Contributors/"test1, test2, test3 and so on"/ with only a single file or missing .ogg files.
I'm new to coding, any help is appreciated . I've tried echoing the variables to make sure they are correct but early on in the process
echo "3" "$dirName"
shows the absolute path being inrorrect.#!/bin/bash sourceDir=$HOME/Downloads/Encoding/Formatted destDir=$HOME/Backup/LEARN/Contributors find ~/Downloads/Encoding/Formatted/ -type f -name "*.ogg" | while IFS= read -r d; do # find -name "*.ogg" echo "1" "$d" baseName=$(basename "$d") echo "2" "$baseName" dirName=$(dirname "$d") echo "3" "$dirName" dirName_0=$(basename "$dirName") echo "4" "$dirName_0" echo "5" "$destDir" outputDir="$destDir/$dirName_0" echo "6" "$outputDir" outputPath="$outputDir/$baseName" # echo "1" "$d" # echo "2" "$baseName" echo "3" "$dirName" # echo "4" "$dirName_0" # echo "5" "$destDirecho" # echo "6" "$outputDir" # echo "7" "$outputPath" # echo "8" "$destDir/$dirName_0/$baseName" # echo "9" "$sourceDir" mkdir -p "$outputDir" ffmpeg -i "$d" -b:a 24k -acodec libopus -map_metadata 0 -map_metadata 0:s:0 "$outputPath" done For the first file found, *echo* returns: 1 /home/user/Downloads/Encoding/Formatted/test/file1.ogg 2 file1.ogg 3 /home/user/Downloads/Encoding/Formatted/test 4 test 5 /home/user/Backup/LEARN/Contributors 6 /home/user/Backup/LEARN/Contributors/test 7 /home/user/Backup/LEARN/Contributors/test/file1.ogg 8 /home/user/Backup/LEARN/Contributors/test/file1.ogg 9 /home/user/Downloads/Encoding/Formatted Which is correct, but then for the next file found: 1 ome/user/Downloads/Encoding/Formatted/test/file2.ogg 2 file2.ogg 3 ome/user/Downloads/Encoding/Formatted/test 4 test 5 /home/user/Backup/LEARN/Contributors 6 /home/user/Backup/LEARN/Contributors/test 7 /home/user/Backup/LEARN/Contributors/test/file2.ogg 8 /home/user/Backup/LEARN/Contributors/test/file2.ogg 9 /home/user/Downloads/Encoding/Formatted line 1 and 3 both miss a h from home? It does this for files in multiple folders.
-
how to combine several video random any one to create 1 new video ? using ffmpeg ? [closed]
28 juillet, par Sky Moonhow to combine several video random any one to create 1 new video? for example, I have 10 videos: 01.mp4; 02.mp4 ... 10.mp4 I want to combine random 5 of them to create 1 video example: (01.mp4+ 03.mp4+ 04.mp4+ 06.mp4 + 08.mp4) = 1 new video
(02.mp4+ 04.mp4+ 05.mp4+ 06.mp4 + 09.mp4) = 1 new video
Similar: random combination of 50 videos of 1000 videos to create 1 new video?