How to get started with Rust and ffmpeg

I'm completely new to Rust. I would like to use ffmpeg (libavformat) to receive an RTSP stream and, on a certain condition, write it to a file.

I have downloaded rustup-init.exe, it told me to also download the MS Visual C++ Build Tools, which I did and then it installed rust. Then I ran cargo new --bin ffmpegtest, which compiles and runs fine.

Now I'm trying to add ffmpeg to the mix, but so far with little success. I looked on crates dot io and found both ffmpeg (crates dot io -> crates/ffmpeg) and ffmpeg-sys (crates dot io -> crates/ffmpeg-sys), the latter having the former as a dependency.

So I tried adding ffmpeg-sys = "3.4.0" to my Cargo.toml file and on cargo build I got:

thread 'main' panicked at 'called Result::unwrap() on an Err value: MSVC', src\libcore\result.rs:906:4
stacktrace: github dot com -> meh/rust-ffmpeg-sys/issues/60

I also tried adding ffmpeg = "0.1.1" and got:

thread 'main' panicked at 'Command failed: Error { repr: Os { code: 2, message: "The system cannot find the file specified." } }', src\libcore\result.rs:906:4
stacktrace: github dot com -> meh/rust-ffmpeg/issues/105

Can you nudge me in the right direction?

Hi. Welcome to Rust. We are incredibly lucky to have verbose error messages. Looking at both the error messages I feel that you are trying to access a file that doesn't exist. Have you tried giving a different file as input?

Different from what? What "input"? I just added the one line to the Cargo.toml that was created by cargo new and ran cargo build, nothing else. If you're on Windows, just try it out, I would assume you would get the same result.

I'm not sure but the first error seems to indicate MSVC Maybe it tries to compile a bunch of C code but can't find the compiler? Can you try to do cl /? from your command line and see if it's there? Otherwise you may need to add it to the path. I'm not sure how the detection of the path to the compiler works.

For MSVC there is usually a vcvars*.bat file included that one can use to set up the environment.

That doesn't seem to be the problem. I think that because:

  • it successfully compiles a bunch of other packages
  • adding cl to the PATH makes no difference
  • running cargo build in the "Visual C++ 2015 x64 Native Build Tools Command Prompt", where cl can be found, makes no difference

I took a look at the build.rs file for the ffmpeg-sys crate and it seems to use configure so I would guess this doesn't actually work to compile on Windows unless you use msys or something similar.

1 Like

I've found ffmpeg crate is very difficult to compile and works only if you have very specific version of ffmpeg installed.

Try gstreamer-rs instead. It's better maintained and easier to set up.

Ok, will do. One question about that: After I have downloaded GStreamer with MSYS2's pacman as described here, how do I tell the Rust toolchain/GStreamer crate where it is?

Yeah, this is what I expected:

error: linking with `gcc` failed: exit code: 1

  = note: ld: cannot find -lgstreamer-1.0
          ld: cannot find -lgobject-2.0
          ld: cannot find -lglib-2.0
          ld: cannot find -lgobject-2.0```

I guess this is because the toolchain, which seems to live in %RUSTUP_HOME%\toolchains\stable-x86_64-pc-windows-gnu\lib\rustlib\x86_64-pc-windows-gnu, of course does not know about the library, which in my case lives in C:\dev\msys64\mingw64.

See installation docs:

https://github.com/sdroege/gstreamer-rs#installation-windows

You probably need to export PKG_CONFIG_PATH to help gstreamer crate find the libraries.

I thought that belonged to the section about using binaries. Anyway, I ran:

set PKG_CONFIG_PATH=C:\dev\msys64\mingw64\lib\pkgconfig

That is the path to a directory called pkgconfig containing a bunch of .pc files, including for example gstreamer-1.0.pc.

But it makes no difference, I still get ld: cannot find -lgstreamer-1.0, etc.

Ok, I got something new.

I set the environment variable LIBRARY_PATH to C:\dev\msys64\mingw64\lib and now I get:

= note: C:\dev-projects\rust-test\ffmpegtest\target\debug\deps\libgstreamer-70220f7014e9955f.rlib(gstreamer-70220f7014e9955f.gstreamer8.rust-cgu.o): In function gstreamer::auto::flags::{{impl}}::static_type': c:\dev\rust\cargo\registry\src\github.com-1ecc6299db9ec823\gstreamer-0.10.0\src\auto/flags.rs:807: undefined reference to gst_stream_type_get_type'

I don't know if that's a step forward or back. :slight_smile: