How to use FFMpeg's FFProbe without resorting to shell/string calls?

I have an ffprobe line of code. I could just work the strings and do a command-line ssh to pull it off, but… strings, reusability, extensibility, maintainability, brittleness…

I am new to ffprobe (and ffmpeg in general), but the working commandline solution is this:

ffprobe -v error -select_streams v:0 -show_entries stream=width,height,display_aspect_ratio -of json=c=1 ./small_test_video.mp4

with results like this:

{
    "programs": [

    ],
    "streams": [
	{ "width": 1280, "height": 720, "display_aspect_ratio": "16:9" }
    ]
}

Here is my current attempt in Kawa. Please pardon all the #_ comments; I am trying to figure this out.

(let [file-path (-> env :FILES :media-url (str "small_test_video.mp4"))
	  test-name :ffprobe
	  #_#_ mp4 (ffmanager/register :mp4 (ffm/ffmpeg! :format "lavfi" :input-url "testsrc" :duration 10
						    :pixel-format "yuv420p" "testsrc.mp4"))
	  ffp (ffmanager/register test-name
				  (ffm/ffprobe! :input-url file-path :output-format "json"))]
      #_(shell/sh "ffprobe" "-v" "error" "-select_streams" "v:0" "-show_entries" "stream=width,height,display_aspect_ratio" "-of" "json=c=1" (-> (:tempfile file) .getAbsolutePath))      
      (-> (ffmanager/ls) test-name :process #_:out #_#_:err slurp)
      ;(is false)
      )

And then the goal is to reason over that return value to make a decision based on the aspect ratio.

I have tried using the Clojure Kawa library, but can’t figure out how to get it to output the data I want. Is system sh munging and then conversion from JSON really the best I can do?

strings, reusability, extensibility, maintainability, brittleness…

Not sure what those words are supposed to mean. They only have meanings in a particular context. If “launch ffprobe and get its output” is the only context, then there’s absolutely nothing wrong with using shell/sh with strings. I myself would definitely go that route, this is not a worthy bike shed.

3 Likes

Sorry; they were rhetorical. I maintain enough code, and have worked with enough maintenance, that string munging is up there with magic numbers for stuff that hurts code quality and will come back to bite you with obscure errors at the worst times. But if scripting-style is the best way to go, that is what I have to work with.

I’m hoping someone more familiar with FFMpeg will come and explain just what that shell command is doing, and understand what needs to happen for something more re-usable and extensible to achieve the same results (and eventually more).

got it, using GitHub - luissantos/ffclj: Clojure ffmpeg wrapper instead

If you’re looking for something more like a library and less like a command-line wrapper, the clj-media project has also has a probe function. It’s built on top of ffmpeg, but it uses the API bindings.

1 Like

Ah, that’s the sort of recommendation I was looking for! Thank you!

1 Like

oops. I spoke to soon. I have not been able to get clj-media to work because, down the dependency line, it’s not enough just to have ffprobe; you need more stuff (Clang’s libxb so that it can expose the C APIs with JNI… TMI, I know. Just sharing some of the pain.)

Yes, sometimes just using the command-line options via a shell subprocess is the most straightforward solution.