unit vlcplayer;

{ TIceVLCPlayer  -  VLC Player for Delphi (0.8.6i) (c)2008 by Norbert Mereg    }

interface

{$mode objfpc}{$H+}

uses
  SysUtils, Classes, Controls, ExtCtrls, libVLC, Graphics, Forms
  {$IFDEF LINUX}, gdk2x, gtk2{$ENDIF};

type
  TEVLCException = class(Exception);
  TEVLCNotFound = class(Exception);
  TEVLCLoadLibrary = class(Exception);

  TErrorEvent = procedure(Sender: TObject; ErrorCode: integer; ErrorMessage: string) of object;

  TVLCPlayer = class(TComponent)
  private
    VLC: libvlc_instance;
    VLCVideo: integer;
    VLCInput: libvlc_input;
    VLCError: libvlc_exception;
    FIsPlaying: boolean;

    FVideoWidth: integer;
    FVideoHeight: integer;

    FDrawParent: TPanel;

    procedure StartPlaying;
    procedure StopPlaying;
    procedure StopIfPlaying;
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
    property VideoWidth: integer read FVideoWidth;
    property VideoHeight: integer read FVideoHeight;
    property DrawParent: TPanel read FDrawParent write FDrawParent;

    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure PlayCam(const CaptureDev: string);

    procedure Stop;
  published
    { Published declarations }
  end;

implementation

{ TVLCPlayer }

constructor TVLCPlayer.Create(AOwner: TComponent);
var
  Args: array [0..1] of PChar;

begin
  inherited Create(AOwner);

  VLC := nil;
  VLCInput := nil;
  FIsPlaying := False;

  //Clear error var.
  FillChar(VLCError, SizeOf(VLCError), 0);

  //Create new VLC object
  Args[0] := PChar(libvlc.LibName);
  Args[1] := nil;
  VLC := libvlc_new(1, @Args[0], VLCError);
end;

destructor TVLCPlayer.Destroy;
begin
  // NTDLL.DLL error :(
  //  if Assigned(VLC) then
  //    libvlc_destroy(VLC);

  inherited;
end;

procedure TVLCPlayer.Stop;
begin
  StopIfPlaying;
end;

procedure TVLCPlayer.StopIfPlaying;
begin
  if FIsPlaying then
  begin
    if Assigned(VLCInput) then
    begin
      libvlc_playlist_stop(VLC, VLCError);
    end;
    libvlc_playlist_clear(VLC, VLCError);

    //libvlc_input_free(VLCInput);
    VLCInput := nil;
  end;
end;

procedure TVLCPlayer.PlayCam(const CaptureDev: string);
var
  Args: array[0..1] of PChar;
  DevStr: string;
begin
  StopIfPlaying;

  args[0] := '';
  args[1] := nil;

  DevStr := 'v4l2://' + CaptureDev;
  VLCVideo := libvlc_playlist_add_extended(VLC, PChar(UTF8Encode(DevStr)), '', 1, @Args[0], VLCError);
  VLCInput := libvlc_playlist_get_input(VLC, VLCError);


  StartPlaying;
end;

procedure TVLCPlayer.StopPlaying;
begin
  //Freeing current input
  //libvlc_input_free(VLCInput);
  VLCInput := nil;
end;

procedure TVLCPlayer.StartPlaying;
begin
  //Set current parent (Self)
  {$IFDEF LINUX}
  libvlc_video_set_parent(VLC, GDK_WINDOW_XWINDOW(PGtkWidget(PtrUInt(DrawParent.Handle))^.window), VLCError);
  {$ENDIF}
  {$IFDEF WINDOWS}
  libvlc_video_set_parent(VLC, Application.MainForm.Handle, VLCError);
  {$ENDIF}
  FVideoWidth := libvlc_video_get_width(VLCInput, VLCError);
  FVideoHeight := libvlc_video_get_height(VLCInput, VLCError);
  //Start play
  libvlc_playlist_play(VLC, VLCVideo, 0, nil, VLCError);

end;


end.

