From 62c310a7b9ac85a1f5eabf80172efcc5204eda4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20D=C3=ADaz=20Fau?= Date: Sun, 19 Apr 2020 22:47:20 +0200 Subject: [PATCH] Update to CEF 81.2.17 - New MediaRouter demo (still buggy) - Removed TCEFMediaObserverComponent and merged all the ICefMediaObserver methods and events into TChromium. - Fixed some Media Observer parameters - Added TChromium.RequestContext - Added TChromium.MediaRouter - Added TChromium.MediaObserver - Added TChromium.Registration --- README.md | 8 +- .../Delphi_VCL/MediaRouter/00-DeleteDCUs.bat | 18 + .../Delphi_VCL/MediaRouter/MediaRouter.dpr | 46 +- .../Delphi_VCL/MediaRouter/MediaRouter.dproj | 1004 +++++++++++++++++ demos/Delphi_VCL/MediaRouter/cef.inc | 409 +++++++ .../MediaRouter/uMediaRouterFrm.dfm | 314 ++++++ .../MediaRouter/uMediaRouterFrm.pas | 704 ++++++++++++ .../SimpleOSRBrowser/SimpleOSRBrowser.lps | 8 +- packages/CEF4Delphi.dpk | 4 +- packages/CEF4Delphi.dproj | 2 - packages/CEF4Delphi_D7.dpk | 4 +- packages/CEF4Delphi_D7_Register.pas | 5 +- packages/CEF4Delphi_FMX.dpk | 4 +- packages/CEF4Delphi_FMX.dproj | 2 - packages/CEF4Delphi_FMX_Register.pas | 4 +- packages/CEF4Delphi_Register.pas | 5 +- packages/cef4delphi_lazarus.lpk | 35 +- packages/cef4delphi_lazarus.pas | 9 +- source/uCEFApplicationCore.pas | 4 +- source/uCEFChromiumCore.pas | 204 +++- source/uCEFChromiumEvents.pas | 7 + source/uCEFInterfaces.pas | 50 +- source/uCEFMediaObserver.pas | 73 +- source/uCEFMediaObserverComponent.pas | 188 --- source/uCEFMediaRoute.pas | 16 +- source/uCEFMediaRouteCreateCallback.pas | 138 ++- source/uCEFTypes.pas | 3 + update_CEF4Delphi.json | 4 +- 28 files changed, 2934 insertions(+), 338 deletions(-) create mode 100644 demos/Delphi_VCL/MediaRouter/00-DeleteDCUs.bat rename source/uCEFMediaObserverEvents.pas => demos/Delphi_VCL/MediaRouter/MediaRouter.dpr (64%) create mode 100644 demos/Delphi_VCL/MediaRouter/MediaRouter.dproj create mode 100644 demos/Delphi_VCL/MediaRouter/cef.inc create mode 100644 demos/Delphi_VCL/MediaRouter/uMediaRouterFrm.dfm create mode 100644 demos/Delphi_VCL/MediaRouter/uMediaRouterFrm.pas delete mode 100644 source/uCEFMediaObserverComponent.pas diff --git a/README.md b/README.md index 37313d9d..57bcaee6 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ CEF4Delphi is an open source project created by Salvador D CEF4Delphi is based on DCEF3, made by Henri Gourvest. The original license of DCEF3 still applies to CEF4Delphi. Read the license terms in the first lines of any *.pas file. -CEF4Delphi uses CEF 81.2.16 which includes Chromium 81.0.4044.92. +CEF4Delphi uses CEF 81.2.17 which includes Chromium 81.0.4044.113. The CEF binaries used by CEF4Delphi are available for download at spotify : -* 32 bits not available at this moment. -* [64 bits](http://opensource.spotify.com/cefbuilds/cef_binary_81.2.16%2Bgdacda4f%2Bchromium-81.0.4044.92_windows64.tar.bz2) +* [32 bits](http://opensource.spotify.com/cefbuilds/cef_binary_81.2.17%2Bgb382c62%2Bchromium-81.0.4044.113_windows32.tar.bz2) +* [64 bits](http://opensource.spotify.com/cefbuilds/cef_binary_81.2.17%2Bgb382c62%2Bchromium-81.0.4044.113_windows64.tar.bz2) -CEF4Delphi was developed and tested on Delphi 10.3.3 and it has been tested in Delphi 7, Delphi XE, Delphi 10, Delphi 10.2 and Lazarus 2.0.6/FPC 3.0.4. CEF4Delphi includes VCL, FireMonkey (FMX) and Lazarus components. +CEF4Delphi was developed and tested on Delphi 10.3.3 and it has been tested in Delphi 7, Delphi XE, Delphi 10, Delphi 10.2 and Lazarus 2.0.8/FPC 3.0.4. CEF4Delphi includes VCL, FireMonkey (FMX) and Lazarus components. ## Links * [Installation instructions and more information about CEF4Delphi](https://www.briskbard.com/index.php?lang=en&pageid=cef) diff --git a/demos/Delphi_VCL/MediaRouter/00-DeleteDCUs.bat b/demos/Delphi_VCL/MediaRouter/00-DeleteDCUs.bat new file mode 100644 index 00000000..a9a84095 --- /dev/null +++ b/demos/Delphi_VCL/MediaRouter/00-DeleteDCUs.bat @@ -0,0 +1,18 @@ +del /s /q *.dcu +del /s /q *.exe +del /s /q *.res +del /s /q *.rsm +del /s /q *.log +del /s /q *.dsk +del /s /q *.identcache +del /s /q *.stat +del /s /q *.local +del /s /q *.~* +rmdir Win32\Debug +rmdir Win32\Release +rmdir Win32 +rmdir Win64\Debug +rmdir Win64\Release +rmdir Win64 +rmdir __history +rmdir __recovery diff --git a/source/uCEFMediaObserverEvents.pas b/demos/Delphi_VCL/MediaRouter/MediaRouter.dpr similarity index 64% rename from source/uCEFMediaObserverEvents.pas rename to demos/Delphi_VCL/MediaRouter/MediaRouter.dpr index 0c2c72ff..0a33cfbe 100644 --- a/source/uCEFMediaObserverEvents.pas +++ b/demos/Delphi_VCL/MediaRouter/MediaRouter.dpr @@ -2,7 +2,7 @@ // ***************************** CEF4Delphi ******************************* // ************************************************************************ // -// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based +// CEF4Delphi is based on DCEF3 which uses CEF3 to embed a chromium-based // browser in Delphi applications. // // The original license of DCEF3 still applies to CEF4Delphi. @@ -10,7 +10,7 @@ // For more information about CEF4Delphi visit : // https://www.briskbard.com/index.php?lang=en&pageid=cef // -// Copyright © 2020 Salvador Diaz Fau. All rights reserved. +// Copyright © 2018 Salvador Díaz Fau. All rights reserved. // // ************************************************************************ // ************ vvvv Original license and comments below vvvv ************* @@ -35,33 +35,35 @@ * *) -unit uCEFMediaObserverEvents; - -{$IFDEF FPC} - {$MODE OBJFPC}{$H+} -{$ENDIF} - -{$IFNDEF CPUX64}{$ALIGN ON}{$ENDIF} -{$MINENUMSIZE 4} +program MediaRouter; {$I cef.inc} -interface - uses {$IFDEF DELPHI16_UP} - System.Classes, + Vcl.Forms, + WinApi.Windows, {$ELSE} - Classes, - {$ENDIF} - uCEFTypes, uCEFInterfaces; + Forms, + Windows, + {$ENDIF } + uCEFApplication, + uMediaRouterFrm in 'uMediaRouterFrm.pas' {MediaRouterFrm}; -type - TOnSinksEvent = procedure(Sender: TObject; const sinks: TCefMediaSinkArray) of object; - TOnRoutesEvent = procedure(Sender: TObject; const routes: TCefMediaRouteArray) of object; - TOnRouteStateChangedEvent = procedure(Sender: TObject; const route: ICefMediaRoute; state: TCefMediaRouteConnectionState) of object; - TOnRouteMessageReceivedEvent = procedure(Sender: TObject; const route: ICefMediaRoute; const message_: Pointer; message_size: NativeUInt) of object; +{$R *.res} -implementation +{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE} +begin + CreateGlobalCEFApp; + + if GlobalCEFApp.StartMainProcess then + begin + Application.Initialize; + Application.MainFormOnTaskbar := True; + Application.CreateForm(TMediaRouterFrm, MediaRouterFrm); + Application.Run; + end; + + DestroyGlobalCEFApp; end. diff --git a/demos/Delphi_VCL/MediaRouter/MediaRouter.dproj b/demos/Delphi_VCL/MediaRouter/MediaRouter.dproj new file mode 100644 index 00000000..a8f932f7 --- /dev/null +++ b/demos/Delphi_VCL/MediaRouter/MediaRouter.dproj @@ -0,0 +1,1004 @@ + + + {9066DF5D-7897-4275-9B69-05383498F465} + 18.8 + VCL + MediaRouter.dpr + True + Debug + Win64 + 3 + Application + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + .\$(Platform)\$(Config) + ..\..\..\bin + false + false + false + false + false + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + MediaRouter + 3082 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + + + DBXSqliteDriver;bindcompdbx;fmxase;DBXDb2Driver;DBXInterBaseDriver;vcl;DBXSybaseASEDriver;vclactnband;RESTComponents;vclFireDAC;CEF4Delphi_runtime;FireDACDb2Driver;IndyCore250;DataSnapFireDAC;svnui;tethering;dsnapcon;FireDACADSDriver;Componentes;FireDACMSAccDriver;fmxFireDAC;DBXMSSQLDriver;vclimg;FireDACInfxDriver;DatasnapConnectorsFreePascal;FireDAC;FireDACMSSQLDriver;vcltouch;VisualStyles_runtime;Componentes_UI;vcldb;bindcompfmx;svn;FireDACSqliteDriver;FireDACPgDriver;DBXOracleDriver;inetdb;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;SVGPackage;soaprtl;DbxCommonDriver;FireDACIBDriver;fmx;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;fmxdae;vclwinx;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;dbexpress;FireDACDBXDriver;vclx;bindcomp;appanalytics;dsnap;DataSnapCommon;DBXInformixDriver;FireDACCommon;bindcompvcl;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;DBXFirebirdDriver;DataSnapProviderClient;FireDACMongoDBDriver;FireDACCommonODBC;FireDACCommonDriver;CloudService;DataSnapClient;IndySystem250;IndyProtocols250;inet;DataSnapServerMidas;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + $(BDS)\bin\default_app.manifest + + + DBXSqliteDriver;bindcompdbx;fmxase;DBXDb2Driver;DBXInterBaseDriver;vcl;DBXSybaseASEDriver;vclactnband;RESTComponents;vclFireDAC;CEF4Delphi_runtime;FireDACDb2Driver;IndyCore250;DataSnapFireDAC;tethering;dsnapcon;FireDACADSDriver;Componentes;FireDACMSAccDriver;fmxFireDAC;DBXMSSQLDriver;vclimg;FireDACInfxDriver;DatasnapConnectorsFreePascal;FireDAC;FireDACMSSQLDriver;vcltouch;VisualStyles_runtime;Componentes_UI;vcldb;bindcompfmx;FireDACSqliteDriver;FireDACPgDriver;DBXOracleDriver;inetdb;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;SVGPackage;soaprtl;DbxCommonDriver;FireDACIBDriver;fmx;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;fmxdae;vclwinx;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;dbexpress;FireDACDBXDriver;vclx;bindcomp;appanalytics;dsnap;DataSnapCommon;DBXInformixDriver;FireDACCommon;bindcompvcl;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;DBXFirebirdDriver;DataSnapProviderClient;FireDACMongoDBDriver;FireDACCommonODBC;FireDACCommonDriver;CloudService;DataSnapClient;IndySystem250;IndyProtocols250;inet;DataSnapServerMidas;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + true + 1033 + $(BDS)\bin\default_app.manifest + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + true + PerMonitorV2 + true + 1033 + + + true + PerMonitorV2 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + true + PerMonitorV2 + + + true + PerMonitorV2 + + + + MainSource + + +
MediaRouterFrm
+ dfm +
+ + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + +
+ + Delphi.Personality.12 + Application + + + + MediaRouter.dpr + + + IP Abstraction Indy Implementation Design Time + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + MediaRouter.exe + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + classes + 1 + + + classes + 1 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + 1 + + + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + True + True + + + 12 + + + + +
diff --git a/demos/Delphi_VCL/MediaRouter/cef.inc b/demos/Delphi_VCL/MediaRouter/cef.inc new file mode 100644 index 00000000..8334dc78 --- /dev/null +++ b/demos/Delphi_VCL/MediaRouter/cef.inc @@ -0,0 +1,409 @@ +// ************************************************************************ +// ***************************** CEF4Delphi ******************************* +// ************************************************************************ +// +// CEF4Delphi is based on DCEF3 which uses CEF3 to embed a chromium-based +// browser in Delphi applications. +// +// The original license of DCEF3 still applies to CEF4Delphi. +// +// For more information about CEF4Delphi visit : +// https://www.briskbard.com/index.php?lang=en&pageid=cef +// +// Copyright © 2017 Salvador Diaz Fau. All rights reserved. +// +// ************************************************************************ +// ************ vvvv Original license and comments below vvvv ************* +// ************************************************************************ +(* + * Delphi Chromium Embedded 3 + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Unit owner : Henri Gourvest + * Web site : http://www.progdigy.com + * Repository : http://code.google.com/p/delphichromiumembedded/ + * Group : http://groups.google.com/group/delphichromiumembedded + * + * Embarcadero Technologies, Inc is not permitted to use or redistribute + * this source code without explicit permission. + * + *) + + // The complete list of compiler versions is here : + // http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Compiler_Versions + +{$DEFINE DELPHI_VERSION_UNKNOW} + +// Delphi 5 +{$IFDEF VER130} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} +{$ENDIF} + +// Delphi 6 +{$IFDEF VER140} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} +{$ENDIF} + +// Delphi 7 +{$IFDEF VER150} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} +{$ENDIF} + +// Delphi 8 +{$IFDEF VER160} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} +{$ENDIF} + +// Delphi 2005 +{$IFDEF VER170} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} +{$ENDIF} + +{$IFDEF VER180} + {$UNDEF DELPHI_VERSION_UNKNOW} + // Delphi 2007 + {$IFDEF VER185} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + // Delphi 2006 + {$ELSE} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$ENDIF} +{$ENDIF} + +// Delphi 2009 +{$IFDEF VER200} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} +{$ENDIF} + +//Delphi 2010 +{$IFDEF VER210} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} +{$ENDIF} + +// Delphi XE +{$IFDEF VER220} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} +{$ENDIF} + +// Delphi XE2 (First FireMonkey and 64bit compiler) +{$IFDEF VER230} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} +{$ENDIF} + +// Delphi XE3 +{$IFDEF VER240} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} +{$ENDIF} + +// Delphi XE4 +{$IFDEF VER250} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} +{$ENDIF} + +// Delphi XE5 +{$IFDEF VER260} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} +{$ENDIF} + +// Delphi XE6 +{$IFDEF VER270} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} +{$ENDIF} + +// Delphi XE7 +{$IFDEF VER280} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} +{$ENDIF} + +// Delphi XE8 +{$IFDEF VER290} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} +{$ENDIF VER290} + +// Rad Studio 10 - Delphi Seattle +{$IFDEF VER300} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} +{$ENDIF} + +// Rad Studio 10.1 - Delphi Berlin +{$IFDEF VER310} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} +{$ENDIF} + +// Rad Studio 10.2 - Delphi Tokyo +{$IFDEF VER320} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI25_UP} +{$ENDIF} + +// Rad Studio 10.3 - Delphi Rio +{$IFDEF VER330} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI26_UP} +{$ENDIF} + +{$IFDEF FPC} + {$DEFINE SUPPORTS_INLINE} +{$ELSE} + {$IFDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI26_UP} + {$ENDIF} +{$ENDIF} + +{$IFDEF DELPHI9_UP} + {$DEFINE SUPPORTS_INLINE} +{$ENDIF} + diff --git a/demos/Delphi_VCL/MediaRouter/uMediaRouterFrm.dfm b/demos/Delphi_VCL/MediaRouter/uMediaRouterFrm.dfm new file mode 100644 index 00000000..b3cf3b31 --- /dev/null +++ b/demos/Delphi_VCL/MediaRouter/uMediaRouterFrm.dfm @@ -0,0 +1,314 @@ +object MediaRouterFrm: TMediaRouterFrm + Left = 0 + Top = 0 + Caption = 'Media Router' + ClientHeight = 757 + ClientWidth = 1029 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + Position = poScreenCenter + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + OnDestroy = FormDestroy + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 13 + object CEFWindowParent1: TCEFWindowParent + Left = 184 + Top = 56 + Width = 0 + Height = 0 + TabOrder = 0 + Visible = False + Enabled = False + end + object MainPnl: TPanel + Left = 0 + Top = 0 + Width = 1029 + Height = 757 + Align = alClient + BevelOuter = bvNone + Padding.Left = 15 + Padding.Top = 15 + Padding.Right = 15 + Padding.Bottom = 15 + TabOrder = 1 + object SinksGbx: TGroupBox + Left = 15 + Top = 15 + Width = 250 + Height = 727 + Align = alLeft + Caption = ' Sinks available on this network ' + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 0 + object SinksLbx: TListBox + Left = 12 + Top = 25 + Width = 226 + Height = 616 + Align = alClient + ItemHeight = 13 + TabOrder = 0 + OnClick = SinksLbxClick + end + object SinksButtonsPnl: TPanel + Left = 12 + Top = 641 + Width = 226 + Height = 74 + Align = alBottom + BevelOuter = bvNone + Padding.Top = 10 + TabOrder = 1 + object CreateRouteBtn: TButton + Left = 0 + Top = 10 + Width = 226 + Height = 27 + Align = alTop + Caption = 'Create route' + Enabled = False + TabOrder = 0 + OnClick = CreateRouteBtnClick + end + object NotifySinksBtn: TButton + Left = 0 + Top = 47 + Width = 226 + Height = 27 + Align = alBottom + Caption = 'Notify sinks' + TabOrder = 1 + OnClick = NotifySinksBtnClick + end + end + end + object CentralPnl: TPanel + Left = 265 + Top = 15 + Width = 499 + Height = 727 + Align = alClient + BevelOuter = bvNone + Padding.Left = 20 + Padding.Right = 20 + TabOrder = 1 + object SourcePnl: TPanel + Left = 20 + Top = 0 + Width = 459 + Height = 41 + Align = alTop + BevelOuter = bvNone + Padding.Top = 10 + Padding.Right = 2 + Padding.Bottom = 10 + TabOrder = 0 + object SourceURNEdt: TEdit + Left = 65 + Top = 10 + Width = 392 + Height = 21 + Align = alClient + TabOrder = 0 + Text = 'cast:?clientId=' + OnChange = SourceURNEdtChange + end + object SourceLblPnl: TPanel + Left = 0 + Top = 10 + Width = 65 + Height = 21 + Align = alLeft + BevelOuter = bvNone + TabOrder = 1 + object SourceURNLbl: TLabel + Left = 0 + Top = 0 + Width = 57 + Height = 13 + Align = alClient + Caption = 'Source URN' + Layout = tlCenter + end + end + end + object MessageGbx: TGroupBox + Left = 20 + Top = 352 + Width = 459 + Height = 375 + Align = alClient + Caption = ' Message ' + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 1 + object SendMessagePnl: TPanel + Left = 12 + Top = 326 + Width = 435 + Height = 37 + Align = alBottom + BevelOuter = bvNone + Padding.Top = 10 + TabOrder = 0 + object SendMsgBtn: TButton + Left = 0 + Top = 10 + Width = 435 + Height = 27 + Align = alClient + Caption = 'Send message' + TabOrder = 0 + OnClick = SendMsgBtnClick + end + end + object MessageMem: TMemo + Left = 12 + Top = 25 + Width = 435 + Height = 301 + Align = alClient + ScrollBars = ssBoth + TabOrder = 1 + end + end + object LogGbx: TGroupBox + Left = 20 + Top = 41 + Width = 459 + Height = 296 + Align = alTop + Caption = ' Log ' + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 2 + object LogMem: TMemo + Left = 12 + Top = 25 + Width = 435 + Height = 222 + Align = alClient + ReadOnly = True + ScrollBars = ssBoth + TabOrder = 0 + end + object ClearLogPnl: TPanel + Left = 12 + Top = 247 + Width = 435 + Height = 37 + Align = alBottom + BevelOuter = bvNone + Padding.Top = 10 + TabOrder = 1 + object ClearLogBtn: TButton + Left = 0 + Top = 10 + Width = 435 + Height = 27 + Align = alClient + Caption = 'Clear log' + TabOrder = 0 + OnClick = ClearLogBtnClick + end + end + end + object SpacerPnl: TPanel + Left = 20 + Top = 337 + Width = 459 + Height = 15 + Align = alTop + BevelOuter = bvNone + TabOrder = 3 + end + end + object RoutesGbx: TGroupBox + Left = 764 + Top = 15 + Width = 250 + Height = 727 + Align = alRight + Caption = ' Routes available ' + Padding.Left = 10 + Padding.Top = 10 + Padding.Right = 10 + Padding.Bottom = 10 + TabOrder = 2 + object RoutesLbx: TListBox + Left = 12 + Top = 25 + Width = 226 + Height = 616 + Align = alClient + ItemHeight = 13 + TabOrder = 0 + end + object RoutesButtonPnl: TPanel + Left = 12 + Top = 641 + Width = 226 + Height = 74 + Align = alBottom + BevelOuter = bvNone + Padding.Top = 10 + TabOrder = 1 + object TerminateRouteBtn: TButton + Left = 0 + Top = 10 + Width = 226 + Height = 27 + Align = alTop + Caption = 'Terminate route' + Enabled = False + TabOrder = 0 + OnClick = TerminateRouteBtnClick + end + object NotifyRoutesBtn: TButton + Left = 0 + Top = 47 + Width = 226 + Height = 27 + Align = alBottom + Caption = 'Notify routes' + TabOrder = 1 + OnClick = NotifyRoutesBtnClick + end + end + end + end + object Chromium1: TChromium + OnMediaRouteCreateFinished = Chromium1MediaRouteCreateFinished + OnAfterCreated = Chromium1AfterCreated + OnBeforeClose = Chromium1BeforeClose + OnClose = Chromium1Close + OnSinks = Chromium1Sinks + OnRoutes = Chromium1Routes + OnRouteStateChanged = Chromium1RouteStateChanged + OnRouteMessageReceived = Chromium1RouteMessageReceived + Left = 72 + Top = 56 + end + object Timer1: TTimer + Enabled = False + Interval = 300 + OnTimer = Timer1Timer + Left = 72 + Top = 136 + end +end diff --git a/demos/Delphi_VCL/MediaRouter/uMediaRouterFrm.pas b/demos/Delphi_VCL/MediaRouter/uMediaRouterFrm.pas new file mode 100644 index 00000000..2243ca1e --- /dev/null +++ b/demos/Delphi_VCL/MediaRouter/uMediaRouterFrm.pas @@ -0,0 +1,704 @@ +// ************************************************************************ +// ***************************** CEF4Delphi ******************************* +// ************************************************************************ +// +// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based +// browser in Delphi applications. +// +// The original license of DCEF3 still applies to CEF4Delphi. +// +// For more information about CEF4Delphi visit : +// https://www.briskbard.com/index.php?lang=en&pageid=cef +// +// Copyright © 2020 Salvador Diaz Fau. All rights reserved. +// +// ************************************************************************ +// ************ vvvv Original license and comments below vvvv ************* +// ************************************************************************ +(* + * Delphi Chromium Embedded 3 + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Unit owner : Henri Gourvest + * Web site : http://www.progdigy.com + * Repository : http://code.google.com/p/delphichromiumembedded/ + * Group : http://groups.google.com/group/delphichromiumembedded + * + * Embarcadero Technologies, Inc is not permitted to use or redistribute + * this source code without explicit permission. + * + *) + +unit uMediaRouterFrm; + +{$I cef.inc} + +interface + +uses + {$IFDEF DELPHI16_UP} + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Menus, + Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, System.Types, Vcl.ComCtrls, Vcl.ClipBrd, + System.UITypes, Vcl.AppEvnts, Winapi.ActiveX, Winapi.ShlObj, System.SyncObjs, + {$ELSE} + Windows, Messages, SysUtils, Variants, Classes, Graphics, Menus, + Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, + AppEvnts, ActiveX, ShlObj, SyncObjs, + {$ENDIF} + uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants, + uCEFWinControl, uCEFSentinel, uCEFChromiumCore; + +const + MEDIA_ROUTER_PENDING_LOG_LINES = WM_APP + $B00; + MEDIA_ROUTER_REFRESH_SINKS = WM_APP + $B01; + MEDIA_ROUTER_REFRESH_ROUTES = WM_APP + $B02; + MEDIA_ROUTER_UPDATE_BUTTONS = WM_APP + $B03; + +type + TMediaRouterFrm = class(TForm) + Chromium1: TChromium; + CEFWindowParent1: TCEFWindowParent; + Timer1: TTimer; + MainPnl: TPanel; + SinksGbx: TGroupBox; + SinksLbx: TListBox; + SinksButtonsPnl: TPanel; + CreateRouteBtn: TButton; + CentralPnl: TPanel; + SourcePnl: TPanel; + SourceURNEdt: TEdit; + SourceLblPnl: TPanel; + SourceURNLbl: TLabel; + RoutesGbx: TGroupBox; + RoutesLbx: TListBox; + RoutesButtonPnl: TPanel; + TerminateRouteBtn: TButton; + MessageGbx: TGroupBox; + SendMessagePnl: TPanel; + SendMsgBtn: TButton; + MessageMem: TMemo; + LogGbx: TGroupBox; + LogMem: TMemo; + SpacerPnl: TPanel; + NotifySinksBtn: TButton; + NotifyRoutesBtn: TButton; + ClearLogPnl: TPanel; + ClearLogBtn: TButton; + + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormShow(Sender: TObject); + + procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); + procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); + procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); + procedure Chromium1Sinks(Sender: TObject; const sinks: TCefMediaSinkArray); + procedure Chromium1Routes(Sender: TObject; const routes: TCefMediaRouteArray); + procedure Chromium1RouteStateChanged(Sender: TObject; const route: ICefMediaRoute; state: TCefMediaRouteConnectionState); + procedure Chromium1RouteMessageReceived(Sender: TObject; const route: ICefMediaRoute; const message_: ustring); + procedure Chromium1MediaRouteCreateFinished(Sender: TObject; result: Integer; const error: ustring; const route: ICefMediaRoute); + + procedure Timer1Timer(Sender: TObject); + procedure SourceURNEdtChange(Sender: TObject); + procedure SinksLbxClick(Sender: TObject); + procedure CreateRouteBtnClick(Sender: TObject); + procedure TerminateRouteBtnClick(Sender: TObject); + procedure SendMsgBtnClick(Sender: TObject); + procedure NotifySinksBtnClick(Sender: TObject); + procedure NotifyRoutesBtnClick(Sender: TObject); + procedure ClearLogBtnClick(Sender: TObject); + + protected + // Variables to control when can we destroy the form safely + FCanClose : boolean; // Set to True in TChromium.OnBeforeClose + FClosing : boolean; // Set to True in the CloseQuery event. + + FMediaCS : TCriticalSection; + FLog : TStringList; + FSinks : TCefMediaSinkInfoArray; + FRoutes : TCefMediaRouteInfoArray; + + procedure BrowserDestroyMsg(var aMessage : TMessage); message CEF_DESTROY; + procedure PendingLogLinesMsg(var aMessage : TMessage); message MEDIA_ROUTER_PENDING_LOG_LINES; + procedure RefreshSinksMsg(var aMessage : TMessage); message MEDIA_ROUTER_REFRESH_SINKS; + procedure RefreshRoutesMsg(var aMessage : TMessage); message MEDIA_ROUTER_REFRESH_ROUTES; + procedure UpdateButtonsMsg(var aMessage : TMessage); message MEDIA_ROUTER_UPDATE_BUTTONS; + + procedure DestroySinksArray; + procedure DestroyRoutesArray; + procedure DestroyAllArrays; + procedure CopySinksArray(const aSinks : TCefMediaSinkArray); + procedure CopyRoutesArray(const aRoutes : TCefMediaRouteArray); + procedure UpdateAvailableSinks; + procedure UpdateAvailableRoutes; + procedure UpdateButtons; + procedure AddLogEntry(const aMessage1, aMessage2 : string; aRec : boolean); overload; + procedure AddLogEntry(const aMessage1 : string; const aMessage2 : string = ''); overload; + end; + +var + MediaRouterFrm: TMediaRouterFrm; + +procedure CreateGlobalCEFApp; + +implementation + +{$R *.dfm} + +uses + {$IFDEF DELPHI16_UP} + System.Math, + {$ELSE} + Math, + {$ENDIF} + uCEFMiscFunctions; + +procedure CreateGlobalCEFApp; +begin + GlobalCEFApp := TCefApplication.Create; + GlobalCEFApp.LogFile := 'debug.log'; + GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO; //LOGSEVERITY_VERBOSE; + GlobalCEFApp.FrameworkDirPath := 'c:\cef'; + GlobalCEFApp.ResourcesDirPath := 'c:\cef'; + GlobalCEFApp.LocalesDirPath := 'c:\cef\locales'; +end; + +procedure TMediaRouterFrm.Chromium1AfterCreated(Sender: TObject; + const browser: ICefBrowser); +begin + AddLogEntry('Browser initialized.'); +end; + +procedure TMediaRouterFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); +begin + FCanClose := True; + PostMessage(Handle, WM_CLOSE, 0, 0); +end; + +procedure TMediaRouterFrm.Chromium1Close(Sender: TObject; + const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); +begin + PostMessage(Handle, CEF_DESTROY, 0, 0); + aAction := cbaDelay; +end; + +procedure TMediaRouterFrm.Chromium1MediaRouteCreateFinished(Sender: TObject; + result: Integer; const error: ustring; const route: ICefMediaRoute); +var + TempMsg, TempID : string; +begin + TempMsg := ''; + + try + FMediaCS.Acquire; + + if (result = CEF_MRCR_OK) then + begin + TempMsg := 'Route created'; + if (route <> nil) then TempID := route.ID; + end + else + TempMsg := error; + finally + PostMessage(Handle, MEDIA_ROUTER_UPDATE_BUTTONS, 0, 0); + FMediaCS.Release; + if (length(TempMsg) > 0) then AddLogEntry(TempID, TempMsg); + end; +end; + +procedure TMediaRouterFrm.Chromium1RouteMessageReceived(Sender: TObject; + const route: ICefMediaRoute; const message_: ustring); +var + TempID : string; +begin + if (route <> nil) then + TempID := route.ID; + + AddLogEntry(TempID, message_, True); +end; + +procedure TMediaRouterFrm.Chromium1Routes(Sender: TObject; + const routes: TCefMediaRouteArray); +begin + CopyRoutesArray(routes); +end; + +procedure TMediaRouterFrm.Chromium1RouteStateChanged(Sender: TObject; + const route: ICefMediaRoute; state: TCefMediaRouteConnectionState); +var + TempMsg, TempID : string; +begin + if (route <> nil) then TempID := route.ID; + + case state of + CEF_MRCS_CONNECTING : TempMsg := 'State : Connecting.'; + CEF_MRCS_CONNECTED : TempMsg := 'State : Connected.'; + CEF_MRCS_CLOSED : TempMsg := 'State : Closed.'; + CEF_MRCS_TERMINATED : TempMsg := 'State : Terminated.'; + else TempMsg := 'State : Unknown.'; + end; + + TempMsg := TempMsg + ' ' + dateTimeToStr(now); + + AddLogEntry(TempID, TempMsg); +end; + +procedure TMediaRouterFrm.Chromium1Sinks(Sender: TObject; + const sinks: TCefMediaSinkArray); +begin + CopySinksArray(sinks); +end; + +procedure TMediaRouterFrm.ClearLogBtnClick(Sender: TObject); +begin + LogMem.Lines.Clear; +end; + +procedure TMediaRouterFrm.FormCloseQuery(Sender: TObject; + var CanClose: Boolean); +begin + CanClose := FCanClose; + + if not(FClosing) then + begin + FClosing := True; + Visible := False; + DestroyAllArrays; + Chromium1.CloseBrowser(True); + end; +end; + +procedure TMediaRouterFrm.FormCreate(Sender: TObject); +begin + FCanClose := False; + FClosing := False; + FSinks := nil; + FRoutes := nil; + FMediaCS := TCriticalSection.Create; + FLog := TStringList.Create; +end; + +procedure TMediaRouterFrm.FormDestroy(Sender: TObject); +begin + FLog.Free; + FMediaCS.Free; +end; + +procedure TMediaRouterFrm.FormShow(Sender: TObject); +begin + UpdateButtons; + + if not(Chromium1.CreateBrowser(CEFWindowParent1)) then + Timer1.Enabled := True; +end; + +procedure TMediaRouterFrm.NotifyRoutesBtnClick(Sender: TObject); +begin + Chromium1.NotifyCurrentRoutes; +end; + +procedure TMediaRouterFrm.NotifySinksBtnClick(Sender: TObject); +begin + Chromium1.NotifyCurrentSinks; +end; + +procedure TMediaRouterFrm.SendMsgBtnClick(Sender: TObject); +var + TempMsg, TempID : string; +begin + TempMsg := ''; + + try + FMediaCS.Acquire; + + if (RoutesLbx.Items.Count > 0) and + (FRoutes <> nil) and + (RoutesLbx.ItemIndex >= 0) and + (RoutesLbx.ItemIndex < length(FRoutes)) and + (MessageMem.Lines.Count > 0) then + begin + TempMsg := trim(MessageMem.Lines.Text); + + if (length(TempMsg) > 0) and + (FRoutes[RoutesLbx.ItemIndex].RouteIntf <> nil) then + try + TempID := FRoutes[RoutesLbx.ItemIndex].RouteIntf.ID; + FRoutes[RoutesLbx.ItemIndex].RouteIntf.SendRouteMessage(TempMsg); + except + on e : exception do + if CustomExceptionHandler('TMediaRouterFrm.SendMsgBtnClick', e) then raise; + end; + end; + finally + FMediaCS.Release; + if (length(TempMsg) > 0) then AddLogEntry(TempID, TempMsg, False); + end; +end; + +procedure TMediaRouterFrm.SinksLbxClick(Sender: TObject); +begin + UpdateButtons; +end; + +procedure TMediaRouterFrm.SourceURNEdtChange(Sender: TObject); +begin + UpdateButtons; +end; + +procedure TMediaRouterFrm.TerminateRouteBtnClick(Sender: TObject); +begin + try + FMediaCS.Acquire; + + if (RoutesLbx.Items.Count > 0) and + (FRoutes <> nil) and + (RoutesLbx.ItemIndex >= 0) and + (RoutesLbx.ItemIndex < length(FRoutes)) and + (FRoutes[RoutesLbx.ItemIndex].RouteIntf <> nil) then + try + FRoutes[RoutesLbx.ItemIndex].RouteIntf.Terminate; + except + on e : exception do + if CustomExceptionHandler('TMediaRouterFrm.TerminateRouteBtnClick', e) then raise; + end; + finally + FMediaCS.Release; + UpdateButtons; + end; +end; + +procedure TMediaRouterFrm.Timer1Timer(Sender: TObject); +begin + Timer1.Enabled := False; + if not(Chromium1.CreateBrowser(CEFWindowParent1)) and not(Chromium1.Initialized) then + Timer1.Enabled := True; +end; + +procedure TMediaRouterFrm.BrowserDestroyMsg(var aMessage : TMessage); +begin + CEFWindowParent1.Free; +end; + +procedure TMediaRouterFrm.PendingLogLinesMsg(var aMessage : TMessage); +begin + if FClosing then exit; + + try + FMediaCS.Acquire; + + if (FLog <> nil) and (FLog.Count > 0) then + begin + LogMem.Lines.AddStrings(FLog); + FLog.Clear; + end; + finally + FMediaCS.Release; + end; +end; + +procedure TMediaRouterFrm.RefreshSinksMsg(var aMessage : TMessage); +begin + if FClosing then exit; + + UpdateAvailableSinks; + UpdateButtons; +end; + +procedure TMediaRouterFrm.RefreshRoutesMsg(var aMessage : TMessage); +begin + if FClosing then exit; + + UpdateAvailableRoutes; + UpdateButtons; +end; + +procedure TMediaRouterFrm.UpdateButtonsMsg(var aMessage : TMessage); +begin + if FClosing then exit; + + UpdateButtons; +end; + +procedure TMediaRouterFrm.DestroyAllArrays; +begin + try + FMediaCS.Acquire; + DestroyRoutesArray; + DestroySinksArray; + finally + FMediaCS.Release; + end; +end; + +procedure TMediaRouterFrm.DestroySinksArray; +var + i : integer; +begin + if (FSinks <> nil) then + begin + i := pred(length(FSinks)); + while (i >= 0) do + begin + FSinks[i].SinkIntf := nil; + dec(i); + end; + + Finalize(FSinks); + FSinks := nil; + end; +end; + +procedure TMediaRouterFrm.DestroyRoutesArray; +var + i : integer; +begin + if (FRoutes <> nil) then + begin + i := pred(length(FRoutes)); + while (i >= 0) do + begin + FRoutes[i].RouteIntf := nil; + dec(i); + end; + + Finalize(FRoutes); + FRoutes := nil; + end; +end; + +procedure TMediaRouterFrm.CopySinksArray(const aSinks : TCefMediaSinkArray); +var + i, TempLen : integer; +begin + try + FMediaCS.Acquire; + + FLog.Add('Sinks available : ' + inttostr(length(aSinks))); + FLog.Add('------------------------------------------'); + + DestroySinksArray; + + if (aSinks <> nil) then + begin + TempLen := length(aSinks); + SetLength(FSinks, TempLen); + + i := 0; + while (i < TempLen) do + begin + FSinks[i].ID := aSinks[i].ID; + FSinks[i].Name := aSinks[i].Name; + FSinks[i].Description := aSinks[i].Description; + FSinks[i].Valid := aSinks[i].IsValid; + FSinks[i].SinkIntf := aSinks[i]; + + if aSinks[i].IsCastSink then + FSinks[i].SinkType := mtCast + else + if aSinks[i].IsDialSink then + FSinks[i].SinkType := mtDial + else + FSinks[i].SinkType := mtUnknown; + + inc(i); + end; + end; + finally + PostMessage(Handle, MEDIA_ROUTER_REFRESH_SINKS, 0, 0); + FMediaCS.Release; + end; +end; + +procedure TMediaRouterFrm.CopyRoutesArray(const aRoutes : TCefMediaRouteArray); +var + i, TempLen : integer; +begin + try + FMediaCS.Acquire; + + FLog.Add('Routes available : ' + inttostr(length(aRoutes))); + FLog.Add('------------------------------------------'); + + DestroyRoutesArray; + + if (aRoutes <> nil) then + begin + TempLen := length(aRoutes); + SetLength(FRoutes, TempLen); + + i := 0; + while (i < TempLen) do + begin + FRoutes[i].ID := aRoutes[i].ID; + FRoutes[i].SourceID := aRoutes[i].GetSource.ID; + FRoutes[i].SinkID := aRoutes[i].GetSink.ID; + FRoutes[i].RouteIntf := aRoutes[i]; + inc(i); + end; + end; + finally + PostMessage(Handle, MEDIA_ROUTER_REFRESH_ROUTES, 0, 0); + FMediaCS.Release; + end; +end; + +procedure TMediaRouterFrm.CreateRouteBtnClick(Sender: TObject); +var + TempURN, TempErrorMsg : string; + TempSource : ICefMediaSource; +begin + TempURN := trim(SourceURNEdt.Text); + + if (length(TempURN) = 0) then + begin + AddLogEntry('Invalid URN'); + exit; + end; + + TempErrorMsg := ''; + + try + try + FMediaCS.Acquire; + + if (FSinks <> nil) and + (SinksLbx.Items.Count > 0) and + (SinksLbx.ItemIndex >= 0) and + (SinksLbx.ItemIndex < length(FSinks)) then + begin + TempSource := Chromium1.GetSource(TempURN); + + if (TempSource <> nil) and TempSource.IsValid then + begin + if (FSinks[SinksLbx.ItemIndex].SinkIntf <> nil) and + FSinks[SinksLbx.ItemIndex].SinkIntf.IsValid then + begin + if FSinks[SinksLbx.ItemIndex].SinkIntf.IsCompatibleWith(TempSource) then + Chromium1.CreateRoute(TempSource, FSinks[SinksLbx.ItemIndex].SinkIntf) + else + TempErrorMsg := 'The selected Sink is not compatible with the Media Source.'; + end + else + TempErrorMsg := 'The selected Sink is not valid.'; + end + else + TempErrorMsg := 'The Media Source is not valid.'; + end + else + TempErrorMsg := 'The sinks list is outdated.'; + except + on e : exception do + begin + TempErrorMsg := e.Message; + if CustomExceptionHandler('TMediaRouterFrm.CreateRouteBtnClick', e) then raise; + end; + end; + finally + FMediaCS.Release; + if (length(TempErrorMsg) > 0) then AddLogEntry(TempErrorMsg); + end; +end; + +procedure TMediaRouterFrm.UpdateAvailableSinks; +var + i : integer; +begin + try + FMediaCS.Acquire; + SinksLbx.Items.Clear; + + if (FSinks <> nil) then + begin + i := 0; + while (i < length(FSinks)) do + begin + case FSinks[i].SinkType of + mtCast : SinksLbx.Items.Add(FSinks[i].Name + ' (CAST)'); + mtDial : SinksLbx.Items.Add(FSinks[i].Name + ' (DIAL)'); + else SinksLbx.Items.Add(FSinks[i].Name + ' (UNKNOWN)'); + end; + + inc(i); + end; + end; + finally + FMediaCS.Release; + end; +end; + +procedure TMediaRouterFrm.UpdateAvailableRoutes; +var + i : integer; +begin + try + FMediaCS.Acquire; + RoutesLbx.Items.Clear; + + if (FRoutes <> nil) then + begin + i := 0; + while (i < length(FRoutes)) do + begin + RoutesLbx.Items.Add('ID : ' + quotedstr(FRoutes[i].ID)); + inc(i); + end; + end; + finally + FMediaCS.Release; + end; +end; + +procedure TMediaRouterFrm.UpdateButtons; +begin + TerminateRouteBtn.Enabled := (RoutesLbx.ItemIndex >= 0) and + (RoutesLbx.Items.Count > 0); + + SendMsgBtn.Enabled := TerminateRouteBtn.Enabled and + (length(trim(MessageMem.Lines.Text)) > 0); + + CreateRouteBtn.Enabled := not(TerminateRouteBtn.Enabled) and + (length(trim(SourceURNEdt.Text)) > 0) and + (SinksLbx.ItemIndex >= 0) and + (SinksLbx.Items.Count > 0); +end; + +procedure TMediaRouterFrm.AddLogEntry(const aMessage1, aMessage2 : string; aRec : boolean); +begin + try + FMediaCS.Acquire; + + if aRec then + FLog.Add('Message received ' + dateTimeToStr(now)) + else + FLog.Add('Message sent ' + dateTimeToStr(now)); + + FLog.Add(aMessage1); + if (length(aMessage2) > 0) then FLog.Add(aMessage2); + FLog.Add('------------------------------------------'); + finally + PostMessage(Handle, MEDIA_ROUTER_PENDING_LOG_LINES, 0, 0); + FMediaCS.Release; + end; +end; + +procedure TMediaRouterFrm.AddLogEntry(const aMessage1, aMessage2 : string); +begin + try + FMediaCS.Acquire; + FLog.Add(aMessage1); + if (length(aMessage2) > 0) then FLog.Add(aMessage2); + FLog.Add('------------------------------------------'); + finally + PostMessage(Handle, MEDIA_ROUTER_PENDING_LOG_LINES, 0, 0); + FMediaCS.Release; + end; +end; + +end. diff --git a/demos/Lazarus/SimpleOSRBrowser/SimpleOSRBrowser.lps b/demos/Lazarus/SimpleOSRBrowser/SimpleOSRBrowser.lps index 2442985d..b4354319 100644 --- a/demos/Lazarus/SimpleOSRBrowser/SimpleOSRBrowser.lps +++ b/demos/Lazarus/SimpleOSRBrowser/SimpleOSRBrowser.lps @@ -8,7 +8,8 @@ - + + @@ -244,11 +245,10 @@ - - + + - diff --git a/packages/CEF4Delphi.dpk b/packages/CEF4Delphi.dpk index ec670959..cad39793 100644 --- a/packages/CEF4Delphi.dpk +++ b/packages/CEF4Delphi.dpk @@ -182,9 +182,7 @@ contains uCEFMediaRouter in '..\source\uCEFMediaRouter.pas', uCEFMediaSink in '..\source\uCEFMediaSink.pas', uCEFMediaSource in '..\source\uCEFMediaSource.pas', - uCEFRegistration in '..\source\uCEFRegistration.pas', - uCEFMediaObserverComponent in '..\source\uCEFMediaObserverComponent.pas', - uCEFMediaObserverEvents in '..\source\uCEFMediaObserverEvents.pas'; + uCEFRegistration in '..\source\uCEFRegistration.pas'; end. diff --git a/packages/CEF4Delphi.dproj b/packages/CEF4Delphi.dproj index 67fe11ad..d27e6638 100644 --- a/packages/CEF4Delphi.dproj +++ b/packages/CEF4Delphi.dproj @@ -277,8 +277,6 @@ - - Base diff --git a/packages/CEF4Delphi_D7.dpk b/packages/CEF4Delphi_D7.dpk index bd70b6ee..26df232a 100644 --- a/packages/CEF4Delphi_D7.dpk +++ b/packages/CEF4Delphi_D7.dpk @@ -179,8 +179,6 @@ contains uCEFMediaRoute in '..\source\uCEFMediaRoute.pas', uCEFMediaObserver in '..\source\uCEFMediaObserver.pas', uCEFMediaRouter in '..\source\uCEFMediaRouter.pas', - uCEFRegistration in '..\source\uCEFRegistration.pas', - uCEFMediaObserverComponent in '..\source\uCEFMediaObserverComponent.pas', - uCEFMediaObserverEvents in '..\source\uCEFMediaObserverEvents.pas'; + uCEFRegistration in '..\source\uCEFRegistration.pas'; end. diff --git a/packages/CEF4Delphi_D7_Register.pas b/packages/CEF4Delphi_D7_Register.pas index de742887..e3443d63 100644 --- a/packages/CEF4Delphi_D7_Register.pas +++ b/packages/CEF4Delphi_D7_Register.pas @@ -50,14 +50,13 @@ implementation uses Classes, uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFBufferPanel, uCEFWorkScheduler, - uCEFServerComponent, uCEFLinkedWindowParent, uCEFUrlRequestClientComponent, uCEFSentinel, - uCEFMediaObserverComponent; + uCEFServerComponent, uCEFLinkedWindowParent, uCEFUrlRequestClientComponent, uCEFSentinel; procedure Register; begin RegisterComponents('Chromium', [TChromium, TCEFWindowParent, TChromiumWindow, TBufferPanel, TCEFWorkScheduler, TCEFServerComponent, TCEFLinkedWindowParent, - TCEFUrlRequestClientComponent, TCEFSentinel, TCEFMediaObserverComponent]); + TCEFUrlRequestClientComponent, TCEFSentinel]); end; end. diff --git a/packages/CEF4Delphi_FMX.dpk b/packages/CEF4Delphi_FMX.dpk index 9f9e7d14..b3225cdb 100644 --- a/packages/CEF4Delphi_FMX.dpk +++ b/packages/CEF4Delphi_FMX.dpk @@ -187,9 +187,7 @@ contains uCEFMediaRoute in '..\source\uCEFMediaRoute.pas', uCEFMediaObserver in '..\source\uCEFMediaObserver.pas', uCEFMediaRouter in '..\source\uCEFMediaRouter.pas', - uCEFRegistration in '..\source\uCEFRegistration.pas', - uCEFMediaObserverComponent in '..\source\uCEFMediaObserverComponent.pas', - uCEFMediaObserverEvents in '..\source\uCEFMediaObserverEvents.pas'; + uCEFRegistration in '..\source\uCEFRegistration.pas'; end. diff --git a/packages/CEF4Delphi_FMX.dproj b/packages/CEF4Delphi_FMX.dproj index fef33a32..3ba002f0 100644 --- a/packages/CEF4Delphi_FMX.dproj +++ b/packages/CEF4Delphi_FMX.dproj @@ -303,8 +303,6 @@ - - Base diff --git a/packages/CEF4Delphi_FMX_Register.pas b/packages/CEF4Delphi_FMX_Register.pas index ecd61247..7bcb0d3e 100644 --- a/packages/CEF4Delphi_FMX_Register.pas +++ b/packages/CEF4Delphi_FMX_Register.pas @@ -52,7 +52,7 @@ uses uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFBufferPanel, uCEFWorkScheduler, uCEFFMXBufferPanel, uCEFFMXChromium, uCEFFMXWorkScheduler, uCEFServerComponent, uCEFLinkedWindowParent, uCEFUrlRequestClientComponent, - uCEFSentinel, uCEFMediaObserverComponent; + uCEFSentinel; procedure Register; begin @@ -61,7 +61,7 @@ begin TFMXWorkScheduler, TCEFWorkScheduler, TCEFServerComponent, TCEFLinkedWindowParent, TCEFUrlRequestClientComponent, - TCEFSentinel, TCEFMediaObserverComponent]); + TCEFSentinel]); end; end. diff --git a/packages/CEF4Delphi_Register.pas b/packages/CEF4Delphi_Register.pas index 4854330e..b349bfa9 100644 --- a/packages/CEF4Delphi_Register.pas +++ b/packages/CEF4Delphi_Register.pas @@ -55,15 +55,14 @@ uses {$ENDIF} uCEFChromium, uCEFWindowParent, uCEFChromiumWindow, uCEFBufferPanel, uCEFWorkScheduler, uCEFServerComponent, uCEFLinkedWindowParent, - uCEFUrlRequestClientComponent, uCEFSentinel, uCEFMediaObserverComponent; + uCEFUrlRequestClientComponent, uCEFSentinel; procedure Register; begin RegisterComponents('Chromium', [TChromium, TCEFWindowParent, TChromiumWindow, TBufferPanel, TCEFWorkScheduler, TCEFServerComponent, TCEFLinkedWindowParent, - TCEFUrlRequestClientComponent, TCEFSentinel, - TCEFMediaObserverComponent]); + TCEFUrlRequestClientComponent, TCEFSentinel]); end; end. diff --git a/packages/cef4delphi_lazarus.lpk b/packages/cef4delphi_lazarus.lpk index d1313e87..c535e678 100644 --- a/packages/cef4delphi_lazarus.lpk +++ b/packages/cef4delphi_lazarus.lpk @@ -21,8 +21,8 @@ - - + + @@ -625,38 +625,29 @@ - - - - - - - - - - - + + - - + + - - + + - - + + - - + + - + diff --git a/packages/cef4delphi_lazarus.pas b/packages/cef4delphi_lazarus.pas index 9a209be8..3a1556fe 100644 --- a/packages/cef4delphi_lazarus.pas +++ b/packages/cef4delphi_lazarus.pas @@ -50,10 +50,9 @@ uses uCEFUrlRequestClientComponent, uCEFOSRIMEHandler, uCEFCookieAccessFilter, uCEFResourceReadCallback, uCEFResourceRequestHandler, uCEFResourceSkipCallback, uCEFSentinel, uCEFApplicationCore, - uCEFOAuth2Helper, uCEFMediaObserver, uCEFMediaObserverComponent, - uCEFMediaObserverEvents, uCEFMediaRoute, uCEFMediaRouteCreateCallback, - uCEFMediaRouter, uCEFMediaSink, uCEFMediaSource, uCEFRegistration, - LazarusPackageIntf; + uCEFOAuth2Helper, uCEFMediaObserver, uCEFMediaRoute, + uCEFMediaRouteCreateCallback, uCEFMediaRouter, uCEFMediaSink, + uCEFMediaSource, uCEFRegistration, LazarusPackageIntf; implementation @@ -69,8 +68,6 @@ begin RegisterUnit('uCEFUrlRequestClientComponent', @uCEFUrlRequestClientComponent.Register); RegisterUnit('uCEFSentinel', @uCEFSentinel.Register); - RegisterUnit('uCEFMediaObserverComponent', - @uCEFMediaObserverComponent.Register); end; initialization diff --git a/source/uCEFApplicationCore.pas b/source/uCEFApplicationCore.pas index eebe3b2c..7ca740cd 100644 --- a/source/uCEFApplicationCore.pas +++ b/source/uCEFApplicationCore.pas @@ -62,13 +62,13 @@ uses const CEF_SUPPORTED_VERSION_MAJOR = 81; CEF_SUPPORTED_VERSION_MINOR = 2; - CEF_SUPPORTED_VERSION_RELEASE = 16; + CEF_SUPPORTED_VERSION_RELEASE = 17; CEF_SUPPORTED_VERSION_BUILD = 0; CEF_CHROMEELF_VERSION_MAJOR = 81; CEF_CHROMEELF_VERSION_MINOR = 0; CEF_CHROMEELF_VERSION_RELEASE = 4044; - CEF_CHROMEELF_VERSION_BUILD = 92; + CEF_CHROMEELF_VERSION_BUILD = 113; {$IFDEF MSWINDOWS} LIBCEF_DLL = 'libcef.dll'; diff --git a/source/uCEFChromiumCore.pas b/source/uCEFChromiumCore.pas index 010024dc..ae80a35f 100644 --- a/source/uCEFChromiumCore.pas +++ b/source/uCEFChromiumCore.pas @@ -78,6 +78,8 @@ type FBrowserId : Integer; FReqContextHandler : ICefRequestContextHandler; FResourceRequestHandler : ICefResourceRequestHandler; + FMediaObserver : ICefMediaObserver; + FRegistration : ICefRegistration; FDefaultUrl : ustring; FOptions : TChromiumOptions; FFontOptions : TChromiumFontOptions; @@ -251,6 +253,12 @@ type FOnBeforePluginLoad : TOnBeforePluginLoad; FOnGetResourceRequestHandler_ReqCtxHdlr : TOnGetResourceRequestHandler; + // ICefMediaObserver + FOnSinks : TOnSinksEvent; + FOnRoutes : TOnRoutesEvent; + FOnRouteStateChanged : TOnRouteStateChangedEvent; + FOnRouteMessageReceived : TOnRouteMessageReceivedEvent; + // Custom FOnTextResultAvailable : TOnTextResultAvailableEvent; FOnPdfPrintFinished : TOnPdfPrintFinishedEvent; @@ -268,6 +276,7 @@ type FOnCookieVisitorDestroyed : TOnCookieVisitorDestroyed; FOnCookieSet : TOnCookieSet; FOnZoomPctAvailable : TOnZoomPctAvailable; + FOnMediaRouteCreateFinished : TOnMediaRouteCreateFinishedEvent; {$IFDEF MSWINDOWS} FOnBrowserCompMsg : TOnCompMsgEvent; FOnWidgetCompMsg : TOnCompMsgEvent; @@ -299,6 +308,8 @@ type function GetRequestContextIsGlobal : boolean; function GetAudioMuted : boolean; function GetParentFormHandle : TCefWindowHandle; virtual; + function GetRequestContext : ICefRequestContext; + function GetMediaRouter : ICefMediaRouter; procedure SetDoNotTrack(aValue : boolean); procedure SetSendReferrer(aValue : boolean); @@ -342,9 +353,11 @@ type procedure DestroyClientHandler; procedure DestroyReqContextHandler; procedure DestroyResourceRequestHandler; + procedure DestroyMediaObserver; procedure ClearBrowserReference; procedure CreateReqContextHandler; procedure CreateResourceRequestHandler; + procedure CreateMediaObserver; procedure InitializeEvents; procedure InitializeSettings(var aSettings : TCefBrowserSettings); @@ -516,6 +529,12 @@ type function doOnBeforePluginLoad(const mimeType, pluginUrl:ustring; isMainFrame : boolean; const topOriginUrl: ustring; const pluginInfo: ICefWebPluginInfo; var pluginPolicy: TCefPluginPolicy): Boolean; virtual; procedure doGetResourceRequestHandler_ReqCtxHdlr(const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; is_navigation, is_download: boolean; const request_initiator: ustring; var disable_default_handling: boolean; var aResourceRequestHandler : ICefResourceRequestHandler); virtual; + // ICefMediaObserver + procedure doOnSinks(const sinks: TCefMediaSinkArray); + procedure doOnRoutes(const routes: TCefMediaRouteArray); + procedure doOnRouteStateChanged(const route: ICefMediaRoute; state: TCefMediaRouteConnectionState); + procedure doOnRouteMessageReceived(const route: ICefMediaRoute; const message_: ustring); + // Custom procedure doCookiesDeleted(numDeleted : integer); virtual; procedure doPdfPrintFinished(aResultOK : boolean); virtual; @@ -540,6 +559,7 @@ type procedure doSetZoomLevel(const aValue : double); virtual; procedure doSetZoomPct(const aValue : double); virtual; procedure doSetZoomStep(aValue : byte); virtual; + procedure doMediaRouteCreateFinished(result: TCefMediaRouterCreateResult; const error: ustring; const route: ICefMediaRoute); virtual; function MustCreateLoadHandler : boolean; virtual; function MustCreateFocusHandler : boolean; virtual; function MustCreateContextMenuHandler : boolean; virtual; @@ -556,6 +576,7 @@ type function MustCreateResourceRequestHandler : boolean; virtual; function MustCreateCookieAccessFilter : boolean; virtual; function MustCreateRequestContextHandler : boolean; virtual; + function MustCreateMediaObserver : boolean; virtual; property ParentFormHandle : TCefWindowHandle read GetParentFormHandle; @@ -687,6 +708,12 @@ type procedure IMEFinishComposingText(keep_selection : boolean); procedure IMECancelComposition; + // ICefMediaRouter methods + function AddObserver(const observer: ICefMediaObserver): ICefRegistration; + function GetSource(const urn: ustring): ICefMediaSource; + procedure NotifyCurrentSinks; + procedure NotifyCurrentRoutes; + procedure CreateRoute(const source: ICefMediaSource; const sink: ICefMediaSink); property DefaultUrl : ustring read FDefaultUrl write FDefaultUrl; property Options : TChromiumOptions read FOptions write FOptions; @@ -700,6 +727,10 @@ type property ResourceRequestHandler : ICefResourceRequestHandler read FResourceRequestHandler; property CefWindowInfo : TCefWindowInfo read FWindowInfo; property VisibleNavigationEntry : ICefNavigationEntry read GetVisibleNavigationEntry; + property RequestContext : ICefRequestContext read GetRequestContext; + property MediaRouter : ICefMediaRouter read GetMediaRouter; + property MediaObserver : ICefMediaObserver read FMediaObserver; + property Registration : ICefRegistration read FRegistration; property MultithreadApp : boolean read GetMultithreadApp; property IsLoading : boolean read GetIsLoading; property HasDocument : boolean read GetHasDocument; @@ -777,6 +808,7 @@ type property OnCookieVisitorDestroyed : TOnCookieVisitorDestroyed read FOnCookieVisitorDestroyed write FOnCookieVisitorDestroyed; property OnCookieSet : TOnCookieSet read FOnCookieSet write FOnCookieSet; property OnZoomPctAvailable : TOnZoomPctAvailable read FOnZoomPctAvailable write FOnZoomPctAvailable; + property OnMediaRouteCreateFinished : TOnMediaRouteCreateFinishedEvent read FOnMediaRouteCreateFinished write FOnMediaRouteCreateFinished; {$IFDEF MSWINDOWS} property OnBrowserCompMsg : TOnCompMsgEvent read FOnBrowserCompMsg write FOnBrowserCompMsg; property OnWidgetCompMsg : TOnCompMsgEvent read FOnWidgetCompMsg write FOnWidgetCompMsg; @@ -891,6 +923,12 @@ type property OnRequestContextInitialized : TOnRequestContextInitialized read FOnRequestContextInitialized write SetOnRequestContextInitialized; property OnBeforePluginLoad : TOnBeforePluginLoad read FOnBeforePluginLoad write SetOnBeforePluginLoad; property OnGetResourceRequestHandler_ReqCtxHdlr : TOnGetResourceRequestHandler read FOnGetResourceRequestHandler_ReqCtxHdlr write FOnGetResourceRequestHandler_ReqCtxHdlr; + + // ICefMediaObserver + property OnSinks : TOnSinksEvent read FOnSinks write FOnSinks; + property OnRoutes : TOnRoutesEvent read FOnRoutes write FOnRoutes; + property OnRouteStateChanged : TOnRouteStateChangedEvent read FOnRouteStateChanged write FOnRouteStateChanged; + property OnRouteMessageReceived : TOnRouteMessageReceivedEvent read FOnRouteMessageReceived write FOnRouteMessageReceived; end; // ********************************************************* @@ -931,9 +969,11 @@ uses uCEFBrowser, uCEFValue, uCEFDictionaryValue, uCEFStringMultimap, uCEFFrame, uCEFApplicationCore, uCEFProcessMessage, uCEFRequestContext, {$IFDEF MSWINDOWS}uCEFOLEDragAndDrop,{$ENDIF} - uCEFPDFPrintCallback, uCEFResolveCallback, uCEFDeleteCookiesCallback, uCEFStringVisitor, - uCEFListValue, uCEFNavigationEntryVisitor, uCEFDownloadImageCallBack, uCEFCookieManager, - uCEFRequestContextHandler, uCEFCookieVisitor, uCEFSetCookieCallback, uCEFResourceRequestHandler; + uCEFPDFPrintCallback, uCEFResolveCallback, uCEFDeleteCookiesCallback, + uCEFStringVisitor, uCEFListValue, uCEFNavigationEntryVisitor, + uCEFDownloadImageCallBack, uCEFCookieManager, uCEFRequestContextHandler, + uCEFCookieVisitor, uCEFSetCookieCallback, uCEFResourceRequestHandler, + uCEFMediaObserver, uCEFMediaRouteCreateCallback; constructor TChromiumCore.Create(AOwner: TComponent); begin @@ -949,6 +989,8 @@ begin FHandler := nil; FReqContextHandler := nil; FResourceRequestHandler := nil; + FMediaObserver := nil; + FRegistration := nil; FOptions := nil; FFontOptions := nil; FDefaultEncoding := ''; @@ -1064,6 +1106,7 @@ begin DestroyClientHandler; DestroyReqContextHandler; DestroyResourceRequestHandler; + DestroyMediaObserver; inherited BeforeDestruction; end; @@ -1231,6 +1274,19 @@ begin FReqContextHandler := TCustomRequestContextHandler.Create(self); end; +procedure TChromiumCore.DestroyMediaObserver; +begin + FRegistration := nil; + FMediaObserver := nil; +end; + +procedure TChromiumCore.CreateMediaObserver; +begin + if MustCreateMediaObserver and + (FMediaObserver = nil) then + FMediaObserver := TCustomMediaObserver.Create(self); +end; + procedure TChromiumCore.DestroyResourceRequestHandler; begin try @@ -1295,6 +1351,7 @@ begin if CreateClientHandler(aIsOSR) then begin CreateResourceRequestHandler; + CreateMediaObserver; aClient := FHandler; Result := True; @@ -1414,6 +1471,12 @@ begin FOnBeforePluginLoad := nil; FOnGetResourceRequestHandler_ReqCtxHdlr := nil; + // ICefMediaObserver + FOnSinks := nil; + FOnRoutes := nil; + FOnRouteStateChanged := nil; + FOnRouteMessageReceived := nil; + // Custom FOnTextResultAvailable := nil; FOnPdfPrintFinished := nil; @@ -1431,6 +1494,7 @@ begin FOnCookieVisitorDestroyed := nil; FOnCookieSet := nil; FOnZoomPctAvailable := nil; + FOnMediaRouteCreateFinished := nil; {$IFDEF MSWINDOWS} FOnBrowserCompMsg := nil; @@ -1470,6 +1534,7 @@ begin GetSettings(FBrowserSettings); InitializeWindowInfo(aParentHandle, aParentRect, aWindowName); CreateResourceRequestHandler; + CreateMediaObserver; if (aContext = nil) then begin @@ -3178,6 +3243,26 @@ begin end; end; +function TChromiumCore.GetRequestContext : ICefRequestContext; +begin + if Initialized then + Result := FBrowser.Host.RequestContext + else + Result := nil; +end; + +function TChromiumCore.GetMediaRouter : ICefMediaRouter; +var + TempRequestContext : ICefRequestContext; +begin + TempRequestContext := RequestContext; + + if (TempRequestContext <> nil) then + Result := TempRequestContext.MediaRouter + else + Result := nil; +end; + procedure TChromiumCore.SimulateMouseWheel(aDeltaX, aDeltaY : integer); var TempEvent : TCefMouseEvent; @@ -4022,6 +4107,14 @@ begin end; end; +procedure TChromiumCore.doMediaRouteCreateFinished( result : TCefMediaRouterCreateResult; + const error : ustring; + const route : ICefMediaRoute); +begin + if assigned(FOnMediaRouteCreateFinished) then + FOnMediaRouteCreateFinished(self, result, error, route); +end; + function TChromiumCore.MustCreateLoadHandler : boolean; begin Result := assigned(FOnLoadStart) or @@ -4135,6 +4228,14 @@ begin MustCreateResourceRequestHandler; end; +function TChromiumCore.MustCreateMediaObserver : boolean; +begin + Result := assigned(FOnSinks) or + assigned(FOnRoutes) or + assigned(FOnRouteStateChanged) or + assigned(FOnRouteMessageReceived); +end; + {$IFDEF MSWINDOWS} procedure TChromiumCore.PrefsAvailableMsg(aResultOK : boolean); begin @@ -4385,6 +4486,7 @@ begin if (browser <> nil) and (FBrowserId = browser.Identifier) then begin FInitialized := False; + DestroyMediaObserver; DestroyResourceRequestHandler; DestroyReqContextHandler; ClearBrowserReference; @@ -4410,6 +4512,9 @@ begin doUpdatePreferences(browser); + if (FMediaObserver <> nil) and (FRegistration = nil) then + FRegistration := AddObserver(FMediaObserver); + if Assigned(FOnAfterCreated) then FOnAfterCreated(Self, browser); end; @@ -4665,9 +4770,37 @@ begin aResourceRequestHandler); end; -procedure TChromiumCore.doOnFullScreenModeChange(const browser: ICefBrowser; fullscreen: Boolean); +procedure TChromiumCore.doOnSinks(const sinks: TCefMediaSinkArray); begin - if Assigned(FOnFullScreenModeChange) then FOnFullScreenModeChange(Self, browser, fullscreen); + if assigned(FOnSinks) then + FOnSinks(self, sinks); +end; + +procedure TChromiumCore.doOnRoutes(const routes: TCefMediaRouteArray); +begin + if assigned(FOnRoutes) then + FOnRoutes(self, routes); +end; + +procedure TChromiumCore.doOnRouteStateChanged(const route : ICefMediaRoute; + state : TCefMediaRouteConnectionState); +begin + if assigned(FOnRouteStateChanged) then + FOnRouteStateChanged(self, route, state); +end; + +procedure TChromiumCore.doOnRouteMessageReceived(const route : ICefMediaRoute; + const message_ : ustring); +begin + if assigned(FOnRouteMessageReceived) then + FOnRouteMessageReceived(self, route, message_); +end; + +procedure TChromiumCore.doOnFullScreenModeChange(const browser : ICefBrowser; + fullscreen : Boolean); +begin + if Assigned(FOnFullScreenModeChange) then + FOnFullScreenModeChange(Self, browser, fullscreen); end; function TChromiumCore.doOnGetAuthCredentials(const browser : ICefBrowser; @@ -5430,6 +5563,67 @@ begin if Initialized then FBrowser.Host.IMECancelComposition; end; +// ICefMediaRouter methods +function TChromiumCore.AddObserver(const observer: ICefMediaObserver): ICefRegistration; +var + TempMediaRouter : ICefMediaRouter; +begin + Result := nil; + TempMediaRouter := MediaRouter; + + if (TempMediaRouter <> nil) then + Result := TempMediaRouter.AddObserver(observer); +end; + +function TChromiumCore.GetSource(const urn: ustring): ICefMediaSource; +var + TempMediaRouter : ICefMediaRouter; +begin + Result := nil; + TempMediaRouter := MediaRouter; + + if (TempMediaRouter <> nil) then + Result := TempMediaRouter.GetSource(urn); +end; + +procedure TChromiumCore.NotifyCurrentSinks; +var + TempMediaRouter : ICefMediaRouter; +begin + TempMediaRouter := MediaRouter; + + if (TempMediaRouter <> nil) then + TempMediaRouter.NotifyCurrentSinks; +end; + +procedure TChromiumCore.NotifyCurrentRoutes; +var + TempMediaRouter : ICefMediaRouter; +begin + TempMediaRouter := MediaRouter; + + if (TempMediaRouter <> nil) then + TempMediaRouter.NotifyCurrentRoutes; +end; + +// This procedure is asynchronous and the result, ICefMediaRoute and the error +// message will be available in the TChromium.OnMediaRouteCreateFinished event. +procedure TChromiumCore.CreateRoute(const source: ICefMediaSource; const sink: ICefMediaSink); +var + TempMediaRouter : ICefMediaRouter; + TempCallback : ICefMediaRouteCreateCallback; +begin + TempMediaRouter := MediaRouter; + + if (TempMediaRouter <> nil) then + try + TempCallback := TCefCustomMediaRouteCreateCallback.Create(self); + TempMediaRouter.CreateRoute(source, sink, TempCallback); + finally + TempCallback := nil; + end; +end; + {$IFDEF MSWINDOWS} function TChromiumCore.CopyDCToBitmapStream(aSrcDC : HDC; const aSrcRect : TRect; var aStream : TStream) : boolean; var diff --git a/source/uCEFChromiumEvents.pas b/source/uCEFChromiumEvents.pas index 11c5e9a3..f701bfc0 100644 --- a/source/uCEFChromiumEvents.pas +++ b/source/uCEFChromiumEvents.pas @@ -166,6 +166,12 @@ type TOnBeforePluginLoad = procedure(Sender: TObject; const mimeType, pluginUrl:ustring; isMainFrame : boolean; const topOriginUrl: ustring; const pluginInfo: ICefWebPluginInfo; var pluginPolicy: TCefPluginPolicy; var aResult : boolean) of Object; // ICefRequestContextHandler uses the same TOnGetResourceRequestHandler event type defined for ICefRequestHandler + // ICefMediaObserver + TOnSinksEvent = procedure(Sender: TObject; const sinks: TCefMediaSinkArray) of object; + TOnRoutesEvent = procedure(Sender: TObject; const routes: TCefMediaRouteArray) of object; + TOnRouteStateChangedEvent = procedure(Sender: TObject; const route: ICefMediaRoute; state: TCefMediaRouteConnectionState) of object; + TOnRouteMessageReceivedEvent = procedure(Sender: TObject; const route: ICefMediaRoute; const message_: ustring) of object; + // Custom TOnTextResultAvailableEvent = procedure(Sender: TObject; const aText : ustring) of object; TOnPdfPrintFinishedEvent = procedure(Sender: TObject; aResultOK : boolean) of object; @@ -179,6 +185,7 @@ type TOnCookieVisitorDestroyed = procedure(Sender: TObject; aID : integer) of object; TOnCookieSet = procedure(Sender: TObject; aSuccess : boolean; aID : integer) of object; TOnZoomPctAvailable = procedure(Sender: TObject; const aZoomPct : double) of object; + TOnMediaRouteCreateFinishedEvent = procedure(Sender: TObject; result: TCefMediaRouterCreateResult; const error: ustring; const route: ICefMediaRoute) of object; {$IFDEF MSWINDOWS} TOnCompMsgEvent = procedure(var aMessage: TMessage; var aHandled: Boolean) of object; {$ENDIF} diff --git a/source/uCEFInterfaces.pas b/source/uCEFInterfaces.pas index e9f38577..a192014b 100644 --- a/source/uCEFInterfaces.pas +++ b/source/uCEFInterfaces.pas @@ -159,7 +159,31 @@ type TCefMediaRouteArray = array of ICefMediaRoute; TCefMediaSinkArray = array of ICefMediaSink; + TCefMediaSinkInfo = record + ID : ustring; + Valid : boolean; + Name : ustring; + Description : ustring; + SinkType : TCefMediaType; + SinkIntf : ICefMediaSink; + end; + TCefMediaSinkInfoArray = array of TCefMediaSinkInfo; + TCefMediaRouteInfo = record + ID : ustring; + SourceID : ustring; + SinkID : ustring; + RouteIntf : ICefMediaRoute; + end; + TCefMediaRouteInfoArray = array of TCefMediaRouteInfo; + + TCefMediaSourceInfo = record + ID : ustring; + Valid : boolean; + SourceType : TCefMediaType; + SourceIntf : ICefMediaSource; + end; + TCefMediaSourceInfoArray = array of TCefMediaSourceInfo; // ******************************************* // ***************** Events ****************** @@ -217,7 +241,7 @@ type TCefNavigationEntryVisitorProc = {$IFDEF DELPHI12_UP}reference to{$ENDIF} function(const entry: ICefNavigationEntry; current: Boolean; index, total: Integer): Boolean; TOnDownloadImageFinishedProc = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure(const imageUrl: ustring; httpStatusCode: Integer; const image: ICefImage); TCefCookieVisitorProc = {$IFDEF DELPHI12_UP}reference to{$ENDIF} function(const name, value, domain, path: ustring; secure, httponly, hasExpires: Boolean; const creation, lastAccess, expires: TDateTime; count, total: Integer; out deleteCookie: Boolean): Boolean; - + TCefMediaRouteCreateCallbackProc = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure(result: TCefMediaRouterCreateResult; const error: ustring; const route: ICefMediaRoute); // ******************************************* @@ -388,6 +412,12 @@ type function doOnBeforePluginLoad(const mimeType, pluginUrl:ustring; isMainFrame : boolean; const topOriginUrl: ustring; const pluginInfo: ICefWebPluginInfo; var pluginPolicy: TCefPluginPolicy): Boolean; procedure doGetResourceRequestHandler_ReqCtxHdlr(const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; is_navigation, is_download: boolean; const request_initiator: ustring; var disable_default_handling: boolean; var aResourceRequestHandler : ICefResourceRequestHandler); + // ICefMediaObserver + procedure doOnSinks(const sinks: TCefMediaSinkArray); + procedure doOnRoutes(const routes: TCefMediaRouteArray); + procedure doOnRouteStateChanged(const route: ICefMediaRoute; state: TCefMediaRouteConnectionState); + procedure doOnRouteMessageReceived(const route: ICefMediaRoute; const message_: ustring); + // Custom procedure doCookiesDeleted(numDeleted : integer); procedure doPdfPrintFinished(aResultOK : boolean); @@ -412,6 +442,7 @@ type procedure doSetZoomPct(const aValue : double); procedure doSetZoomStep(aValue : byte); procedure doReadZoom; + procedure doMediaRouteCreateFinished(result: TCefMediaRouterCreateResult; const error: ustring; const route: ICefMediaRoute); function MustCreateLoadHandler : boolean; function MustCreateFocusHandler : boolean; function MustCreateContextMenuHandler : boolean; @@ -427,6 +458,8 @@ type function MustCreateFindHandler : boolean; function MustCreateResourceRequestHandler : boolean; function MustCreateCookieAccessFilter : boolean; + function MustCreateRequestContextHandler : boolean; + function MustCreateMediaObserver : boolean; end; IServerEvents = interface @@ -1263,7 +1296,7 @@ type procedure OnSinks(const sinks: TCefMediaSinkArray); procedure OnRoutes(const routes: TCefMediaRouteArray); procedure OnRouteStateChanged(const route: ICefMediaRoute; state: TCefMediaRouteConnectionState); - procedure OnRouteMessageReceived(const route: ICefMediaRoute; const message_: Pointer; message_size: NativeUInt); + procedure OnRouteMessageReceived(const route: ICefMediaRoute; const message_: ustring); end; ICefMediaObserverEvents = interface @@ -1271,7 +1304,7 @@ type procedure doOnSinks(const sinks: TCefMediaSinkArray); procedure doOnRoutes(const routes: TCefMediaRouteArray); procedure doOnRouteStateChanged(const route: ICefMediaRoute; state: TCefMediaRouteConnectionState); - procedure doOnRouteMessageReceived(const route: ICefMediaRoute; const message_: Pointer; message_size: NativeUInt); + procedure doOnRouteMessageReceived(const route: ICefMediaRoute; const message_: ustring); end; // TCefMediaRoute @@ -1281,10 +1314,12 @@ type function GetId: ustring; function GetSource: ICefMediaSource; function GetSink: ICefMediaSink; - procedure SendRouteMessage(const message_: Pointer; message_size: NativeUInt); + procedure SendRouteMessage(const message_: ustring); procedure Terminate; - property ID : ustring read GetId; + property ID : ustring read GetId; + property Source : ICefMediaSource read GetSource; + property Sink : ICefMediaSink read GetSink; end; // TCefMediaRouteCreateCallback @@ -2123,8 +2158,9 @@ type function GetExtension(const extension_id: ustring): ICefExtension; function GetMediaRouter: ICefMediaRouter; - property CachePath : ustring read GetCachePath; - property IsGlobalContext : boolean read IsGlobal; + property CachePath : ustring read GetCachePath; + property IsGlobalContext : boolean read IsGlobal; + property MediaRouter : ICefMediaRouter read GetMediaRouter; end; // TCefPrintSettings diff --git a/source/uCEFMediaObserver.pas b/source/uCEFMediaObserver.pas index 70051539..ad5ae4c4 100644 --- a/source/uCEFMediaObserver.pas +++ b/source/uCEFMediaObserver.pas @@ -57,7 +57,7 @@ type procedure OnSinks(const sinks: TCefMediaSinkArray); virtual; procedure OnRoutes(const routes: TCefMediaRouteArray); virtual; procedure OnRouteStateChanged(const route: ICefMediaRoute; state: TCefMediaRouteConnectionState); virtual; - procedure OnRouteMessageReceived(const route: ICefMediaRoute; const message_: Pointer; message_size: NativeUInt); virtual; + procedure OnRouteMessageReceived(const route: ICefMediaRoute; const message_: ustring); virtual; public constructor Create; virtual; @@ -70,10 +70,10 @@ type procedure OnSinks(const sinks: TCefMediaSinkArray); override; procedure OnRoutes(const routes: TCefMediaRouteArray); override; procedure OnRouteStateChanged(const route: ICefMediaRoute; state: TCefMediaRouteConnectionState); override; - procedure OnRouteMessageReceived(const route: ICefMediaRoute; const message_: Pointer; message_size: NativeUInt); override; + procedure OnRouteMessageReceived(const route: ICefMediaRoute; const message_: ustring); override; public - constructor Create(const events: ICefMediaObserverEvents); reintroduce; + constructor Create(const events: IChromiumEvents); reintroduce; destructor Destroy; override; end; @@ -95,26 +95,28 @@ uses procedure cef_media_observer_on_sinks( self : PCefMediaObserver; sinksCount : NativeUInt; const sinks : PPCefMediaSink); stdcall; +type + TSinkArray = array of PCefMediaSink; var TempObject : TObject; TempArray : TCefMediaSinkArray; i : NativeUInt; - TempItem : PCefMediaSink; begin TempArray := nil; TempObject := CefGetObject(self); if (TempObject <> nil) and (TempObject is TCefMediaObserverOwn) then try - SetLength(TempArray, sinksCount); - TempItem := PCefMediaSink(sinks^); - - i := 0; - while (i < sinksCount) do + if (sinksCount > 0) and (sinks <> nil) then begin - TempArray[i] := TCefMediaSinkRef.UnWrap(TempItem); - inc(TempItem); - inc(i); + SetLength(TempArray, sinksCount); + + i := 0; + while (i < sinksCount) do + begin + TempArray[i] := TCefMediaSinkRef.UnWrap(TSinkArray(sinks)[i]); + inc(i); + end; end; TCefMediaObserverOwn(TempObject).OnSinks(TempArray); @@ -137,26 +139,28 @@ end; procedure cef_media_observer_on_routes( self : PCefMediaObserver; routesCount : NativeUInt; const routes : PPCefMediaRoute); stdcall; +type + TRouteArray = array of PCefMediaRoute; var TempObject : TObject; TempArray : TCefMediaRouteArray; i : NativeUInt; - TempItem : PCefMediaRoute; begin TempArray := nil; TempObject := CefGetObject(self); if (TempObject <> nil) and (TempObject is TCefMediaObserverOwn) then try - SetLength(TempArray, routesCount); - TempItem := PCefMediaRoute(routes^); - - i := 0; - while (i < routesCount) do + if (routesCount > 0) and (routes <> nil) then begin - TempArray[i] := TCefMediaRouteRef.UnWrap(TempItem); - inc(TempItem); - inc(i); + SetLength(TempArray, routesCount); + + i := 0; + while (i < routesCount) do + begin + TempArray[i] := TCefMediaRouteRef.UnWrap(TRouteArray(routes)[i]); + inc(i); + end; end; TCefMediaObserverOwn(TempObject).OnRoutes(TempArray); @@ -193,14 +197,19 @@ procedure cef_media_observer_on_route_message_received( self : PCef const message_ : Pointer; message_size : NativeUInt); stdcall; var - TempObject : TObject; + TempObject : TObject; + TempMessage : Ansistring; begin TempObject := CefGetObject(self); if (TempObject <> nil) and (TempObject is TCefMediaObserverOwn) then - TCefMediaObserverOwn(TempObject).OnRouteMessageReceived(TCefMediaRouteRef.UnWrap(route), - message_, - message_size); + begin + if (message_size > 0) and (message_ <> nil) then + SetString(TempMessage, PAnsiChar(message_), message_size); + + TCefMediaObserverOwn(TempObject).OnRouteMessageReceived(TCefMediaRouteRef.UnWrap(route), + ustring(TempMessage)); + end; end; constructor TCefMediaObserverOwn.Create; @@ -231,7 +240,7 @@ begin // end; -procedure TCefMediaObserverOwn.OnRouteMessageReceived(const route: ICefMediaRoute; const message_: Pointer; message_size: NativeUInt); +procedure TCefMediaObserverOwn.OnRouteMessageReceived(const route: ICefMediaRoute; const message_: ustring); begin // end; @@ -240,7 +249,7 @@ end; // ************** TCustomMediaObserver ************** // ************************************************** -constructor TCustomMediaObserver.Create(const events: ICefMediaObserverEvents); +constructor TCustomMediaObserver.Create(const events: IChromiumEvents); begin inherited Create; @@ -258,7 +267,7 @@ procedure TCustomMediaObserver.OnSinks(const sinks: TCefMediaSinkArray); begin try if (FEvents <> nil) then - ICefMediaObserverEvents(FEvents).doOnSinks(sinks); + IChromiumEvents(FEvents).doOnSinks(sinks); except on e : exception do if CustomExceptionHandler('TCustomMediaObserver.OnSinks', e) then raise; @@ -269,7 +278,7 @@ procedure TCustomMediaObserver.OnRoutes(const routes: TCefMediaRouteArray); begin try if (FEvents <> nil) then - ICefMediaObserverEvents(FEvents).doOnRoutes(routes); + IChromiumEvents(FEvents).doOnRoutes(routes); except on e : exception do if CustomExceptionHandler('TCustomMediaObserver.OnRoutes', e) then raise; @@ -280,18 +289,18 @@ procedure TCustomMediaObserver.OnRouteStateChanged(const route: ICefMediaRoute; begin try if (FEvents <> nil) then - ICefMediaObserverEvents(FEvents).doOnRouteStateChanged(route, state); + IChromiumEvents(FEvents).doOnRouteStateChanged(route, state); except on e : exception do if CustomExceptionHandler('TCustomMediaObserver.OnRouteStateChanged', e) then raise; end; end; -procedure TCustomMediaObserver.OnRouteMessageReceived(const route: ICefMediaRoute; const message_: Pointer; message_size: NativeUInt); +procedure TCustomMediaObserver.OnRouteMessageReceived(const route: ICefMediaRoute; const message_: ustring); begin try if (FEvents <> nil) then - ICefMediaObserverEvents(FEvents).doOnRouteMessageReceived(route, message_, message_size); + IChromiumEvents(FEvents).doOnRouteMessageReceived(route, message_); except on e : exception do if CustomExceptionHandler('TCustomMediaObserver.OnRouteMessageReceived', e) then raise; diff --git a/source/uCEFMediaObserverComponent.pas b/source/uCEFMediaObserverComponent.pas deleted file mode 100644 index b1b0bc9f..00000000 --- a/source/uCEFMediaObserverComponent.pas +++ /dev/null @@ -1,188 +0,0 @@ -// ************************************************************************ -// ***************************** CEF4Delphi ******************************* -// ************************************************************************ -// -// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based -// browser in Delphi applications. -// -// The original license of DCEF3 still applies to CEF4Delphi. -// -// For more information about CEF4Delphi visit : -// https://www.briskbard.com/index.php?lang=en&pageid=cef -// -// Copyright © 2020 Salvador Diaz Fau. All rights reserved. -// -// ************************************************************************ -// ************ vvvv Original license and comments below vvvv ************* -// ************************************************************************ -(* - * Delphi Chromium Embedded 3 - * - * Usage allowed under the restrictions of the Lesser GNU General Public License - * or alternatively the restrictions of the Mozilla Public License 1.1 - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * Unit owner : Henri Gourvest - * Web site : http://www.progdigy.com - * Repository : http://code.google.com/p/delphichromiumembedded/ - * Group : http://groups.google.com/group/delphichromiumembedded - * - * Embarcadero Technologies, Inc is not permitted to use or redistribute - * this source code without explicit permission. - * - *) - -unit uCEFMediaObserverComponent; - -{$IFDEF FPC} - {$MODE OBJFPC}{$H+} -{$ENDIF} - -{$IFNDEF CPUX64}{$ALIGN ON}{$ENDIF} -{$MINENUMSIZE 4} - -{$I cef.inc} - -interface - -uses - {$IFDEF DELPHI16_UP} - {$IFDEF MSWINDOWS}WinApi.Windows, WinApi.Messages, WinApi.ActiveX,{$ENDIF} - System.Classes, System.Math, - {$ELSE} - {$IFDEF MSWINDOWS}Windows, ActiveX,{$ENDIF} Classes, Math, - {$IFDEF FPC} - LCLProc, LCLType, LCLIntf, LResources, LMessages, InterfaceBase, - {$ELSE} - Messages, - {$ENDIF} - {$ENDIF} - uCEFTypes, uCEFInterfaces, uCEFMediaObserver, uCEFMediaObserverEvents; - -type - {$IFNDEF FPC}{$IFDEF DELPHI16_UP}[ComponentPlatformsAttribute(pidWin32 or pidWin64)]{$ENDIF}{$ENDIF} - TCEFMediaObserverComponent = class(TComponent, ICefMediaObserverEvents) - protected - FMediaObserver : ICefMediaObserver; - FOnSinks : TOnSinksEvent; - FOnRoutes : TOnRoutesEvent; - FOnRouteStateChanged : TOnRouteStateChangedEvent; - FOnRouteMessageReceived : TOnRouteMessageReceivedEvent; - - // ICefMediaObserverEvents - procedure doOnSinks(const sinks: TCefMediaSinkArray); virtual; - procedure doOnRoutes(const routes: TCefMediaRouteArray); virtual; - procedure doOnRouteStateChanged(const route: ICefMediaRoute; state: TCefMediaRouteConnectionState); virtual; - procedure doOnRouteMessageReceived(const route: ICefMediaRoute; const message_: Pointer; message_size: NativeUInt); virtual; - - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - procedure AfterConstruction; override; - - property MediaObserver : ICefMediaObserver read FMediaObserver; - - published - property OnSinks : TOnSinksEvent read FOnSinks write FOnSinks; - property OnRoutes : TOnRoutesEvent read FOnRoutes write FOnRoutes; - property OnRouteStateChanged : TOnRouteStateChangedEvent read FOnRouteStateChanged write FOnRouteStateChanged; - property OnRouteMessageReceived : TOnRouteMessageReceivedEvent read FOnRouteMessageReceived write FOnRouteMessageReceived; - end; - -{$IFDEF FPC} -procedure Register; -{$ENDIF} - -implementation - -// ********************************************************* -// ********************** ATTENTION ! ********************** -// ********************************************************* -// ** ** -// ** MANY OF THE EVENTS IN CEF4DELPHI COMPONENTS LIKE ** -// ** TCHROMIUM, TFMXCHROMIUM OR TCEFAPPLICATION ARE ** -// ** EXECUTED IN A CEF THREAD BY DEFAULT. ** -// ** ** -// ** WINDOWS CONTROLS MUST BE CREATED AND DESTROYED IN ** -// ** THE SAME THREAD TO AVOID ERRORS. ** -// ** SOME OF THEM RECREATE THE HANDLERS IF THEY ARE ** -// ** MODIFIED AND CAN CAUSE THE SAME ERRORS. ** -// ** ** -// ** DON'T CREATE, MODIFY OR DESTROY WINDOWS CONTROLS ** -// ** INSIDE THE CEF4DELPHI EVENTS AND USE ** -// ** SYNCHRONIZATION OBJECTS TO PROTECT VARIABLES AND ** -// ** FIELDS IF THEY ARE ALSO USED IN THE MAIN THREAD. ** -// ** ** -// ** READ THIS FOR MORE INFORMATION : ** -// ** https://www.briskbard.com/index.php?pageid=cef ** -// ** ** -// ** USE OUR FORUMS FOR MORE QUESTIONS : ** -// ** https://www.briskbard.com/forum/ ** -// ** ** -// ********************************************************* -// ********************************************************* - -constructor TCEFMediaObserverComponent.Create(AOwner: TComponent); -begin - inherited Create(aOwner); - - FMediaObserver := nil; - FOnSinks := nil; - FOnRoutes := nil; - FOnRouteStateChanged := nil; - FOnRouteMessageReceived := nil; -end; - -destructor TCEFMediaObserverComponent.Destroy; -begin - FMediaObserver := nil; - - inherited Destroy; -end; - -procedure TCEFMediaObserverComponent.AfterConstruction; -begin - inherited AfterConstruction; - - FMediaObserver := TCustomMediaObserver.Create(self); -end; - -procedure TCEFMediaObserverComponent.doOnSinks(const sinks: TCefMediaSinkArray); -begin - if assigned(FOnSinks) then - FOnSinks(self, sinks); -end; - -procedure TCEFMediaObserverComponent.doOnRoutes(const routes: TCefMediaRouteArray); -begin - if assigned(FOnRoutes) then - FOnRoutes(self, routes); -end; - -procedure TCEFMediaObserverComponent.doOnRouteStateChanged(const route : ICefMediaRoute; - state : TCefMediaRouteConnectionState); -begin - if assigned(FOnRouteStateChanged) then - FOnRouteStateChanged(self, route, state); -end; - -procedure TCEFMediaObserverComponent.doOnRouteMessageReceived(const route : ICefMediaRoute; - const message_ : Pointer; - message_size : NativeUInt); -begin - if assigned(FOnRouteMessageReceived) then - FOnRouteMessageReceived(self, route, message_, message_size); -end; - -{$IFDEF FPC} -procedure Register; -begin - {$I res/tcefmediaobservercomponent.lrs} - RegisterComponents('Chromium', [TCEFMediaObserverComponent]); -end; -{$ENDIF} - -end. diff --git a/source/uCEFMediaRoute.pas b/source/uCEFMediaRoute.pas index c567b61f..f26f2d3e 100644 --- a/source/uCEFMediaRoute.pas +++ b/source/uCEFMediaRoute.pas @@ -57,7 +57,7 @@ type function GetId: ustring; function GetSource: ICefMediaSource; function GetSink: ICefMediaSink; - procedure SendRouteMessage(const message_: Pointer; message_size: NativeUInt); + procedure SendRouteMessage(const message_: ustring); procedure Terminate; public class function UnWrap(data: Pointer): ICefMediaRoute; @@ -83,9 +83,19 @@ begin Result := TCefMediaSinkRef.UnWrap(PCefMediaRoute(FData)^.get_sink(PCefMediaRoute(FData))); end; -procedure TCefMediaRouteRef.SendRouteMessage(const message_: Pointer; message_size: NativeUInt); +procedure TCefMediaRouteRef.SendRouteMessage(const message_: ustring); +var + TempMsg : pointer; + TempSize : NativeUInt; begin - PCefMediaRoute(FData)^.send_route_message(PCefMediaRoute(FData), message_, message_size); + TempSize := length(message_); + + if (TempSize > 0) then + TempMsg := @message_[1] + else + TempMsg := nil; + + PCefMediaRoute(FData)^.send_route_message(PCefMediaRoute(FData), TempMsg, TempSize); end; procedure TCefMediaRouteRef.Terminate; diff --git a/source/uCEFMediaRouteCreateCallback.pas b/source/uCEFMediaRouteCreateCallback.pas index 127ae08c..19a35ceb 100644 --- a/source/uCEFMediaRouteCreateCallback.pas +++ b/source/uCEFMediaRouteCreateCallback.pas @@ -52,37 +52,135 @@ uses uCEFBaseRefCounted, uCEFInterfaces, uCEFTypes; type - TCefMediaRouteCreateCallbackRef = class(TCefBaseRefCountedRef, ICefMediaRouteCreateCallback) - protected - procedure OnMediaRouteCreateFinished(result: TCefMediaRouterCreateResult; const error: ustring; const route: ICefMediaRoute); - public - class function UnWrap(data: Pointer): ICefMediaRouteCreateCallback; + TCefMediaRouteCreateCallbackOwn = class(TCefBaseRefCountedOwn, ICefMediaRouteCreateCallback) + protected + procedure OnMediaRouteCreateFinished(result: TCefMediaRouterCreateResult; const error: ustring; const route: ICefMediaRoute); virtual; abstract; + public + constructor Create; virtual; + end; + + TCefFastMediaRouteCreateCallback = class(TCefMediaRouteCreateCallbackOwn) + protected + FCallback: TCefMediaRouteCreateCallbackProc; + + procedure OnMediaRouteCreateFinished(result: TCefMediaRouterCreateResult; const error: ustring; const route: ICefMediaRoute); override; + public + constructor Create(const callback: TCefMediaRouteCreateCallbackProc); reintroduce; + destructor Destroy; override; + end; + + TCefCustomMediaRouteCreateCallback = class(TCefMediaRouteCreateCallbackOwn) + protected + FEvents : Pointer; + + procedure OnMediaRouteCreateFinished(result: TCefMediaRouterCreateResult; const error: ustring; const route: ICefMediaRoute); override; + public + constructor Create(const aEvents : IChromiumEvents); reintroduce; + destructor Destroy; override; end; implementation uses - uCEFMiscFunctions, uCEFLibFunctions; + {$IFDEF DELPHI16_UP} + System.SysUtils, + {$ELSE} + SysUtils, + {$ENDIF} + uCEFMiscFunctions, uCEFLibFunctions, uCEFMediaRoute; -procedure TCefMediaRouteCreateCallbackRef.OnMediaRouteCreateFinished( result : TCefMediaRouterCreateResult; - const error : ustring; - const route : ICefMediaRoute); +procedure cef_media_route_create_callback_on_media_route_create_finished( self : PCefMediaRouteCreateCallback; + result : TCefMediaRouterCreateResult; + const error : PCefString; + route : PCefMediaRoute); stdcall; var - TempError : TCefString; + TempObject : TObject; begin - TempError := CefString(error); - PCefMediaRouteCreateCallback(FData)^.on_media_route_create_finished(PCefMediaRouteCreateCallback(FData), - result, - @TempError, - CefGetData(route)); + TempObject := CefGetObject(self); + + if (TempObject <> nil) and (TempObject is TCefMediaRouteCreateCallbackOwn) then + TCefMediaRouteCreateCallbackOwn(TempObject).OnMediaRouteCreateFinished(result, + CefString(error), + TCefMediaRouteRef.UnWrap(route)); end; -class function TCefMediaRouteCreateCallbackRef.UnWrap(data: Pointer): ICefMediaRouteCreateCallback; + +// ************************************************************* +// ************** TCefMediaRouteCreateCallbackOwn ************** +// ************************************************************* + +constructor TCefMediaRouteCreateCallbackOwn.Create; begin - if (data <> nil) then - Result := Create(data) as ICefMediaRouteCreateCallback - else - Result := nil; + inherited CreateData(SizeOf(TCefMediaRouteCreateCallback)); + + PCefMediaRouteCreateCallback(FData)^.on_media_route_create_finished := + {$IFDEF FPC}@{$ENDIF}cef_media_route_create_callback_on_media_route_create_finished; end; + +// ************************************************************** +// ************** TCefFastMediaRouteCreateCallback ************** +// ************************************************************** + +constructor TCefFastMediaRouteCreateCallback.Create(const callback: TCefMediaRouteCreateCallbackProc); +begin + inherited Create; + + FCallback := callback; +end; + +procedure TCefFastMediaRouteCreateCallback.OnMediaRouteCreateFinished( result : TCefMediaRouterCreateResult; + const error : ustring; + const route : ICefMediaRoute); +begin + if assigned(FCallback) then + FCallback(result, error, route); +end; + +destructor TCefFastMediaRouteCreateCallback.Destroy; +begin + FCallback := nil; + + inherited Destroy; +end; + + +// **************************************************************** +// ************** TCefCustomMediaRouteCreateCallback ************** +// **************************************************************** + +constructor TCefCustomMediaRouteCreateCallback.Create(const aEvents : IChromiumEvents); +begin + inherited Create; + + FEvents := Pointer(aEvents); +end; + +destructor TCefCustomMediaRouteCreateCallback.Destroy; +begin + FEvents := nil; + + inherited Destroy; +end; + +procedure TCefCustomMediaRouteCreateCallback.OnMediaRouteCreateFinished( result : TCefMediaRouterCreateResult; + const error : ustring; + const route : ICefMediaRoute); +begin + try + try + if (FEvents <> nil) then + IChromiumEvents(FEvents).doMediaRouteCreateFinished(result, error, route); + except + on e : exception do + if CustomExceptionHandler('TCefCustomMediaRouteCreateCallback.OnMediaRouteCreateFinished', e) then raise; + end; + finally + FEvents := nil; + end; +end; + + + + end. diff --git a/source/uCEFTypes.pas b/source/uCEFTypes.pas index 55b00555..ffc6b72d 100644 --- a/source/uCEFTypes.pas +++ b/source/uCEFTypes.pas @@ -423,6 +423,9 @@ type hpDisableNonProxiedUDP ); + // Used by TCefMediaSinkInfo and TCefMediaSourceInfo + TCefMediaType = (mtCast, mtDial, mtUnknown); + // /include/internal/cef_types_win.h (cef_main_args_t) TCefMainArgs = record {$IFDEF MSWINDOWS} diff --git a/update_CEF4Delphi.json b/update_CEF4Delphi.json index 11d6edb0..ba9b68b2 100644 --- a/update_CEF4Delphi.json +++ b/update_CEF4Delphi.json @@ -2,9 +2,9 @@ "UpdateLazPackages" : [ { "ForceNotify" : true, - "InternalVersion" : 118, + "InternalVersion" : 119, "Name" : "cef4delphi_lazarus.lpk", - "Version" : "81.2.16.0" + "Version" : "81.2.17.0" } ], "UpdatePackageData" : {