Hello, I'm trying to run this command in godot 4:
ffmpeg -v error -i "/home/komi/Videos/meteor-fall.mp4" -map 0:1 -f null - 2> /tmp/result.log
This command worked if I ran them from terminal.

I tried this:

func _ready():
    #ffmpeg -v error -i "/home/komi/Videos/meteor-fall.mp4" -map 0:1 -f null - 2> /tmp/result.log
    var output = []
    var arguments = ["-v","error","-i","/home/komi/Videos/meteor-fall.mp4","-map","0:1","-f","null","-","2>","/tmp/result.log"]
    var err = OS.execute("ffmpeg",arguments,output)
    printt(err,output)

But this doesn't work,
it prints 234 [""], and the file that is supposed to be in /tmp/result.log is not there. Unlike when calling it from terminal.

How would I ran command I mentioned above using OS.execute?


note, using arguments = ["-version"] gives correct output.
using var arguments = ["-v error -i '/home/komi/Videos/meteor-fall.mp4' -map 0:1 -f null - 2> /tmp/result.log"] also didn't work.
using /usr/bin/ffmpeg as path doesn't work either.

  • Haystack replied to this.
  • pegasusearl The 'arguments' list is the set of arguments that get passed to whatever executable you request. In this case, ffmpeg. But "2>" isn't a ffmpeg argument, it's a command-shell argument.

    If you want to use the redirection symbol, you need to invoke the cmd-shell itself, not ffmpeg. (You can then pass the ffmpeg cmd-line to the cmd shell).

    Try the following:

    
    var my_cmd = "ffmpeg -v error -i \"/home/komi/Videos/meteor-fall.mp4\" -map 0:1 -f null -" # command you want to run
    var path = "CMD.exe" 
    var args = ["/C", my_cmd, "2> /tmp results.log"] # args to cmd.exe
    var output = []
    var errcode = OS.execute( path, args, output )
    
    # this will return the output of the command as a single line.  :-(
    var alloneline = output[0]
    var cmd_output : Array = alloneline.split("\n")
    # Remove trailing newline
    var numlines = cmd_output.size()
    if numlines > 0:
    	if cmd_output[ numlines-1 ] == "":
    		cmd_output.remove_at( numlines-1 )

    if you launch godot via terminal and try this again, any sort of error or feedback to go off of?

      Megalomaniak

      No it's exactly the same as the output inside the game engine.

      But someone on discord suggested me to remove 2> and the things after that var arguments = ["-v","error","-i","/home/komi/Videos/broken_video.mkv","-map","0:1","-f","null","-"] and then uses the output with stderr enabled. That is what I wanted to do originally, but I'm not familiar with these kind of linux command. The 2> and stuffs.

      Even though I still don't know why the first command and argument worked in terminal but not in Godot, I now have the behavior I wanted, so I guess it's kinda solved.

      (I can't rename the title!!)

        pegasusearl (I can't rename the title!!)

        When you're the creator of a discussion, the Reply drop-down on the right has a Rename option for changing the title.

        pegasusearl changed the title to [solved??] Help me use OS.execute(), I don't understand. .

        kuligs2 that was my initial question too, but thinking about it that shouldn't be an issue here since the path in this case gets piped to ffmpeg rather than used by godot itself.

          Megalomaniak interesting, can confirm that on binbows, its the same

          with argument -v it dont work -> []
          and with argument -version it works.

          but from terminal -v works.. maybe OS does some parsing?

          the ffmpeg is on some random drive, so the path is not the problem.

          xyz Where did you get that command line from?

          From here, but there are many places that mention this commands.

          I was looking for a way to detect video for corruption, some of the videos on my HDD probably rot. How spooky, data can rot?! I should have put them in the freezer!!

          Out of all the commands that people suggest, this is the one that can actually tell if a video is corrupted or not, while still be fast enough.

          pegasusearl The 'arguments' list is the set of arguments that get passed to whatever executable you request. In this case, ffmpeg. But "2>" isn't a ffmpeg argument, it's a command-shell argument.

          If you want to use the redirection symbol, you need to invoke the cmd-shell itself, not ffmpeg. (You can then pass the ffmpeg cmd-line to the cmd shell).

          Try the following:

          
          var my_cmd = "ffmpeg -v error -i \"/home/komi/Videos/meteor-fall.mp4\" -map 0:1 -f null -" # command you want to run
          var path = "CMD.exe" 
          var args = ["/C", my_cmd, "2> /tmp results.log"] # args to cmd.exe
          var output = []
          var errcode = OS.execute( path, args, output )
          
          # this will return the output of the command as a single line.  :-(
          var alloneline = output[0]
          var cmd_output : Array = alloneline.split("\n")
          # Remove trailing newline
          var numlines = cmd_output.size()
          if numlines > 0:
          	if cmd_output[ numlines-1 ] == "":
          		cmd_output.remove_at( numlines-1 )

            Haystack isnt cmd.exe a windows thing and then you mix unix path in?
            https://docs.godotengine.org/en/stable/classes/class_os.html#class-os-method-execute

            Note: This method is implemented on Android, iOS, Linux, macOS and Windows.

            Note: To execute a Windows command interpreter built-in command, specify cmd.exe in path, /c as the first argument, and the desired command as the second argument.

            Note: To execute a PowerShell built-in command, specify powershell.exe in path, -Command as the first argument, and the desired command as the second argument.

            Note: To execute a Unix shell built-in command, specify shell executable name in path, -c as the first argument, and the desired command as the second argument.

            Note: On macOS, sandboxed applications are limited to run only embedded helper executables, specified during export.

            Note: On Android, system commands such as dumpsys can only be run on a rooted device.

            But also this does not explain why ffmpeg returns "something" in standard terminal with -v argument while in godot using execute() it returns only when using -version argument

            pegasusearl changed the title to Help me understand OS.execute() .