mirror of
https://gitlab.com/freepascal.org/fpc/pas2js.git
synced 2025-04-05 04:17:54 +02:00
236 lines
6.5 KiB
ObjectPascal
236 lines
6.5 KiB
ObjectPascal
program helloworld;
|
|
|
|
{$mode objfpc}
|
|
|
|
uses
|
|
JS, Classes, SysUtils, Web, libkurento, node.events, browserapp, browserconsole;
|
|
|
|
Type
|
|
|
|
{ TKurentoApp }
|
|
|
|
TKurentoApp = class(TBrowserApplication)
|
|
Private
|
|
FURL : TJSHTMLInputElement;
|
|
FVideoInput,
|
|
FVideoOutput,
|
|
FStartButton,
|
|
FStopButton : TJSHTMLElement;
|
|
FWebRTCPeer : TWebRtcPeer;
|
|
FClient: TKurentoClient;
|
|
FPipeLine : TKurentoMediaPipeline;
|
|
FRTCEndPoint : TKurentoWebRtcEndPoint;
|
|
FMyOffer: TKurentoOffer;
|
|
// Helper routine to display offers.
|
|
procedure DoError(aError: TJSError);
|
|
// Helper routine to set needed ICE callbacks.
|
|
procedure setIceCandidateCallbacks(webRtcPeer : TWebRtcPeer; webRtcEp : TKurentoWebRtcEndPoint; onerror : TErrorCallBack);
|
|
// Here we start the ball rolling , we create the WebRTCPeer, and create an offer
|
|
function DoStart(aEvent: TJSMouseEvent): boolean;
|
|
function DoStop(aEvent: TJSMouseEvent): boolean;
|
|
// When the offer is received, we create a Kurento client
|
|
procedure OnOfferReceived(aError: TJSError; aOffer: TKurentoOffer);
|
|
// When the kurento client is created, we use it to create a media pipeline
|
|
procedure HaveClient(aError: TJSError; aClient: TKurentoClient);
|
|
// When the pipeline is created, we use it to create an endpoint for it
|
|
procedure HavePipeLine(aError: TJSError; aResult: TKurentoMediaObject);
|
|
// When the endpoint was created, we handle ICE candidates, process the offer, and start gathering candidates
|
|
// In the end, we connect. When the connect succeeds, we're all done.
|
|
procedure HaveEndPoint(aError: TJSError; aResult: TKurentoMediaObject);
|
|
// When the offer is processed, here we handle the answer.
|
|
procedure OfferProcessed(aError: TJSError; aAnswer: TKurentoAnswer);
|
|
// Helper routines to Show/Hide a spinner.
|
|
procedure HideSpinner(Els: array of TJSHTMLElement);
|
|
procedure ShowSpinner(Els: array of TJSHTMLElement);
|
|
Public
|
|
procedure DoRun; override;
|
|
end;
|
|
|
|
procedure TKurentoApp.OfferProcessed(aError: TJSError; aAnswer: TKurentoAnswer);
|
|
|
|
begin
|
|
if assigned(aError) then
|
|
DoError(aError)
|
|
else
|
|
FWebRTCPeer.processAnswer(aAnswer,@DoError);
|
|
end;
|
|
|
|
Procedure TKurentoApp.HaveEndPoint(aError : TJSError; aResult : TKurentoMediaObject);
|
|
|
|
begin
|
|
Writeln('TKurentoApp.HaveEndPoint callback. Have error:',Assigned(aError));
|
|
if assigned(aError) then
|
|
DoError(aError)
|
|
else
|
|
begin
|
|
FRTCEndPoint:= TKurentoWebRtcEndPoint(aResult);
|
|
setIceCandidateCallbacks(FWebRTCPeer,FRTCEndPoint,@DoError);
|
|
FRTCEndPoint.processOffer(FMyOffer,@OfferProcessed);
|
|
FRTCEndPoint.gatherCandidates(@DoError);
|
|
FRTCEndPoint.connect(FRTCEndPoint,Procedure(aError : TJSError)
|
|
begin
|
|
if Assigned(aError) then
|
|
DoError(aError)
|
|
else
|
|
Writeln('We should be all set')
|
|
end);
|
|
end;
|
|
end;
|
|
|
|
Procedure TKurentoApp.HavePipeLine(aError : TJSError; aResult : TKurentoMediaObject);
|
|
|
|
begin
|
|
Writeln('TKurentoApp.HavePipeline callback. Have error:',Assigned(aError));
|
|
if assigned(aError) then
|
|
DoError(aError)
|
|
else
|
|
begin
|
|
FPipeLine:=TKurentoMediaPipeline(aResult);
|
|
FPipeLine.Create('WebRtcEndpoint',@HaveEndPoint);
|
|
end;
|
|
end;
|
|
|
|
procedure TKurentoApp.HaveClient(aError: TJSError; aClient: TKurentoClient);
|
|
|
|
begin
|
|
Writeln('TKurentoApp.HaveClient callback. Have error:',Assigned(aError));
|
|
if assigned(aError) then
|
|
DoError(aError)
|
|
else
|
|
begin
|
|
FClient:=aClient;
|
|
FClient.create('MediaPipeline',@HavePipeLine);
|
|
end;
|
|
end;
|
|
|
|
procedure TKurentoApp.OnOfferReceived(aError: TJSError; aOffer: TKurentoOffer);
|
|
begin
|
|
Writeln('TKurentoApp.OnOfferReceived callback. Have error:',Assigned(aError));
|
|
if assigned(aError) then
|
|
DoError(aError)
|
|
else
|
|
begin
|
|
FMyOffer:=aOffer;
|
|
KurentoClient(FURL.Value,@HaveClient);
|
|
end;
|
|
end;
|
|
|
|
procedure TKurentoApp.setIceCandidateCallbacks(webRtcPeer : TWebRtcPeer; webRtcEp : TKurentoWebRtcEndPoint; onerror : TErrorCallBack);
|
|
|
|
Type
|
|
TIceCandidateCreateFunction = function(arg : string) : TKurentoIceCandidate;
|
|
|
|
begin
|
|
webRtcPeer.on_('icecandidate', Procedure(candidate : JSValue)
|
|
var
|
|
Cand :TKurentoIceCandidate;
|
|
begin
|
|
console.log('Local candidate:',String(candidate));
|
|
cand:=TIceCandidateCreateFunction(TKurentoClientGlobal.getComplexType('IceCandidate'))(candidate);
|
|
webRtcEp.addIceCandidate(cand, onerror)
|
|
end
|
|
);
|
|
|
|
webRtcEp.on_('OnIceCandidate', Procedure(event : JSValue)
|
|
var
|
|
Cand :TKurentoIceCandidate;
|
|
begin
|
|
cand:=TKurentoIceCandidate(TJSObject(event)['candidate']);
|
|
console.log('Remote candidate:',TJSJSON.Stringify(cand));
|
|
webRtcPeer.addIceCandidate(cand, onerror);
|
|
end
|
|
);
|
|
end;
|
|
|
|
Procedure TKurentoApp.HideSpinner(Els : Array of TJSHTMLElement);
|
|
|
|
Var
|
|
El : TJSHTMLElement;
|
|
|
|
begin
|
|
For El in Els do
|
|
begin
|
|
El['src']:='';
|
|
El['poster']:='img/webrtc.png';
|
|
El.style.setProperty('background','');
|
|
end;
|
|
end;
|
|
|
|
Procedure TKurentoApp.ShowSpinner(Els : Array of TJSHTMLElement);
|
|
|
|
Var
|
|
El : TJSHTMLElement;
|
|
|
|
begin
|
|
For El in Els do
|
|
begin
|
|
El['poster']:='img/transparent-1px.png';
|
|
El.style.setProperty('background','center transparent url("img/spinner.gif") no-repeat');
|
|
end;
|
|
end;
|
|
|
|
Procedure TKurentoApp.DoError(aError : TJSError);
|
|
|
|
begin
|
|
if Assigned(aError) then
|
|
writeln('An error occurred: ',aError.Message);
|
|
end;
|
|
|
|
function TKurentoApp.DoStop(aEvent: TJSMouseEvent): boolean;
|
|
|
|
begin
|
|
if Assigned(FWebRTCPeer) then
|
|
begin
|
|
FWebRTCPeer.dispose;
|
|
FWebRTCPeer:=Nil;
|
|
end;
|
|
if Assigned(FPipeLine) then
|
|
begin
|
|
FPipeLine.release();
|
|
FPipeLine:=Nil;
|
|
end;
|
|
hideSpinner([FvideoInput, FvideoOutput]);
|
|
end;
|
|
|
|
function TKurentoApp.DoStart(aEvent: TJSMouseEvent): boolean;
|
|
|
|
Var
|
|
Opts : TWebRtcPeerOptions;
|
|
|
|
begin
|
|
Writeln('DoStart');
|
|
Opts:=TWebRtcPeerOptions.New;
|
|
Opts.localVideo:=FVideoInput;
|
|
Opts.remoteVideo:=FVideoOutput;
|
|
FWebRTCPeer:=TWebRtcPeer.WebRtcPeerSendRecv(Opts,procedure(aError : TJSError)
|
|
begin
|
|
Writeln('TWebRtcPeer.WebRtcPeerSendRecv callback. Have error:',Assigned(aError));
|
|
if Assigned(aError) then
|
|
DoError(aError)
|
|
else
|
|
FWebRTCPeer.generateOffer(@OnOfferReceived);
|
|
end
|
|
);
|
|
end;
|
|
|
|
procedure TKurentoApp.DoRun;
|
|
begin
|
|
Terminate; // Avoid a loop.
|
|
FVideoInput:=getHTMLElement('videoInput');
|
|
FVideoOutput:=getHTMLElement('videoOutput');
|
|
FStartButton:=getHTMLElement('start');
|
|
FStopButton:=getHTMLElement('stop');
|
|
FURL:=TJSHTMLInputElement(getHTMLElement('edtServer'));
|
|
FStartButton.OnCLick:=@DoStart;
|
|
FStopButton.OnClick:=@DoStop;
|
|
end;
|
|
|
|
|
|
begin
|
|
With TKurentoApp.Create(Nil) do
|
|
begin
|
|
Initialize;
|
|
Run;
|
|
end;
|
|
end.
|