1- // Copyright (C) 2009-2016 Christopher Brochtrup
1+ // Copyright (C) 2009-2016 Christopher Brochtrup
22// Copyright (C) 2026 fkzys and contributors
33//
44// This file is part of subs2srs.
2323using System . Diagnostics ;
2424using System . IO ;
2525using System . Linq ;
26+ using System . Text ;
2627
2728namespace subs2srs
2829{
@@ -173,7 +174,7 @@ private static IEnumerable<string> getFFmpegPaths()
173174 /// <summary>
174175 /// Try to call an exe with provided arguments. Returns true on success.
175176 /// </summary>
176- private static bool callExe ( string exe , string args , bool useShellExecute , bool createNoWindow )
177+ private static string ? callExe ( string exe , string args , bool useShellExecute , bool createNoWindow )
177178 {
178179 try
179180 {
@@ -182,11 +183,15 @@ private static bool callExe(string exe, string args, bool useShellExecute, bool
182183 process . StartInfo . Arguments = args ;
183184 process . StartInfo . UseShellExecute = useShellExecute ;
184185 process . StartInfo . CreateNoWindow = createNoWindow ;
186+ var stderr = new StringBuilder ( ) ;
185187 if ( ! useShellExecute )
186188 {
187189 process . StartInfo . RedirectStandardError = true ;
188190 process . StartInfo . RedirectStandardOutput = true ;
189- process . ErrorDataReceived += ( s , e ) => { } ;
191+ process . ErrorDataReceived += ( s , e ) =>
192+ {
193+ if ( e . Data != null ) stderr . AppendLine ( e . Data ) ;
194+ } ;
190195 process . OutputDataReceived += ( s , e ) => { } ;
191196 }
192197 process . Start ( ) ;
@@ -196,14 +201,36 @@ private static bool callExe(string exe, string args, bool useShellExecute, bool
196201 process . BeginOutputReadLine ( ) ;
197202 }
198203 process . WaitForExit ( ) ;
199- return true ;
204+ if ( ! useShellExecute && process . ExitCode != 0 )
205+ {
206+ string full = stderr . ToString ( ) ;
207+ if ( full . Length > 0 )
208+ Console . Error . WriteLine ( $ "[ffmpeg stderr]\n { full } ") ;
209+ string lastLine = GetLastNonEmptyLine ( full ) ;
210+ return $ "ffmpeg exited with code { process . ExitCode } : { lastLine } ";
211+ }
212+ return null ;
200213 }
201- catch
214+ catch ( Exception ex )
202215 {
203- return false ;
216+ return ex . Message ;
204217 }
205218 }
206219
220+ private static string GetLastNonEmptyLine ( string text )
221+ {
222+ if ( string . IsNullOrWhiteSpace ( text ) )
223+ return "(no output)" ;
224+ var lines = text . Split ( '\n ' , StringSplitOptions . RemoveEmptyEntries ) ;
225+ for ( int i = lines . Length - 1 ; i >= 0 ; i -- )
226+ {
227+ string line = lines [ i ] . Trim ( ) ;
228+ if ( line . Length > 0 )
229+ return line ;
230+ }
231+ return "(no output)" ;
232+ }
233+
207234
208235 /// <summary>
209236 /// Try to call an exe and return stdout. Returns "Error." on failure.
@@ -296,24 +323,29 @@ private static bool runProcessWithProgress(string exe, string args, IProgressRep
296323
297324 /// <summary>
298325 /// Call an exe with the provided arguments, trying multiple paths.
326+ /// Returns null on success, error message on failure.
299327 /// </summary>
300- public static void startProcess ( string relExePath , string fullExePath , string args ,
328+ public static string ? startProcess ( string relExePath , string fullExePath , string args ,
301329 bool useShellExecute , bool createNoWindow )
302330 {
331+ string ? lastError = null ;
303332 foreach ( string exe in getExePaths ( relExePath , fullExePath ) )
304333 {
305- if ( callExe ( exe , args , useShellExecute , createNoWindow ) )
306- return ;
334+ lastError = callExe ( exe , args , useShellExecute , createNoWindow ) ;
335+ if ( lastError == null )
336+ return null ;
307337 }
338+ return lastError ;
308339 }
309340
310341
311342 /// <summary>
312343 /// Call an exe with the provided arguments. Don't open a window.
344+ /// Returns null on success, error message on failure.
313345 /// </summary>
314- public static void startProcess ( string relExePath , string fullExePath , string args )
346+ public static string ? startProcess ( string relExePath , string fullExePath , string args )
315347 {
316- startProcess ( relExePath , fullExePath , args , false , true ) ;
348+ return startProcess ( relExePath , fullExePath , args , false , true ) ;
317349 }
318350
319351
@@ -335,11 +367,14 @@ public static string startProcessAndGetStdout(string relExePath, string fullExeP
335367
336368 /// <summary>
337369 /// Call ffmpeg with provided arguments. Blocking.
370+ /// Throws Exception on ffmpeg failure.
338371 /// </summary>
339372 public static void startFFmpeg ( string ffmpegArgs , bool useShellExecute , bool createNoWindow )
340373 {
341- startProcess ( ConstantSettings . PathFFmpegExe , ConstantSettings . PathFFmpegFullExe ,
374+ string ? error = startProcess ( ConstantSettings . PathFFmpegExe , ConstantSettings . PathFFmpegFullExe ,
342375 ffmpegArgs , useShellExecute , createNoWindow ) ;
376+ if ( error != null )
377+ throw new Exception ( error ) ;
343378 }
344379
345380
0 commit comments