?
Solved

Media Player "Streaming Media"

Posted on 2005-03-02
7
Medium Priority
?
2,049 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

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…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
Suggested Courses
Course of the Month15 days, 2 hours left to enroll

771 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