002

Foreign Function Interface & MediaInfo

For my renaming utility, I wanted to the user to be able to use information beyond what the file system offered. The ability to add metadata about the filetype itself is a powerful feature that increases the usefulness of the application by a lot.

The best tool for accomplishing this with audio and video files is MediaInfo. It does an incredible job at extracting information about a media file without having to read all of it. Fortunately, they provide a C/C++ library for external applications, but unfortunately the crates available already do not seem to be actively maintained.

Since my use cases do not require the entirety of the library, I thought it would be better to write a small one that only provides what functions my application needs. This way I do not have to spend a lot of time writing a complete library and the maintanence of this in relation to the rest of the app should be minimal. If any new requirements arise, then they can be added with later work.

I’ve also never written one of these before and it’s a good starting point.

The first thing I did was go through the Foreign Function Interface documentation within the Rustonomicon. It gives a good overview of how the pieces fit together. I used the MediaInfo SDK documentation to get an understanding of how the libary works. Overall the process was as described in the Rustonomicon.

The primary pain points were:

  • The MediaInfo library offers interfaces for C and C++ and you need to make sure you use the C versions of the instructions to make it work.
    • This required the use of the MediaInfo_XXXX style of methods mentioned in the MediaInfo docs.
    • Using the C interface also requires you to manually free the object using MediaInfo_Delete.
  • The C interface uses Unicode strings, which are 2 or 4 bytes per character vs. 1 byte in ASCII.
    • This requires use of the wchar_t type in C, which libc gives a type for, but it does not support converting the wider 2 or 4 byte Unicode strings, only 1 byte ASCII chars.
    • The widestring crate offers a solution for this exact scenario. It functions very similar to the CStrings type in libc.

© 2023 David Benjamin