Register WebRTC with Cordova

Not favoritedFavorited Favorited 0 favourites
  • 1 posts
From the Asset Store
Member System Register Login Logout Verify Email with database
  • cordova-plugin-save-blob (registerWebRTC)

    WebRTC Convert Blob to base64Data save/downlaod

    WebRTC: webrtc.github.io/samples

    WebRTC: full example github.com/webrtc/samples/tree/gh-pages/src/content

    cordova plugin add cordova-plugin-save-blob

    clobbers: cordova.plugin.CordovaSaveBlob

    1. registerWebRTC
    2. checkAndRequestPermissions
    3. selectFiles
    4. selectTargetPath
    5. downloadBlob
    6. downloadFile

    selectFiles

    example > all mime: "" | image/* | video/* | audio/* | application/pdf | image/png | image/jpeg | video/mp4 | audio/mpeg
    

    checkAndRequestPermissions

    1. CAMERA
    2. RECORD_AUDIO
    3. MODIFY_AUDIO_SETTINGS
    4. READ_EXTERNAL_STORAGE
    5. WRITE_EXTERNAL_STORAGE
    6. MANAGE_EXTERNAL_STORAGE
    7. READ_MEDIA_AUDIO
    8. READ_MEDIA_VIDEO
    9. READ_MEDIA_IMAGES

    Support android min 6 to 15 or higher

    Depends on the user whether permission has been granted

    Shared storage location (selectTargetPath)

    set by the user to avoid errors on android 15 or higher.

    example

    1. video call plugin
    2. live streaming plugin
    3. screenshot plugin
    4. screen record plugin
    5. Video chat plugin
    6. Transfer a file plugin
    7. data transfer plugin
    8. send text messages
    9. and many more

    You can also make some combinations such as with scoket.io, arduino and the like.

    	
    
    <!DOCTYPE html>
    <html>
    <head>
     <meta charset="UTF-8">
     <title>Complete WebRTC Demo - Video Call</title>
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
     <style>
     body {
     font-family: Arial, sans-serif;
     margin: 10px;
     padding: 0;
     background-color: #f7f7f7;
     }
     h1 {
     text-align: center;
     color: #333;
     }
     .section {
     background-color: #fff;
     margin: 10px auto;
     padding: 15px;
     border: 1px solid #ccc;
     border-radius: 5px;
     max-width: 800px;
     }
     .section h2 {
     margin-top: 0;
     color: #444;
     }
     video {
     width: 100%;
     max-width: 320px;
     height: auto;
     background-color: #000;
     margin: 5px;
     border: 1px solid #333;
     }
     textarea, select, .output {
     width: 90%;
     max-width: 700px;
     display: block;
     margin: 10px auto;
     padding: 8px;
     font-size: 14px;
     }
     button {
     margin: 5px;
     padding: 8px 12px;
     font-size: 14px;
     cursor: pointer;
     border: none;
     background-color: #4285F4;
     color: #fff;
     border-radius: 3px;
     }
     button:hover {
     background-color: #3367D6;
     }
     .output {
     border: 1px solid #ccc;
     background-color: #eef;
     border-radius: 3px;
     min-height: 30px;
     padding: 5px;
     }
     @media (max-width: 600px) {
     button, textarea, select, .output { width: 95%; }
     }
     </style>
     <!-- cordova.js will be injected during build -->
     <script type="text/javascript" src="cordova.js"></script>
    </head>
    <body>
    <h1>Complete WebRTC Demo - Video Call</h1>
    
    <!-- Media & Camera Section -->
    <div class="section">
     <h2>Media & Camera</h2>
     <!-- Local video for displaying stream -->
     <video id="localVideo" autoplay muted></video>
     <!-- Remote video for the video call -->
     <video id="remoteVideo" autoplay style="display:none;"></video>
     <br>
     <!-- Buttons to control media & switch camera -->
     <button id="startButton">Start Media (Default)</button>
     <button id="useFrontCamera">Front Camera</button>
     <button id="useBackCamera">Back Camera</button>
     <button id="closeCamera">Close Camera</button>
    </div>
    
    <!-- Video Call Section (Manual Signaling) -->
    <div class="section">
     <h2>Video Call</h2>
     <button id="startCall">Create Offer</button>
     <button id="answerCall">Create Answer</button>
     <button id="setRemoteSDP">Set Remote SDP</button>
     <br>
     <textarea id="sdpArea" placeholder="Paste or copy SDP here..."></textarea>
    </div>
    
    <!-- Additional Features Section: Screenshot & Recording -->
    <div class="section">
     <h2>Additional Features</h2>
     <button id="captureScreenshot">Capture Screenshot</button>
     <button id="startRecording">Start Recording</button>
     <button id="stopRecording">Stop Recording</button>
    </div>
    
    <!-- File Functions Section: Select Files & Select Target Path -->
    <div class="section">
     <h2>File Functions</h2>
     <button id="selectFiles">Select Files</button>
     <div id="selectFilesOutput" class="output" placeholder="selectFiles output"></div>
     <br>
     <button id="selectTargetPath">Select Target Path</button>
     <div id="selectTargetPathOutput" class="output" placeholder="selectTargetPath output"></div>
    </div>
    
    <!-- Permissions Section: Dropdown & Check Permissions -->
    <div class="section">
     <h2>Check Permissions</h2>
     <label for="permissionsDropdown">Select permissions (multiple):</label>
     <select id="permissionsDropdown" multiple>
     <option value="CAMERA">CAMERA</option>
     <option value="RECORD_AUDIO">RECORD_AUDIO</option>
     <option value="MODIFY_AUDIO_SETTINGS">MODIFY_AUDIO_SETTINGS</option>
     <option value="MANAGE_EXTERNAL_STORAGE">MANAGE_EXTERNAL_STORAGE</option>
     <option value="READ_EXTERNAL_STORAGE">READ_EXTERNAL_STORAGE</option>
     <option value="WRITE_EXTERNAL_STORAGE">WRITE_EXTERNAL_STORAGE</option>
     <option value="READ_MEDIA_AUDIO">READ_MEDIA_AUDIO</option>
     <option value="READ_MEDIA_VIDEO">READ_MEDIA_VIDEO</option>
     <option value="READ_MEDIA_IMAGES">READ_MEDIA_IMAGES</option>
     </select>
     <button id="checkPermissionsBtn">Check Permissions</button>
     <div id="permissionsOutput" class="output"></div>
    </div>
    
    <script>
    
    
     // WebRTC: https://webrtc.github.io/samples/
    
     document.addEventListener("deviceready", function () {
    
     // Initialize the CordovaSaveBlob plugin
     cordova.plugin.CordovaSaveBlob.registerWebRTC();
     // Call initial checkAndRequestPermissions with default permissions
     cordova.plugin.CordovaSaveBlob.checkAndRequestPermissions({
     permissions: ["CAMERA", "RECORD_AUDIO", "MODIFY_AUDIO_SETTINGS", "MANAGE_EXTERNAL_STORAGE"]
     }, function(success) {
     console.log("Initial Permissions:", success);
     }, function(error) {
     console.error("Initial Permissions error:", error);
     });
    
     let localStream;
     let mediaRecorder;
     let recordedChunks = [];
     let pc; // RTCPeerConnection for video call
     let currentCamera = "user"; // Default: front camera
    
     const configuration = {
     iceServers: [
     { urls: 'stun:stun.l.google.com:19302' }
     ]
     };
    
     const localVideo = document.getElementById("localVideo");
     const remoteVideo = document.getElementById("remoteVideo");
     const sdpArea = document.getElementById("sdpArea");
    
     // Function to start media with the selected camera
     async function startMedia() {
     if (localStream) {
     localStream.getTracks().forEach(track => track.stop());
     }
     try {
     const constraints = {
     video: { facingMode: currentCamera },
     audio: true
     };
     localStream = await navigator.mediaDevices.getUserMedia(constraints);
     localVideo.srcObject = localStream;
     alert("Media stream started with camera: " + currentCamera);
     } catch (err) {
     console.error("Failed to get media:", err);
     alert("Failed to get media: " + err);
     }
     }
    
     // Media & Camera control event listeners
     document.getElementById("startButton").addEventListener("click", startMedia);
     document.getElementById("useFrontCamera").addEventListener("click", function() {
     currentCamera = "user";
     startMedia();
     });
     document.getElementById("useBackCamera").addEventListener("click", function() {
     currentCamera = "environment";
     startMedia();
     });
     document.getElementById("closeCamera").addEventListener("click", function() {
     if (localStream) {
     localStream.getTracks().forEach(track => track.stop());
     localStream = null;
     localVideo.srcObject = null;
     alert("Camera has been closed.");
     } else {
     alert("Camera is not active.");
     }
     });
    
     // -------------------------------
     // VIDEO CALL FUNCTIONS (Manual Signaling)
     // -------------------------------
     document.getElementById("startCall").addEventListener("click", async function() {
     if (!localStream) {
     alert("Media is not started. Please click 'Start Media' first.");
     return;
     }
     if (!pc) {
     pc = new RTCPeerConnection(configuration);
     localStream.getTracks().forEach(track => {
     pc.addTrack(track, localStream);
     });
     pc.addEventListener('track', event => {
     remoteVideo.style.display = "block";
     remoteVideo.srcObject = event.streams[0];
     });
     pc.addEventListener('icecandidate', event => {
     if (event.candidate) {
     console.log("ICE Candidate:", event.candidate);
     }
     });
     }
     try {
     const offer = await pc.createOffer();
     await pc.setLocalDescription(offer);
     sdpArea.value = JSON.stringify(pc.localDescription);
     alert("Offer created. Copy the SDP from the textarea and share with the remote peer.");
     } catch (err) {
     console.error("Error creating offer:", err);
     alert("Error creating offer: " + err);
     }
     });
    
     document.getElementById("answerCall").addEventListener("click", async function() {
     if (!localStream) {
     alert("Media is not started. Please click 'Start Media' first.");
     return;
     }
     if (!pc) {
     pc = new RTCPeerConnection(configuration);
     localStream.getTracks().forEach(track => {
     pc.addTrack(track, localStream);
     });
     pc.addEventListener('track', event => {
     remoteVideo.style.display = "block";
     remoteVideo.srcObject = event.streams[0];
     });
     pc.addEventListener('icecandidate', event => {
     if (event.candidate) {
     console.log("ICE Candidate:", event.candidate);
     }
     });
     }
     try {
     const remoteDesc = JSON.parse(sdpArea.value);
     await pc.setRemoteDescription(remoteDesc);
     const answer = await pc.createAnswer();
     await pc.setLocalDescription(answer);
     sdpArea.value = JSON.stringify(pc.localDescription);
     alert("Answer created. Share the SDP with the remote peer.");
     } catch (err) {
     console.error("Error creating answer:", err);
     alert("Error creating answer: " + err);
     }
     });
    
     document.getElementById("setRemoteSDP").addEventListener("click", async function() {
     if (!pc) {
     alert("RTCPeerConnection is not created. Please start a call first.");
     return;
     }
     try {
     const remoteDesc = JSON.parse(sdpArea.value);
     await pc.setRemoteDescription(remoteDesc);
     alert("Remote SDP is set.");
     } catch (err) {
     console.error("Error setting remote SDP:", err);
     alert("Error setting remote SDP: " + err);
     }
     });
    
     // -------------------------------
     // ADDITIONAL FEATURES: SCREENSHOT & RECORDING
     // -------------------------------
     document.getElementById("captureScreenshot").addEventListener("click", function() {
     if (!localStream) {
     alert("Media is not started. Please click 'Start Media' first.");
     return;
     }
     const canvas = document.createElement("canvas");
     const videoWidth = localVideo.videoWidth;
     const videoHeight = localVideo.videoHeight;
     if (videoWidth === 0 || videoHeight === 0) {
     alert("Video is not ready for capture. Please try again later.");
     return;
     }
     canvas.width = videoWidth;
     canvas.height = videoHeight;
     const ctx = canvas.getContext("2d");
     ctx.drawImage(localVideo, 0, 0, videoWidth, videoHeight);
    
     canvas.toBlob(function(blob) {
     if (blob) {
     const reader = new FileReader();
     reader.onloadend = function() {
     const dataUrl = reader.result; // Format: data:image/png;base64,...
     const base64Data = dataUrl.replace(/^data:.*;base64,/, '');
     const uniqueName = "screenshot_" + new Date().getTime() + ".png";
     // Call plugin to save the file
     cordova.plugin.CordovaSaveBlob.downloadBlob({
     base64Data: base64Data,
     fileName: uniqueName
     },
     function(msg) { alert("Screenshot saved successfully: " + msg); },
     function(err) { alert("Download error: " + err); });
     };
     reader.readAsDataURL(blob);
     } else {
     alert("Failed to create blob from screenshot.");
     }
     }, "image/png");
     });
    
     document.getElementById("startRecording").addEventListener("click", function() {
     if (localStream) {
     recordedChunks = [];
     const options = { mimeType: 'video/webm; codecs=vp9' };
     try {
     mediaRecorder = new MediaRecorder(localStream, options);
     } catch (e) {
     console.error("MediaRecorder does not support the given options:", e);
     alert("MediaRecorder not supported: " + e);
     return;
     }
     mediaRecorder.ondataavailable = (event) => {
     if (event.data && event.data.size > 0) {
     recordedChunks.push(event.data);
     }
     };
     mediaRecorder.start();
     console.log("Recording started.");
     alert("Recording started.");
     } else {
     alert("Media is not started. Please click 'Start Media' first.");
     }
     });
    
     document.getElementById("stopRecording").addEventListener("click", function() {
     if (mediaRecorder && mediaRecorder.state !== "inactive") {
     mediaRecorder.stop();
     mediaRecorder.onstop = function() {
     const blob = new Blob(recordedChunks, { type: "video/webm" });
     console.log("Recording finished. Blob size:", blob.size);
     const reader = new FileReader();
     reader.onloadend = function() {
     const dataUrl = reader.result;
     const base64Data = dataUrl.replace(/^data:.*;base64,/, '');
     const uniqueName = "recording_" + new Date().getTime() + ".webm";
     cordova.plugin.CordovaSaveBlob.downloadBlob({
     base64Data: base64Data,
     fileName: uniqueName
     },
     function(msg) { alert("Recording saved successfully: " + msg); },
     function(err) { alert("Download error: " + err); });
     };
     reader.readAsDataURL(blob);
     };
     } else {
     alert("Recording is not started or already stopped.");
     }
     });
    
     // -------------------------------
     // FILE FUNCTIONS: Select Files & Select Target Path with Callback Outputs
     // -------------------------------
     document.getElementById("selectFiles").addEventListener("click", function() {
     if (cordova.plugin.CordovaSaveBlob && cordova.plugin.CordovaSaveBlob.selectFiles) {
     // example > all mime: "" | image/* | video/* | audio/* | application/pdf | image/png | image/jpeg | video/mp4 | audio/mpeg
     cordova.plugin.CordovaSaveBlob.selectFiles({ mime: "image/*" },
     function(response) {
     document.getElementById("selectFilesOutput").innerText = "Response: " + response;
     },
     function(error) {
     document.getElementById("selectFilesOutput").innerText = "Error: " + error;
     }
     );
     } else {
     alert("selectFiles function is not available.");
     }
     });
    
     document.getElementById("selectTargetPath").addEventListener("click", function() {
     if (cordova.plugin.CordovaSaveBlob && cordova.plugin.CordovaSaveBlob.selectTargetPath) {
     cordova.plugin.CordovaSaveBlob.selectTargetPath(
     function(response) {
     document.getElementById("selectTargetPathOutput").innerText = "Response: " + response;
     },
     function(error) {
     document.getElementById("selectTargetPathOutput").innerText = "Error: " + error;
     }
     );
     } else {
     alert("selectTargetPath function is not available.");
     }
     });
    
     // -------------------------------
     // PERMISSIONS: Dropdown & Check Permissions
     // -------------------------------
     document.getElementById("checkPermissionsBtn").addEventListener("click", function() {
     const dropdown = document.getElementById("permissionsDropdown");
     const selectedOptions = Array.from(dropdown.selectedOptions).map(opt => opt.value);
     // Call checkAndRequestPermissions with selected permissions
     cordova.plugin.CordovaSaveBlob.checkAndRequestPermissions({ permissions: selectedOptions },
     function(success) {
     document.getElementById("permissionsOutput").innerText = "Success: " + success;
     },
     function(error) {
     document.getElementById("permissionsOutput").innerText = "Error: " + error;
     }
     );
     });
    
     }, false);
    </script>
    </body>
    </html>
    
    
    
  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)