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.
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
A dog in high speed motion
Using the code
MCIPlayerControl exposes the following properties
public bool ShowControls
public string Mediafilename
public string Caption
public int Alias
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
public bool LoadMediaFile()
public bool LoadMediaFile(string filename, int alias,bool resize)
public void CloseMediaFile()
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
public void Pause_Play()
public void PlayLoop()
public void ToggleAudio()
public void SeekPlayPosition(int pos)
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
The code below shows how we make use of an array of controls to display a video wall.
if (listBox1.SelectedIndex < 0) return;
this.WindowState = FormWindowState.Maximized;
this.FormBorderStyle = FormBorderStyle.None;
panel1 = new Panel();
this.panel1.Location = new Point(0, 0);
this.panel1.Size = new Size(rect.Width, rect.Height);
int s_width = panel1.Width / 3;
int s_height = panel1.Height / 3;
MCIControl.MCIPlayerControl testmc = new MCIControl.MCIPlayerControl();
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();
int n_height = testmc.Height, n_width = testmc.Width ;
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();
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()
xpos += (n_width);
ypos += (n_height);
xpos = 0;
If listBox1.SelectedIndex < 0 Then
Me.WindowState = FormWindowState.Maximized
Me.FormBorderStyle = FormBorderStyle.None
panel1 = New Panel()
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
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()
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()
Dim n_height As Integer = testmc.Height, n_width As Integer = testmc.Width
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()
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()
next_alias += 1
xpos += (n_width )
ypos += (n_height )
xpos = 0
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.
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.
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.
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