54

I'm using ffmpeg to get info about a video file and I don't want to save the info into a file. ffmpeg is returning all the video info, but it's returning as an error because I'm not specifying an output file. The command I'm using is:

 ffmpeg -i C:\Test\3FA8D0E6-BD61-D160-98BB41304D63FAE3.mp4

The error I get is "At least one output file must be specified"

I'm calling this in ColdFusion using <cfexecute>, and the output is being stored in a local variable, which is why I don't want to specify a file... I just don't need to store this in a file.

If it makes any difference, I'm running this on Windows.

David Moles
  • 39,436
  • 24
  • 121
  • 210
Redtopia
  • 4,036
  • 6
  • 43
  • 65
  • well, does it really output anything? If not, give it an output param maybe that's all it needs to pass their call validation. – Henry Jul 09 '12 at 17:54
  • If ffmpeg requires it, then you have to live with it I guess. I'd create a temporary file name in CF, pass it to ffmpeg, read it, then delete it. – Raymond Camden Jul 09 '12 at 17:59
  • Can you show your ColdFusion code? Or at least the relevant part of it? – Tim Cunningham Jul 09 '12 at 18:02
  • I did a search on ffmpeg stdout, and found results. You want to use that. Here is one example: http://superuser.com/questions/322216/how-can-i-pipe-output-of-ffmpeg-to-ffplay – Raymond Camden Jul 09 '12 at 18:04
  • 1
    Using ffmpeg without specifying an output file caused to put the output into the "errorVariable" param instead of the "variable" param. I tried specifying "info.txt" as an output file, but ffmpeg didn't like that either. I could have parsed the errorVariable output, but I found that ffprobe works WAY BETTER because I can get the output as JSON and use DeserializeJSON () to parse it into a native CF structure. (See my answer below). Thanks everyone! – Redtopia Jul 09 '12 at 18:34

4 Answers4

93

It's giving an error because FFmpeg requires that an output file be specified. Using it just to get information about a file isn't its intended use.

Option 1: Ignore the error. FFmpeg prints the file information first, so you can simply get the information you need and ignore the error.

Option 2: Use ffprobe instead. FFprobe is another tool usually packaged with FFmpeg that's designed for getting information about media files. It can even output the information in a variety of easily parsed formats so you don't have to mess around parsing FFmpeg's output.

blahdiblah
  • 30,909
  • 18
  • 92
  • 149
  • 2
    Using ffprobe is the way to go. I'm outputting the results as JSON and then deserializing them into a native coldfusion struct. Pretty slick. – Redtopia Jul 09 '12 at 18:23
  • Yeah, ffprobe is not widely known enough for how useful it is. – blahdiblah Jul 09 '12 at 18:26
  • 1
    Maybe the error message in ffmpeg could be changed to suggest this. – Some Guy on the Internet Jul 21 '12 at 19:06
  • 9
    This is how you use ffProbe : `ffprobe -v quiet -print_format json -show_format -show_streams -print_format json "C:\Files\somefile.asf"` or to get XML : `ffprobe -v quiet -print_format json -show_format -show_streams -print_format xml "C:\Files\somefile.asf"`. THis will help people get started because the docs seem messy... – user2173353 Mar 10 '16 at 10:42
6

I ended up using ffprobe instead. Here's my ColdFusion test code... keep in mind that this could be written better. At this point, I'm only interested in width/height/duration.

<cfset fsVideoFile = "C:\videos\test.mp4">
<cfset width = 270>
<cfset height = 480>
<cfset duration = 0>

<cfexecute
   name="ffmpeg\bin\ffprobe.exe"
   arguments="#fsVideoFile# -v quiet -print_format json -show_format -show_streams"
   timeout="60"
   variable="jsonInfo"
   errorVariable="errorOut" />

<cfif IsJSON (jsonInfo)>
   <cfset videoInfo = DeserializeJSON (jsonInfo)>
   <cfdump var="#videoInfo#">
   <cfset duration = videoInfo.format.duration>
   <cfloop array="#videoInfo.streams#" index="stream">
      <cfif stream.codec_type EQ "video">
         <cfset width = stream.width>
         <cfset height = stream.height>
         <cfbreak />
      </cfif>
   </cfloop>
</cfif>
Redtopia
  • 4,036
  • 6
  • 43
  • 65
4

Very late, but hopefully it can help someone if he doesn't want to use ffprobe (see @blahdiblah answer).

You can use Null with ffmpeg as stated in the documentation:

ffmpeg -i C:\Test\3FA8D0E6-BD61-D160-98BB41304D63FAE3.mp4 -f null -
O.Badr
  • 2,045
  • 2
  • 20
  • 27
  • 1
    This can take a long time because it will initiate decoding of the whole file. No practical advantage compared to just `ffmpeg -i input.mp4`. – llogan Sep 19 '20 at 22:06
  • @llogan Exit code of `ffmpeg -i input.mp4` command won't be `0`, and in case you need to just get media info in a clean way (using `ffmpeg`), like sometimes in a **Shell/Batch** script – O.Badr Sep 20 '20 at 16:37
2

It is possible to do it with ffmpeg and if you don't want to save the info into a file you just could send it to /dev/null in *nix systems.

ffmpeg -i file.mp4 -hide_banner -f null /dev/null
alemol
  • 6,344
  • 1
  • 18
  • 27