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