0

I have a C# application that displays videos using the Windows Media Player control (WMPLib) in Winforms.

I can display the videos correctly, but I have to manually insert the width and height of the parent control so the video doesn't look distorted. My use case has evolved to the point where I no longer know beforehand what the video dimensions are and as such I need to find a way to get the video's actual width and height.

I have been doing some digging about whether I can or cannot do this upon the video's loading to the playlist to be played and then pass those values to the Width and Height parameters of the parent control, but I have come up short...

Is this even possible? Or is it only possible to get that information when the videos are being played? where should I go from here?

Thanks!

pteixeira
  • 1,617
  • 3
  • 24
  • 40
  • 1
    Can you provide more information on what type of video files your application supports? That may determine the approach you need to take. – Rajaraam Murali Apr 28 '14 at 17:39
  • My application supports almost every type of video files. In this thread I only requested help for WMPLib which is what I use for .wmv files. the other file types are handled with vlclib – pteixeira Apr 29 '14 at 07:57

1 Answers1

0

You can use FFmpeg tool from within your C# application to obtain metadata information from a video file including the width and height information. Not knowing your application workflow, I cannot suggest when exactly you should read the metadata information. But one possible scenario is this.

  1. Users select a bunch of video files from disk to tell you application to load them in to a playlist for playback.
  2. While showing a loading animation, you run each video through the FFmpeg tool to get metadata information which you either store in memory or in a database along with the file name.
  3. When you have completed step 2, the user is able to see the videos in the playlist.
  4. When user selects a video to play, you load the corresponding width and height information and set the properties of the media player control in your application.
  5. When user moves to a different video you repeat step 4.

Now there are many C# libraries for FFmpeg. Some paid and some free. But I've been using some code that I obtained from a co-worker a while back. It does more than just get the metadata. It also performs conversion of the video to FLV format. I'm uploading that to github here. The actual method that extracts the metadata will look like this.

    public void GetVideoInfo(VideoFile input)
    {
        //set up the parameters for video info
        string Params = string.Format("-i {0}", input.Path);
        string output = RunProcess(Params);
        input.RawInfo = output;

        //get duration
        Regex re = new Regex("[D|d]uration:.((\\d|:|\\.)*)");
        Match m = re.Match(input.RawInfo);

        if (m.Success)
        {
            string duration = m.Groups[1].Value;
            string[] timepieces = duration.Split(new char[] { ':', '.' });
            if (timepieces.Length == 4)
            {
                input.Duration = new TimeSpan(0, Convert.ToInt16(timepieces[0]), Convert.ToInt16(timepieces[1]), Convert.ToInt16(timepieces[2]), Convert.ToInt16(timepieces[3]));
            }
        }

        //get audio bit rate
        re = new Regex("[B|b]itrate:.((\\d|:)*)");
        m = re.Match(input.RawInfo);
        double kb = 0.0;
        if (m.Success)
        {
            Double.TryParse(m.Groups[1].Value, out kb);
        }
        input.BitRate = kb;

        //get the audio format
        re = new Regex("[A|a]udio:.*");
        m = re.Match(input.RawInfo);
        if (m.Success)
        {
            input.AudioFormat = m.Value;
        }

        //get the video format
        re = new Regex("[V|v]ideo:.*");
        m = re.Match(input.RawInfo);
        if (m.Success)
        {
            input.VideoFormat = m.Value;
        }

        //get the video format
        re = new Regex("(\\d{2,3})x(\\d{2,3})");
        m = re.Match(input.RawInfo);
        if (m.Success)
        {
            int width = 0; int height = 0;
            int.TryParse(m.Groups[1].Value, out width);
            int.TryParse(m.Groups[2].Value, out height);
            input.Width = width;
            input.Height = height;
        }
        input.infoGathered = true;
    }

The code could probably use some optimization including the implementation of IDisposable and the dispose pattern. However it should be a good starting point for you. You also need to download FFmpeg executable from here and update your App.config file with the path to the FFmpeg executable.

  • thank you for the reply.. currently my application creates a bunch of controls that are attached to a panel, one of those controls being the wmpcontrol that reads the file from somewhere and displays it. once the controls are all created, they are "initialized/activated" and displayed. – pteixeira Apr 29 '14 at 09:01