Create a Video Chat App with Twilio, Rails, and JS Tutorial (Part 2)

Page 1

Create a Video Chat App with Twilio, Rails, and JS Tutorial (Part 2) www.bacancytechnology.com


Introduction


In the last tutorial, we’ve built a video chat app with Twilio, Rails, and Javascript with basic calling functionality. Make sure you have visited the part 1 and have configured the video chat app as directed. Because, here, in this guideline, we will discuss the same demo app. So, don’t skip the last tutorial before going ahead with this guide.

We all are quite aware that adding basic calling functionality is not enough. A video chat application should have features like audio mute/unmute, turning the video on/off, and screen sharing.

So, here is the step-by-step guideline to make you clear how we can add such functionalities to your video chat app.


Tutorial Goal: Build Video Chat App with Twilio, Rails, and JS


Let’s discuss what we are going to do in this tutorial. These are the new features that we will implement in our demo application

Audio mute and unmute Video on and off Screen sharing

Refer to the below video to have an idea of the final output with the user interface and functionality.


How to Mute and Unmute Audio in Video Chat App with Twilio?


The first step is to generate the user interface. For that, open the below file and add the buttons to our view for muting and unmuting audio. Every participant will have a clickable button, toggle, or another element to mute and unmute themselves.

//views/rooms/show.htm.e rb

<button class="btn btn-success p-3 rounded-circle d-none m-3" id="call-mutebtn"> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-mic-fill" viewBox="0 0 16 16"> <path d="M5 3a3 3 0 0 1 6 0v5a3 3 0 0 1-6 0V3z"/> <path d="M3.5 6.5A.5.5 0 0 1 4 7v1a4 4 0 0 0 8 0V7a.5.5 0 0 1 1 0v1a5 5 0 0 1-4.5 4.975V15h3a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1h3v2.025A5 5 0 0 1 3 8V7a.5.5 0 0 1 .5-.5z"/> </svg>


</button> <button class="btn btn-danger p-3 rounded-circle d-none m-3" id="callunmute-btn"> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-mic-mute-fill" viewBox="0 0 16 16"> <path d="M13 8c0 .564-.094 1.107-.266 1.613l-.814-.814A4.02 4.02 0 0 0 12 8V7a.5.5 0 0 1 1 0v1zm-5 4c.818 0 1.578-.245 2.212-.667l.718.719a4.973 4.973 0 0 12.43.923V15h3a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 01h3v-2.025A5 5 0 0 1 3 8V7a.5.5 0 0 1 1 0v1a4 4 0 0 0 4 4zm3-9v4.879L5.158 2.037A3.001 3.001 0 0 1 11 3z"/> <path d="M9.486 10.607 5 6.12V8a3 3 0 0 0 4.486 2.607zm-7.84-9.253 12 12 .708-.708-1212-.708.708z"/> </svg> </button>


To handle the logic part, use the below code.

// javascript/packs/video_call.js

window.onMuteAudioButton = function(room){ room.localParticipant.audioTracks.forEach(func tion(audioTrack) { audioTrack.track.disable(); }); $("#call-mute-btn").addClass("d-none"); $("#call-unmute-btn").removeClass("d-none"); }; window.onUnMuteAudioButton = function(room){ room.localParticipant.audioTracks.forEach(func tion(audioTrack) { audioTrack.track.enable(); }); $("#call-mute-btn").removeClass("d-none"); $("#call-unmute-btn").addClass("d-none"); };


LocalAudioTrack handles the audio of the LocalParticipant of a particular room. The disable() method is used to mute the microphone. This will stop publishing the audio track to the room. To unmute the audio, you can start publishing LocalAudioTrack using enable() method.

Now, add the below code in the joinRoom function.

$("#call-mute-btn").removeClass("d-none"); $("#call-mute-btn").on("click",function() { onMuteAudioButton(room); }) $("#call-unmute-btn").on("click",function() { onUnMuteAudioButton(room); })


The onMuteAudioButton and onUnMuteAudioButton functions will handle the logic for muting and unmuting the audio. These functions will be called when the user clicks on the call-mute-btn and call-unmutebtn buttons.

That’s it for Audio mute and unmute functionality.

Looking for a helping hand to build a feature-rich app with 05x faster performance?

Hire RoR developer from us to delight your end-users with meaningful CX.


Implement Video On/Off in Twilio Video Chat App


Add these Video on and off buttons to our view using the below code.

//views/rooms/show.htm.e rb <button class="btn btn-success p-3 rounded-circle d-none m-3" id="videodisable-btn"> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-camera-video-fill" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M0 5a2 2 0 0 1 2-2h7.5a2 2 0 0 1 1.983 1.738l3.11-1.382A1 1 0 0 1 16 4.269v7.462a1 1 0 0 1-1.406.913l-3.1111.382A2 2 0 0 1 9.5 13H2a2 2 0 0 1-2-2V5z"/> </svg> </button>


<button class="btn btn-danger p-3 roundedcircle d-none m-3" id="video-enable-btn"> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-camera-video-off-fill" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M10.961 12.365a1.99 1.99 0 0 0 .522-1.103l3.11 1.382A1 1 0 0 0 16 11.731V4.269a1 1 0 0 0-1.406-.913l3.111 1.382A2 2 0 0 0 9.5 3H4.272l6.69 9.365zm-10.114-9A2.001 2.001 0 0 0 0 5v6a2 2 0 0 0 2 2h5.728L.847 3.366zm9.746 11.925-1014 .814-.58 10 14-.814.58z"/> </svg> </button> For handling business logic, add this code in javascript/packs/video_call.js


// javascript/packs/video_call.js

window.onDisableVideoButton = function(room){ room.localParticipant.videoTracks.forEach(functi on(videoTrack) { videoTrack.track.disable(); }); $("#video-disable-btn").addClass("d-none"); $("#video-enable-btn").removeClass("d-none"); };

window.onEnableVideoButton = function(room){ room.localParticipant.videoTracks.forEach(functi on(videoTrack) { videoTrack.track.enable(); }); $("#video-disable-btn").removeClass("d-none"); $("#video-enable-btn").addClass("d-none"); };


The logic is similar to the audio mute and unmute feature. Here, LocalVideoTrack works like LocalAudioTrack. You can use the disable() and enable() method for disabling and enabling the video track.

Now add the below code in the joinRoom function.

$("#video-disable-btn").removeClass("dnone"); $("#video-disable-btn").on("click",function() { onDisableVideoButton(room); }) $("#video-enable-btn").on("click",function() { onEnableVideoButton(room); })


We bind that code in onDisableVideoButton and onEnableVideoButton function. You have to call this function when clicking on the video-disable-btn and video-enable-btn buttons. Add the below code in the onParticipantConnected() function.

participant.on('trackDisabled', track => { if (track.kind == "video"){ $("#remote-video video:first").addClass("d-none"); } }); participant.on('trackEnabled', track => { if (track.kind == "video"){ $("#remote-video video:first").removeClass("d-none"); } });


So, this was about the Video On and Off functionality. Go to the show page of the room and test it out.


Add Screen Sharing to Twilio Video Chat Application


Now, it’s time to implement the last feature in our video chat app with Twilio, Rails, and JS, i.e., screen sharing. Like the above sessions, add screen share and unshare buttons to our view.

//views/rooms/show.htm.e rb <button class="btn btn-success p-3 rounded-circle d-none m-3" id="screenshare-btn"> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-cast" viewBox="0 0 16 16"> <path d="m7.646 9.354-3.792 3.792a.5.5 0 0 0 .353.854h7.586a.5.5 0 0 0 .354-.854L8.354 9.354a.5.5 0 0 0-.708 0z"/>


<path d="M11.414 11H14.5a.5.5 0 0 0 .5-.5v7a.5.5 0 0 0-.5-.5h-13a.5.5 0 0 0-.5.5v7a.5.5 0 0 0 .5.5h3.086l-1 1H1.5A1.5 1.5 0 0 1 0 10.5v7A1.5 1.5 0 0 1 1.5 2h13A1.5 1.5 0 0 1 16 3.5v7a1.5 1.5 0 0 1-1.5 1.5h-2.086l-1-1z"/> </svg> </button> <button class="btn btn-danger p-3 rounded-circle d-none m-3" id="stopscreen-share-btn"> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-cast" viewBox="0 0 16 16"> <path d="m7.646 9.354-3.792 3.792a.5.5 0 0 0 .353.854h7.586a.5.5 0 0 0 .354-.854L8.354 9.354a.5.5 0 0 0-.708 0z"/> <path d="M11.414 11H14.5a.5.5 0 0 0 .5-.5v7a.5.5 0 0 0-.5-.5h-13a.5.5 0 0 0-.5.5v7a.5.5 0 0 0 .5.5h3.086l-1 1H1.5A1.5 1.5 0 0 1 0 10.5v7A1.5 1.5 0 0 1 1.5 2h13A1.5 1.5 0 0 1 16 3.5v7a1.5 1.5 0 0 1-1.5 1.5h-2.086l-1-1z"/> </svg> </button>


Use the below code to capture your screen.

// javascript/packs/video_call.js window.createScreenTrack= function(height, width) { const Video = Twilio.Video; if (typeof navigator === 'undefined' || !navigator.mediaDevices || !navigator.mediaDevices.getDisplayMedia) { return Promise.reject(new Error('getDisplayMedia is not supported')); } return navigator.mediaDevices.getDisplayMedia({ video: { height: height, width: width } }).then(function(stream) { return new Video.LocalVideoTrack(stream.getVideoTracks() [0]); }); }


The function will publish your captured screen. And will display a small preview for you. window.PublishedTracks =function( room, track){ room.localParticipant.publishTrack(track); let localMediaContainer = document.getElementById("local-video"); localMediaContainer.appendChild(track.att ach()); $("#stop-screen-sharebtn").on("click",function() { onStopScreenShareButton(room,track); }) } The below function will stop publishing your captured screen. And will remove your screen share preview.


window.StopTracks =function( room, track){ room.localParticipant.unpublishTrack(track ); track.stop(); track = null; let localMediaContainer = document.getElementById("local-video"); localMediaContainer.removeChild(localMedi aContainer.lastChild); }

The below function would be called when you click on the share screen button.


window.onScreenShareButton = async function(room){ let screenTrack = await createScreenTrack(700, 700); PublishedTracks( room, screenTrack ); $("#screen-share-btn").addClass("d-none"); $("#stop-screen-sharebtn").removeClass("d-none"); }

The below function would be called when you click on the share screen button.

window.onScreenShareButton = async function(room){ let screenTrack = await createScreenTrack(700, 700); PublishedTracks( room, screenTrack ); $("#screen-share-btn").addClass("dnone"); $("#stop-screen-sharebtn").removeClass("d-none"); }


The below function would be called when you click on the stop share screen button.

window.onStopScreenShareButton = function(room,track){ StopTracks( room, track ); $("#screen-share-btn").removeClass("dnone"); $("#stop-screen-share-btn").addClass("dnone"); } }

Call all these functions from the joinRoom() function.


$("#screen-share-btn").removeClass("dnone"); $("#screen-share-btn").on("click",function() { onScreenShareButton(room); })

When you share your screen, it should display to the remote participant on priority.

For that, add the following code in the onParticipantConnected() function.


participant.on("trackPublished", (publication) =>{ $("#remote-video video:first").addClass("d-none"); } ); participant.on("trackUnpublished", (publication) =>{ $("#remote-video video:first").removeClass("d-none"); } );

Now go to your root path and create a room. After that, go to the show page of that room and wait 3-4 sec while Twilio js is loaded from CDN. Copy that URL and paste it into the incognito tab, and Here we go. Your functionality is ready to use.

The entire source code is available here: twilio-video-chat-app


Conclusion


So, this was about building a video chat app with Twilio, Rails, and JS and later adding features like audio and video mute/unmute, sharing screen to the application. I hope you have got the idea and will start implementing it! We are always open for suggestions/feedbacks/queries; please feel free to contact us. You can visit the Rails tutorials page and explore more for more such Ruby on Rails tutorials.


Thank You

www.bacancytechnology.com


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.