Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Golang FFmpeg wrapper for simple Video I/O and Webcam Streaming (github.com/alexeidt)
129 points by crypt0lution on April 16, 2022 | hide | past | favorite | 32 comments



You can instruct ffprobe to output the metadata in JSON (-print_format json), removing the need for manual parsing. Although you already utilize "-print_format compact" - was this a deliberate choice?

Also, you don't have to do manual stdout buffering. Have a look at ReadChapters function in here: https://github.com/MawKKe/audiobook-split-ffmpeg-go/blob/f95... (fyi it's my own repo)


I originally wanted to use json for parsing, however the unmarshalling would have required a large struct with fields for all the metadata ffprobe outputs. I thought that using "-print_format compact" resulted in a simpler parsing approach. Correct me if I'm wrong there, I'm still relatively new to Go.

Thanks for sharing the link to your project. I'll try to implement the stdout buffering with "bytes" rather than doing it manually.


You could do non-strict parsing and would be fine. You can also parse it directly into an untyped map.

https://golangbyexample.com/json-to-map-golang/


You don’t need fields for everything that’s printed, you only need to specify fields of interest, the rest are automatically discarded. You can also use alternative json parsers like fastjson that are more dynamic instead of upfront.


A couple years ago I tried making a GIF generator in Go and a decent FFMPEG wrapper is something the Golang community needs.


Did you look at joy4[0] (or now joy5[1])? These wrappers expose a lot of ffmpeg functionality in a Go idiomatic style. You could easily write a GIF generator using them.

[0]: https://github.com/nareix/joy4

[1]: https://github.com/nareix/joy5


No I didn't find it in my search for FFMPEG wrappers.


I’m not familiar with FFMPEG. How hard would it be to reproduce bits of it in Go natively? Why does everyone need to sub process out to this one library.


It packs an awful lot of assembly-optimized codecs and transformations into it.

It would be a huge undertaking to re-write it, let alone keep up with the pace of development.

An awful lot of the video processing on the internet makes it's way through ffmpeg in one way or another.


Yeah, it feels like something I don’t want to replicate all of (because I probably won’t need all of it), but it would also be nice to be able to use the bits I need from Go without depending on C. :/


Side note the image-rs crate in the Rust ecosystem has no external dependencies and can encode and decode animated gifs and a variety of other image formats, 100% rust https://github.com/image-rs/image. At my startup we use this in a lambda to process user-uploaded images, with great success.


The image-rs crate has some serious design flaws and it has put me off trying to do any image processing in Rust at all. It may support many formats, but the basic image type is complete garbage. It’s conceptually a 2D array of some specific pixel type—which means that any pixel value must carry with it colorspace information. I can’t honestly recommend it to anyone.

The issues I’m talking about are acknowledged as design flaws / mistakes if you start browsing the GitHub issues.


Sounds like typical Rust... They're well-meaning people in general, but they usually lack domain knowledge in the particular field they're trying to reinvent in Rust, so the end result often looks like a square-shaped wheel.


In our case this hasn't caused any issues for us, and it has worked great as a general purpose converter


Glad it worked out for you—it seemed like the features are there for basic image conversion, but try to do something a little more sophisticated and you run into some severe design limits. Here is the kind of underlying problem I’m talking about:

https://github.com/image-rs/image/issues/1523


Why would you do something more sophisticated though, versus just using your own pixel data structures and the converting if/when you want to load/save. This is supposed to be a stand-in for image magic, not a panacea for doing image processing in Rust. Maybe start an image-processing crate if that is your interest?


Nice! Looks like a good start. As some have noted in this thread there are some issues but nothing you can't fix.

I'd recommend running `go vet -a` and `golangci-lint` on it to see some of the current issues:

  $ go vet -a

  $ docker run --rm "--volume=$(pwd):/app" --workdir=/app golangci/golangci-lint:latest golangci-lint run


Done, thanks!


Awesome work! Projects like this are the gems that keep me excited about hobby software


Thanks!


README shows various structs with zero exported fields, and example code working with those unexported fields which don't make sense and won't work unless directly placed in this package. There are other problems like non-idiomatic snake_case naming. I guess this is OP's golang learning project? (To be clear, making mistakes in the beginning is completely fine.)


That's correct. I like to use go for image processing and wanted to apply some of the algorithms I made to video but did not find a simple way to do so. I set out to make a video I/O module.

I'm currently fixing all the non-idiomatic problems as well as adding some getters for each struct. Thanks for the feedback!


Yeah, you wouldn't be able to import this into a separate module and use it.


There's quite a bit of overhead in execing and piping data from ffmpeg. If performance is a concern, then using the C ffmpeg API is a better bet(see pyav for a good example of this) . Cool project though!


I also wrote a similar thing years ago...

https://github.com/unixpickle/ffmpego


This module isn't actually usable, because every error produces a panic.

If a function or method is fallible, it should return `(..., error)`, not panic.


I'll fix that up when I have some time. Thanks for pointing it out. Most panics come from when something went wrong with the ffmpeg subprocess. I didn't know that there is a way for the user to handle errors coming from this subprocess.


Even if an error is unrecoverable by the caller, that doesn't mean it should be a `panic`. If a server is running your code in a request handler, a `panic` would normally terminate the entire process. That's never what anyone wants.


correct me if im wrong but lowercase struct fields do not get exported right ?


Made a push adding getters for relevant fields and making field names uppercase in the Options struct. Don't know how long it takes for pkg.dev to update, but the issue should be resolved now.


Yeah. A good place to see just the exported API (and its documentation) is https://pkg.go.dev/github.com/AlexEidt/Vidio.





Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: