Introduction
At long last I have finally made what I have wanted to make for so long. Being new to the coding world, this media player (which I call 'MediaShow') is my first working software. It is based on the famous DirectShow multimedia API from Microsoft.
DirectShow divides the processing of multimedia tasks such as video playback into a set of steps known as filters. Each filter represents a stage in the processing of the data. Filters have a number of input and output pins which connect them together. The generic design of the connection mechanism means that filters can be connected in many different ways for different tasks to build a filter graph.
It is possible to make custom filters which can be used to play a variety of media file formats; clearly displaying the power of DirectShow API. But the complexity for customization and making filters from scratch makes the use of this API rather difficult.
Features
I used a C# example of media playback with DirectShow and modified it to suit my requirements. The following features are there in MediaShow:
- Play media/audio files (WAV, WMA, **MOV, QT, AVI, DAT, MP3, MPEG/MPG)
- Playlist in a new format(*.ms)
- Voice Recorder
- CD tray Open and Close
- Subtitles Play
- Set rate of play of file
- Single frame step which displays one frame at a time until the user presses a key to move to the next frame
- Different Screen Modes
- Volume Control
- Mute option
- Position Trackbar to jump to desired position
- Displays the total duration of file
- Displays the duration of play of file
Using the Code
The code is divided into two parts:
- First part uses directshow.dll and performs: basic media playback, set rate of play of file, single frame step, volume control, different screen modes and duration of file.
private void PlayMovieInWindow(string filename)
{
int hr = 0;
if (filename == string.Empty)
return;
this.graphBuilder = (IGraphBuilder)new FilterGraph();
hr = this.graphBuilder.RenderFile(filename, null);
DsError.ThrowExceptionForHR(hr);
this.mediaControl = (IMediaControl)this.graphBuilder;
this.mediaEventEx = (IMediaEventEx)this.graphBuilder;
this.mediaSeeking = (IMediaSeeking)this.graphBuilder;
this.mediaPosition = (IMediaPosition)this.graphBuilder;
this.videoWindow = this.graphBuilder as IVideoWindow;
this.basicVideo = this.graphBuilder as IBasicVideo;
this.basicAudio = this.graphBuilder as IBasicAudio;
CheckVisibility();
hr = this.mediaEventEx.SetNotifyWindow(this.Handle, WMGraphNotify,
IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
if (!this.isAudioOnly)
{
this.ClientSize = new Size(379,331);
hr = this.videoWindow.put_Owner(this.Handle);
DsError.ThrowExceptionForHR(hr);
hr = this.videoWindow.put_WindowStyle(WindowStyle.Child |
WindowStyle.ClipSiblings | WindowStyle.ClipChildren);
DsError.ThrowExceptionForHR(hr);
hr = InitVideoWindow(1, 1);
DsError.ThrowExceptionForHR(hr);
GetFrameStepInterface();
}
else
{
hr = InitPlayerWindow();
DsError.ThrowExceptionForHR(hr);
}
this.isFullScreen = false;
this.currentPlaybackRate = 1.0;
UpdateStatusBar();
UpdateToolStrip();
#if DEBUG
rot = new DsROTEntry(this.graphBuilder);
#endif
this.Focus();
hr = this.mediaControl.Run();
DsError.ThrowExceptionForHR(hr);
this.currentState = PlayState.Running;
Increment.Start();
}
private void CloseClip()
{
int hr = 0;
if (this.mediaControl != null)
hr = this.mediaControl.Stop();
this.currentState = PlayState.Stopped;
this.isAudioOnly = true;
this.isFullScreen = false;
CloseInterfaces();
this.filename = string.Empty;
this.currentState = PlayState.Init;
UpdateStatusBar();
UpdateToolStrip();
InitPlayerWindow();
}
private int InitVideoWindow(int nMultiplier, int nDivider)
{
int hr = 0;
int lHeight, lWidth;
if (this.basicVideo == null)
return 0;
hr = this.basicVideo.GetVideoSize(out lWidth, out lHeight);
if (hr == DsResults.E_NoInterface)
return 0;
lWidth = lWidth * nMultiplier / nDivider;
lHeight = lHeight * nMultiplier / nDivider;
if (!this.isAudioOnly)
{
panel1.Size = new Size(lWidth, lHeight);
PositionTracker.Location = new Point(0, lHeight + 52);
this.ClientSize = new Size(lWidth+1, lHeight+139);
Application.DoEvents();
hr = this.videoWindow.SetWindowPosition(panel1.Left, panel1.Top,
panel1.Width, panel1.Height);
}
return hr;
}
private void MoveVideoWindow()
{
int hr = 0;
if (this.videoWindow != null)
{
hr = this.videoWindow.SetWindowPosition(panel1.Left,panel1.Top,
panel1.Width,panel1.Height);
DsError.ThrowExceptionForHR(hr);
}
}
private void CheckVisibility()
{
int hr = 0;
OABool lVisible;
if ((this.videoWindow == null) || (this.basicVideo == null))
{
this.isAudioOnly = true;
return;
}
else
{
this.isAudioOnly = false;
}
hr = this.videoWindow.get_Visible(out lVisible);
if (hr < 0)
{
if (hr == unchecked((int)0x80004002))
{
this.isAudioOnly = true;
}
else
DsError.ThrowExceptionForHR(hr);
}
}
I could also use mciSendString
to play media/audio files but I preferred not to do so because DirectShow has the capability of playing a wider range of formats than mciSendString
.
The code on the whole is very simple to understand and well indented. But as I said before, I am new in to the field of software development and the scope of improving the quality of code is tremendous, so any suggestions regarding that would be very much appreciated.
More…
I am working on the player to make it optimized in every sense of the word. I am also trying to add better features to it. Any suggestions are most welcome. I have also have not checked for bugs which might be in the software so I request all you guys out there to please look into 'MediaShow' and please report the bugs to me.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.