(* ******************************************************************************* * FmxPasLibVlcPlayerUnit.pas - FMX component for VideoLAN libvlc 3.0.5 * * See copyright notice below. * * Last modified: 2019.03.24 * * author: Robert Jędrzejczyk * e-mail: robert@prog.olsztyn.pl * www: http://prog.olsztyn.pl/paslibvlc * * * See FmxPasLibVlcPlayerUnit.txt for change log * ******************************************************************************* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Any non-GPL usage of this software or parts of this software is strictly * forbidden. * * The "appropriate copyright message" mentioned in section 2c of the GPLv2 * must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" * ******************************************************************************* * * libvlc is part of project VideoLAN * * Copyright (c) 1996-2018 VideoLAN Team * * For more information about VideoLAN * * please visit http://www.videolan.org * *) {$I ..\source\compiler.inc} unit FmxPasLibVlcPlayerUnit; {$IFDEF DELPHI_XE7_UP} {$ENDIF} interface uses {$IFDEF UNIX}Unix,{$ENDIF} {$IFDEF MSWINDOWS}Windows,{$ENDIF} Classes, SysUtils, SyncObjs, FMX.Types, FMX.Objects, FMX.Graphics, System.UITypes, PasLibVlcClassUnit, PasLibVlcUnit; type TFmxPasLibVlcPlayerState = ( plvPlayer_NothingSpecial, plvPlayer_Opening, plvPlayer_Buffering, plvPlayer_Playing, plvPlayer_Paused, plvPlayer_Stopped, plvPlayer_Ended, plvPlayer_Error ); type TNotifySeekableChanged = procedure(Sender : TObject; val : Boolean) of object; TNotifyPausableChanged = procedure(Sender : TObject; val : Boolean) of object; TNotifyTitleChanged = procedure(Sender : TObject; title : Integer) of object; TNotifySnapshotTaken = procedure(Sender : TObject; fileName : string) of object; TNotifyTimeChanged = procedure(Sender : TObject; time : Int64) of object; TNotifyLengthChanged = procedure(Sender : TObject; time : Int64) of object; TNotifyPositionChanged = procedure(Sender : TObject; position : Single) of object; TNotifyMediaChanged = procedure(Sender : TObject; mrl : string) of object; TNotifyVideoOutChanged = procedure(Sender : TObject; video_out : Integer) of object; TNotifyScrambledChanged = procedure(Sender : TObject; scrambled : Integer) of object; TNotifyPlayerEvent = procedure(p_event: libvlc_event_t_ptr; data : Pointer) of object; TNotifyAudioVolumeChanged = procedure(Sender : TObject; volume : Single) of object; TNotifyVideoSizeChanged = procedure(Sender : TObject; view_w, video_h, video_w_a32, video_h_a32 : LongWord) of object; TNotifyMediaPlayerEsAdded = procedure(Sender : TObject; i_type : libvlc_track_type_t; i_id : Integer) of object; TNotifyMediaPlayerEsDeleted = procedure(Sender : TObject; i_type : libvlc_track_type_t; i_id : Integer) of object; TNotifyMediaPlayerEsSelected = procedure(Sender : TObject; i_type : libvlc_track_type_t; i_id : Integer) of object; TNotifyMediaPlayerAudioDevice = procedure(Sender : TObject; audio_device : string) of object; TNotifyMediaPlayerChapterChanged = procedure(Sender : TObject; chapter : Integer) of object; TNotifyRendererDiscoveredItemAdded = procedure(Sender : TObject; item : libvlc_renderer_item_t_ptr) of object; TNotifyRendererDiscoveredItemDeleted = procedure(Sender : TObject; item : libvlc_renderer_item_t_ptr) of object; type TFmxPasLibVlcVideoCbCtx = class vctx : TVideoCbCtx; view : FMX.Objects.TImage; frame_buff : Pointer; frame_lock : TCriticalSection; frame_pixel_format : TPixelFormat; public constructor Create(AView : FMX.Objects.TImage; aWidth : Integer = 320; aHeight : Integer = 160); destructor Destroy; override; end; type [ComponentPlatformsAttribute(pidWin32 or pidWin64 or pidOSX32)] // or pidiOSSimulator or pidAndroid or pidLinux32 or pidiOSDevice TFmxPasLibVlcPlayer = class(FMX.Objects.TImage) private FVLC : TPasLibVlc; p_mi : libvlc_media_player_t_ptr; p_mi_ev_mgr : libvlc_event_manager_t_ptr; FVideoCbCtx : TFmxPasLibVlcVideoCbCtx; // FError : string; FMute : Boolean; FAudioOutput : TAudioOutput; FTitleShow : Boolean; FTitleShowPos : TPasLibVlcTitlePosition; FTitleShowTimeOut : LongWord; FSnapshotFmt : string; FSnapshotPrv : Boolean; FSpuShow : Boolean; FOsdShow : Boolean; FViewTeleText : Boolean; FDeinterlaceFilter : TDeinterlaceFilter; FDeinterlaceMode : TDeinterlaceMode; FLastAudioOutput : WideString; FLastAudioOutputDeviceId : WideString; // events handlers FOnMediaPlayerMediaChanged : TNotifyMediaChanged; FOnMediaPlayerNothingSpecial : TNotifyEvent; FOnMediaPlayerOpening : TNotifyEvent; FOnMediaPlayerBuffering : TNotifyEvent; FOnMediaPlayerPlaying : TNotifyEvent; FOnMediaPlayerPaused : TNotifyEvent; FOnMediaPlayerStopped : TNotifyEvent; FOnMediaPlayerForward : TNotifyEvent; FOnMediaPlayerBackward : TNotifyEvent; FOnMediaPlayerEndReached : TNotifyEvent; FOnMediaPlayerEncounteredError : TNotifyEvent; FOnMediaPlayerTimeChanged : TNotifyTimeChanged; FOnMediaPlayerPositionChanged : TNotifyPositionChanged; FOnMediaPlayerSeekableChanged : TNotifySeekableChanged; FOnMediaPlayerPausableChanged : TNotifyPausableChanged; FOnMediaPlayerTitleChanged : TNotifyTitleChanged; FOnMediaPlayerSnapshotTaken : TNotifySnapshotTaken; FOnMediaPlayerLengthChanged : TNotifyLengthChanged; FOnMediaPlayerVideoOutChanged : TNotifyVideoOutChanged; FOnMediaPlayerScrambledChanged : TNotifyScrambledChanged; FOnMediaPlayerEvent : TNotifyPlayerEvent; FOnMediaPlayerCorked : TNotifyEvent; FOnMediaPlayerUnCorked : TNotifyEvent; FOnMediaPlayerMuted : TNotifyEvent; FOnMediaPlayerUnMuted : TNotifyEvent; FOnMediaPlayerAudioVolumeChanged : TNotifyAudioVolumeChanged; FOnMediaPlayerVideoSizeChanged : TNotifyVideoSizeChanged; FOnMediaPlayerEsAdded : TNotifyMediaPlayerEsAdded; FOnMediaPlayerEsDeleted : TNotifyMediaPlayerEsDeleted; FOnMediaPlayerEsSelected : TNotifyMediaPlayerEsSelected; FOnMediaPlayerAudioDevice : TNotifyMediaPlayerAudioDevice; FOnMediaPlayerChapterChanged : TNotifyMediaPlayerChapterChanged; FOnRendererDiscoveredItemAdded : TNotifyRendererDiscoveredItemAdded; FOnRendererDiscoveredItemDeleted : TNotifyRendererDiscoveredItemDeleted; FUseEvents : boolean; FStartOptions : TStringList; function GetVlcInstance() : TPasLibVlc; procedure SetStartOptions(Value: TStringList); procedure SetSnapshotFmt(aFormat: string); procedure SetSnapshotPrv(aValue : Boolean); procedure SetSpuShow(aValue: Boolean); procedure SetOsdShow(aValue: Boolean); procedure SetViewTeleText(aValue : Boolean); procedure SetTitleShow(aValue: Boolean); procedure SetTitleShowPos(aValue: TPasLibVlcTitlePosition); procedure SetTitleShowTimeOut(aValue: LongWord); procedure SetDeinterlaceFilter(aValue: TDeinterlaceFilter); procedure SetDeinterlaceMode(aValue: TDeinterlaceMode); function GetDeinterlaceModeName(): WideString; procedure InternalHandleEvent_MediaChanged(p_md : libvlc_media_t_ptr); procedure InternalHandleEvent_NothingSpecial(); procedure InternalHandleEvent_Opening(); procedure InternalHandleEvent_Buffering(); procedure InternalHandleEvent_Playing(); procedure InternalHandleEvent_Paused(); procedure InternalHandleEvent_Stopped(); procedure InternalHandleEvent_Forward(); procedure InternalHandleEvent_Backward(); procedure InternalHandleEvent_EndReached(); procedure InternalHandleEvent_EncounteredError(); procedure InternalHandleEvent_TimeChanged(new_time : libvlc_time_t); procedure InternalHandleEvent_PositionChanged(new_position : Single); procedure InternalHandleEvent_SeekableChanged(new_seekable : Integer); procedure InternalHandleEvent_PausableChanged(new_pausable : Integer); procedure InternalHandleEvent_TitleChanged(new_title : Integer); procedure InternalHandleEvent_SnapshotTaken(psz_filename : PAnsiChar); procedure InternalHandleEvent_LengthChanged(new_length : libvlc_time_t); procedure InternalHandleEvent_VOutChanged(new_count : Integer); procedure InternalHandleEvent_ScrambledChanged(new_scrambled : Integer); procedure InternalHandleEvent_Corked(); procedure InternalHandleEvent_UnCorked(); procedure InternalHandleEvent_Muted(); procedure InternalHandleEvent_UnMuted(); procedure InternalHandleEvent_AudioVolumeChanged(volume : Single); procedure InternalHandleEvent_VideoSizeChanged(video_w, video_h, video_w_a32, video_h_a32 : LongWord); procedure InternalHandleEvent_MediaPlayerEsAdded (i_type : libvlc_track_type_t; i_id : Integer); procedure InternalHandleEvent_MediaPlayerEsDeleted (i_type : libvlc_track_type_t; i_id : Integer); procedure InternalHandleEvent_MediaPlayerEsSelected (i_type : libvlc_track_type_t; i_id : Integer); procedure InternalHandleEvent_MediaPlayerAudioDevice (audio_device : PAnsiChar); procedure InternalHandleEvent_MediaPlayerChapterChanged (chapter : Integer); procedure InternalHandleEvent_RendererDiscoveredItemAdded (item : libvlc_renderer_item_t_ptr); procedure InternalHandleEvent_RendererDiscoveredItemDeleted(item : libvlc_renderer_item_t_ptr); protected procedure DestroyPlayer(); procedure Paint; override; procedure PlayContinue(audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); overload; procedure PlayContinue(mediaOptions : array of WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); overload; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function GetPlayerHandle(): libvlc_media_player_t_ptr; procedure Play (var media : TPasLibVlcMedia; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); overload; procedure Play (mrl : WideString; mediaOptions : array of WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); overload; procedure Play (stm : TStream; mediaOptions : array of WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); overload; procedure PlayNormal (mrl : WideString; mediaOptions : array of WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); overload; procedure PlayYoutube(mrl : WideString; mediaOptions : array of WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000; youtubeTimeout : Cardinal = 10000); overload; procedure Play (mrl : WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); overload; procedure Play (stm : TStream; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); overload; procedure PlayNormal (mrl : WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); overload; procedure PlayYoutube(mrl : WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000; youtubeTimeout : Cardinal = 10000); overload; function GetMediaMrl(): string; procedure Pause(); procedure Resume(); function IsPlay(): Boolean; function IsPause(): Boolean; procedure Stop(const stopTimeOut : Cardinal = 1000); function GetState(): TFmxPasLibVlcPlayerState; function GetStateName(): string; function CanPlay(): Boolean; function CanPause(): Boolean; function CanSeek(): Boolean; function HasVout() : Boolean; function IsScrambled() : Boolean; function Snapshot(fileName: WideString): Boolean; overload; function Snapshot(fileName: WideString; width, height: LongWord): Boolean; overload; procedure NextFrame(); procedure SetPlayRate(rate: Integer); function GetPlayRate(): Integer; function GetVideoWidth(): LongInt; function GetVideoHeight(): LongInt; function GetVideoDimension(var width, height: LongWord) : Boolean; function GetVideoScaleInPercent(): Single; function GetVideoAspectRatio(): string; function GetVideoSampleAspectRatio(var sar_num, sar_den : Longword): Boolean; overload; function GetVideoSampleAspectRatio(): Single; overload; procedure SetVideoScaleInPercent(newScaleInPercent: Single); procedure SetVideoAspectRatio(newAspectRatio: string); function GetVideoLenInMs(): Int64; function GetVideoPosInMs(): Int64; function GetVideoPosInPercent(): Single; function GetVideoFps(): Single; procedure SetVideoPosInMs(newPos: Int64); procedure SetVideoPosInPercent(newPos: Single); function GetVideoLenStr(fmt: string = 'hh:mm:ss'): string; function GetVideoPosStr(fmt: string = 'hh:mm:ss'): string; procedure SetTeleText(page: Integer); function GetTeleText() : Integer; function ShowTeleText() : Boolean; function HideTeleText() : Boolean; function GetAudioMute(): Boolean; procedure SetAudioMute(mute: Boolean); function GetAudioVolume(): Integer; procedure SetAudioVolume(volumeLevel: Integer); function GetAudioChannel(): libvlc_audio_output_channel_t; procedure SetAudioChannel(chanel: libvlc_audio_output_channel_t); function GetAudioDelay(): Int64; procedure SetAudioDelay(delay: Int64); function GetAudioFilterList(return_name_type : Integer = 0): TStringList; function GetVideoFilterList(return_name_type : Integer = 0): TStringList; function GetAudioTrackList(): TStringList; function GetAudioTrackCount(): Integer; function GetAudioTrackId(): Integer; procedure SetAudioTrackById(const track_id : Integer); function GetAudioTrackNo(): Integer; procedure SetAudioTrackByNo(track_no : Integer); function GetAudioTrackDescriptionById(const track_id : Integer): WideString; function GetAudioTrackDescriptionByNo(track_no : Integer): WideString; function GetAudioOutputList(withDescription : Boolean = FALSE; separator : string = '|'): TStringList; function GetAudioOutputDeviceList(aOut : WideString; withDescription : Boolean = FALSE; separator : string = '|'): TStringList; function GetAudioOutputDeviceEnum(withDescription : Boolean = FALSE; separator : string = '|') : TStringList; function SetAudioOutput(aOut: WideString) : Boolean; procedure SetAudioOutputDevice(aOut: WideString; aOutDeviceId: WideString); overload; procedure SetAudioOutputDevice(aOutDeviceId: WideString); overload; {$IFDEF USE_VLC_DEPRECATED_API} function GetAudioOutputDeviceCount(aOut: WideString): Integer; function GetAudioOutputDeviceId(aOut: WideString; deviceIdx : Integer) : WideString; function GetAudioOutputDeviceName(aOut: WideString; deviceIdx : Integer): WideString; {$ENDIF} function EqualizerGetPresetList(): TStringList; function EqualizerGetBandCount(): unsigned_t; function EqualizerGetBandFrequency(bandIndex : unsigned_t): Single; function EqualizerCreate(APreset : unsigned_t = $FFFF) : TPasLibVlcEqualizer; procedure EqualizerApply(AEqualizer : TPasLibVlcEqualizer); procedure EqualizerSetPreset(APreset : unsigned_t = $FFFF); procedure SetVideoAdjustEnable(value : Boolean); function GetVideoAdjustEnable(): Boolean; procedure SetVideoAdjustContrast(value : Single = 1); function GetVideoAdjustContrast(): Single; procedure SetVideoAdjustBrightness(value : Single = 1); function GetVideoAdjustBrightness(): Single; procedure SetVideoAdjustHue(value : Integer = 0); function GetVideoAdjustHue(): Integer; procedure SetVideoAdjustSaturation(value : Single = 1); function GetVideoAdjustSaturation(): Single; procedure SetVideoAdjustGamma(value : Single = 1); function GetVideoAdjustGamma(): Single; function GetVideoChapter(): Integer; procedure SetVideoChapter(newChapter: Integer); function GetVideoChapterCount(): Integer; function GetVideoChapterCountByTitleId(const title_id : Integer): Integer; function GetVideoSubtitleList(): TStringList; function GetVideoSubtitleCount(): Integer; function GetVideoSubtitleId(): Integer; procedure SetVideoSubtitleById(const subtitle_id : Integer); function GetVideoSubtitleNo(): Integer; procedure SetVideoSubtitleByNo(subtitle_no : Integer); function GetVideoSubtitleDescriptionById(const subtitle_id : Integer): WideString; function GetVideoSubtitleDescriptionByNo(subtitle_no : Integer): WideString; procedure SetVideoSubtitleFile(subtitle_file : WideString); function GetVideoTitleList() : TStringList; function GetVideoTitleCount(): Integer; function GetVideoTitleId():Integer; procedure SetVideoTitleById(const title_id:Integer); function GetVideoTitleNo(): Integer; procedure SetVideoTitleByNo(title_no : Integer); function GetVideoTitleDescriptionById(const track_id : Integer): WideString; function GetVideoTitleDescriptionByNo(title_no : Integer): WideString; // https://wiki.videolan.org/Documentation:Modules/logo/ procedure LogoSetFile(file_name : WideString); procedure LogoSetFiles(file_names : array of WideString; delay_ms : Integer = 1000; loop : Boolean = TRUE); procedure LogoSetPosition(position_x, position_y : Integer); overload; procedure LogoSetPosition(position : libvlc_position_t); overload; procedure LogoSetOpacity(opacity : libvlc_opacity_t); procedure LogoSetDelay(delay_ms : Integer = 1000); // delay before show next logo file, default 1000 procedure LogoSetRepeat(loop : boolean = TRUE); procedure LogoSetEnable(enable : Integer); procedure LogoShowFile(file_name : WideString; position_x, position_y : Integer; opacity: libvlc_opacity_t = libvlc_opacity_full); overload; procedure LogoShowFile(file_name : WideString; position: libvlc_position_t = libvlc_position_top; opacity: libvlc_opacity_t = libvlc_opacity_full); overload; procedure LogoShowFiles(file_names : array of WideString; position_x, position_y : Integer; opacity: libvlc_opacity_t = libvlc_opacity_full; delay_ms : Integer = 1000; loop : Boolean = TRUE); overload; procedure LogoShowFiles(file_names : array of WideString; position: libvlc_position_t = libvlc_position_top; opacity: libvlc_opacity_t = libvlc_opacity_full; delay_ms : Integer = 1000; loop : Boolean = TRUE); overload; procedure LogoHide(); // https://wiki.videolan.org/Documentation:Modules/marq/ procedure MarqueeSetText(marquee_text : WideString); procedure MarqueeSetPosition(position_x, position_y : Integer); overload; procedure MarqueeSetPosition(position : libvlc_position_t); overload; procedure MarqueeSetColor(color : libvlc_video_marquee_color_t); procedure MarqueeSetFontSize(font_size: Integer); procedure MarqueeSetOpacity(opacity: libvlc_opacity_t); procedure MarqueeSetTimeOut(time_out_ms: Integer); procedure MarqueeSetRefresh(refresh_after_ms: Integer); procedure MarqueeSetEnable(enable : Integer); procedure MarqueeShowText(marquee_text : WideString; position_x, position_y : Integer; color : libvlc_video_marquee_color_t = libvlc_video_marquee_color_White; font_size: Integer = libvlc_video_marquee_default_font_size; opacity: libvlc_opacity_t = libvlc_opacity_full; time_out_ms: Integer = 0); overload; procedure MarqueeShowText(marquee_text : WideString; position : libvlc_position_t = libvlc_position_bottom; color : libvlc_video_marquee_color_t = libvlc_video_marquee_color_White; font_size: Integer = libvlc_video_marquee_default_font_size; opacity: libvlc_opacity_t = libvlc_opacity_full; time_out_ms: Integer = 0); overload; procedure MarqueeHide(); procedure EventsDisable(); procedure EventsEnable(); procedure UpdateDeInterlace(); procedure UpdateTitleShow(); property VLC : TPasLibVlc read GetVlcInstance; published property Align; property PopupMenu; property ShowHint; property Visible; property OnClick; property OnDblClick; property OnDragDrop; property OnDragOver; property OnEnter; property OnExit; property OnMouseDown; property OnMouseEnter; property OnMouseLeave; property OnMouseMove; property OnMouseUp; property OnResize; property SpuShow : Boolean read FSpuShow write SetSpuShow default TRUE; property OsdShow : Boolean read FOsdShow write SetOsdShow default TRUE; property TitleShow : Boolean read FTitleShow write SetTitleShow default FALSE; property TitleShowPos : TPasLibVlcTitlePosition read FTitleShowPos write SetTitleShowPos default plvPosCenter; property TitleShowTimeOut : LongWord read FTitleShowTimeOut write SetTitleShowTimeOut default 2000; property AudioOutput : TAudioOutput read FAudioOutput write FAudioOutput default aoDefault; property SnapShotFmt : string read FSnapShotFmt write SetSnapshotFmt; property SnapshotPrv : Boolean read FSnapShotPrv write SetSnapshotPrv default FALSE; property DeinterlaceFilter : TDeinterlaceFilter read FDeinterlaceFilter write SetDeinterlaceFilter default deOFF; property DeinterlaceModeName: WideString read GetDeinterlaceModeName; property DeinterlaceMode : TDeinterlaceMode read FDeinterlaceMode write SetDeinterlaceMode default dmDISCARD; property ViewTeletext : Boolean read FViewTeleText write SetViewTeleText default FALSE; property LastError: string read FError write FError; property StartOptions : TStringList read FStartOptions write SetStartOptions; property OnMediaPlayerEvent : TNotifyPlayerEvent read FOnMediaPlayerEvent write FOnMediaPlayerEvent; property OnMediaPlayerMediaChanged : TNotifyMediaChanged read FOnMediaPlayerMediaChanged write FOnMediaPlayerMediaChanged; property OnMediaPlayerNothingSpecial : TNotifyEvent read FOnMediaPlayerNothingSpecial write FOnMediaPlayerNothingSpecial; property OnMediaPlayerOpening : TNotifyEvent read FOnMediaPlayerOpening write FOnMediaPlayerOpening; property OnMediaPlayerBuffering : TNotifyEvent read FOnMediaPlayerBuffering write FOnMediaPlayerBuffering; property OnMediaPlayerPlaying : TNotifyEvent read FOnMediaPlayerPlaying write FOnMediaPlayerPlaying; property OnMediaPlayerPaused : TNotifyEvent read FOnMediaPlayerPaused write FOnMediaPlayerPaused; property OnMediaPlayerStopped : TNotifyEvent read FOnMediaPlayerStopped write FOnMediaPlayerStopped; property OnMediaPlayerForward : TNotifyEvent read FOnMediaPlayerForward write FOnMediaPlayerForward; property OnMediaPlayerBackward : TNotifyEvent read FOnMediaPlayerBackward write FOnMediaPlayerBackward; property OnMediaPlayerEndReached : TNotifyEvent read FOnMediaPlayerEndReached write FOnMediaPlayerEndReached; property OnMediaPlayerEncounteredError : TNotifyEvent read FOnMediaPlayerEncounteredError write FOnMediaPlayerEncounteredError; property OnMediaPlayerTimeChanged : TNotifyTimeChanged read FOnMediaPlayerTimeChanged write FOnMediaPlayerTimeChanged; property OnMediaPlayerPositionChanged : TNotifyPositionChanged read FOnMediaPlayerPositionChanged write FOnMediaPlayerPositionChanged; property OnMediaPlayerSeekableChanged : TNotifySeekableChanged read FOnMediaPlayerSeekableChanged write FOnMediaPlayerSeekableChanged; property OnMediaPlayerPausableChanged : TNotifyPausableChanged read FOnMediaPlayerPausableChanged write FOnMediaPlayerPausableChanged; property OnMediaPlayerTitleChanged : TNotifyTitleChanged read FOnMediaPlayerTitleChanged write FOnMediaPlayerTitleChanged; property OnMediaPlayerSnapshotTaken : TNotifySnapshotTaken read FOnMediaPlayerSnapshotTaken write FOnMediaPlayerSnapshotTaken; property OnMediaPlayerLengthChanged : TNotifyLengthChanged read FOnMediaPlayerLengthChanged write FOnMediaPlayerLengthChanged; property OnMediaPlayerVideoOutChanged : TNotifyVideoOutChanged read FOnMediaPlayerVideoOutChanged write FOnMediaPlayerVideoOutChanged; property OnMediaPlayerScrambledChanged : TNotifyScrambledChanged read FOnMediaPlayerScrambledChanged write FOnMediaPlayerScrambledChanged; property OnMediaPlayerCorked : TNotifyEvent read FOnMediaPlayerCorked write FOnMediaPlayerCorked; property OnMediaPlayerUnCorked : TNotifyEvent read FOnMediaPlayerUnCorked write FOnMediaPlayerUnCorked; property OnMediaPlayerMuted : TNotifyEvent read FOnMediaPlayerMuted write FOnMediaPlayerMuted; property OnMediaPlayerUnMuted : TNotifyEvent read FOnMediaPlayerUnMuted write FOnMediaPlayerUnMuted; property OnMediaPlayerAudioVolumeChanged : TNotifyAudioVolumeChanged read FOnMediaPlayerAudioVolumeChanged write FOnMediaPlayerAudioVolumeChanged; property OnMediaPlayerVideoSizeChanged : TNotifyVideoSizeChanged read FOnMediaPlayerVideoSizeChanged write FOnMediaPlayerVideoSizeChanged; property OnMediaPlayerEsAdded : TNotifyMediaPlayerEsAdded read FOnMediaPlayerEsAdded write FOnMediaPlayerEsAdded; property OnMediaPlayerEsDeleted : TNotifyMediaPlayerEsDeleted read FOnMediaPlayerEsDeleted write FOnMediaPlayerEsDeleted; property OnMediaPlayerEsSelected : TNotifyMediaPlayerEsSelected read FOnMediaPlayerEsSelected write FOnMediaPlayerEsSelected; property OnMediaPlayerAudioDevice : TNotifyMediaPlayerAudioDevice read FOnMediaPlayerAudioDevice write FOnMediaPlayerAudioDevice; property OnMediaPlayerChapterChanged : TNotifyMediaPlayerChapterChanged read FOnMediaPlayerChapterChanged write FOnMediaPlayerChapterChanged; property OnRendererDiscoveredItemAdded : TNotifyRendererDiscoveredItemAdded read FOnRendererDiscoveredItemAdded write FOnRendererDiscoveredItemAdded; property OnRendererDiscoveredItemDeleted : TNotifyRendererDiscoveredItemDeleted read FOnRendererDiscoveredItemDeleted write FOnRendererDiscoveredItemDeleted; property UseEvents : boolean read FUseEvents write FUseEvents default TRUE; property LastAudioOutput : WideString read FLastAudioOutput; property LastAudioOutputDeviceId : WideString read FLastAudioOutputDeviceId; end; procedure Register; implementation {$R *.RES} {$IFDEF DELPHI_XE6_UP} uses System.AnsiStrings; {$ENDIF} procedure Register; begin RegisterComponents('FmxPasLibVlc', [TFmxPasLibVlcPlayer]); end; //////////////////////////////////////////////////////////////////////////////// procedure fmx_lib_vlc_player_event_hdlr(p_event: libvlc_event_t_ptr; data: Pointer); cdecl; forward; function fmx_libvlc_video_lock_cb(ptr : Pointer; planes : PVCBPlanes) : Pointer; cdecl; forward; procedure fmx_libvlc_video_unlock_cb(ptr : Pointer; picture : Pointer; planes : PVCBPlanes); cdecl; forward; procedure fmx_libvlc_video_display_cb(ptr : Pointer; picture : Pointer); cdecl; forward; function fmx_libvlc_video_format_cb(var ptr : Pointer; chroma : PAnsiChar; var width : LongWord; var height : LongWord; pitches : PVCBPitches; lines : PVCBLines) : LongWord; cdecl; forward; procedure fmx_libvlc_video_cleanup_cb(ptr : Pointer); cdecl; forward; //////////////////////////////////////////////////////////////////////////////// constructor TFmxPasLibVlcPlayer.Create(AOwner: TComponent); begin inherited Create(AOwner); Width := 320; Height := 240; FAudioOutput := aoDefault; FLastAudioOutput := ''; FLastAudioOutputDeviceId := ''; FTitleShow := FALSE; FTitleShowPos := plvPosCenter; FTitleShowTimeOut := 2000; FSnapshotFmt := 'png'; FSnapShotPrv := FALSE; FSpuShow := TRUE; FOsdShow := TRUE; FViewTeleText := FALSE; p_mi := NIL; p_mi_ev_mgr := NIL; FMute := FALSE; FVLC := NIL; p_mi := NIL; FUseEvents := TRUE; FStartOptions := TStringList.Create; FVideoCbCtx := TFmxPasLibVlcVideoCbCtx.Create(SELF); // if (csDesigning in ComponentState) then exit; end; procedure TFmxPasLibVlcPlayer.DestroyPlayer(); begin EventsDisable(); Sleep(50); if (p_mi <> NIL) then begin libvlc_video_set_callbacks(p_mi, NIL, NIL, NIL, NIL); libvlc_video_set_format_callbacks(p_mi, NIL, NIL); Stop(); libvlc_media_player_release(p_mi); p_mi := NIL; end; Sleep(50); end; destructor TFmxPasLibVlcPlayer.Destroy; begin DestroyPlayer(); if Assigned(FVLC) then begin FreeAndNil(FVLC); end; FreeAndNil(FVideoCbCtx); FreeAndNil(FStartOptions); inherited Destroy; end; procedure TFmxPasLibVlcPlayer.EventsEnable(); begin EventsDisable(); if (p_mi <> NIL) then begin p_mi_ev_mgr := libvlc_media_player_event_manager(p_mi); if Assigned(p_mi_ev_mgr) then begin libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerMediaChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerNothingSpecial, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerOpening, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerBuffering, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerPlaying, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerPaused, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerStopped, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerForward, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerBackward, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerEndReached, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerEncounteredError, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerTimeChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerPositionChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerSeekableChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerPausableChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerTitleChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerSnapshotTaken, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerLengthChanged, fmx_lib_vlc_player_event_hdlr, SELF); // availiable from 2.2.0 libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerVout, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerScrambledChanged, fmx_lib_vlc_player_event_hdlr, SELF); // availiable from 2.2.2 libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerCorked, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerUncorked, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerMuted, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerUnmuted, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerAudioVolume, fmx_lib_vlc_player_event_hdlr, SELF); // availiable from 3.0.0 libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerESAdded, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerESDeleted, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerESSelected, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerAudioDevice, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_MediaPlayerChapterChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_RendererDiscovererItemAdded, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_attach(p_mi_ev_mgr, libvlc_RendererDiscovererItemDeleted, fmx_lib_vlc_player_event_hdlr, SELF); end; end; end; procedure TFmxPasLibVlcPlayer.EventsDisable(); begin if Assigned(p_mi_ev_mgr) then begin libvlc_event_detach(p_mi_ev_mgr, libvlc_RendererDiscovererItemDeleted, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_RendererDiscovererItemAdded, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerChapterChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerAudioDevice, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerESSelected, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerESDeleted, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerESAdded, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerAudioVolume, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerUnmuted, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerMuted, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerUncorked, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerCorked, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerScrambledChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerVout, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerLengthChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerSnapshotTaken, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerTitleChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerPausableChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerSeekableChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerPositionChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerTimeChanged, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerEncounteredError, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerEndReached, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerBackward, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerForward, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerStopped, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerPaused, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerPlaying, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerBuffering, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerOpening, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerNothingSpecial, fmx_lib_vlc_player_event_hdlr, SELF); libvlc_event_detach(p_mi_ev_mgr, libvlc_MediaPlayerMediaChanged, fmx_lib_vlc_player_event_hdlr, SELF); p_mi_ev_mgr := NIL; end; end; procedure TFmxPasLibVlcPlayer.SetSnapshotFmt(aFormat: string); begin FSnapShotFmt := 'png'; aFormat := AnsiLowerCase(aFormat); if ((aFormat = 'png') or (aFormat = 'jpg')) then begin FSnapShotFmt := aFormat; end; end; procedure TFmxPasLibVlcPlayer.SetSnapshotPrv(aValue: Boolean); begin if (FSnapshotPrv <> aValue) then begin FSnapshotPrv := aValue; end; end; procedure TFmxPasLibVlcPlayer.SetSpuShow(aValue: Boolean); begin if (FSpuShow <> aValue) then begin FSpuShow := aValue; end; end; procedure TFmxPasLibVlcPlayer.SetOsdShow(aValue: Boolean); begin if (FOsdShow <> aValue) then begin FOsdShow := aValue; end; end; procedure TFmxPasLibVlcPlayer.UpdateTitleShow(); begin if (p_mi <> NIL) and (VLC.VersionBin >= $020100) then begin if FTitleShow then begin case FTitleShowPos of plvPosCenter: libvlc_media_player_set_video_title_display(p_mi, libvlc_position_center, FTitleShowTimeOut); plvPosLeft: libvlc_media_player_set_video_title_display(p_mi, libvlc_position_left, FTitleShowTimeOut); plvPosRight: libvlc_media_player_set_video_title_display(p_mi, libvlc_position_right, FTitleShowTimeOut); plvPosTop: libvlc_media_player_set_video_title_display(p_mi, libvlc_position_top, FTitleShowTimeOut); plvPosTopLeft: libvlc_media_player_set_video_title_display(p_mi, libvlc_position_top_left, FTitleShowTimeOut); plvPosTopRight: libvlc_media_player_set_video_title_display(p_mi, libvlc_position_top_right, FTitleShowTimeOut); plvPosBottom: libvlc_media_player_set_video_title_display(p_mi, libvlc_position_bottom, FTitleShowTimeOut); plvPosBottomLeft: libvlc_media_player_set_video_title_display(p_mi, libvlc_position_bottom_left, FTitleShowTimeOut); plvPosBottomRight: libvlc_media_player_set_video_title_display(p_mi, libvlc_position_bottom_right, FTitleShowTimeOut); end; end else begin libvlc_media_player_set_video_title_display(p_mi, libvlc_position_disable, FTitleShowTimeOut); end; end; end; procedure TFmxPasLibVlcPlayer.SetTitleShow(aValue: Boolean); begin if (FTitleShow <> aValue) then begin FTitleShow := aValue; UpdateTitleShow(); end; end; procedure TFmxPasLibVlcPlayer.SetTitleShowPos(aValue: TPasLibVlcTitlePosition); begin if (FTitleShowPos <> aValue) then begin FTitleShowPos := aValue; UpdateTitleShow(); end; end; procedure TFmxPasLibVlcPlayer.SetTitleShowTimeOut(aValue: LongWord); begin if (FTitleShowTimeOut <> aValue) then begin FTitleShowTimeOut := aValue; UpdateTitleShow(); end; end; procedure TFmxPasLibVlcPlayer.SetViewTeleText(aValue : Boolean); begin if (FViewTeleText <> aValue) then begin if aValue then ShowTeleText() else HideTeleText(); end; end; procedure TFmxPasLibVlcPlayer.UpdateDeInterlace(); var dm: string; begin if (p_mi = NIL) then exit; if (FDeinterlaceFilter = deON) then begin dm := vlcDeinterlaceModeNames[FDeinterlaceMode]; end else begin dm := ''; end; if (dm <> '') then begin libvlc_video_set_deinterlace(p_mi, PAnsiChar(Utf8Encode(dm))); end else begin libvlc_video_set_deinterlace(p_mi, NIL); end; end; function TFmxPasLibVlcPlayer.GetDeinterlaceModeName(): WideString; begin Result := vlcDeinterlaceModeNames[FDeinterlaceMode]; end; procedure TFmxPasLibVlcPlayer.SetDeinterlaceFilter(aValue: TDeinterlaceFilter); begin if (FDeinterlaceFilter <> aValue) then begin FDeinterlaceFilter := aValue; UpdateDeInterlace(); end; end; procedure TFmxPasLibVlcPlayer.SetDeinterlaceMode(aValue: TDeinterlaceMode); begin if (FDeinterlaceMode <> aValue) then begin FDeinterlaceMode := aValue; UpdateDeInterlace(); end; end; function TFmxPasLibVlcPlayer.GetVlcInstance() : TPasLibVlc; var oIdx : Integer; begin if not Assigned(FVLC) then begin FVLC := TPasLibVlc.Create; for oIdx := 0 to FStartOptions.Count - 1 do begin FVLC.AddOption(FStartOptions.Strings[oIdx]); end; FVLC.AddOption('--drop-late-frames'); // for versions before 2.1.0 FVLC.TitleShow := FTitleShow; if not FSpuShow then FVLC.AddOption('--no-spu') else FVLC.AddOption('--spu'); if not FOsdShow then FVLC.AddOption('--no-osd') else FVLC.AddOption('--osd'); if not FSnapshotPrv then FVLC.AddOption('--no-snapshot-preview') else FVLC.AddOption('--snapshot-preview'); if (FAudioOutput <> aoDefault) then FVLC.AddOption('--aout=' + vlcAudioOutputNames[FAudioOutput]); end; Result := FVLC; end; procedure TFmxPasLibVlcPlayer.SetStartOptions(Value: TStringList); begin FStartOptions.Assign(Value); end; function TFmxPasLibVlcPlayer.GetPlayerHandle(): libvlc_media_player_t_ptr; var p_instance : libvlc_instance_t_ptr; begin if (p_mi = NIL) then begin // get instance p_instance := VLC.Handle; if (p_instance <> NIL) then begin // create media player p_mi := libvlc_media_player_new(p_instance); // handling mouse events by vlc ??? if (p_mi <> NIL) then begin // libvlc_video_set_mouse_input(p_mi, 1); // libvlc_video_set_key_input(p_mi, 1); libvlc_video_set_callbacks( p_mi, fmx_libvlc_video_lock_cb, fmx_libvlc_video_unlock_cb, fmx_libvlc_video_display_cb, Pointer(FVideoCbCtx) ); libvlc_video_set_format_callbacks( p_mi, fmx_libvlc_video_format_cb, fmx_libvlc_video_cleanup_cb ); end; // libvlc_video_set_format(p_mi, 'RV32', 640, 480, 640 * 4); // // with context do // begin // video_w := 640; // video_h := 480; // pitch_w := video_w * FMX.Types.PixelFormatBytes[TPixelFormat.BGRA]; // // (* // * Furthermore, we recommend that pitches and lines be multiple of 32 // * to not break assumption that might be made by various optimizations // * in the video decoders, video filters and/or video converters. // *) // video_w_a32 := (((640 + 31) shr 5) shl 5); // video_h_a32 := (((640 + 31) shr 5) shl 5); // pitch_w_a32 := video_w_a32 * FMX.Types.PixelFormatBytes[TPixelFormat.BGRA]; // // if (buff <> NIL) then // begin // FreeMem(buff); // buff_size := 0; // end; // buff_size := video_w_a32 * pitch_w_a32 + 32; // GetMem(buff, buff_size); // buff_a32 := Pointer(((NativeInt(buff) + 31) shr 5) shl 5); // // bmpi.SetSize(640, 480); // // (view as TFmxPasLibVlcPlayer).Bitmap.Assign(bmpi); // end; end; end; UpdateTitleShow(); if FUseEvents then begin EventsEnable(); end; Result := p_mi; end; function GetToSep(var str : WideString; sep : WideString) : WideString; var p : Integer; begin p := Pos(sep, str); if (p > 0) then begin Result := Copy(str, 1, p - 1); Delete(str, 1, p - 1 + Length(sep)); end else begin Result := str; str := ''; end; end; procedure TFmxPasLibVlcPlayer.Play(var media : TPasLibVlcMedia; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); begin // assign media to player libvlc_media_player_set_media(p_mi, media.MD); // play libvlc_media_player_play(p_mi); // release media media.Free; media := NIL; UpdateTitleShow(); if ((audioOutput <> '') or (audioOutputDeviceId <> '')) then begin while (libvlc_media_player_is_playing(p_mi) = 0) do begin Sleep(10); if (audioSetTimeOut < 10) then break; Dec(audioSetTimeOut, 10); end; SetAudioOutputDevice(audioOutput, audioOutputDeviceId); end else if ((FLastAudioOutput <> '') or (FLastAudioOutputDeviceId <> '')) then begin while (libvlc_media_player_is_playing(p_mi) = 0) do begin Sleep(10); if (audioSetTimeOut < 10) then break; Dec(audioSetTimeOut, 10); end; SetAudioOutputDevice(FLastAudioOutput, FLastAudioOutputDeviceId); end; FMute := FALSE; end; (* * mrl - media resource location * * This can be file: c:\movie.avi * ulr: http://host/movie.avi * rtp: rstp://host/movie *) procedure TFmxPasLibVlcPlayer.Play(mrl : WideString; mediaOptions : array of WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); var lcMRL : WideString; proto : WideString; host : WideString; begin lcMRL := Trim(LowerCase(mrl)); // get media protocol, http, rtp, file, etc. proto := GetToSep(lcMRL, '://'); if (proto = 'http') or (proto = 'https') then begin host := GetToSep(lcMRL, '/'); if (host = 'youtube.com') or (host = 'www.youtube.com') then begin PlayYoutube(mrl, mediaOptions, audioOutput, audioOutputDeviceId); exit; end; end; PlayNormal(mrl, mediaOptions, audioOutput, audioOutputDeviceId, audioSetTimeOut); end; procedure TFmxPasLibVlcPlayer.Play(stm : TStream; mediaOptions : array of WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); var media : TPasLibVlcMedia; mediaOptionIdx : Integer; begin GetPlayerHandle(); if (p_mi = NIL) then exit; Stop(); // create media media := TPasLibVlcMedia.Create(VLC, stm); media.SetDeinterlaceFilter(FDeinterlaceFilter); media.SetDeinterlaceFilterMode(FDeinterlaceMode); for mediaOptionIdx := Low(mediaOptions) to High(mediaOptions) do begin media.AddOption(mediaOptions[mediaOptionIdx]); end; Play(media, audioOutput, audioOutputDeviceId, audioSetTimeOut); end; procedure TFmxPasLibVlcPlayer.PlayNormal(mrl : WideString; mediaOptions : array of WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); var media : TPasLibVlcMedia; mediaOptionsIdx : Integer; begin GetPlayerHandle(); if (p_mi = NIL) then exit; // create media media := TPasLibVlcMedia.Create(VLC, mrl); media.SetDeinterlaceFilter(FDeinterlaceFilter); media.SetDeinterlaceFilterMode(FDeinterlaceMode); for mediaOptionsIdx := Low(mediaOptions) to High(mediaOptions) do begin media.AddOption(mediaOptions[mediaOptionsIdx]); end; Play(media, audioOutput, audioOutputDeviceId, audioSetTimeOut); end; procedure TFmxPasLibVlcPlayer.PlayYoutube(mrl : WideString; mediaOptions : array of WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000; youtubeTimeout: Cardinal = 10000); begin // http://www.youtube.com/watch?feature=player_detailpage&v=ZHHOYmERmDc PlayNormal(mrl, mediaOptions, audioOutput, audioOutputDeviceId, audioSetTimeOut); // wait for media switch, for example while (youtubeTimeout > 0) do begin Sleep(10); if (youtubeTimeout < 10) then break; Dec(youtubeTimeout, 10); if (GetState() = plvPlayer_Ended) then begin // if media ended, then check subitem list and // try continue play with first subitem mrl // for example: // http://r2---sn-4g57kn6z.googlevideo.com/videoplayback?sver=3&ipbits=0&itag=22&ip=83.31.142.43&sparams=id%2Cip%2Cipbits%2Citag%2Cratebypass%2Csource%2Cupn%2Cexpire&fexp=900064%2C902408%2C924222%2C930008%2C934030%2C946020&upn=PPuY3_P4Og8&mv=m&ms=au&id=o-ANEBC2i5aojuRlQK5Kj-nfzUUQQbvGvG3MI2udImzhm9&mws=yes&key=yt5&signature=80D290D0D7957DBC3013E7A225B64B0AE7A561CA.EE07EA42ACCCF387DACA6FF59D81135E823ED161&mt=1403761633&expire=1403784000&ratebypass=yes&source=youtube PlayContinue(mediaOptions, audioOutput, audioOutputDeviceId, audioSetTimeOut); break; end; end; end; procedure TFmxPasLibVlcPlayer.PlayContinue(mediaOptions : array of WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); var p_md : libvlc_media_t_ptr; p_ml : libvlc_media_list_t_ptr; sub_p_md : libvlc_media_t_ptr; cnt : Integer; mrl : String; begin mrl := ''; if (p_mi = NIL) then exit; p_md := libvlc_media_player_get_media(p_mi); if (p_md <> NIL) then begin p_ml := libvlc_media_subitems(p_md); if (p_ml <> NIL) then begin libvlc_media_list_lock(p_ml); cnt := libvlc_media_list_count(p_ml); if (cnt > 0) then begin sub_p_md := libvlc_media_list_item_at_index(p_ml, 0); mrl := UTF8ToWideString(libvlc_media_get_mrl(sub_p_md)); libvlc_media_release(sub_p_md); end; libvlc_media_list_unlock(p_ml); libvlc_media_list_release(p_ml); end; // libvlc_media_release(p_md); end; if (mrl <> '') then Play(mrl, mediaOptions, audioOutput, audioOutputDeviceId, audioSetTimeOut); end; (* * mrl - media resource location * * This can be file: c:\movie.avi * ulr: http://host/movie.avi * rtp: rstp://host/movie *) procedure TFmxPasLibVlcPlayer.Play(mrl : WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); begin Play(mrl, [], audioOutput, audioOutputDeviceId, audioSetTimeOut); end; procedure TFmxPasLibVlcPlayer.Play(stm : TStream; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); begin Play(stm, [], audioOutput, audioOutputDeviceId, audioSetTimeOut); end; procedure TFmxPasLibVlcPlayer.PlayNormal(mrl : WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); begin PlayNormal(mrl, [], audioOutput, audioOutputDeviceId, audioSetTimeOut); end; procedure TFmxPasLibVlcPlayer.PlayYoutube(mrl : WideString; audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000; youtubeTimeout : Cardinal = 10000); begin PlayYoutube(mrl, [], audioOutput, audioOutputDeviceId, audioSetTimeOut, youtubeTimeout); end; procedure TFmxPasLibVlcPlayer.PlayContinue(audioOutput : WideString = ''; audioOutputDeviceId : WideString = ''; audioSetTimeOut : Cardinal = 1000); begin PlayContinue([], audioOutput, audioOutputDeviceId, audioSetTimeOut); end; function TFmxPasLibVlcPlayer.GetMediaMrl(): string; var p_md : libvlc_media_t_ptr; p_ml : libvlc_media_list_t_ptr; sub_p_md : libvlc_media_t_ptr; cnt : Integer; begin if (p_mi = NIL) then exit; p_md := libvlc_media_player_get_media(p_mi); if (p_md <> NIL) then begin p_ml := libvlc_media_subitems(p_md); if (p_ml <> NIL) then begin libvlc_media_list_lock(p_ml); cnt := libvlc_media_list_count(p_ml); if (cnt > 0) then begin sub_p_md := libvlc_media_list_item_at_index(p_ml, 0); Result := UTF8ToWideString(libvlc_media_get_mrl(sub_p_md)); libvlc_media_release(sub_p_md); end; libvlc_media_list_unlock(p_ml); libvlc_media_list_release(p_ml); end else begin Result := UTF8ToWideString(libvlc_media_get_mrl(p_md)); end; libvlc_media_release(p_md); end; end; procedure TFmxPasLibVlcPlayer.Pause(); begin if (p_mi = NIL) then exit; if (GetState() = plvPlayer_Playing) then begin libvlc_media_player_pause(p_mi); end; end; procedure TFmxPasLibVlcPlayer.Resume(); begin if (p_mi = NIL) then exit; if (GetState() = plvPlayer_Paused) then begin libvlc_media_player_play(p_mi); end; end; function TFmxPasLibVlcPlayer.IsPlay(): Boolean; begin Result := (GetState() = plvPlayer_Playing); end; function TFmxPasLibVlcPlayer.IsPause(): Boolean; begin Result := (GetState() = plvPlayer_Paused); end; procedure TFmxPasLibVlcPlayer.Stop(const stopTimeOut : Cardinal = 1000); const TIME_STEP = 50; var timeElapsed : Cardinal; begin Pause(); if IsPlay() then begin libvlc_media_player_stop(p_mi); Sleep(TIME_STEP); timeElapsed := TIME_STEP; while IsPlay() do begin if (timeElapsed > stopTimeOut) then break; Sleep(TIME_STEP); Inc(timeElapsed, TIME_STEP); end; end; end; function TFmxPasLibVlcPlayer.GetState(): TFmxPasLibVlcPlayerState; begin Result := plvPlayer_NothingSpecial; if (p_mi = NIL) then exit; case libvlc_media_player_get_state(p_mi) of libvlc_NothingSpecial: Result := plvPlayer_NothingSpecial; libvlc_Opening: Result := plvPlayer_Opening; libvlc_Buffering: Result := plvPlayer_Buffering; libvlc_Playing: Result := plvPlayer_Playing; libvlc_Paused: Result := plvPlayer_Paused; libvlc_Stopped: Result := plvPlayer_Stopped; libvlc_Ended: Result := plvPlayer_Ended; libvlc_Error: Result := plvPlayer_Error; end; end; function TFmxPasLibVlcPlayer.GetStateName(): string; begin if (p_mi <> NIL) then begin case GetState of plvPlayer_NothingSpecial: Result := 'Nothing Special'; plvPlayer_Opening: Result := 'Opening'; plvPlayer_Buffering: Result := 'Buffering'; plvPlayer_Playing: Result := 'Playing'; plvPlayer_Paused: Result := 'Paused'; plvPlayer_Stopped: Result := 'Stopped'; plvPlayer_Ended: Result := 'Ended'; plvPlayer_Error: Result := 'Error'; else Result := 'Invalid State'; end; end else Result := 'Player not initialised'; end; (* * Get current video width in pixels * If autoscale (scale = 0) then return original video width * If not autoscale (scale = xxx) then return video width * scale *) function TFmxPasLibVlcPlayer.GetVideoWidth(): LongInt; var px, py: LongWord; begin px := 0; py := 0; if (Assigned(p_mi) and (libvlc_video_get_size(p_mi, 0, px, py) = 0)) then begin Result := px; end else begin Result := 0; end; end; (* * Get current video height in pixels * If autoscale (scale = 0) then return original video height * If not autoscale (scale = xxx) then return video height * scale *) function TFmxPasLibVlcPlayer.GetVideoHeight(): LongInt; var px, py: LongWord; begin px := 0; py := 0; if (Assigned(p_mi) and (libvlc_video_get_size(p_mi, 0, px, py) = 0)) then begin Result := py; end else begin Result := 0; end; end; function TFmxPasLibVlcPlayer.GetVideoDimension(var width, height: LongWord) : Boolean; begin width := 0; height := 0; Result := (Assigned(p_mi) and (libvlc_video_get_size(p_mi, 0, width, height) = 0)); end; (* * Get current video scale * I scale this by 100 (lib vlc return this im range 0..1) * If autoscale is on then return 0 else return actual scale * *) function TFmxPasLibVlcPlayer.GetVideoScaleInPercent(): Single; begin Result := -1; if (p_mi = NIL) then exit; Result := libvlc_video_get_scale(p_mi) * 100; end; (* * Set current video scale * I scale this by 100 (lib vlc return this im range 0..1) * If return 0 then autoscale is on * *) procedure TFmxPasLibVlcPlayer.SetVideoScaleInPercent(newScaleInPercent: Single); begin if (p_mi = NIL) then exit; libvlc_video_set_scale(p_mi, newScaleInPercent / 100); end; function TFmxPasLibVlcPlayer.GetVideoAspectRatio(): string; var libvlcaspect : PAnsiChar; begin Result := ''; if (p_mi = NIL) then exit; libvlcaspect := libvlc_video_get_aspect_ratio(p_mi); if (libvlcaspect <> NIL) then begin Result := UTF8ToWideString(AnsiString(libvlcaspect)); libvlc_free(libvlcaspect); end; end; function TFmxPasLibVlcPlayer.GetVideoSampleAspectRatio(var sar_num, sar_den : Longword): Boolean; var md : libvlc_media_t_ptr; tracks_ptr : Pointer; tracks_list : libvlc_media_track_list_t_ptr; tracks_count : Integer; tracks_idx : Integer; track_record : libvlc_media_track_t_ptr; begin Result := FALSE; if (p_mi = NIL) then exit; md := libvlc_media_player_get_media(p_mi); tracks_count := libvlc_media_tracks_get(md, tracks_ptr); if (tracks_count > 0) then begin tracks_list := libvlc_media_track_list_t_ptr(@tracks_ptr); for tracks_idx := 0 to tracks_count-1 do begin track_record := tracks_list^[tracks_idx]; if (track_record^.i_type = libvlc_track_video) then begin sar_num := track_record^.u.video^.i_sar_num; sar_den := track_record^.u.video^.i_sar_den; Result := TRUE; break; end; end; libvlc_media_tracks_release(tracks_ptr, tracks_count); end; end; function TFmxPasLibVlcPlayer.GetVideoSampleAspectRatio() : Single; var sar_num, sar_den : Longword; begin Result := 0; if GetVideoSampleAspectRatio(sar_num, sar_den) and (sar_den > 0) then begin Result := sar_num / sar_den; end; end; procedure TFmxPasLibVlcPlayer.SetVideoAspectRatio(newAspectRatio: string); begin if (p_mi = NIL) then exit; libvlc_video_set_aspect_ratio(p_mi, PAnsiChar(AnsiString(newAspectRatio))); end; (* * Return video time length in miliseconds *) function TFmxPasLibVlcPlayer.GetVideoLenInMs(): Int64; begin Result := 0; if (p_mi = NIL) then exit; Result := libvlc_media_player_get_length(p_mi); end; (* * Return current video time length as string hh:mm:ss *) function TFmxPasLibVlcPlayer.GetVideoLenStr(fmt: string = 'hh:mm:ss'): string; begin Result := time2str(GetVideoLenInMs(), fmt); end; (* * Return current video time position in miliseconds *) function TFmxPasLibVlcPlayer.GetVideoPosInMs(): Int64; begin Result := 0; if (p_mi = NIL) then exit; Result := libvlc_media_player_get_time(p_mi); end; (* * Return current video time position as string hh:mm:ss *) function TFmxPasLibVlcPlayer.GetVideoPosStr(fmt: string = 'hh:mm:ss'): string; begin Result := time2str(GetVideoPosInMs(), fmt); end; (* * Set current video time position in miliseconds * Not working for all media *) procedure TFmxPasLibVlcPlayer.SetVideoPosInMs(newPos: Int64); begin if (p_mi = NIL) then exit; libvlc_media_player_set_time(p_mi, newPos); if (GetState() <> plvPlayer_Playing) then if Assigned(FOnMediaPlayerTimeChanged) then FOnMediaPlayerTimeChanged(Self, newPos); end; (* * Return current video position where 0 - start, 100 - end * I scale this by 100 (lib vlc return this in range 0..1) *) function TFmxPasLibVlcPlayer.GetVideoPosInPercent(): Single; begin Result := 0; if (p_mi = NIL) then exit; Result := libvlc_media_player_get_position(p_mi) * 100; end; (* * Set current video position where 0 - start, 100 - end * I scale this by 100 (lib vlc return this in range 0..1) * Not working for all media *) procedure TFmxPasLibVlcPlayer.SetVideoPosInPercent(newPos: Single); begin if (p_mi = NIL) then exit; libvlc_media_player_set_position(p_mi, newPos / 100); if (GetState() <> plvPlayer_Playing) then if Assigned(FOnMediaPlayerPositionChanged) then FOnMediaPlayerPositionChanged(Self, newPos / 100); end; (* * Return frames per second *) function TFmxPasLibVlcPlayer.GetVideoFps(): Single; begin Result := -1; if (p_mi = NIL) then exit; Result := libvlc_media_player_get_fps(p_mi); end; (* * Return true if player can play *) function TFmxPasLibVlcPlayer.CanPlay(): Boolean; begin Result := FALSE; if (p_mi = NIL) then exit; Result := (libvlc_media_player_will_play(p_mi) > 0); end; (* * Return true if player can pause *) function TFmxPasLibVlcPlayer.CanPause(): Boolean; begin Result := FALSE; if (p_mi = NIL) then exit; Result := (libvlc_media_player_can_pause(p_mi) > 0); end; (* * Return true if player can seek (can set time or percent position) *) function TFmxPasLibVlcPlayer.CanSeek(): Boolean; begin Result := FALSE; if (p_mi = NIL) then exit; Result := (libvlc_media_player_is_seekable(p_mi) > 0); end; (* * Return true if player has video output *) function TFmxPasLibVlcPlayer.HasVout() : Boolean; begin Result := FALSE; if (p_mi = NIL) then exit; Result := (libvlc_media_player_has_vout(p_mi) > 0); end; (* * Return true if video is scrambled *) function TFmxPasLibVlcPlayer.IsScrambled() : Boolean; begin Result := FALSE; if (p_mi = NIL) then exit; Result := (libvlc_media_player_program_scrambled(p_mi) > 0) end; (* * Create snapshot of current video frame to specified fileName * The file is in PNG format *) function TFmxPasLibVlcPlayer.Snapshot(fileName: WideString): Boolean; var i_width, i_height: LongWord; begin Result := FALSE; if (p_mi = NIL) then exit; i_width := 0; i_height := 0; if (libvlc_video_get_size(p_mi, 0, i_width, i_height) <> 0) then exit; Result := (libvlc_video_take_snapshot(p_mi, 0, PAnsiChar(Utf8Encode(fileName)), i_width, i_height) = 0); end; (* * Create snapshot of current video frame * to specified fileName with size width x heght * The file is in PNG format *) function TFmxPasLibVlcPlayer.Snapshot(fileName: WideString; width, height: LongWord): Boolean; begin Result := FALSE; if (p_mi = NIL) then exit; Result := (libvlc_video_take_snapshot(p_mi, 0, PAnsiChar(Utf8Encode(fileName)), width, height) = 0); end; procedure TFmxPasLibVlcPlayer.NextFrame(); begin if (p_mi = NIL) then exit; libvlc_media_player_next_frame(p_mi); end; function TFmxPasLibVlcPlayer.GetAudioMute(): Boolean; begin Result := FMute; end; procedure TFmxPasLibVlcPlayer.SetAudioMute(mute: Boolean); begin if (p_mi = NIL) then exit; if mute then libvlc_audio_set_mute(p_mi, 1) else libvlc_audio_set_mute(p_mi, 0); FMute := mute; end; function TFmxPasLibVlcPlayer.GetAudioVolume(): Integer; begin Result := -1; if (p_mi = NIL) then exit; Result := libvlc_audio_get_volume(p_mi); end; procedure TFmxPasLibVlcPlayer.SetAudioVolume(volumeLevel: Integer); begin if (p_mi = NIL) then exit; if (volumeLevel < 0) then exit; if (volumeLevel > 200) then exit; // if (FVLC.VersionBin < $020100) then begin libvlc_audio_set_volume(p_mi, volumeLevel); end; end; procedure TFmxPasLibVlcPlayer.SetPlayRate(rate: Integer); begin if (p_mi = NIL) then exit; if (rate < 1) then exit; if (rate > 1000) then exit; libvlc_media_player_set_rate(p_mi, rate / 100); end; function TFmxPasLibVlcPlayer.GetPlayRate(): Integer; begin Result := -1; if (p_mi = NIL) then exit; Result := Round(100 * libvlc_media_player_get_rate(p_mi)); end; //////////////////////////////////////////////////////////////////////////////// function TFmxPasLibVlcPlayer.GetAudioFilterList(return_name_type : Integer = 0): TStringList; var p_list : libvlc_module_description_t_ptr; begin Result := TStringList.Create; if (p_mi = NIL) then exit; p_list := libvlc_audio_filter_list_get(p_mi); if (return_name_type = 0) then begin while (p_list <> NIL) do begin if (p_list^.psz_name <> NIL) then begin Result.AddObject( UTF8ToWideString(p_list^.psz_name), NIL); end; p_list := p_list^.p_next; end; end; if (return_name_type = 1) then begin while (p_list <> NIL) do begin if (p_list^.psz_shortname <> NIL) then begin Result.AddObject( UTF8ToWideString(p_list^.psz_shortname), NIL); end; p_list := p_list^.p_next; end; end; if (return_name_type = 2) then begin while (p_list <> NIL) do begin if (p_list^.psz_longname <> NIL) then begin Result.AddObject( UTF8ToWideString(p_list^.psz_longname), NIL); end; p_list := p_list^.p_next; end; end; if (return_name_type = 3) then begin while (p_list <> NIL) do begin if (p_list^.psz_help <> NIL) then begin Result.AddObject( UTF8ToWideString(p_list^.psz_help), NIL); end; p_list := p_list^.p_next; end; end; libvlc_module_description_list_release(p_list); end; function TFmxPasLibVlcPlayer.GetVideoFilterList(return_name_type : Integer = 0): TStringList; var p_list : libvlc_module_description_t_ptr; begin Result := TStringList.Create; if (p_mi = NIL) then exit; p_list := libvlc_video_filter_list_get(p_mi); if (return_name_type = 0) then begin while (p_list <> NIL) do begin if (p_list^.psz_name <> NIL) then begin Result.AddObject( UTF8ToWideString(p_list^.psz_name), NIL); end; p_list := p_list^.p_next; end; end; if (return_name_type = 1) then begin while (p_list <> NIL) do begin if (p_list^.psz_shortname <> NIL) then begin Result.AddObject( UTF8ToWideString(p_list^.psz_shortname), NIL); end; p_list := p_list^.p_next; end; end; if (return_name_type = 2) then begin while (p_list <> NIL) do begin if (p_list^.psz_longname <> NIL) then begin Result.AddObject( UTF8ToWideString(p_list^.psz_longname), NIL); end; p_list := p_list^.p_next; end; end; if (return_name_type = 3) then begin while (p_list <> NIL) do begin if (p_list^.psz_help <> NIL) then begin Result.AddObject( UTF8ToWideString(p_list^.psz_help), NIL); end; p_list := p_list^.p_next; end; end; libvlc_module_description_list_release(p_list); end; //////////////////////////////////////////////////////////////////////////////// function TFmxPasLibVlcPlayer.GetAudioTrackList() : TStringList; var p_track : libvlc_track_description_t_ptr; begin Result := TStringList.Create; if (p_mi = NIL) then exit; p_track := libvlc_audio_get_track_description(p_mi); while (p_track <> NIL) do begin if (p_track^.psz_name <> NIL) then begin Result.AddObject( UTF8ToWideString(p_track^.psz_name), TObject(p_track^.i_id)); end; p_track := p_track^.p_next; end; end; function TFmxPasLibVlcPlayer.GetAudioTrackCount(): Integer; begin Result := -1; if (p_mi = NIL) then exit; Result := libvlc_audio_get_track_count(p_mi); end; function TFmxPasLibVlcPlayer.GetAudioTrackId(): Integer; begin Result := -1; if (p_mi = NIL) then exit; Result := libvlc_audio_get_track(p_mi); end; procedure TFmxPasLibVlcPlayer.SetAudioTrackById(const track_id : Integer); begin if (p_mi = NIL) then exit; if (track_id < 0) then exit; libvlc_audio_set_track(p_mi, track_id); end; function TFmxPasLibVlcPlayer.GetAudioTrackNo(): Integer; var track_id : Integer; p_track : libvlc_track_description_t_ptr; begin Result := 0; if not Assigned(p_mi) then exit; track_id := libvlc_audio_get_track(p_mi); p_track := libvlc_audio_get_track_description(p_mi); while (p_track <> NIL) do begin if (p_track^.i_id = track_id) then exit; Inc(Result); p_track := p_track^.p_next; end; Result := -1; end; procedure TFmxPasLibVlcPlayer.SetAudioTrackByNo(track_no : Integer); var p_track : libvlc_track_description_t_ptr; begin if (p_mi = NIL) then exit; if (track_no < 0) then exit; p_track := libvlc_audio_get_track_description(p_mi); while ((track_no > 0) and (p_track <> NIL)) do begin Dec(track_no); p_track := p_track^.p_next; end; if (p_track <> NIL) then begin libvlc_audio_set_track(p_mi, p_track^.i_id); end; end; function TFmxPasLibVlcPlayer.GetAudioTrackDescriptionById(const track_id : Integer): WideString; var p_track : libvlc_track_description_t_ptr; begin Result := ''; if (track_id < 0) then exit; if not Assigned(p_mi) then exit; p_track := libvlc_audio_get_track_description(p_mi); while (p_track <> NIL) do begin if (p_track^.i_id = track_id) then begin if (p_track^.psz_name <> NIL) then begin Result := UTF8ToWideString(p_track^.psz_name); end; break; end; p_track := p_track^.p_next; end; end; function TFmxPasLibVlcPlayer.GetAudioTrackDescriptionByNo(track_no: Integer): WideString; var p_track : libvlc_track_description_t_ptr; begin Result := ''; if (track_no < 0) then exit; if not Assigned(p_mi) then exit; p_track := libvlc_audio_get_track_description(p_mi); while ((track_no > 0) and (p_track <> NIL)) do begin Dec(track_no); p_track := p_track^.p_next; end; if (p_track <> NIL) then begin if (p_track^.psz_name <> NIL) then begin Result := UTF8ToWideString(p_track^.psz_name); end; end; end; //////////////////////////////////////////////////////////////////////////////// function TFmxPasLibVlcPlayer.EqualizerGetPresetList(): TStringList; var preset : PAnsiChar; count : Word; index : Word; begin Result := TStringList.Create; if (VLC.Handle = NIL) then exit; count := libvlc_audio_equalizer_get_preset_count(); index := 0; while (index < count) do begin preset := libvlc_audio_equalizer_get_preset_name(index); if ((preset <> NIL) and (preset <> '')) then begin Result.AddObject( UTF8ToWideString(preset), TObject(index) ); end; Inc(index); end; end; function TFmxPasLibVlcPlayer.EqualizerGetBandCount(): unsigned_t; begin Result := 0; if (VLC.Handle = NIL) then exit; Result := libvlc_audio_equalizer_get_band_count(); end; function TFmxPasLibVlcPlayer.EqualizerGetBandFrequency(bandIndex : unsigned_t): Single; begin Result := 0; if (VLC.Handle = NIL) then exit; Result := libvlc_audio_equalizer_get_band_frequency(bandIndex); end; function TFmxPasLibVlcPlayer.EqualizerCreate(APreset : unsigned_t = $FFFF) : TPasLibVlcEqualizer; begin Result := TPasLibVlcEqualizer.Create(FVLC, APreset); end; procedure TFmxPasLibVlcPlayer.EqualizerApply(AEqualizer : TPasLibVlcEqualizer); begin if (VLC.Handle = NIL) then exit; GetPlayerHandle(); if not Assigned(p_mi) then exit; if (AEqualizer <> NIL) then begin libvlc_media_player_set_equalizer(p_mi, AEqualizer.GetHandle()); end else begin libvlc_media_player_set_equalizer(p_mi, NIL); end; end; procedure TFmxPasLibVlcPlayer.EqualizerSetPreset(APreset : unsigned_t = $FFFF); var equalizer : TPasLibVlcEqualizer; begin if (VLC.Handle = NIL) then exit; GetPlayerHandle(); if not Assigned(p_mi) then exit; if (APreset <> $FFFF) then begin equalizer := TPasLibVlcEqualizer.Create(FVLC, APreset); libvlc_media_player_set_equalizer(p_mi, equalizer.GetHandle()); equalizer.Free; end else begin libvlc_media_player_set_equalizer(p_mi, NIL); end; end; //////////////////////////////////////////////////////////////////////////////// function TFmxPasLibVlcPlayer.GetAudioOutputList(withDescription : Boolean = FALSE; separator : string = '|'): TStringList; var p_list_head : libvlc_audio_output_t_ptr; p_list_item : libvlc_audio_output_t_ptr; begin Result := TStringList.Create; p_list_head := libvlc_audio_output_list_get(VLC.Handle); if (p_list_head <> NIL) then begin p_list_item := p_list_head; while (p_list_item <> NIL) do begin if (p_list_item^.psz_name <> NIL) then begin if (withDescription) then begin Result.Add( UTF8ToWideString(p_list_item^.psz_name) + separator + UTF8ToWideString(p_list_item^.psz_description) ); end else begin Result.Add(UTF8ToWideString(p_list_item^.psz_name)); end; end; p_list_item := p_list_item^.p_next; end; libvlc_audio_output_list_release(p_list_head); end; end; function TFmxPasLibVlcPlayer.GetAudioOutputDeviceList(aOut : WideString; withDescription : Boolean = FALSE; separator : string = '|'): TStringList; var p_list_head : libvlc_audio_output_device_t_ptr; p_list_item : libvlc_audio_output_device_t_ptr; begin Result := TStringList.Create; p_list_head := libvlc_audio_output_device_list_get(VLC.Handle, PAnsiChar(Utf8Encode(aOut))); if (p_list_head <> NIL) then begin p_list_item := p_list_head; while (p_list_item <> NIL) do begin if (p_list_item^.psz_device <> NIL) then begin if (withDescription) then begin Result.Add( UTF8ToWideString(p_list_item^.psz_device) + separator + UTF8ToWideString(p_list_item^.psz_description) ); end else begin Result.Add( UTF8ToWideString(p_list_item^.psz_device) ); end; end; p_list_item := p_list_item^.p_next; end; libvlc_audio_output_device_list_release(p_list_head); end; end; function TFmxPasLibVlcPlayer.GetAudioOutputDeviceEnum(withDescription : Boolean = FALSE; separator : string = '|') : TStringList; var p_list_head : libvlc_audio_output_device_t_ptr; p_list_item : libvlc_audio_output_device_t_ptr; begin Result := TStringList.Create; if (p_mi = NIL) then GetPlayerHandle(); if not Assigned(p_mi) then exit; p_list_head := libvlc_audio_output_device_enum(p_mi); if (p_list_head <> NIL) then begin p_list_item := p_list_head; while (p_list_item <> NIL) do begin if (p_list_item^.psz_device <> NIL) then begin if (withDescription) then begin Result.Add( UTF8ToWideString(p_list_item^.psz_device) + separator + UTF8ToWideString(p_list_item^.psz_description) ); end else begin Result.Add( UTF8ToWideString(p_list_item^.psz_device) ); end; end; p_list_item := p_list_item^.p_next; end; libvlc_audio_output_device_list_release(p_list_head); end; end; function TFmxPasLibVlcPlayer.SetAudioOutput(aOut: WideString) : Boolean; begin Result := FALSE; if (p_mi = NIL) then GetPlayerHandle(); if (p_mi <> NIL) then begin Result := (libvlc_audio_output_set(p_mi, PAnsiChar(Utf8Encode(aOut))) = 0); if Result then begin FLastAudioOutput := aOut; end; end; end; procedure TFmxPasLibVlcPlayer.SetAudioOutputDevice(aOut: WideString; aOutDeviceId: WideString); begin if (p_mi = NIL) then begin GetPlayerHandle(); end; if (p_mi <> NIL) then begin if (aOut <> '') then begin libvlc_audio_output_device_set(p_mi, PAnsiChar(Utf8Encode(aOut)), PAnsiChar(Utf8Encode(aOutDeviceId))); FLastAudioOutput := aOut; FLastAudioOutputDeviceId := aOutDeviceId; end else begin libvlc_audio_output_device_set(p_mi, NIL, PAnsiChar(Utf8Encode(aOutDeviceId))); FLastAudioOutput := ''; FLastAudioOutputDeviceId := aOutDeviceId; end; end; end; procedure TFmxPasLibVlcPlayer.SetAudioOutputDevice(aOutDeviceId: WideString); begin if (p_mi = NIL) then begin GetPlayerHandle(); end; if (p_mi <> NIL) then begin libvlc_audio_output_device_set(p_mi, NIL, PAnsiChar(Utf8Encode(aOutDeviceId))); FLastAudioOutput := ''; FLastAudioOutputDeviceId := aOutDeviceId; end; end; {$IFDEF USE_VLC_DEPRECATED_API} function TFmxPasLibVlcPlayer.GetAudioOutputDeviceCount(aOut: WideString): Integer; begin Result := libvlc_audio_output_device_count(VLC.Handle, PAnsiChar(Utf8Encode(aOut))); end; function TFmxPasLibVlcPlayer.GetAudioOutputDeviceId(aOut: WideString; deviceIdx : Integer) : WideString; var device_id : PAnsiChar; begin Result := ''; device_id := libvlc_audio_output_device_id(VLC.Handle, PAnsiChar(Utf8Encode(aOut)), deviceIdx); if (device_id <> NIL) then begin Result := UTF8ToWideString(device_id); libvlc_free(device_id); end; end; function TFmxPasLibVlcPlayer.GetAudioOutputDeviceName(aOut: WideString; deviceIdx : Integer): WideString; var device_name : PAnsiChar; begin device_name := libvlc_audio_output_device_longname(VLC.Handle, PAnsiChar(Utf8Encode(aOut)), deviceIdx); Result := ''; if (device_name <> NIL) then begin Result := UTF8ToWideString(device_name); // libvlc_free(device_name); end; end; {$ENDIF} //////////////////////////////////////////////////////////////////////////////// procedure TFmxPasLibVlcPlayer.SetVideoAdjustEnable(value : Boolean); begin if (p_mi = NIL) then exit; if (value) then libvlc_video_set_adjust_int(p_mi, libvlc_adjust_Enable, 1) else libvlc_video_set_adjust_int(p_mi, libvlc_adjust_Enable, 0); end; function TFmxPasLibVlcPlayer.GetVideoAdjustEnable(): Boolean; begin Result := FALSE; if (p_mi = NIL) then exit; Result := (libvlc_video_get_adjust_int(p_mi, libvlc_adjust_Enable) <> 0); end; // Set the image contrast, between 0 and 2. Defaults to 1 procedure TFmxPasLibVlcPlayer.SetVideoAdjustContrast(value : Single); begin if (p_mi = NIL) then exit; libvlc_video_set_adjust_float(p_mi, libvlc_adjust_Contrast, value); end; function TFmxPasLibVlcPlayer.GetVideoAdjustContrast(): Single; begin Result := 0; if (p_mi = NIL) then exit; Result := libvlc_video_get_adjust_float(p_mi, libvlc_adjust_Contrast); end; // Set the image brightness, between 0 and 2. Defaults to 1. procedure TFmxPasLibVlcPlayer.SetVideoAdjustBrightness(value : Single); begin if (p_mi = NIL) then exit; libvlc_video_set_adjust_float(p_mi, libvlc_adjust_Brightness, value); end; function TFmxPasLibVlcPlayer.GetVideoAdjustBrightness(): Single; begin Result := 0; if (p_mi = NIL) then exit; Result := libvlc_video_get_adjust_float(p_mi, libvlc_adjust_Brightness); end; // Set the image hue, between 0 and 360. Defaults to 0. procedure TFmxPasLibVlcPlayer.SetVideoAdjustHue(value : Integer); begin if (p_mi = NIL) then exit; libvlc_video_set_adjust_int(p_mi, libvlc_adjust_Hue, value); end; function TFmxPasLibVlcPlayer.GetVideoAdjustHue(): Integer; begin Result := 0; if (p_mi = NIL) then exit; Result := libvlc_video_get_adjust_int(p_mi, libvlc_adjust_Hue); end; // Set the image saturation, between 0 and 3. Defaults to 1. procedure TFmxPasLibVlcPlayer.SetVideoAdjustSaturation(value : Single); begin if (p_mi = NIL) then exit; libvlc_video_set_adjust_float(p_mi, libvlc_adjust_Saturation, value); end; function TFmxPasLibVlcPlayer.GetVideoAdjustSaturation(): Single; begin Result := 0; if (p_mi = NIL) then exit; Result := libvlc_video_get_adjust_float(p_mi, libvlc_adjust_Saturation); end; // Set the image gamma, between 0.01 and 10. Defaults to 1 procedure TFmxPasLibVlcPlayer.SetVideoAdjustGamma(value : Single); begin if (p_mi = NIL) then exit; libvlc_video_set_adjust_float(p_mi, libvlc_adjust_Gamma, value); end; function TFmxPasLibVlcPlayer.GetVideoAdjustGamma(): Single; begin Result := 0; if (p_mi = NIL) then exit; Result := libvlc_video_get_adjust_float(p_mi, libvlc_adjust_Gamma); end; //////////////////////////////////////////////////////////////////////////////// function TFmxPasLibVlcPlayer.GetVideoChapter(): Integer; begin Result := -1; if (p_mi = NIL) then exit; Result := libvlc_media_player_get_chapter(p_mi); end; procedure TFmxPasLibVlcPlayer.SetVideoChapter(newChapter: Integer); begin if (p_mi = NIL) then exit; libvlc_media_player_set_chapter(p_mi, newChapter); end; function TFmxPasLibVlcPlayer.GetVideoChapterCount(): Integer; begin Result := -1; if (p_mi = NIL) then exit; Result := libvlc_media_player_get_chapter_count(p_mi); end; function TFmxPasLibVlcPlayer.GetVideoChapterCountByTitleId(const title_id : Integer): Integer; begin Result := -1; if (p_mi = NIL) then exit; Result := libvlc_media_player_get_chapter_count_for_title(p_mi, title_id); end; //////////////////////////////////////////////////////////////////////////////// function TFmxPasLibVlcPlayer.GetVideoSubtitleList(): TStringList; var p_track : libvlc_track_description_t_ptr; begin Result := TStringList.Create; if (p_mi = NIL) then exit; p_track := libvlc_video_get_spu_description(p_mi); while (p_track <> NIL) do begin if (p_track^.psz_name <> NIL) then begin Result.AddObject( UTF8ToWideString(p_track^.psz_name), TObject(p_track^.i_id)); end; p_track := p_track^.p_next; end; end; function TFmxPasLibVlcPlayer.GetVideoSubtitleCount(): Integer; begin Result := -1; if (p_mi = NIL) then exit; Result := libvlc_video_get_spu_count(p_mi); end; function TFmxPasLibVlcPlayer.GetVideoSubtitleId(): Integer; begin Result := -1; if (p_mi = NIL) then Exit; Result := libvlc_video_get_spu(p_mi); end; procedure TFmxPasLibVlcPlayer.SetVideoSubtitleById(const subtitle_id : Integer); begin if (p_mi = NIL) then exit; libvlc_video_set_spu(p_mi, subtitle_id); end; function TFmxPasLibVlcPlayer.GetVideoSubtitleNo(): Integer; var track_id : Integer; p_track : libvlc_track_description_t_ptr; begin Result := 0; if not Assigned(p_mi) then exit; track_id := libvlc_video_get_spu(p_mi); p_track := libvlc_video_get_spu_description(p_mi); while (p_track <> NIL) do begin if (p_track^.i_id = track_id) then exit; Inc(Result); p_track := p_track^.p_next; end; Result := -1; end; procedure TFmxPasLibVlcPlayer.SetVideoSubtitleByNo(subtitle_no: Integer); var p_track: libvlc_track_description_t_ptr; begin if (p_mi = NIL) then exit; if (subtitle_no < 0) then exit; p_track := libvlc_video_get_spu_description(p_mi); while ((subtitle_no > 0) and (p_track <> NIL)) do begin Dec(subtitle_no); p_track := p_track^.p_next; end; if (p_track <> NIL) then begin libvlc_video_set_spu(p_mi, p_track^.i_id); end; end; function TFmxPasLibVlcPlayer.GetVideoSubtitleDescriptionById(const subtitle_id : Integer): WideString; var p_track: libvlc_track_description_t_ptr; begin Result := ''; if (subtitle_id < 0) then exit; if not Assigned(p_mi) then exit; p_track := libvlc_video_get_spu_description(p_mi); while (p_track <> NIL) do begin if (p_track^.i_id = subtitle_id) then begin if (p_track^.psz_name <> NIL) then begin Result := UTF8ToWideString(p_track^.psz_name); end; break; end; p_track := p_track^.p_next; end; end; function TFmxPasLibVlcPlayer.GetVideoSubtitleDescriptionByNo(subtitle_no: Integer): WideString; var p_track: libvlc_track_description_t_ptr; begin Result := ''; if (subtitle_no < 0) then exit; if not Assigned(p_mi) then exit; p_track := libvlc_video_get_spu_description(p_mi); while ((subtitle_no > 0) and (p_track <> NIL)) do begin Dec(subtitle_no); p_track := p_track^.p_next; end; if (p_track <> NIL) then begin if (p_track^.psz_name <> NIL) then begin Result := UTF8ToWideString(p_track^.psz_name); end; end; end; procedure TFmxPasLibVlcPlayer.SetVideoSubtitleFile(subtitle_file : WideString); begin if (p_mi = NIL) then exit; libvlc_video_set_subtitle_file(p_mi, PAnsiChar(UTF8Encode(subtitle_file))); end; //////////////////////////////////////////////////////////////////////////////// function TFmxPasLibVlcPlayer.GetVideoTitleList(): TStringList; var p_track : libvlc_track_description_t_ptr; begin Result := TStringList.Create; if (p_mi = NIL) then exit; p_track := libvlc_video_get_title_description(p_mi); while (p_track <> NIL) do begin if (p_track^.psz_name <> NIL) then begin Result.AddObject( UTF8ToWideString(p_track^.psz_name), TObject(p_track^.i_id)); end; p_track := p_track^.p_next; end; end; function TFmxPasLibVlcPlayer.GetVideoTitleCount(): Integer; begin Result := -1; if (p_mi = NIL) then exit; Result := libvlc_media_player_get_title_count(p_mi); end; function TFmxPasLibVlcPlayer.GetVideoTitleId():Integer; begin Result := -1; if (p_mi = NIL) then exit; Result := libvlc_media_player_get_title(p_mi); end; procedure TFmxPasLibVlcPlayer.SetVideoTitleById(const title_id:Integer); begin if (p_mi = NIL) then exit; libvlc_media_player_set_title(p_mi, title_id); end; function TFmxPasLibVlcPlayer.GetVideoTitleNo(): Integer; var title_id : Integer; p_track : libvlc_track_description_t_ptr; begin Result := 0; if not Assigned(p_mi) then exit; title_id := libvlc_media_player_get_title(p_mi); p_track := libvlc_video_get_title_description(p_mi); while (p_track <> NIL) do begin if (p_track^.i_id = title_id) then exit; Inc(Result); p_track := p_track^.p_next; end; Result := -1; end; procedure TFmxPasLibVlcPlayer.SetVideoTitleByNo(title_no : Integer); var p_track: libvlc_track_description_t_ptr; begin if (p_mi = NIL) then exit; if (title_no < 0) then exit; p_track := libvlc_video_get_title_description(p_mi); while ((title_no > 0) and (p_track <> NIL)) do begin Dec(title_no); p_track := p_track^.p_next; end; if (p_track <> NIL) then begin libvlc_media_player_set_title(p_mi, p_track^.i_id); end; end; function TFmxPasLibVlcPlayer.GetVideoTitleDescriptionById(const track_id : Integer): WideString; var p_track: libvlc_track_description_t_ptr; begin Result := ''; if (track_id < 0) then exit; if not Assigned(p_mi) then exit; p_track := libvlc_video_get_title_description(p_mi); while (p_track <> NIL) do begin if (p_track^.i_id = track_id) then begin if (p_track^.psz_name <> NIL) then begin Result := UTF8ToWideString(p_track^.psz_name); end; break; end; p_track := p_track^.p_next; end; end; function TFmxPasLibVlcPlayer.GetVideoTitleDescriptionByNo(title_no : Integer): WideString; var p_track: libvlc_track_description_t_ptr; begin Result := ''; if (title_no < 0) then exit; if not Assigned(p_mi) then exit; p_track := libvlc_video_get_title_description(p_mi); while ((title_no > 0) and (p_track <> NIL)) do begin Dec(title_no); p_track := p_track^.p_next; end; if (p_track <> NIL) then begin if (p_track^.psz_name <> NIL) then begin Result := UTF8ToWideString(p_track^.psz_name); end; end; end; //////////////////////////////////////////////////////////////////////////////// function TFmxPasLibVlcPlayer.GetAudioChannel(): libvlc_audio_output_channel_t; begin Result := libvlc_AudioChannel_Error; if not Assigned(p_mi) then exit; Result := libvlc_audio_get_channel(p_mi); end; procedure TFmxPasLibVlcPlayer.SetAudioChannel(chanel: libvlc_audio_output_channel_t); begin if not Assigned(p_mi) then exit; libvlc_audio_set_channel(p_mi, chanel); end; function TFmxPasLibVlcPlayer.GetAudioDelay(): Int64; begin Result := 0; if not Assigned(p_mi) then exit; Result := libvlc_audio_get_delay(p_mi); end; procedure TFmxPasLibVlcPlayer.SetAudioDelay(delay: Int64); begin if not Assigned(p_mi) then exit; libvlc_audio_set_delay(p_mi, delay); end; //////////////////////////////////////////////////////////////////////////////// procedure TFmxPasLibVlcPlayer.SetTeleText(page: Integer); begin if not Assigned(p_mi) then exit; libvlc_video_set_teletext(p_mi, page); end; function TFmxPasLibVlcPlayer.GetTeleText() : Integer; begin Result := -1; if not Assigned(p_mi) then exit; Result := libvlc_video_get_teletext(p_mi); end; function TFmxPasLibVlcPlayer.ShowTeleText() : Boolean; begin Result := FViewTeleText; if FViewTeleText then exit; if not Assigned(p_mi) then exit; if (libvlc_media_player_is_playing(p_mi) = 0) then exit; libvlc_toggle_teletext(p_mi); Result := FViewTeleText; end; function TFmxPasLibVlcPlayer.HideTeleText() : Boolean; begin Result := FViewTeleText; if not FViewTeleText then exit; if not Assigned(p_mi) then exit; if (libvlc_media_player_is_playing(p_mi) = 0) then exit; libvlc_toggle_teletext(p_mi); Result := FViewTeleText; end; //////////////////////////////////////////////////////////////////////////////// // // https://wiki.videolan.org/Documentation:Modules/logo/ // //////////////////////////////////////////////////////////////////////////////// procedure TFmxPasLibVlcPlayer.LogoSetFile(file_name : WideString); begin if not Assigned(p_mi) then exit; libvlc_video_set_logo_string(p_mi, libvlc_logo_File, PAnsiChar(UTF8Encode(file_name))); end; procedure TFmxPasLibVlcPlayer.LogoSetFiles(file_names : array of WideString; delay_ms : Integer = 1000; loop : Boolean = TRUE); var file_name : WideString; file_indx : Integer; begin file_name := ''; for file_indx := Low(file_names) to High(file_names) do begin file_name := file_name + file_names[file_indx] + {$IFDEF MSWINDOWS} ';'; {$ELSE} ':'; {$ENDIF}; end; // remove last PATH_SEPARATOR; if (file_name <> '') then SetLength(file_name, Length(file_name)-1); LogoSetFile(file_name); LogoSetDelay(delay_ms); LogoSetRepeat(loop); end; procedure TFmxPasLibVlcPlayer.LogoSetPosition(position_x, position_y : Integer); begin if not Assigned(p_mi) then exit; libvlc_video_set_logo_int(p_mi, libvlc_logo_X, position_x); libvlc_video_set_logo_int(p_mi, libvlc_logo_Y, position_y); end; procedure TFmxPasLibVlcPlayer.LogoSetPosition(position : libvlc_position_t); begin if not Assigned(p_mi) then exit; libvlc_video_set_logo_int(p_mi, libvlc_logo_Position, Ord(position)); end; procedure TFmxPasLibVlcPlayer.LogoSetOpacity(opacity : libvlc_opacity_t); begin if not Assigned(p_mi) then exit; libvlc_video_set_logo_int(p_mi, libvlc_logo_Opacity, opacity); end; procedure TFmxPasLibVlcPlayer.LogoSetDelay(delay_ms : Integer = 1000); // delay before show next logo file, default 1000 begin if not Assigned(p_mi) then exit; libvlc_video_set_logo_int(p_mi, libvlc_logo_Delay, delay_ms); end; procedure TFmxPasLibVlcPlayer.LogoSetRepeat(loop : Boolean = TRUE); begin if not Assigned(p_mi) then exit; if loop then libvlc_video_set_logo_int(p_mi, libvlc_logo_Repeat, -1) // -1 = loop, else libvlc_video_set_logo_int(p_mi, libvlc_logo_Repeat, 0); // 0 - disable end; procedure TFmxPasLibVlcPlayer.LogoSetEnable(enable : Integer); begin if not Assigned(p_mi) then exit; libvlc_video_set_logo_int(p_mi, libvlc_logo_Enable, enable); // not work end; procedure TFmxPasLibVlcPlayer.LogoShowFile(file_name : WideString; position_x, position_y : Integer; opacity: libvlc_opacity_t = libvlc_opacity_full); begin LogoSetFile(file_name); LogoSetPosition(position_x, position_y); LogoSetOpacity(opacity); LogoSetEnable(1); end; procedure TFmxPasLibVlcPlayer.LogoShowFile(file_name : WideString; position: libvlc_position_t = libvlc_position_top; opacity: libvlc_opacity_t = libvlc_opacity_full); begin LogoSetFile(file_name); LogoSetPosition(position); LogoSetOpacity(opacity); LogoSetEnable(1); end; procedure TFmxPasLibVlcPlayer.LogoShowFiles(file_names : array of WideString; position_x, position_y : Integer; opacity: libvlc_opacity_t = libvlc_opacity_full; delay_ms : Integer = 1000; loop : Boolean = TRUE); begin LogoSetFiles(file_names); LogoSetPosition(position_x, position_y); LogoSetOpacity(opacity); LogoSetDelay(delay_ms); LogoSetRepeat(loop); LogoSetEnable(1); end; procedure TFmxPasLibVlcPlayer.LogoShowFiles(file_names : array of WideString; position: libvlc_position_t = libvlc_position_top; opacity: libvlc_opacity_t = libvlc_opacity_full; delay_ms : Integer = 1000; loop : Boolean = TRUE); begin LogoSetFiles(file_names); LogoSetPosition(position); LogoSetOpacity(opacity); LogoSetDelay(delay_ms); LogoSetRepeat(loop); LogoSetEnable(1); end; procedure TFmxPasLibVlcPlayer.LogoHide(); begin if not Assigned(p_mi) then exit; libvlc_video_set_logo_int (p_mi, libvlc_logo_Enable, 1); // not work libvlc_video_set_logo_string(p_mi, libvlc_logo_File, NIL); // this work end; //////////////////////////////////////////////////////////////////////////////// // // https://wiki.videolan.org/Documentation:Modules/marq/ // //////////////////////////////////////////////////////////////////////////////// procedure TFmxPasLibVlcPlayer.MarqueeSetText(marquee_text : WideString); begin if not Assigned(p_mi) then exit; if (marquee_text = '') then libvlc_video_set_marquee_string(p_mi, libvlc_marquee_Text, NIL) else libvlc_video_set_marquee_string(p_mi, libvlc_marquee_Text, PAnsiChar(UTF8Encode(marquee_text))); end; procedure TFmxPasLibVlcPlayer.MarqueeSetPosition(position_x, position_y : Integer); begin if not Assigned(p_mi) then exit; libvlc_video_set_marquee_int(p_mi, libvlc_marquee_X, position_x); libvlc_video_set_marquee_int(p_mi, libvlc_marquee_Y, position_y); end; procedure TFmxPasLibVlcPlayer.MarqueeSetPosition(position : libvlc_position_t); begin if not Assigned(p_mi) then exit; libvlc_video_set_marquee_int(p_mi, libvlc_marquee_Position, Ord(position)); end; procedure TFmxPasLibVlcPlayer.MarqueeSetColor(color : libvlc_video_marquee_color_t); begin if not Assigned(p_mi) then exit; libvlc_video_set_marquee_int(p_mi, libvlc_marquee_Color, color); end; procedure TFmxPasLibVlcPlayer.MarqueeSetFontSize(font_size: Integer); begin if not Assigned(p_mi) then exit; libvlc_video_set_marquee_int(p_mi, libvlc_marquee_Size, font_size); end; procedure TFmxPasLibVlcPlayer.MarqueeSetOpacity(opacity: libvlc_opacity_t); begin if not Assigned(p_mi) then exit; libvlc_video_set_marquee_int(p_mi, libvlc_marquee_Opacity, opacity); end; procedure TFmxPasLibVlcPlayer.MarqueeSetTimeOut(time_out_ms: Integer); begin if not Assigned(p_mi) then exit; libvlc_video_set_marquee_int(p_mi, libvlc_marquee_Timeout, time_out_ms); end; procedure TFmxPasLibVlcPlayer.MarqueeSetRefresh(refresh_after_ms: Integer); begin if not Assigned(p_mi) then exit; libvlc_video_set_marquee_int(p_mi, libvlc_marquee_Refresh, refresh_after_ms); end; procedure TFmxPasLibVlcPlayer.MarqueeSetEnable(enable : Integer); begin if not Assigned(p_mi) then exit; libvlc_video_set_marquee_int(p_mi, libvlc_marquee_Enable, enable); // not work end; procedure TFmxPasLibVlcPlayer.MarqueeShowText(marquee_text : WideString; position_x, position_y : Integer; color : libvlc_video_marquee_color_t = libvlc_video_marquee_color_White; font_size: Integer = libvlc_video_marquee_default_font_size; opacity: libvlc_opacity_t = libvlc_opacity_full; time_out_ms: Integer = 0); begin MarqueeSetText(marquee_text); MarqueeSetPosition(position_x, position_y); MarqueeSetColor(color); MarqueeSetOpacity(opacity); MarqueeSetFontSize(font_size); MarqueeSetTimeOut(time_out_ms); // hide after timeout ms, 0 - show always MarqueeSetRefresh(0); MarqueeSetEnable(1); // handle dynamic strings in form %H:%M:%S if (Pos(WideString('%H'), marquee_text) > 0) then MarqueeSetRefresh(3600 * 1000); if (Pos(WideString('%M'), marquee_text) > 0) then MarqueeSetRefresh( 60 * 1000); if (Pos(WideString('%S'), marquee_text) > 0) then MarqueeSetRefresh( 1000); end; procedure TFmxPasLibVlcPlayer.MarqueeShowText(marquee_text : WideString; position : libvlc_position_t = libvlc_position_bottom; color : libvlc_video_marquee_color_t = libvlc_video_marquee_color_White; font_size: Integer = libvlc_video_marquee_default_font_size; opacity: libvlc_opacity_t = libvlc_opacity_full; time_out_ms: Integer = 0); begin MarqueeSetText(marquee_text); MarqueeSetPosition(position); MarqueeSetColor(color); MarqueeSetOpacity(opacity); MarqueeSetFontSize(font_size); MarqueeSetTimeOut(time_out_ms); // hide after timeout ms, 0 - show always MarqueeSetRefresh(0); MarqueeSetEnable(1); // handle dynamic strings in form %H:%M:%S if (Pos(WideString('%H'), marquee_text) > 0) then MarqueeSetRefresh(3600 * 1000); if (Pos(WideString('%M'), marquee_text) > 0) then MarqueeSetRefresh( 60 * 1000); if (Pos(WideString('%S'), marquee_text) > 0) then MarqueeSetRefresh( 1000); end; procedure TFmxPasLibVlcPlayer.MarqueeHide(); begin MarqueeSetEnable(0); MarqueeSetRefresh(0); MarqueeSetText(''); end; //////////////////////////////////////////////////////////////////////////////// procedure TFmxPasLibVlcPlayer.InternalHandleEvent_MediaChanged(p_md : libvlc_media_t_ptr); var tmp : PAnsiChar; mrl : string; begin if Assigned(FOnMediaPlayerMediaChanged) then begin if (p_md <> NIL) then begin tmp := libvlc_media_get_mrl(p_md); mrl := UTF8ToWideString(tmp); end else begin mrl := ''; end; FOnMediaPlayerMediaChanged(SELF, mrl); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_NothingSpecial(); begin if Assigned(FOnMediaPlayerNothingSpecial) then FOnMediaPlayerNothingSpecial(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_Opening(); begin if Assigned(FOnMediaPlayerOpening) then FOnMediaPlayerOpening(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_Buffering(); begin if Assigned(FOnMediaPlayerBuffering) then FOnMediaPlayerBuffering(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_Playing(); begin if Assigned(FOnMediaPlayerPlaying) then FOnMediaPlayerPlaying(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_Paused(); begin if Assigned(FOnMediaPlayerPaused) then FOnMediaPlayerPaused(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_Stopped(); begin if Assigned(FOnMediaPlayerStopped) then FOnMediaPlayerStopped(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_Forward(); begin if Assigned(FOnMediaPlayerForward) then FOnMediaPlayerForward(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_Backward(); begin if Assigned(FOnMediaPlayerBackward) then FOnMediaPlayerBackward(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_EndReached(); begin if Assigned(FOnMediaPlayerEndReached) then FOnMediaPlayerEndReached(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_EncounteredError(); var tmp : PAnsiChar; begin tmp := libvlc_errmsg(); if (tmp <> NIL) then begin FError := UTF8ToWideString(tmp); end else begin FError := ''; end; if Assigned(FOnMediaPlayerEncounteredError) then FOnMediaPlayerEncounteredError(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_TimeChanged(new_time : libvlc_time_t); begin if Assigned(FOnMediaPlayerTimeChanged) then begin FOnMediaPlayerTimeChanged(SELF, new_time); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_PositionChanged(new_position : Single); begin if Assigned(FOnMediaPlayerPositionChanged) then begin FOnMediaPlayerPositionChanged(SELF, new_position); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_SeekableChanged(new_seekable : Integer); begin if Assigned(FOnMediaPlayerSeekableChanged) then begin FOnMediaPlayerSeekableChanged(SELF, new_seekable <> 0); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_PausableChanged(new_pausable : Integer); begin if Assigned(FOnMediaPlayerPausableChanged) then begin FOnMediaPlayerPausableChanged(SELF, new_pausable <> 0); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_TitleChanged(new_title : Integer); begin if Assigned(FOnMediaPlayerTitleChanged) then begin FOnMediaPlayerTitleChanged(SELF, new_title); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_SnapshotTaken(psz_filename : PAnsiChar); begin if Assigned(FOnMediaPlayerSnapshotTaken) then begin FOnMediaPlayerSnapshotTaken(SELF, UTF8ToWideString(psz_filename)); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_LengthChanged(new_length : libvlc_time_t); begin if Assigned(FOnMediaPlayerLengthChanged) then begin FOnMediaPlayerLengthChanged(SELF, new_length); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_VOutChanged(new_count : Integer); begin if Assigned(FOnMediaPlayerVideoOutChanged) then begin FOnMediaPlayerVideoOutChanged(SELF, new_count); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_ScrambledChanged(new_scrambled : Integer); begin if Assigned(FOnMediaPlayerScrambledChanged) then begin FOnMediaPlayerScrambledChanged(SELF, new_scrambled); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_Corked(); begin if Assigned(FOnMediaPlayerCorked) then FOnMediaPlayerCorked(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_UnCorked(); begin if Assigned(FOnMediaPlayerUnCorked) then FOnMediaPlayerUnCorked(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_Muted(); begin if Assigned(FOnMediaPlayerMuted) then FOnMediaPlayerMuted(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_Unmuted(); begin if Assigned(FOnMediaPlayerUnMuted) then FOnMediaPlayerUnMuted(SELF); end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_AudioVolumeChanged(volume : Single); begin if Assigned(FOnMediaPlayerAudioVolumeChanged) then begin FOnMediaPlayerAudioVolumeChanged(SELF, volume); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_VideoSizeChanged(video_w, video_h, video_w_a32, video_h_a32 : LongWord); begin if Assigned(FOnMediaPlayerVideoSizeChanged) then begin FOnMediaPlayerVideoSizeChanged(SELF, video_w, video_h, video_w_a32, video_h_a32); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_MediaPlayerEsAdded(i_type : libvlc_track_type_t; i_id : Integer); begin if Assigned(FOnMediaPlayerEsAdded) then begin FOnMediaPlayerEsAdded(SELF, i_type, i_id); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_MediaPlayerEsDeleted(i_type : libvlc_track_type_t; i_id : Integer); begin if Assigned(FOnMediaPlayerEsDeleted) then begin FOnMediaPlayerEsDeleted(SELF, i_type, i_id); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_MediaPlayerEsSelected(i_type : libvlc_track_type_t; i_id : Integer); begin if Assigned(FOnMediaPlayerEsSelected) then begin FOnMediaPlayerEsSelected(SELF, i_type, i_id); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_MediaPlayerAudioDevice(audio_device : PAnsiChar); begin if Assigned(FOnMediaPlayerAudioDevice) then begin FOnMediaPlayerAudioDevice(SELF, UTF8ToWideString(audio_device)); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_MediaPlayerChapterChanged(chapter : Integer); begin if Assigned(FOnMediaPlayerChapterChanged) then begin FOnMediaPlayerChapterChanged(SELF, chapter); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_RendererDiscoveredItemAdded(item : libvlc_renderer_item_t_ptr); begin if Assigned(FOnRendererDiscoveredItemAdded) then begin FOnRendererDiscoveredItemAdded(SELF, item); end; end; procedure TFmxPasLibVlcPlayer.InternalHandleEvent_RendererDiscoveredItemDeleted(item : libvlc_renderer_item_t_ptr); begin if Assigned(FOnRendererDiscoveredItemDeleted) then begin FOnRendererDiscoveredItemDeleted(SELF, item); end; end; procedure TFmxPasLibVlcPlayer.Paint; var bmp : TBitmap; bmd : TBitmapData; src_buff : PByte; dst_buff : PByte; pitch : LongWord; video_l : LongWord; begin inherited Paint; if (FVideoCbCtx = NIL) then exit; with FVideoCbCtx do begin with vctx do begin bmp := TBitmap.Create(video_w, video_h); frame_lock.Enter(); try if (frame_buff <> NIL) then begin if bmp.Map(TMapAccess.Write, bmd) then begin src_buff := frame_buff; dst_buff := bmd.GetScanline(0); if (video_h = LongWord(bmd.Height)) and (LongWord(bmd.Pitch) = pitch_w_a32) then begin System.Move(src_buff^, dst_buff^, bmd.Pitch * bmd.Height); end else begin pitch := pitch_w_a32; if (Integer(pitch) > bmd.Pitch) then begin pitch := bmd.Pitch; end; video_l := video_h; if (Integer(video_l) > bmd.Height) then begin video_l := bmd.Height; end; while (video_l > 0) do begin System.Move(src_buff^, dst_buff^, pitch); Inc(src_buff, pitch_w_a32); Inc(dst_buff, bmd.Pitch); Dec(video_l); end; end; bmp.Unmap(bmd); end; end else begin bmp.Clear(TAlphaColorRec.Black); end; finally frame_lock.Leave(); end; Bitmap.Assign(bmp); FreeAndNil(bmp); end; end; end; //////////////////////////////////////////////////////////////////////////////// function fmx_libvlc_video_lock_cb(ptr : Pointer; planes : PVCBPlanes) : Pointer; cdecl; var ctx : TFmxPasLibVlcVideoCbCtx; pIdx : Integer; begin Result := NIL; if (ptr = NIL) then exit; ctx := TFmxPasLibVlcVideoCbCtx(ptr); with ctx do begin with vctx do begin lock.Enter(); for pIdx := 0 to VOUT_MAX_PLANES - 1 do begin planes^[pIdx] := buff_a32[pIdx]; end; Result := buff_a32[0]; end; end; end; procedure fmx_libvlc_video_unlock_cb(ptr : Pointer; picture : Pointer; planes : PVCBPlanes); cdecl; var ctx : TFmxPasLibVlcVideoCbCtx; begin if (ptr = NIL) then exit; ctx := TFmxPasLibVlcVideoCbCtx(ptr); with ctx do begin with vctx do begin lock.Leave(); end; end; end; procedure fmx_libvlc_video_display_cb(ptr : Pointer; picture : Pointer); cdecl; var ctx : TFmxPasLibVlcVideoCbCtx; begin if (ptr = NIL) then exit; ctx := TFmxPasLibVlcVideoCbCtx(ptr); with ctx do begin with vctx do begin if frame_lock.TryEnter() then begin try // RV32, RGBA, BGRA we show only first plane if (frame_buff <> NIL) then begin if (buff_a32[0] <> NIL) then begin Move(buff_a32[0]^, frame_buff^, pitch_w_a32 * video_h); end; end; finally frame_lock.Leave(); end; if (view <> NIL) then begin view.InvalidateRect(view.BoundsRect); end; end; end; end; end; function fmx_libvlc_video_format_cb(var ptr : Pointer; chroma : PAnsiChar; var width : LongWord; var height : LongWord; pitches : PVCBPitches; lines : PVCBLines) : LongWord; cdecl; const // src/misc/fourcc.c: fourcc helpers functions PixelFormatChromas: array[FMX.Types.TPixelFormat] of string[4] = ( { None 0}'RV32', { RGB 4}'RV32', { RGBA 4}'RGBA', // OSX 10.7.5, 32bits { BGR 4}'RV32', { BGRA 4}'BGRA', // Windows 7, 32bits { RGBA16 8}'RV32', { BGR_565 2}'RV32', { BGRA4 2}'RV32', { BGR4 2}'RV32', { BGR5_A1 2}'RV32', { BGR5 2}'RV32', { BGR10_A2 4}'RV32', { RGB10_A2 4}'RV32', { L 1}'RV32', { LA 2}'RV32', { LA4 1}'RV32', { L16 2}'RV32', { A 1}'RV32', { R16F 2}'RV32', { RG16F 4}'RV32', { RGBA16F 8}'RV32', { R32F 4}'RV32', { RG32F 8}'RV32', { RGBA32F 16}'RV32' ); type PChromaStr = ^TChromaStr; TChromaStr = packed array[0..3] of AnsiChar; var ctx : TFmxPasLibVlcVideoCbCtx; idx : Integer; begin Result := 0; if (ptr = NIL) then exit; ctx := TFmxPasLibVlcVideoCbCtx(ptr); with ctx do begin for idx := 1 to 4 do begin PChromaStr(chroma)^[idx-1] := AnsiChar(PixelFormatChromas[frame_pixel_format][idx]); end; with vctx do begin lock.Enter(); try libvlc_video_cb_vctx_set_buffers(@vctx, width, height, PixelFormatBytes[frame_pixel_format], pitches, lines); frame_lock.Enter(); try if (frame_buff <> NIL) then begin FreeMem(frame_buff); frame_buff := NIL; end; GetMem(frame_buff, pitch_w_a32 * video_h_a32); finally frame_lock.Leave(); end; (view as TFmxPasLibVlcPlayer).InternalHandleEvent_VideoSizeChanged(video_w, video_h, video_w_a32, video_h_a32); if (view <> NIL) then begin view.InvalidateRect(view.BoundsRect); end; finally lock.Leave(); end; end; // with vctx do end; // with ctx do Result := 1; end; procedure fmx_libvlc_video_cleanup_cb(ptr : Pointer); cdecl; var ctx : TFmxPasLibVlcVideoCbCtx; begin if (ptr = NIL) then exit; ctx := TFmxPasLibVlcVideoCbCtx(ptr); with ctx do begin with vctx do begin lock.Enter(); try libvlc_video_cb_vctx_clr_buffers(@vctx); frame_lock.Enter(); try if (frame_buff <> NIL) then begin FreeMem(frame_buff); frame_buff := NIL; end; finally frame_lock.Leave(); end; finally lock.Leave(); end end; // with vctx do end; // with ctx do end; procedure fmx_lib_vlc_player_event_hdlr(p_event: libvlc_event_t_ptr; data: Pointer); cdecl; var player: TFmxPasLibVlcPlayer; begin if (data = NIL) then exit; player := TFmxPasLibVlcPlayer(data); if not Assigned(player) then exit; if Assigned(player.FOnMediaPlayerEvent) then player.FOnMediaPlayerEvent(p_event, data); with p_event^ do begin case event_type of libvlc_MediaPlayerMediaChanged: player.InternalHandleEvent_MediaChanged(media_player_media_changed.new_media); libvlc_MediaPlayerTimeChanged: player.InternalHandleEvent_TimeChanged(media_player_time_changed.new_time); libvlc_MediaPlayerSnapshotTaken: player.InternalHandleEvent_SnapshotTaken(media_player_snapshot_taken.psz_filename); libvlc_MediaPlayerLengthChanged: player.InternalHandleEvent_LengthChanged(media_player_length_changed.new_length); libvlc_MediaPlayerPositionChanged: player.InternalHandleEvent_PositionChanged(media_player_position_changed.new_position); libvlc_MediaPlayerSeekableChanged: player.InternalHandleEvent_SeekableChanged(media_player_seekable_changed.new_seekable); libvlc_MediaPlayerPausableChanged: player.InternalHandleEvent_PausableChanged(media_player_pausable_changed.new_pausable); libvlc_MediaPlayerTitleChanged: player.InternalHandleEvent_TitleChanged(media_player_title_changed.new_title); libvlc_MediaPlayerNothingSpecial: player.InternalHandleEvent_NothingSpecial(); libvlc_MediaPlayerOpening: player.InternalHandleEvent_Opening(); libvlc_MediaPlayerBuffering: player.InternalHandleEvent_Buffering(); libvlc_MediaPlayerPlaying: player.InternalHandleEvent_Playing(); libvlc_MediaPlayerPaused: player.InternalHandleEvent_Paused(); libvlc_MediaPlayerStopped: player.InternalHandleEvent_Stopped(); libvlc_MediaPlayerForward: player.InternalHandleEvent_Forward(); libvlc_MediaPlayerBackward: player.InternalHandleEvent_Backward(); libvlc_MediaPlayerEndReached: player.InternalHandleEvent_EndReached(); libvlc_MediaPlayerEncounteredError: player.InternalHandleEvent_EncounteredError(); libvlc_MediaPlayerVout: player.InternalHandleEvent_VoutChanged(media_player_vout.new_count); libvlc_MediaPlayerScrambledChanged: player.InternalHandleEvent_ScrambledChanged(media_player_scrambled_changed.new_scrambled); libvlc_MediaPlayerCorked: player.InternalHandleEvent_Corked(); libvlc_MediaPlayerUncorked: player.InternalHandleEvent_Uncorked(); libvlc_MediaPlayerMuted: player.InternalHandleEvent_Muted(); libvlc_MediaPlayerUnmuted: player.InternalHandleEvent_Unmuted(); libvlc_MediaPlayerAudioVolume: player.InternalHandleEvent_AudioVolumeChanged(media_player_audio_volume.volume); libvlc_MediaPlayerESAdded: player.InternalHandleEvent_MediaPlayerEsAdded(media_player_es_changed.i_type, media_player_es_changed.i_id); libvlc_MediaPlayerESDeleted: player.InternalHandleEvent_MediaPlayerEsDeleted(media_player_es_changed.i_type, media_player_es_changed.i_id); libvlc_MediaPlayerESSelected: player.InternalHandleEvent_MediaPlayerEsSelected(media_player_es_changed.i_type, media_player_es_changed.i_id); libvlc_MediaPlayerAudioDevice: player.InternalHandleEvent_MediaPlayerAudioDevice(media_player_audio_device.device); libvlc_MediaPlayerChapterChanged: player.InternalHandleEvent_MediaPlayerChapterChanged(media_player_chapter_changed.new_chapter); libvlc_RendererDiscovererItemAdded: player.InternalHandleEvent_RendererDiscoveredItemAdded(renderer_discoverer_item_added.item); libvlc_RendererDiscovererItemDeleted: player.InternalHandleEvent_RendererDiscoveredItemDeleted(renderer_discoverer_item_deleted.item); end; end; end; //////////////////////////////////////////////////////////////////////////////// constructor TFmxPasLibVlcVideoCbCtx.Create(AView : FMX.Objects.TImage; aWidth : Integer = 320; aHeight : Integer = 160); var bmpt : TBitmap; bmpd : TBitmapData; begin inherited Create; frame_lock := TCriticalSection.Create; with vctx do begin lock := TCriticalSection.Create; libvlc_video_cb_vctx_set_buffers(@vctx, aWidth, aHeight); end; GetMem(frame_buff, vctx.pitch_w_a32 * vctx.video_h_a32); view := AView; frame_pixel_format := TPixelFormat.BGRA; bmpt := TBitmap.Create(vctx.video_w_a32, vctx.video_h_a32); bmpt.Clear(TAlphaColorRec.Black); if (bmpt.Map(TMapAccess.Read, bmpd)) then begin frame_pixel_format := bmpd.PixelFormat; System.Move(bmpd.GetScanline(0)^, frame_buff^, vctx.pitch_w_a32 * vctx.video_h_a32); bmpt.Unmap(bmpd); end; FreeAndNil(bmpt); end; destructor TFmxPasLibVlcVideoCbCtx.Destroy; begin view := NIL; FreeAndNil(frame_lock); if (frame_buff <> NIL) then begin FreeMem(frame_buff); frame_buff := NIL; end; libvlc_video_cb_vctx_clr_buffers(@vctx); with vctx do begin FreeAndNil(lock); end; inherited Destroy; end; initialization finalization end.