3
votes

I have an coldfusion application. I am converting recorded video from mobile through ffmpeg and coldfusion. Here is the ffmpeg command which i am running.

ffmpegPath -i "inputfile" -vcodec libx264 -acodec aac "OutputFile"

Output file type is mp4. I want to convert my all videos to mp4 with h.264 and ACC sound. So that it will work on all platforms.

I am getting the following error:

java.io.IOException: ffmpeg returned non-zero exit status. Check stdout.

Here is the CF code that i am running.

<cfset resultLog        = "path\to\directory\testOuput_result.log">
<cfset errorLog         = "path\to\directory\testOuput_error.log">
<cfset results  = structNew()> 
        <cfscript>
            try {  
                runtime = createObject("java", "java.lang.Runtime").getRuntime();
                command = 'ffmpegPath -i "inputfile" -vcodec libx264 -acodec aac "OutputFile"';
                process = runtime.exec(#command#);
                results.errorLogSuccess = processStream(process.getErrorStream(), errorLog);  
                results.resultLogSuccess = processStream(process.getInputStream(), resultLog);  
                results.exitCode = process.waitFor();  
            }  
            catch(exception e) {  
                results.status = e;      
            }  
        </cfscript>
<cffunction name="processStream" access="public" output="false" returntype="boolean" hint="Returns true if stream was successfully processed">  
    <cfargument name="in" type="any" required="true" hint="java.io.InputStream object">  
    <cfargument name="logPath" type="string" required="false" default="" hint="Full path to LogFile">  
    <cfset var out = "">  
    <cfset var writer = "">  
    <cfset var reader = "">  
    <cfset var buffered = "">  
    <cfset var line = "">  
    <cfset var sendToFile = false>  
    <cfset var errorFound = false>  

    <cfscript>  
        if ( len(trim(arguments.logPath)) ) {  
            out = createObject("java", "java.io.FileOutputStream").init(arguments.logPath);  
            writer = createObject("java", "java.io.PrintWriter").init(out);  
            sendToFile = true;  
        }  

        reader = createObject("java", "java.io.InputStreamReader").init(arguments.in);  
        buffered = createObject("java", "java.io.BufferedReader").init(reader);  
        line = buffered.readLine();  
        while ( IsDefined("line") ) {  
            if (sendToFile) {  
                writer.println(line);  
            }  
            line = buffered.readLine();  
        }      
           if (sendToFile) {  
           errorFound = writer.checkError();  
           writer.flush();  
           writer.close();  
        }  
    </cfscript>  
    <!--- return true if no errors found. --->  
    <cfreturn (NOT errorFound)>  
</cffunction> 

I have also used different ffmpeg.exe but got same error. I have also used ffmpeg-cli-wrapper java wrapper in coldfusion. Still i got the same error. Can any one help me to sort out this issue.

2
Check stdout - so what does the stdout say? Did you see these similar questions? reference 1 - reference 2 - reference 3Miguel-F
@Miguel-F. Thanks for your response. Yes i see them. I am able to resolve it. I was not passing absolute path of input file to ffmpeg that was causing the issue.Abdul Rauf
Ok great. Glad you resolved it. Please add an answer to this question with the details so that others will see what the solution was.Miguel-F
@Miguel-F. ok. thanksAbdul Rauf

2 Answers

2
votes

I am able to resolve this issue. The problem is in inputfile path. I have fixed this by passing absolute path of inputfile to ffmpeg

2
votes

Nothing to do with the error, but are you sure you really need Runtime.exec()? It is usually overkill. Most applications can be invoked with <cfexecute>, which is basically a wrapper of Runtime.exec(), which does the same thing, only with less code.

There was an issue with cfexecute and ffmpeg.exe way back in CF8, caused by the fact that early versions of cfexecute did not capture StdErr. However, that was resolved in one of the CF8 updates. Assuming you are using a recent version of CF, it should work right out of the box. Not tested, but something along these lines:

NB: Note the use of absolute paths for all files

<!--- change to the appropriate timeout --->
<cfexecute name="c:\path\to\ffmpeg.exe" 
    arguments=' -i "c:\path\to\in.file" -vcodec libx264 -acodec aac "c:\path\to\out.file"'
    timeout="120" 
    variable="result"
    errorVariable="errorMessage"
    /> 

<!--- Display results --->
<cfoutput>
   result = #result#
   errorVariable = #errorVariable #
</cfoutput>

See the cfexecute documentation for more details on arguments and syntax.