
Recherche avancée
Autres articles (101)
-
Publier sur MédiaSpip
13 juin 2013Puis-je poster des contenus à partir d’une tablette Ipad ?
Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir -
Les autorisations surchargées par les plugins
27 avril 2010, parMediaspip core
autoriser_auteur_modifier() afin que les visiteurs soient capables de modifier leurs informations sur la page d’auteurs -
Soumettre bugs et patchs
10 avril 2011Un logiciel n’est malheureusement jamais parfait...
Si vous pensez avoir mis la main sur un bug, reportez le dans notre système de tickets en prenant bien soin de nous remonter certaines informations pertinentes : le type de navigateur et sa version exacte avec lequel vous avez l’anomalie ; une explication la plus précise possible du problème rencontré ; si possibles les étapes pour reproduire le problème ; un lien vers le site / la page en question ;
Si vous pensez avoir résolu vous même le bug (...)
Sur d’autres sites (8243)
-
Write EPIPE after upgrade NodeJS
28 juillet, par RougherI am using this code for detecting audio replay gain. It was working well with NodeJs 16, but after upgrading to NodeJs 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<number> {
 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}`));
 }
 });
 }
</number>


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


Thanks.


-
Open Banking Security 101 : Is open banking safe ?
3 décembre 2024, par Daniel Crough — Banking and Financial Services -
libavutil/thread.h : Fixed g++ build error when ASSERT_LEVEL is greater than 1
17 avril 2017, par Aaron Levinsonlibavutil/thread.h : Fixed g++ build error when ASSERT_LEVEL is greater than 1
Purpose : libavutil/thread.h : Fixed g++ build error when ASSERT_LEVEL
is greater than 1. This is only relevant when thread.h is included by
C++ files. In this case, the relevant code is only defined if
HAVE_PTHREADS is defined as 1. Use configure —assert-level=2 to do
so.Note : Issue discovered as a result of Coverity build failure. Cause
of build failure pinpointed by Hendrik Leppkes.Comments :
— libavutil/thread.h : Altered ASSERT_PTHREAD_NORET definition such
that it uses av_make_error_string instead of av_err2str().
av_err2str() uses a "parenthesized type followed by an initializer
list", which is apparently not valid C++. This issue started
occurring because thread.h is now included by the DeckLink C++
files. The alteration does the equivalent of what av_err2str()
does, but instead declares the character buffer as a local
variable.Signed-off-by : Marton Balint <cus@passwd.hu>