pas2js/demo/kurento/helloworld.lpr
2020-08-27 12:11:53 +00:00

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.