Introduction
When it comes to get maximum details about multimedia files, you may use the well known MediaInfo open source software, as it will go deeply in the contained streams, and report all relevant details.
But if you like to build your own application to manage your multimedia files, and want to get all these details, you won't re-invent the wheel, but get the MediaInfo DLL library. It ships with a lot of code samples in several languages to help you get started, but it consists on calls to a "Get" method, giving the property name as a string parameter, not always so easy to remember and so use.
Some people already tryed to build some wrappers over this, but heavily suffers on compatibility breaks when something changes in the original library, leaving folks alone and waiting until the author finds time to fix the wrapper.
Here you will find a new type of wrapper, based on reflexion, allowing end users to easily add new properties with only a single line of code.
The library is published on GitHub to allow further contributors or just to fork it to your own use : https://github.com/sierramike/ZM.Media.Info
Using the code
Usage of the wrapper only takes 2 lines of code (and a third line or more to use the result):
var MI = new ZM.Media.Info.MediaInfoWrapper();
var mfi = MI.Read("MyFile.mkv");
string allDetails = mfi.Display();
The Read()
method called on the wrapper will return an object of type "MediaFileInfo".
The Display()
method called on the MediaFileInfo object will return a string listing all read properties except blank properties. Call Display(true)
to list all properties, including blank ones. The returned string uses newline character as a line separator, therefore you can call .Replace("\n", "\r\n")
on the result to have the text display properly in regular windows textbox.
MediaFileInfo
object contains the following properties:
GeneralInfo
: contains general details on the file VideoStreams
: contains a list of VideoStream
objects, each for a video stream found in the file. AudioStreams
: contains a list of AudioStream
objects, each for an audio stream found in the file. TextStreams
: contains a list of TextStream
objects, each for a text stream found in the file. MenuStreams
: contains a list of MenuStream
objects, each for a menu stream found in the file.
Simply check all these objects properties to get the data from the file.
The stream types objects are built over inheritance following this diagram:
Not all available properties have been implemented yet, but only a most current set that were needed by the author. You can Fork this project to add more properties to be retrieved from the MediaInfo library and even send back your additions so they can be added to this project.
To simplify properties additions, the wrapping has been implemented using reflexion. That means, just add a property to an object and the wrapper will map it to the MediaInfo library's corresponding property that has the same name. When the MediaInfo property name is incompatible with .NET property naming, you can decorate the property using the "MediaInfoFieldName" attribute, like the following code sample:
[MediaInfoFieldName("Channel(s)")]
public string Channels { get; set; }
This will wrap the "Channel(s)" property of the MediaInfo library to the Channels POCO class property.
You can even add your own calculated (or not) properties and avoid them for being mapped, using the "Ignore" attribure, like in the following code sample:
[IgnoreProperty]
public TimeSpan DurationSpan
{
get { return new TimeSpan(TimeSpan.TicksPerMillisecond * (long)Duration); }
}
Some properties may report more than one value (e.g. on DTS Master Audio streams, BitRate
property may report 2 or 3 values for Core, MA, ES streams etc.), therefore you can declare a propery as an array, and use the MediaInfoFieldName
attribute to link it to the right property. The wrapper will automatically detect the array property and split the MediaInfo result on the slash '/' character to build the array. The following code sample shows how you can have the raw BitRate
property and another property declared as an array of int:
public string BitRate { get; set; }
[MediaInfoFieldName("BitRate")]
public long[] BitRateArr { get; set; }
As a naming convention, it has been decided that array properties are named according to the original property with the "Arr" suffix, like in the last code sample.
The MediaInfo library returns all properties as strings. If you declare a property as an int, long or double, the wrapper will automatically convert the resulting value in the type you chose. Be carefull as some properties may not always return a single number, as in the BitRate sample, where you can find several values separated by a slash.
Points of Interest
This small wrapper is also a good sample of using reflexion on properties to automatically map them at run time, and also provides a good sample of attributes usage to decorate properties and customize the wrapper behaviour.
History
August 18, 2017 : First release