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.
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-
Refer to the below video to have an idea of the final output with the user interface and functionality.
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.
To handle the logic part, use the below code.
window.onMuteAudioButton = function(room){ room.localParticipant.audioTracks.forEach(function(audioTrack) { audioTrack.track.disable(); }); $("#call-mute-btn").addClass("d-none"); $("#call-unmute-btn").removeClass("d-none"); }; window.onUnMuteAudioButton = function(room){ room.localParticipant.audioTracks.forEach(function(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-unmute-btn 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.
Add these Video on and off buttons to our view using the below code.
For handling business logic, add this code in javascript/packs/video_call.js
window.onDisableVideoButton = function(room){ room.localParticipant.videoTracks.forEach(function(videoTrack) { videoTrack.track.disable(); }); $("#video-disable-btn").addClass("d-none"); $("#video-enable-btn").removeClass("d-none"); }; window.onEnableVideoButton = function(room){ room.localParticipant.videoTracks.forEach(function(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("d-none"); $("#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.
When a user disables the video, it should stop streaming it from the remote participant’s view. For that, we will use the trackDisabled and trackEnabled track events.
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.
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.
Use the below code to capture your screen.
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.attach()); $("#stop-screen-share-btn").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(localMediaContainer.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-share-btn").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("d-none"); $("#stop-screen-share-btn").addClass("d-none"); }
Call all these functions from the joinRoom() function.
$("#screen-share-btn").removeClass("d-none"); $("#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
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.
Your Success Is Guaranteed !
We accelerate the release of digital product and guaranteed their success
We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.