Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Media Player "Streaming Media"

Posted on 2005-03-02
7
Medium Priority
?
2,058 Views
Last Modified: 2008-01-09
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
0
Comment
Question by:Wayne Barron
  • 4
  • 3
7 Comments
 
LVL 2

Accepted Solution

by:
philipjc earned 200 total points
ID: 13444377
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
 
LVL 31

Author Comment

by:Wayne Barron
ID: 13444749
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
 
LVL 2

Expert Comment

by:philipjc
ID: 13447069
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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 2

Expert Comment

by:philipjc
ID: 13447111
I apologize, the jedi headers are the dircetx headers available on www.jedi.org ,a great resource for the community
0
 
LVL 31

Author Comment

by:Wayne Barron
ID: 13448459
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
 
LVL 31

Author Comment

by:Wayne Barron
ID: 13452028
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
 
LVL 31

Author Comment

by:Wayne Barron
ID: 13490722
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

Featured Post

Become an Android App Developer

Ready to kick start your career in 2018? Learn how to build an Android app in January’s Course of the Month and open the door to new opportunities.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
With just a little bit of  SQL and VBA, many doors open to cool things like synchronize a list box to display data relevant to other information on a form.  If you have never written code or looked at an SQL statement before, no problem! ...  give i…
Enter Foreign and Special Characters Enter characters you can't find on a keyboard using its ASCII code ... and learn how to make a handy reference for yourself using Excel ~ Use these codes in any Windows application! ... whether it is a Micr…
Suggested Courses
Course of the Month15 days, 6 hours left to enroll

577 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question