Click here to Skip to main content
15,881,757 members
Articles / Programming Languages / Visual Basic

Video Wall with MCIPlayerControl

Rate me:
Please Sign up or sign in to vote.
4.94/5 (9 votes)
5 Oct 2016CPOL6 min read 31.6K   3.6K   26   3
Using a simple custom made video player control to display a video wall

Image 1

Introduction

Video walls are everywhere. They add colors to city life. In this article, we would be creating a video wall using our custom made video player control.

Background

This article is based on ideas from my earlier article Fun with Video. In that article, we explore how to make use of mciSendString API to play video files. Here we encapsulate all main functionalities of video display and playing into a simple Window Form control. With the video functionalities encapsulated, we do not have to worry about the intricacies of the mcisSendString command and just concentrate on making use of the control to create something fun and useful.

I have included some animated gif and mp4 files in the downland zip. To be able to playback these files, you may need to get the codec from http://www.windows7codecs.com/

Beside the obvious use of video wall for advertisement, we can also use it for

  • forensic video analysis
  • motion study

Video analysis of a train accident

Image 2

A dog in high speed motion

Image 3

Using the code

Our MCIPlayerControl exposes the following properties

C#
public bool ShowControls
public string Mediafilename
public string Caption
public int Alias
VB.NET
Public Property ShowControls() As Boolean
Public Property Mediafilename() As String
Public Property Caption() As String
Public Property [Alias]() As Integer

 

The following methods are for loading and closing of the media files

C#
public bool LoadMediaFile()
public bool LoadMediaFile(string filename, int alias,bool resize)
public void CloseMediaFile()
VB.NET
Public Function LoadMediaFile() As Boolean
Public Function LoadMediaFile(filename As String, alias__1 As Integer, resize As Boolean) As Boolean
Public Sub CloseMediaFile() 

These methods control video play and audio

C#
public void Pause_Play()
public void PlayLoop()
public void ToggleAudio()
public void SeekPlayPosition(int pos)
VB.NET
Public Sub Pause_Play()
Public Sub PlayLoop()
Public Sub ToggleAudio()
Public Sub SeekPlayPosition(pos As Integer)  

To make use of the MCIPlayerControl, you can either drag it into the form at design time or call its default constructor

MCIControl.MCIPlayerControl()

The code below shows how we make use of an array of controls to display a video wall.

C#
if (listBox1.SelectedIndex < 0) return;
this.WindowState = FormWindowState.Maximized;
this.FormBorderStyle = FormBorderStyle.None;
panel1 = new Panel();
this.Controls.Add(panel1);

this.panel1.Location = new Point(0, 0);
Rectangle rect=ScreenCapture.GetClientRect(this.Handle);
this.panel1.Size = new Size(rect.Width, rect.Height);
this.panel1.Visible=true;
this.panel1.BringToFront();
//mciPlayerControl1.CloseMediaFile();
buttonClose1_Click(null, null);
mciPlayerControl2.CloseMediaFile();

int s_width = panel1.Width / 3;
int s_height = panel1.Height / 3;
MCIControl.MCIPlayerControl testmc = new MCIControl.MCIPlayerControl();
panel1.Controls.Add(testmc);
testmc.Location = new Point(0, 0);
testmc.Size = new Size(s_width, s_height);
testmc.ShowControls = false;
testmc.Visible = true;
testmc.Alias = 0;
testmc.Mediafilename = listBox1.Items[listBox1.SelectedIndex].ToString();
testmc.LoadMediaFile();
int n_height = testmc.Height, n_width = testmc.Width ;
testmc.PlayLoop();
int next_alias = 1;
int xpos =( n_width-2) , ypos = 0;
while (ypos < panel1.Height)
{
    while (xpos < panel1.Width)
    {
        MCIControl.MCIPlayerControl newmc = new MCIControl.MCIPlayerControl();
        panel1.Controls.Add(newmc );
        newmc.Location = new Point(xpos, ypos);
        newmc.ShowControls = false;
        newmc.Size = new Size(n_width, n_height);

        newmc.Visible = true;
        newmc.Alias = next_alias ;
        newmc.Mediafilename = listBox1.Items[listBox1.SelectedIndex].ToString()
        newmc.LoadMediaFile();
        newmc.PlayLoop();
        newmc.ToggleAudio();
        next_alias++;
        xpos += (n_width);

    }
    ypos += (n_height);
    xpos = 0;
}

panel1.Focus();
VB.NET
If listBox1.SelectedIndex < 0 Then
      Return
  End If
  Me.WindowState = FormWindowState.Maximized
  Me.FormBorderStyle = FormBorderStyle.None
  panel1 = New Panel()
  Me.Controls.Add(panel1)

  Me.panel1.Location = New Point(0, 0)
  Dim rect As Rectangle = ScreenCapture.GetClientRect(Me.Handle)
  Me.panel1.Size = New Size(rect.Width, rect.Height)
  Me.panel1.Visible = True
  Me.panel1.BringToFront()
  'mciPlayerControl1.CloseMediaFile();
  buttonClose1_Click(Nothing, Nothing)
  mciPlayerControl2.CloseMediaFile()

  ' divide to 3 columns
  Dim s_width As Integer = panel1.Width \ 3 - 2
  Dim s_height As Integer = panel1.Height \ 3 - 2
  Dim testmc As New MCIControl.MCIControl.MCIPlayerControl()
  panel1.Controls.Add(testmc)
  testmc.Location = New Point(0, 0)

  testmc.Size = New Size(s_width, s_height)

  testmc.Visible = True
  testmc.[Alias] = 0
  testmc.Mediafilename = listBox1.Items(listBox1.SelectedIndex).ToString()
  testmc.LoadMediaFile()
  Dim n_height As Integer = testmc.Height, n_width As Integer = testmc.Width
  testmc.PlayLoop()
  Dim next_alias As Integer = 1
  Dim xpos As Integer = (n_width - 2), ypos As Integer = 0
  While ypos < panel1.Height
      While xpos < panel1.Width
          Dim newmc As New MCIControl.MCIControl.MCIPlayerControl()
          panel1.Controls.Add(newmc)
          newmc.Location = New Point(xpos, ypos)
          newmc.ShowControls = False
          newmc.Size = New Size(n_width, n_height)

          newmc.Visible = True
          newmc.[Alias] = next_alias
          newmc.Mediafilename = listBox1.Items(listBox1.SelectedIndex).ToString()
          newmc.LoadMediaFile()
          newmc.PlayLoop()
          newmc.ToggleAudio()
          next_alias += 1
          xpos += (n_width )
      End While
      ypos += (n_height )
      xpos = 0
  End While

  panel1.Focus()

Panel1 is created at run time to occupy the complete client area of the maximized demo form. Then we created the first MCIPlayerControl control, add it to the panel and set it at the top left hand corner. We want each control not to occcupy more than 1/3 of the width or the 1/3 of the height of the maximized form. The initial size of the control is set to this dimension: 1/3 form height and 1/3 form width. Before we load the file to the control, we set its ShowControls property to false. This is to inform the control not to show its UI components (track bar, caption, buttons ..). With this property set to false, the control would be resized to fit the display of the video file, maintaining the aspect ratio and keeping to within the area of the initial size set. After the required area has been calculated, the excess area in the control is cut off, such that all the area of the control will be used for video display with no border margin.

Once we get the new size, we store it in n_width and n_height variable. We use the while loops to create all the other controls, so that each control will just overlap the previous one slightly. As each control is created and added to the panel, it is being played.

As the controls are played at sightly different time, each one would be sightly out of sync with the previous one. The time lapse between the displays may be in tens or hundreds millisec, depending on how fast your system loads and plays back the media files. 

Demo

Image 4

The left listbox shows all the video files in the current directory. There are 2 MCIPlayerControl controls in the form.

The left one has no UI controls and the right one with UI controls.

To control the play of the left control, I have added in some buttons. You get the control with no UI controls by setting its ShowControls property to false. The advantage of not having UI controls is that you can set the size of the control (by using the mouse at design time, or setting the control's size property or width and height property at run time) and the display will be sized accordingly.

For the right control, you can click on the UI controls to manage the video play. The left bottom'buttons' are for "seek start", "pause/play","seek end", "slow motion" and  "fast forward". The right button is to toggle the audio on/off. You can also use the track bar to position to the frame that you want to resume playing from.

You will have to select a video file from the listbox to load into the control. You can load each control with the same file or different file. Then click the Load buttons. 

If you click the top right [ ] (round rectangle) 'button' for the right MCIPlayerControl control , you will get a pop up viewer window.  You can use the <space> bar to pause and resume play. Press 'P' to get save a screen shot of the current frame. 

 Image 5

Press F11 to toggle showing the viewer in full screen and normal  window. If the viewer window is closed (using <Esc> key or the Close button), the display will be back into the  MCIPlayerControl control. 

In Version 2, I have enhanced the viewer to show/hide the various video controls, as shown in the picture above. If there is no mouse activity, the controls and the mouse cursor will auto-hide. Once you move the mouse, the mouse cursor and controls will appear again. 

To show the video wall, first select a video file from the listbox and then configure the following parameters, and finally click the Video Wall button

  • Video Lapse (ms): The time delay before starting the next video 
  • Min Num Across: Minimum number of video across the wall
  • Min Num Down: Minimun number of video down the wall
  • Sync Video: If this is set the Video Lapse parameter will be ignored. All video will be in sync
  • Random Overlap: Video will appear overlapped and entire wall will be covered with video of slightly uneven size, just as in the Top picture for this article

All the video that are currently loaded will be unloaded, the form would be maximized,and the selected video file will be played in an array of MCIPlayerControl controls. 

While the video wall is displayed, you can use the <space> bar to pause and resume play.  

To unload the video wall, press the Esc key.

Points of Interest

The MCIPlayerControl is quite a light weight control, compared to Windows Media Player. On a fast system, loading a wall of controls (about 12 - 16) should take up less than 50% of the CPU processing.

Maybe you can think of some more interesting use for the control besides those already mentioned here. 

It is very easy to use the   MCIPlayerControl  in your Window Form projects, just drag it into your form and at runtime use the method:

LoadMediaFile(string filename, int alias,bool resize)

to load the filename with a unique numeric alias and resize as false to get a video player with full UI controls.

Have fun playing the MCIPlayerControl. 

History

18 June 2014: MCIPlayerControl V1

19 June 2014: MCIPayerControl V1a:

Pop up Viewer window and Video wall in full screen mode

25 Jun 2014: MCIPlayerControl V1b

Add in configuration settings for the Video wall

27 Jun 2014: MCIPlayerControl V2

Add in Overlay to Viewer with controls that show/hide based on mouse activity just like Windows Media Player

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Singapore Singapore
Coder. Hacker. Fixer.

Comments and Discussions

 
Questionrtsp Pin
elichka250724-Jul-17 20:14
elichka250724-Jul-17 20:14 
AnswerRe: rtsp Pin
Yang Kok Wah24-Jul-17 20:50
Yang Kok Wah24-Jul-17 20:50 
GeneralMy vote of 5 Pin
Volynsky Alex28-Jun-14 9:22
professionalVolynsky Alex28-Jun-14 9:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.