Juhara.com
Language : English Indonesia

Multimedia Player dengan DirectShow Part 2

Zamrony P. Juhara
15 September 2006 14:30:00
 (7579 views)
Sambungan tutorial berjudul sama. Di sini akan dibahas cara menampilkan video di Form terpisah dan juga menampilkan video secara fullscreen

Pendahuluan

Tutorial ini adalah lanjutan tutorial sebelumnya Multimedia Player dengan DirectShow Part 1. Kali ini kita akan mendiskusikan bagaimana menampilkan video pada suatu window.

Menampilkan Video pada suatu Window.

Jika anda sudah mencoba aplikasi multimedia player pada tutorial bagian 1, ketika memainkan file video, anda akan mendapatkan bahwa video ditampilkan pada window tersendiri. Lalu bagaimana bila kita ingin menampilkan video tersebut, misal di form milik kita sendiri?

Filter Graph Manager mengimplementasikan interface IVideoWindow. Interface ini adalah interface yang kita pergunakan untuk manipulasi bagaimana video ditampilkan. Kita bisa menampilkan video pada skala zoom 50%, 100%, 200% atau skala sembarang pada window yang kita inginkan. Video bisa juga ditampilkan fullscreen.

Untuk mendapatkan pointer ke interface ini kita panggil QueryInterface milik Filter graph manager

var FVideoWindow:IVideoWindow;

FFilterGraph.QueryInterface(IID_IVideoWindow,FVideoWindow);

Jika sukses FVideoWindow akan berisi pointer ke instance IVideoWindow. Untuk dapat menampilkan video pada suatu window, langkah-langkahnya adalah:

  1. Set video ke handle window yang menjadi target. Menggunakan metode put_Owner(). Parameter fungsi ini adalah handle window. DirectShow menggunakan tipe OAHWND untuk mengacu pada handle window. So handle window harus dicast ke OAHWND.
    var FWindowHandle:HWND;
    FVideoWindow.put_Owner(OAHWND(FWindowHandle));
  2. Mengubah status visibility. Agar video terlihat di window, kita perlu mengubah visibility video dengan metode put_visible() milik IVideoWindow. Parameternya adalah visibility bertipe longbool.
    FVideoWindow.put_visible(true);
    Catatan: window yang direferensi oleh FWindowHandle harus juga visible agar video terlihat di layar.
  3. Mengubah Style Window. Style window diset menggunakan SetWindowStyle milik IVideoWindow. Window perlu diset menjadi child window mengunakan WS_CHILD dan agar video tidak digambar diluar area window, kita perlu menggunakan style WS_CLIPSIBLINGS.
    FVideoWindow.SetWindowStyle(WS_CLIPSIBLINGS or WS_CHILD);
  4. Mengubah Posisi video pada Window. Video bisa kita letakkan dimana saja pada clientarea window FWindowHandle menggunakan metode SetPosition milik IVideoWindow.
    var arect:TRect;
    aRect.Left:=0;
    aRect.Top:=0;
    aRect.Right:=ClientWidth;
    aRcet.Bottom:=ClientHeight;
    FVideoWindow.SetPosition(aRect.left,aRect.Top,aRect.Right,aRect.Bottom);
    Mengubah ukuran tinggi dan lebar menyebabkan terjadi zoom bila lebar dan tinggi tidak sama dengan lebar tinggi original video. Proses zoom tidak peduli aspek ratio. Jika kita butuh zoom dimana aspek rasio tidak berubah, kita perlu mendapatkan lebar tinggi original video. Cara mendapatkan data ini akan kita bahas setelah ini.

Menampilkan Video Fullscreen

IVideoWindow memiliki metode put_FullscreenMode(), yang kita gunakan mengubah tampilan fullscreen atau window. Bila true, video ditampilkan fullscreen, bila sebaliknya dalam windowed mode.

Fullscreen mode:

FVideoWindow.put_FullscreenMode(true);

Windowed mode:

FVideoWindow.put_FullscreenMode(false);

Untuk mendapatkan status mode fullscreen,

var statusFull:longBool;
FVideoWindow.get_FullscreenMode(statusFull);

Ketika berada pada mode fullscreen, aplikasi kita tidak menerima focus, sehingga semua message akan dikirim ke filter graph manager. Agar pada mode fullscreen aplikasi kita tetap bisa menerima message input keyboard dan input mouse (sehingga kita melakukan toggle fullscreen on/off misalnya), kita perlu membelokkan message tersebut ke aplikasi kita dgn fungsi put_MesageDrain() milik IVideoWindow.

Put_MessageDrain mengharapkan handle window yang akan menghandle message-message.

FVideoWindow.put_MessageDrain(FHandleWindow);

Untuk mendapatkan handle window yang membelokkan message-message kita menggunakan IVideoWindow.get_MessageDrain().

FVideoWindow.Get_MessageDrain(FHandleWindow);

Bersih-bersih

Setelah finish dengan IVideoWindow, kita perlu mengubah status visibility menjadi false, jika tidak, maka video tetap akan tampil di layar dan tidak bisa dihilangkan oleh user. Setelah itu owner window harus kita nol kan menggunakan put_Owner().

FVideoWindow.put_Visible(false);
FvideoWindow.put_Owner(0);

Mendapatkan lebar tinggi asli video

Agar kita bisa melakukan zoom dengan mempertahankan aspek rasio, kita perlu mengetahui lebar tinggi asli video. Interface IBasicVideo, yang bisa di-QueryInterface dari Filter graph manager, disediakan salah satunya untuk keperluan ini.

var orgVideoWidth,orgVideoHeight:integer;
FBasicVideo.get_VideoWidth(orgVideoWidth);
FBasicVideo.get_VideoHeight(orgVideoHeight);

Mengecek Apakah Suatu Media Memiliki data video.

Ada kalanya kita perlu mengecek apakah media yang akan kita mainkan mengandung data video dan audio ataukah hanya audio saja. Misal kita akan menampilkan window video hanya bila media tersebut mengandung data video dan audio. Caranya dengan meng-queryInterface FilterGraph untuk interface IBasicVideo. Jika nil berarti media bukan video atau codec untuk format tersebut belum terinstall. Jika tidak nil, kita perlu mengecek status visible IVideoWindow. Jika pemanggilan get_visible() gagal berarti media bukan video. Contoh:

var basicVideo:IBasicVideo;
    vis:longBool;

FFilterGraph.QueryInterface(IID_IBasicVideo,basicVideo);
audioOnly:=(basicVideo=nil) or (failed(FVideoWindow.get_Visible(vis)));

Berikut ini adalah implementasi kelas TBasicPlayer yang baru.

{---------------------------------
DirectShow wrapper unit
----------------------------------
(c) 2006 juhara.com All rights
reserved.
----------------------------------
coder:zamrony p juhara
----------------------------------
history:

-bug in RemoveAllFilter(). Lack of
 enum.Reset()
----------------------------------}
unit uDirectShowPlayer;

interface

uses classes,windows,messages,directShow,controls;

const WM_MMNOTIFY=WM_APP+$1234;

type
     TPlayPosition=record
       Current:int64;
       Stop:int64;
     end;

     TBasicPlayer=class(TObject)
     private
       FFilterGraph:IGraphBuilder;
       FMediaControl:IMediaControl;
       FMediaEvent:IMediaEventEx;
       FMediaSeek:IMediaSeeking;
       FVideoWindow:IVideoWindow;

       FHandle: HWND;
       FControl: TWinControl;

       FVideoRect:TRect;

       procedure SetHandle(const Value: HWND);

       procedure SetDrainHandle(const Value: HWND);
       function GetDrainHandle: HWND;

       function GetDuration: int64;
       function GetPosition: TPlayPosition;
       procedure SetPosition(const Value: TPlayPosition);
       procedure SetControl(const Value: TWinControl);
       procedure SetFullScreen(const Value: boolean);


       function GetFullScreen:boolean;

       function GetOrgHeight: integer;
       function GetOrgWidth: integer;
       procedure SetVideoRect(const Value: TRect);

       procedure UpdateVideoWindowPos;

       function GetAudioOnly:boolean;
     protected
       procedure SetNotifyWindow(const ahandle:HWND);
       procedure SetWindow(const aHandle:HWND);virtual;
     public
       constructor Create;
       destructor Destroy;override;

       procedure BuildFilterGraph;virtual;abstract;
       procedure RemoveAllFilters;

       procedure Run;
       procedure Stop;
       procedure Pause;
       procedure Rewind;

       procedure GetVideoOrgSize(out width,height:integer);
     published
       property Control:TWinControl read FControl write SetControl;
       property Handle:HWND read FHandle write SetHandle;
       property DrainHandle:HWND read GetDrainHandle write SetDrainHandle;

       property GraphObj:IGraphBuilder read FFilterGraph;
       property ControlObj:IMediaControl read FMediaControl;
       property EventObj:IMediaEventEx read FMediaEvent;
       property SeekObj:IMediaSeeking read FMediaSeek;
       property VideoWindow:IMediaSeeking read FMediaSeek;

       property Position:TPlayPosition read GetPosition write SetPosition;
       property Duration:int64 read GetDuration;

       property FullScreen:boolean read GetFullScreen write SetFullScreen;

       property VideoRect:TRect read FVideoRect write SetVideoRect;

       property OrgWidth:integer read GetOrgWidth;
       property OrgHeight:integer read GetOrgHeight;

       property AudioOnly:boolean read GetAudioOnly;
     end;

     TMMPlayer=class(TBasicPlayer)
     private
       FFilename: string;
       procedure SetFilename(const Value: string);
     public
       procedure BuildFilterGraph;override;
     published
       property Filename:string read FFilename write SetFilename;
     end;

     TFilter=class(TCollectionItem)
     private
       FFilterInstance: IBaseFilter;
       FFriendlyName: string;
       procedure SetFilterInstance(const Value: IBaseFilter);
       procedure SetFriendlyName(const Value: string);
     published
       property FilterInstance:IBaseFilter read FFilterInstance write SetFilterInstance;
       property FriendlyName:string read FFriendlyName write SetFriendlyName;
     end;


function SetPlayPosition(const curr,stop:int64):TPlayPosition;

implementation

uses sysutils,activeX;

function SetPlayPosition(const curr,stop:int64):TPlayPosition;
begin
  result.Current:=curr;
  result.Stop:=stop;
end;

{ TBasicPlayer }

constructor TBasicPlayer.Create;
var aEvent:IMediaEvent;
begin
  CoCreateInstance(CLSID_FilterGraph,nil,
                   CLSCTX_INPROC_SERVER,
                   IID_IGraphBuilder,FFilterGraph);

  if FFilterGraph=nil then
    raise Exception.Create('Inisialisasi filter graph manager gagal');

  FFilterGraph.QueryInterface(IID_IMediaControl,FMediaControl);
  FFilterGraph.QueryInterface(IID_IMediaEvent,aEvent);
  aEvent.QueryInterface(IID_IMediaEventEx,FMediaEvent);
  FFilterGraph.QueryInterface(IID_IMediaSeeking,FMediaSeek);
  FFilterGraph.QueryInterface(IID_IVideoWindow,FVideoWindow);
end;

destructor TBasicPlayer.Destroy;
begin
  RemoveAllFilters;

  FVideoWindow.put_Visible(FALSE);
  FVideoWindow.put_Owner(0);

  FFilterGraph:=nil;
  FMediaControl:=nil;
  FMediaEvent:=nil;
  FMediaSeek:=nil;
  inherited;
end;

procedure TBasicPlayer.Run;
begin
  FMediaControl.Run;
end;

procedure TBasicPlayer.Stop;
begin
  FMediaControl.Stop;
end;

procedure TBasicPlayer.Pause;
begin
  FMediaControl.Pause;
end;

procedure TBasicPlayer.SetHandle(const Value: HWND);
begin
  if FHandle<>Value then
  begin
    FHandle := Value;
    SetWindow(FHandle);
  end;
end;

procedure TBasicPlayer.SetWindow(const aHAndle: HWND);
begin
  SetNotifyWindow(AHandle);
end;

procedure TBasicPlayer.SetNotifyWindow(const ahandle: HWND);
begin
  FMediaEvent.SetNotifyWindow(aHandle,WM_MMNOTIFY,integer(self));
end;

function TBasicPlayer.GetDuration: int64;
begin
  FMediaSeek.GetDuration(result);
end;

function TBasicPlayer.GetPosition: TPlayPosition;
begin
  FMediaSeek.GetPositions(result.current,
                         result.Stop);
end;

procedure TBasicPlayer.SetPosition(const Value: TPlayPosition);
var apos:TPlayPosition;
begin
  apos:=value;
  FMediaSeek.SetPositions(aPos.Current,
                 AM_SEEKING_AbsolutePositioning,
                 aPos.Stop,
                 AM_SEEKING_AbsolutePositioning);
end;

procedure TBasicPlayer.Rewind;
begin
  SetPosition(SetPlayPosition(0,GetDuration));
end;


procedure TBasicPlayer.RemoveAllFilters;
var enum:IEnumFilters;
    aFilter:IBaseFilter;
    totread:cardinal;
begin
  totRead:=0;
  Stop;
  FFilterGraph.EnumFilters(enum);
  while (enum.Next(1,afilter,@totRead)=S_OK) do
  begin
    FFilterGraph.RemoveFilter(aFilter);
    enum.Reset;
  end;
  enum:=nil;
end;

procedure TBasicPlayer.SetControl(const Value: TWinControl);
begin
  FControl:= Value;
  if FControl<>nil then
  begin
    FVideoWindow.put_Owner(OAHWND(FControl.handle));
    FVideoWindow.put_WindowStyle(WS_CHILD or WS_CLIPSIBLINGS);

    FVideoRect:=Rect(0,0,FControl.ClientWidth,FControl.ClientHeight);
    UpdateVideoWindowPos;

    FVideoWindow.put_Visible(true);
    FVideoWindow.SetWindowForeground(1);
  end;
end;

procedure TBasicPlayer.SetFullScreen(const Value: boolean);
begin
  FVideoWindow.put_FullScreenMode(value);
end;

function TBasicPlayer.GetFullScreen: boolean;
var full:longBool;
begin
  FVideoWindow.get_FullScreenMode(full);
  result:=full;
end;

procedure TBasicPlayer.SetVideoRect(const Value: TRect);
begin
  FVideoRect := Value;
  UpdateVideoWindowPos;
end;

function TBasicPlayer.GetOrgHeight: integer;
var awidth,aheight:integer;
begin
  GetVideoOrgSize(aWidth,aHeight);
  result:=aHeight;
end;

function TBasicPlayer.GetOrgWidth: integer;
var awidth,aheight:integer;
begin
  GetVideoOrgSize(aWidth,aHeight);
  result:=awidth;
end;

procedure TBasicPlayer.GetVideoOrgSize(out width, height: integer);
var basicVideo:IBasicVideo;
begin
  FFilterGraph.QueryInterface(IID_IBasicVideo,basicVideo);
  if basicVideo<>nil then
    basicVideo.GetVideoSize(width,height)
  else
  begin
    width:=0;
    height:=0;
  end;
end;

procedure TBasicPlayer.UpdateVideoWindowPos;
begin
  FVideoWindow.SetWindowPosition(FVideoRect.Left,
                           FVideoRect.Top,
                           FVideoRect.Right,
                           FVideoRect.Bottom);
end;


procedure TBasicPlayer.SetDrainHandle(const Value: HWND);
begin
  FVideoWindow.put_MessageDrain(Value);
end;

function TBasicPlayer.GetDrainHandle: HWND;
var hdrain:integer;
begin
  FVideoWindow.get_MessageDrain(hdrain);
  result:=hdrain;
end;

function TBasicPlayer.GetAudioOnly: boolean;
var basicVideo:IBasicVideo;
    vis:longBool;
begin
  FFilterGraph.QueryInterface(IID_IBasicVideo,basicVideo);
  result:=(basicVideo=nil) or (failed(FVideoWindow.get_Visible(vis)));
end;


{TMMPlayer}
procedure TMMPlayer.BuildFilterGraph;
var wFilename:widestring;
begin
  wFilename:=WideString(FFilename);
  FFilterGraph.RenderFile(PWideChar(wFilename),nil);
end;

procedure TMMPlayer.SetFilename(const Value: string);
begin
  FFilename := Value;
end;

initialization
 CoInitialize(nil);

finalization
 CoUnInitialize;
end.

Berikut ini contoh aplikasi yang memanfaatkan kelas TMMPlayer yang baru.

unit ufrmMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,DirectShow, StdCtrls, ExtCtrls,
  uDirectShowPlayer, ComCtrls, ActnList;

type
  TfrmMediaPlayer = class(TForm)
    btnOpen: TButton;
    OpenDialog1: TOpenDialog;
    btnPlay: TButton;
    btnStop: TButton;
    Timer1: TTimer;
    ProgressBar1: TProgressBar;
    lblProgress: TLabel;
    btnPause: TButton;
    chkbxFullscreen: TCheckBox;
    ActionList1: TActionList;
    actToggleFullscreen: TAction;
    rdgrpZoom: TRadioGroup;
    procedure btnOpenClick(Sender: TObject);
    procedure btnPlayClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure btnPauseClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure chkbxFullscreenClick(Sender: TObject);
    procedure actToggleFullscreenExecute(Sender: TObject);
    procedure rdgrpZoomClick(Sender: TObject);
  private
    FDuration:int64;
    FMMPlayer:TMMPlayer;
    OldDrain:HWND;

    procedure WM_MMNotify(var msg:TMessage);message WM_MMNOTIFY;

    { Private declarations }
  public
    constructor Create(AOwner:TComponent);override;
    destructor Destroy;override;
    { Public declarations }
  end;

var
  frmMediaPlayer: TfrmMediaPlayer;

implementation

uses ufrmVideo;

{$R *.dfm}

{ TForm1 }

constructor TfrmMediaPlayer.Create(AOwner: TComponent);
begin
  inherited;
  FMMPlayer:=TMMPlayer.Create;
  FMMPlayer.Handle:=Handle;
  OldDrain:=0;
end;

destructor TfrmMediaPlayer.Destroy;
begin
  FMMPlayer.Free;
  inherited;
end;

procedure TfrmMediaPlayer.WM_MMNotify(var msg: TMessage);
var aplayer:TBasicPlayer;
    evCode,param1,param2:integer;
begin
  aplayer:=TBasicPlayer(msg.LParam);
  aplayer.EventObj.GetEvent(evCode,param1,param2,0);
  case evCode of
    EC_COMPLETE:begin
                  Timer1.Enabled:=false;
                  aplayer.Stop;
                  aplayer.Rewind;
                  ProgressBar1.Position:=0;
                  lblProgress.Caption:='0%';
                end;
   EC_FULLSCREEN_LOST:chkbxFullscreen.Checked:=false;
  end;
  aplayer.EventObj.FreeEventParams(evCode,param1,param2);
end;

procedure TfrmMediaPlayer.btnOpenClick(Sender: TObject);
var orgW,orgH:integer;
begin
  if opendialog1.Execute then
  begin
    FMMPlayer.Stop;
    FMMPlayer.Rewind;
    FMMPlayer.RemoveAllFilters;
    ProgressBar1.Position:=0;
    lblProgress.Caption:='0%';

    FMMPlayer.Filename:=opendialog1.FileName;
    FMMPlayer.BuildFilterGraph;
    FDuration:=FMMPlayer.Duration;

    if not FMMPlayer.AudioOnly then
    begin
      //zoom 100%
      FMMPlayer.GetVideoOrgSize(orgW,orgH);
      frmVideo.ClientWidth:=OrgW;
      frmVideo.ClientHeight:=OrgH;
      rdgrpZoom.ItemIndex:=1;
      frmVideo.Show;
    end;
  end;
end;

procedure TfrmMediaPlayer.btnPlayClick(Sender: TObject);

begin
  Timer1.Enabled:=true;
  FMMPlayer.Run;
end;

procedure TfrmMediaPlayer.btnStopClick(Sender: TObject);
begin
  Timer1.Enabled:=false;
  FMMPlayer.Stop;
  FMMPlayer.Rewind;
  ProgressBar1.Position:=0;
  lblProgress.Caption:='0%';
  frmVideo.Hide;
end;

procedure TfrmMediaPlayer.Timer1Timer(Sender: TObject);


begin
  ProgressBar1.Position:=round(FMMPlayer.Position.Current/FDuration*ProgressBar1.Max);
  lblProgress.Caption:=inttostr(ProgressBar1.Position)+'%';
end;

procedure TfrmMediaPlayer.btnPauseClick(Sender: TObject);
begin
  FMMPlayer.Pause;
end;

procedure TfrmMediaPlayer.FormActivate(Sender: TObject);
begin
  FMMPlayer.Control:=frmVideo;
end;

procedure TfrmMediaPlayer.chkbxFullscreenClick(Sender: TObject);
begin
  if chkbxFullscreen.Checked then
  begin
    OldDrain:=FMMPlayer.DrainHandle;
    FMMPlayer.DrainHandle:=Handle;
  end else
    FMMPlayer.DrainHandle:=OldDrain;

  FMMPlayer.FullScreen:=chkbxFullscreen.Checked;
end;

procedure TfrmMediaPlayer.actToggleFullscreenExecute(Sender: TObject);
begin
  chkbxFullscreen.Checked:=not chkbxFullscreen.Checked;
end;

procedure TfrmMediaPlayer.rdgrpZoomClick(Sender: TObject);
var orgW,orgH:integer;
    aspect:single;
begin
  FMMPlayer.GetVideoOrgSize(orgW,orgH);
  if (orgW<>0) and (orgH<>0) then
  begin
    case rdgrpZoom.ItemIndex of
      0:begin
          //zoom 50%
          aspect:=orgW/orgH;
          frmVideo.ClientWidth:=trunc(0.5*OrgW);
          frmVideo.ClientHeight:=trunc(frmVideo.ClientWidth/aspect);
          FMMPlayer.VideoRect:=Rect(0,0,frmVideo.ClientWidth,frmVideo.ClientHeight);
        end;
      1:begin
          //zoom 100%
          frmVideo.ClientWidth:=OrgW;
          frmVideo.ClientHeight:=OrgH;
          FMMPlayer.VideoRect:=Rect(0,0,frmVideo.ClientWidth,frmVideo.ClientHeight);
        end;
      2:begin
          //zoom 50%
          aspect:=orgW/orgH;
          frmVideo.ClientWidth:=trunc(2*OrgW);
          frmVideo.ClientHeight:=trunc(frmVideo.ClientWidth/aspect);
          FMMPlayer.VideoRect:=Rect(0,0,frmVideo.ClientWidth,frmVideo.ClientHeight);
        end;
    end;
  end;
end;

end.

DFM untuk form di atas sebagai berikut:

object frmMediaPlayer: TfrmMediaPlayer
  Left = 192
  Top = 127
  BorderStyle = bsDialog
  Caption = 'Simple MediaPlayer DirectShow'
  ClientHeight = 86
  ClientWidth = 681
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnActivate = FormActivate
  PixelsPerInch = 96
  TextHeight = 13
  object lblProgress: TLabel
    Left = 647
    Top = 16
    Width = 22
    Height = 13
  end
  object btnOpen: TButton
    Left = 16
    Top = 16
    Width = 75
    Height = 25
    Caption = 'Open'
    TabOrder = 0
    OnClick = btnOpenClick
  end
  object btnPlay: TButton
    Left = 96
    Top = 16
    Width = 75
    Height = 25
    Caption = 'Play'
    TabOrder = 1
    OnClick = btnPlayClick
  end
  object btnStop: TButton
    Left = 16
    Top = 48
    Width = 75
    Height = 25
    Caption = 'Stop'
    TabOrder = 2
    OnClick = btnStopClick
  end
  object ProgressBar1: TProgressBar
    Left = 200
    Top = 16
    Width = 441
    Height = 19
    Smooth = True
    TabOrder = 3
  end
  object btnPause: TButton
    Left = 96
    Top = 48
    Width = 75
    Height = 25
    Caption = 'Pause'
    TabOrder = 4
    OnClick = btnPauseClick
  end
  object chkbxFullscreen: TCheckBox
    Left = 192
    Top = 56
    Width = 97
    Height = 17
    Caption = 'Fullscreen'
    TabOrder = 5
    OnClick = chkbxFullscreenClick
  end
  object rdgrpZoom: TRadioGroup
    Left = 288
    Top = 40
    Width = 353
    Height = 33
    Caption = 'Zoom'
    Columns = 3
    ItemIndex = 1
    Items.Strings = (
      '50%'
      '100%'
      '200%')
    TabOrder = 6
    OnClick = rdgrpZoomClick
  end
  object OpenDialog1: TOpenDialog
    Left = 560
    Top = 40
  end
  object Timer1: TTimer
    Enabled = False
    Interval = 1
    OnTimer = Timer1Timer
    Left = 592
    Top = 40
  end
  object ActionList1: TActionList
    Left = 632
    Top = 40
    object actToggleFullscreen: TAction
      Caption = 'actToggleFullscreen'
      ShortCut = 16454
      OnExecute = actToggleFullscreenExecute
    end
  end
end

Form di mana video ditampilkan

unit ufrmVideo;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ActnList,uDirectShowPlayer;

type
  TfrmVideo = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  published
  end;

var
  frmVideo: TfrmVideo;

implementation

{$R *.dfm}

end.

DFM nya sebagai berikut:

object frmVideo: TfrmVideo
  Left = 208
  Top = 194
  BorderStyle = bsDialog
  Caption = 'Video'
  ClientHeight = 442
  ClientWidth = 688
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
end

Download source code tersedia di sini.

Ringkasan

Kita telah mendiskusikan langkah-langkah yang diperlukan untuk menampilkan video di window kita sendiri. Kita juga telah mendiskusikan cara menampilkan video dalam mode fullscreen, membelokkan message-message dan juga bagaimana melakukan zooming ukuran display video sesuai keinginan kita.

Artikel Terkait

Anda suka artikel ini? Bantu website ini berkembang dengan menyumbang. Berapapun jumlahnya akan sangat dihargai.

Atau Anda dapat membantu dengan membuat bookmark. Delicious Bookmark this on Delicious