2

Using MediaInfo DLL (64-bit), I am attempting to get the standard text output providing information about an mp4 file.

To wrap the dll, I have created a MediaInfo class, based on my (limited) understanding from the quickstart guide.

public class MediaInfo
{
    [DllImport("MediaInfo.dll")]
    private static extern IntPtr MediaInfo_New();

    [DllImport("MediaInfo.dll")]
    private static extern void MediaInfo_Open(string FileName);

    [DllImport("MediaInfo.dll")]
    private static extern IntPtr MediaInfo_Inform(IntPtr Handle);

    [DllImport("MediaInfo.DLL")]
    private static extern void MediaInfo_Close(IntPtr Handle);

    IntPtr Handle;

    public MediaInfo()
    {
        Handle = MediaInfo_New();
    }

    public void Open(string FileName)
    {
        MediaInfo_Open(FileName);
    }

    public string Inform()
    {   
        return Marshal.PtrToStringUni(MediaInfo_Inform(Handle));
    }

    public void Close()
    {
        MediaInfo_Close(Handle);
    }
}

And I am calling this class using the below console app:

static void Main(string[] args)
    {
        var objMediaInfo = new MediaInfo();
        objMediaInfo.Open("test.mp4");
        string result = objMediaInfo.Inform();
        objMediaInfo.Close();

        Console.WriteLine(result);
        Console.ReadKey();
    }

However, I am only getting a blank string in return. I have tried a few different media files.

I am aware there is already a fully developed wrapper for this, but I would like to keep this simple and lightweight.

Quantum_Kernel
  • 303
  • 1
  • 7
  • 19

2 Answers2

2

Try this might work for you:

Changes

[System.Runtime.InteropServices.DllImport("MediaInfo.DLL")]
private static extern UIntPtr MediaInfo_Open(IntPtr Handle, string FileName);

[System.Runtime.InteropServices.DllImport("MediaInfo.DLL")]
private static extern IntPtr MediaInfo_Inform(IntPtr Handle, UIntPtr Reserved);

public System.UIntPtr Open(string FileName)
{
    return MediaInfo_Open(Handle, FileName);
}

public string Inform()
{
    return Marshal.PtrToStringUni(MediaInfo_Inform(Handle, (UIntPtr)0));
}

Clean up

Don't forget to delete the pointer (Handle) that created by _MediaInfo_New_. You need to add:

[DllImport("MediaInfo.dll")]
private static extern void MediaInfo_Delete(IntPtr Handle);

Thus:

~MediaInfo() { if (Handle == (IntPtr)0) return; MediaInfo_Delete(Handle); }

Implement

Then in your implementation, you must pass the full path of the media file not just its name:

static void Main(string[] args)
{
    var objMediaInfo = new MediaInfo();
    objMediaInfo.Open(@"TheFullPathOf\test.mp4");
    string result = objMediaInfo.Inform();
    objMediaInfo.Close();

    Console.WriteLine(result);
    Console.ReadKey();
}

Good luck.

Edit

Sorry for the incomplete answer. I forgot to include in my last post that you also need to set the Inform option through the MediaInfo_Option API, this is important step to define the returned data:

[System.Runtime.InteropServices.DllImport("MediaInfo.DLL")]
private static extern IntPtr MediaInfo_Option(IntPtr Handle, string option, string Value);

Create function for that:

public string Option(string option, string Value = "")
{
    return Marshal.PtrToStringUni(MediaInfo_Option(Handle, option, Value));
}

Finally, modify your implementation:

static void Main(string[] args)
{
    var objMediaInfo = new MediaInfo();
    objMediaInfo.Open(@"TheFullPathOf\test.mp4");
    objMediaInfo.Option("Complete"); //or mi.Option("Complete", "1") or mi.Option("Info_Parameters") try them..
    string result = objMediaInfo.Inform();
    objMediaInfo.Close();
    Console.WriteLine(result);
    Console.ReadKey();
}

Hope it works this time.

enter image description here

  • Unfortunately, it still results in an empty string. – Quantum_Kernel Oct 23 '19 at 04:20
  • No problem. What about your project's setting? are targeting x64 machines or AnyCPU? How about trying the 32bit version just to see whether it works? How about trying older version like v18.05? Don;t give up, I feel its just a minor issue. Keep me in the loop if don't mind. Meanwhile I'll check my code again to see if I missed something again. –  Oct 23 '19 at 04:34
  • Tried 32-bit v19 dll with 'any cpu' and 'x86'. Tried 32-bit v18 dll with 'any cpu' and 'x86'. No errors for any combination, but still getting blank string. – Quantum_Kernel Oct 23 '19 at 04:47
  • I double checked my code, nothing not mentioned here. I uploaded a screenshot just to show you that everything is working. Sorry for not being helpful. Good luck, –  Oct 23 '19 at 05:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/201296/discussion-between-quantum-kernel-and-jqsoft). – Quantum_Kernel Oct 23 '19 at 05:21
  • Added `internal static extern IntPtr MediaInfo_Open(IntPtr Handle, [MarshalAs(UnmanagedType.LPWStr)] string FileName);` to your solution and it's now working. – Quantum_Kernel Oct 23 '19 at 05:37
1
namespace Test_MediaInfo{
  public partial class MainWindow : Window
  {

    public class MediaInfo
    {
      [DllImport("MediaInfo.dll")]
      private static extern IntPtr MediaInfo_New();

      [System.Runtime.InteropServices.DllImport("MediaInfo.DLL")]
      internal static extern IntPtr MediaInfo_Open(IntPtr Handle, [MarshalAs(UnmanagedType.LPWStr)] string FileName);

      [System.Runtime.InteropServices.DllImport("MediaInfo.DLL")]
      private static extern IntPtr MediaInfo_Option(IntPtr Handle, [MarshalAs(UnmanagedType.LPWStr)] string option, [MarshalAs(UnmanagedType.LPWStr)] string Value);

      [System.Runtime.InteropServices.DllImport("MediaInfo.DLL")]
      private static extern IntPtr MediaInfo_Inform(IntPtr Handle, UIntPtr Reserved);

      [System.Runtime.InteropServices.DllImport("MediaInfo.DLL")]
      private static extern void MediaInfo_Close(IntPtr Handle);

      [System.Runtime.InteropServices.DllImport("MediaInfo.dll")]
      private static extern void MediaInfo_Delete(IntPtr Handle);

      [DllImport("MediaInfo.dll")]
      private static extern IntPtr MediaInfoA_Option(IntPtr Handle, IntPtr Option, IntPtr Value);

      IntPtr Handle;
      public MediaInfo()
      {
        Handle = MediaInfo_New();
      }
      public System.IntPtr Open(string FileName)
      {
        return MediaInfo_Open(Handle, FileName);
      }
      public string Option(string option, string Value = "")
      {
        return Marshal.PtrToStringUni(MediaInfo_Option(Handle, option, Value));
      }
      public string Inform()
      {
        return Marshal.PtrToStringUni(MediaInfo_Inform(Handle, (UIntPtr)0));
      }
      public void Close()
      {
        MediaInfo_Close(Handle);
      }
      public void delete_pointeur()
      {
        MediaInfo_Delete(Handle);
      }

    }
    //---------------------------------------------------------------------------------
    public MainWindow()
      {
        InitializeComponent();
        btn_go_Click(null, null);
      }
    //---------------------------------------------------------------------------------
     private void btn_go_Click(object sender, RoutedEventArgs e)
    {
      string hhhh;
      string FileName = "";
    //  FileName = @"F:\mkv\American Nightmare 2 - Anarchy (2014).mkv";
      //   FileName = @"F:\mp4\Cinq cartes à abattre (1968).mp4";
      FileName = @"F:\avi\Danse avec les loups.avi";

      string[] msg = new string[15];

      var tmp = new MediaInfo();
      tmp.Open(FileName);
      tmp.Option("Inform", "General;%OverallBitRate/String%");    msg[0] = tmp.Inform();// 1 h 38 min
      tmp.Option("Inform", "General;%Format%");                   msg[1] = tmp.Inform();// MpEG-4
      tmp.Option("Inform", "General;%FileSize/String3%");         msg[2] = tmp.Inform();// 3.67 GiB
      tmp.Option("Inform", "General;%Duration/String2%");         msg[3] = tmp.Inform();// 1 h 38 min
      tmp.Option("Inform", "Video;%Width% x %Height%");           msg[4] = tmp.Inform();// 1920 x 1080    
      tmp.Option("Inform", "Video;%DisplayAspectRatio/String%");  msg[5] = tmp.Inform();// 16.9
      tmp.Option("Inform", "Video;%Format_Commercial%");          msg[6] = tmp.Inform();// AVC
      tmp.Option("Inform", "General;%FrameRate/String%");         msg[7] = tmp.Inform();// 60.000 FPS
      tmp.Option("Inform", "Video;%BitRate/String%");             msg[8] = tmp.Inform();// 5 165 kb/s
      tmp.Option("Inform", "Video;%CodecID/Hint%");               msg[9] = tmp.Inform();// DivX 3 low
      tmp.Option("Inform", "Audio;%SamplingRate/String%");        msg[10] = tmp.Inform();// 44.1 kHz
      tmp.Option("Inform", "Audio;%Language/String%, %Channel(s)% channels, %Codec/String%, %SamplingRate/String%, %BitRate/String%"); msg[11] = tmp.Inform(); // ,2 channels,, 44.1kHz, 160 kb/s
        tmp.Option("Inform", "Audio;%BitDepth/String%");          msg[12] = tmp.Inform();// 
      tmp.Option("Inform", "General;%Text_Language_List%");       msg[13] = tmp.Inform();// French / French / English
      tmp.Option("Inform", "Video;%CodecID%");                    msg[14] = tmp.Inform();// avc1
      hhhh = tmp.Option("Complete", "1");                         // end of session
      tmp.Close();
      tmp.delete_pointeur();

    }
    //---------------------------------------------------------------------------------
  }
}
FoxyError
  • 694
  • 1
  • 4
  • 19
steelwork
  • 11
  • 1
  • 1
    Welcome, try to explain the code you posted and leave out unnecessary pieces like comments etc. It might be easier to divide it in parts and explain it one by one. Don't hesitate to check the [Code of conduct](https://stackoverflow.com/conduct) – FoxyError Jun 22 '21 at 12:32