Media Player "Streaming Media"

Hello All;

  For the project that we are currently in development on.
A Media Player is one of the Extra's that will be available to the Users
As a Add-On to the Main Program.

  What we are needing to know is the following:

How Microsoft Windows Media Player gives you the option to open a media file
Via:  URL:  mms://media-server/some-music-file/
And stream the music to the Clients Player.

Can this be done using the Media Player in Delphi?
Or a better more Robust 3rd Party Media Player component set.
That will allow the end-user to play Streaming Media and their own files
From their PC Hard Drive, and from a CD as well.

Thank you all;
Carrzkiss
LVL 31
Wayne BarronAuthor, Web DeveloperAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

philipjcCommented:
You probably want to look into Directshow for help on this. Windows mediaplayer is based on this and this is the prefered way to build windows applications for the future. My understanding of delphi media player is that it is a wrapper on for the older mmsystem tecnologies. There are a number of delphi components, DSPack, DelphiX etc. for this but with an understanding of COM it is not that difficult to write a player using just the jedi header files

Phil
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Wayne BarronAuthor, Web DeveloperAuthor Commented:
Hello Phil;

  Yes, I have heard about using "DirectShow" and have played around with it in the past.
But never really got that far into learning it, to mount to much.

Do you perhaps have any links for using DS to make a Media Player?

you refer to "jedi Headers"?
Could you explain this a little as well?

Thank you, and please excuse my not knowing that much about this topic.
As I have been away from Delphi for nearly 6-months, and have just
Jumped back into it, to start the development of our new program.
Which is going to be integrated into the site that we are building for it as well.
So a bunch of my time has been taken up with the planing of the site and
Of the program. (Idea's of the such) so now it is time to put it all together.

Take Care
Carrzkiss
0
philipjcCommented:
The jedi headers are type library definitions that allow you to compile directshow dll calls

its all about creating interfaces

unit DSPlay5;

interface

uses Windows, SysUtils, Messages, ActiveX, DirectShow, ExtCtrls;

const wm_GraphNotify = wm_App + 1;
      wm_Cue         = wm_App + 2;
      wm_Duration    = wm_app + 3;
      wm_Stopped     = wm_App + 4;

type  EDirectShowException = Class(Exception);

      TStartProc = procedure of object;

      TDSPlayer = class
          graph           : IGraphBuilder;
          MediaControl    : IMediaControl;
          MediaEvent      : IMediaEventEx;
          VideoWindow     : IVideoWindow;
          BasicAudio      : IBasicAudio;
          BasicVideo      : IBasicVideo;
          MediaSeeking    : IMediaSeeking;

          HWindow : Hwnd;
          FileName : String;
          Duration : Double;
          timer    : TTimer;
          StartProc : TStartProc;

          constructor Create(Handle : HWnd; FName : PWideChar);
          destructor Destroy;   OVERRIDE;
          procedure DSPlay;
          procedure DSStop;
          procedure DSPause;
          procedure DSUnPause;

          procedure InitDS;
          procedure FreeDS;
          procedure ResetDS;
          procedure EnumFilters;
          procedure TimerTick(Sender : TObject);
        end;

        function GetBitmap(FName : String) : String;
        function GetDuration(FName : String) : Double;

var  OATRUE, OAFALSE : LongBool;

implementation

constructor TDSPlayer.Create(Handle : HWnd; FName : PWideChar);
var Rect : TRect;
begin
    inherited Create;
    HWindow := Handle;
    FileName := FName;
    InitDS;
    if not Succeeded(Graph.RenderFile(Fname, Nil)) then
         raise EDirectShowException.create('Unable to Render File');
    EnumFilters;
    MediaEvent.SetNotifyWindow(HWindow, wm_GraphNotify, 0);
    Duration := GetDuration(FName);
    Duration := Duration - 0.01;
    VideoWindow.HideCursor(OATRUE);
    {Timer := TTimer.Create(nil);
    Timer.Enabled := False;
    Timer.Interval := 10;
    Timer.OnTimer := TimerTick;}
end;

procedure TDSPlayer.EnumFilters;
var EFilter : IEnumFilters;
    BFilter : IBaseFilter;
    DVDecoder : IIPDVDec;
    Fetched : Cardinal;
    FilterInfo :TFilterinfo;
    hr : HResult;
    DisplayPix : Integer;
begin
    Graph.EnumFilters(EFilter);
    while (EFilter.Next(1, BFilter, @Fetched) = S_OK) do
    begin
        BFilter.QueryFilterInfo(FilterInfo);
        if FilterInfo.achName = 'DV Video Decoder' then
        begin
           if Succeeded(BFilter.QueryInterface( IID_IIPDVDec, DVDecoder)) then
           begin
             DVDecoder.get_IPDisplay(DisplayPix);
             if DisplayPix <> DVRESOLUTION_FULL then
                DVDecoder.put_IPDisplay(DVRESOLUTION_FULL);
           end;
           DVDecoder := nil;
        end;
        FilterInfo.pGraph := nil;
        BFilter := nil;
    end;
    EFilter := Nil;
end;


destructor TDSPlayer.Destroy;
begin
     FreeDS;
     Inherited Destroy;
end;

procedure TDSPlayer.DSPlay;
begin
    VideoWindow.put_FullScreenMode(OATRUE);
    MediaControl.Run();
    if assigned(StartProc) then
        StartProc;
    {Timer.Enabled := True;}
end;

procedure TDSPlayer.TimerTick(Sender : TObject);
begin
    Duration := Duration - 0.01;
    if duration <= 0 then
    begin
        DSStop;
        Timer.Enabled := False;
        SendMessage(HWindow, wm_Stopped, 0, 0);
    end;
end;

procedure TDSPlayer.DSStop;
begin
    if Assigned(MediaControl) then MediaControl.Stop;
end;

procedure TDSPlayer.DSPause;
begin
    if assigned(MediaControl) then MediaControl.Pause;
end;

procedure TDSPlayer.DSUnPause;
begin
    if assigned(MediaControl) then MediaControl.Run;
end;

procedure TDSPlayer.FreeDS;
begin
    if Assigned(MediaControl) then MediaControl.Stop;
    if Assigned(VideoWindow) then
    begin
         VideoWindow.put_Visible(OAFALSE);
         VideoWindow.put_Owner(0);
    end;
    if assigned(MediaControl)    then MediaControl := nil;
    if assigned(MediaSeeking)    then MediaSeeking := nil;
    if assigned(VideoWindow)     then VideoWindow  := nil;
    if assigned(BasicVideo)      then BasicVideo   := nil;
    if assigned(BasicAudio)      then BasicAudio   := nil;
    if assigned(MediaEvent)      then
                                    begin
                                       MediaEvent.SetNotifyWindow(0, 0, 0);
                                       MediaEvent   := nil;
                                     end;
    if assigned(Graph)           then Graph        := nil;
    if assigned(Timer) then Timer.Free;
end;

procedure TDSPlayer.InitDS;
begin
    try
        CoCreateInstance(CLSID_FilterGraph, Nil, CLSCTX_INPROC_SERVER,
                        IID_IGraphBuilder, Graph);
        Graph.QueryInterface(IID_IMediaControl, MediaControl);
        Graph.QueryInterface(IID_IMediaEventEx, MediaEvent);
        Graph.QueryInterface(IID_IVideoWindow, VideoWindow);
        Graph.QueryInterface(IID_IMediaSeeking, MediaSeeking);
        Graph.QueryInterface(IID_IBasicVideo, BasicVideo);
        Graph.QueryInterface(IID_IBasicAudio, BasicAudio);
    except
        Raise EDirectShowException.Create('Unable to Initialize DirectShow SubSystem');
    end;
end;

procedure TDSPlayer.ResetDS;
begin
    FreeDS;
    InitDS;
end;

function GetBitmap(FName : String) : String;
var VidGuid    : WideString;
    i,count    : Integer;
    StreamType : WideString;
    Duration   : Double;
    MediaDet   : IMediaDet;
    Dest       : PWideChar;
    TempFName  : String;
begin
    VidGuid := '73646976-0000-0010-8000-00AA00389B71';
    TempFName := ChangeFileExt(FName, '.bmp');
    GetMem(Dest, 512);
    dest := StringToWideChar(FName, dest, 512);
    coCreateInstance(CLSID_MediaDet, nil, CLSCTX_INPROC_SERVER,
                     IID_IMediaDet, MediaDet);
    MediaDet.put_Filename(Dest);
    MediaDet.get_OutputStreams(Count);
    for i := 0 to  count - 1 do
    begin
       MediaDet.put_CurrentStream(i);
       MediaDet.get_StreamTypeB(StreamType);
       if WideCompareStr(StreamType, VidGUID) = 0 then
          break;
    end;
    dest := StringToWideChar(TempFName, dest, 512);
    MediaDet.get_StreamLength(Duration);
    MediaDet.WriteBitmapBits(Duration - 0.01, 720, 480, Dest);
    result := WideCharToString(Dest);
    FreeMem(Dest);
    if assigned(MediaDet) then MediaDet := nil;
end;

function GetDuration(FName : String) : Double;
var VidGuid    : WideString;
    i,count    : Integer;
    StreamType : WideString;
    MediaDet   : IMediaDet;
    Dest       : PWideChar;
begin
    VidGuid := '73646976-0000-0010-8000-00AA00389B71';
    GetMem(Dest, 512);
    dest := StringToWideChar(FName, dest, 512);
    coCreateInstance(CLSID_MediaDet, nil, CLSCTX_INPROC_SERVER,
                     IID_IMediaDet, MediaDet);
    MediaDet.put_Filename(Dest);
    MediaDet.get_OutputStreams(Count);
    for i := 0 to  count - 1 do
    begin
       MediaDet.put_CurrentStream(i);
       MediaDet.get_StreamTypeB(StreamType);
       if WideCompareStr(StreamType, VidGUID) = 0 then
          break;
    end;
    MediaDet.get_StreamLength(Result);
    FreeMem(Dest);
    if assigned(MediaDet) then MediaDet := nil;
end;

initialization
begin
    OATRUE := LongBool(-1);
    OAFALSE := LongBool(0);
    CoInitialize(nil);
end;

finalization
begin
    CoUnInitialize;
end;

end.
this is ancent old code I am just using it for illistration

This is about the simplest interface to the player object that you can create but it will stream from an url player := TDs player.createI('etc  url la la la

To do streaming media for real there are a lot of ways to create OS objects but they all depend on this fundemental understanding that the OS will do most of the work for you

I may be the only delphi programmer in the world that thinks that COM is our friend
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

philipjcCommented:
I apologize, the jedi headers are the dircetx headers available on www.jedi.org ,a great resource for the community
0
Wayne BarronAuthor, Web DeveloperAuthor Commented:
Hello Phillip;

That you so very much for the code and explaination.
Jedi, I have installed (Or atleast I think that I installed it this go around, will have to check)

The link   www.jedi.org   is a dead link now.
They changed it to:  http://www.delphi-jedi.org/

I will post back my findings later on.

Thank you
Carrzkiss
0
Wayne BarronAuthor, Web DeveloperAuthor Commented:
The Demo's that come with DSPack.
Have some great examples of how to make a Media Player.

The one Demo: PlayWin
Allows you to open a URL. But I get the following Error when trying to open a URL
(Which is being streamed from our [Win2003 Media Server]
The url looks like this "Which is behind out network"
mms://192.168.1.184/Metal80s

Typed into "Windows Media Player" this URL works great.
Typed into the "DSPack" Demo, I receive the following Error:
---------------------------
playwin
---------------------------
The operation cannot be performed because the pins are not connected. ($80040209).
---------------------------
OK  
---------------------------

If you are able to assist me to get this working.
I will be more then happy to up the points for you.

Thank You
Carrzkiss
0
Wayne BarronAuthor, Web DeveloperAuthor Commented:
I beleive that the DSPack will do what I need it to do.
I will just need to do some research on how to make everything work
The way I need it to.

Thank you for your assistance.

Carrzkiss
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.