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
This commit is contained in:
Salvador Díaz Fau 2020-04-19 22:47:20 +02:00
parent 02ef32b474
commit 62c310a7b9
28 changed files with 2934 additions and 338 deletions

View File

@ -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)

View File

@ -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

View File

@ -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 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.

File diff suppressed because it is too large Load Diff

View File

@ -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 <hgourvest@gmail.com>
* 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}

View File

@ -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:<appId>?clientId=<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

View File

@ -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 <hgourvest@gmail.com>
* 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.

View File

@ -8,7 +8,8 @@
<Unit0>
<Filename Value="SimpleOSRBrowser.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="2"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="1"/>
<TopLine Value="30"/>
<CursorPos X="28" Y="39"/>
<UsageCount Value="20"/>
@ -244,11 +245,10 @@
</Unit28>
<Unit29>
<Filename Value="..\..\..\source\uCEFApplicationCore.pas"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="1"/>
<EditorIndex Value="-1"/>
<TopLine Value="43"/>
<CursorPos X="57" Y="67"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit29>
</Units>
<JumpHistory Count="30" HistoryIndex="29">

View File

@ -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.

View File

@ -277,8 +277,6 @@
<DCCReference Include="..\source\uCEFMediaSink.pas"/>
<DCCReference Include="..\source\uCEFMediaSource.pas"/>
<DCCReference Include="..\source\uCEFRegistration.pas"/>
<DCCReference Include="..\source\uCEFMediaObserverComponent.pas"/>
<DCCReference Include="..\source\uCEFMediaObserverEvents.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -303,8 +303,6 @@
<DCCReference Include="..\source\uCEFMediaObserver.pas"/>
<DCCReference Include="..\source\uCEFMediaRouter.pas"/>
<DCCReference Include="..\source\uCEFRegistration.pas"/>
<DCCReference Include="..\source\uCEFMediaObserverComponent.pas"/>
<DCCReference Include="..\source\uCEFMediaObserverEvents.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>

View File

@ -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.

View File

@ -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.

View File

@ -21,8 +21,8 @@
</CompilerOptions>
<Description Value="CEF4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC."/>
<License Value="MPL 1.1"/>
<Version Major="81" Minor="2" Release="16"/>
<Files Count="156">
<Version Major="81" Minor="2" Release="17"/>
<Files Count="154">
<Item1>
<Filename Value="..\source\uCEFAccessibilityHandler.pas"/>
<UnitName Value="uCEFAccessibilityHandler"/>
@ -625,38 +625,29 @@
<UnitName Value="uCEFMediaObserver"/>
</Item148>
<Item149>
<Filename Value="..\source\uCEFMediaObserverComponent.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="uCEFMediaObserverComponent"/>
</Item149>
<Item150>
<Filename Value="..\source\uCEFMediaObserverEvents.pas"/>
<UnitName Value="uCEFMediaObserverEvents"/>
</Item150>
<Item151>
<Filename Value="..\source\uCEFMediaRoute.pas"/>
<UnitName Value="uCEFMediaRoute"/>
</Item151>
<Item152>
</Item149>
<Item150>
<Filename Value="..\source\uCEFMediaRouteCreateCallback.pas"/>
<UnitName Value="uCEFMediaRouteCreateCallback"/>
</Item152>
<Item153>
</Item150>
<Item151>
<Filename Value="..\source\uCEFMediaRouter.pas"/>
<UnitName Value="uCEFMediaRouter"/>
</Item153>
<Item154>
</Item151>
<Item152>
<Filename Value="..\source\uCEFMediaSink.pas"/>
<UnitName Value="uCEFMediaSink"/>
</Item154>
<Item155>
</Item152>
<Item153>
<Filename Value="..\source\uCEFMediaSource.pas"/>
<UnitName Value="uCEFMediaSource"/>
</Item155>
<Item156>
</Item153>
<Item154>
<Filename Value="..\source\uCEFRegistration.pas"/>
<UnitName Value="uCEFRegistration"/>
</Item156>
</Item154>
</Files>
<RequiredPkgs Count="4">
<Item1>

View File

@ -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

View File

@ -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';

View File

@ -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

View File

@ -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}

View File

@ -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

View File

@ -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;

View File

@ -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 <hgourvest@gmail.com>
* 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.

View File

@ -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;

View File

@ -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.

View File

@ -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}

View File

@ -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" : {