SlideShare a Scribd company logo
1 of 31
Download to read offline
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
Audio mute and unmute
Video on and off
Screen sharing
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.
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-mute-
btn">
<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-1h3v-
2.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="call-
unmute-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 1-
2.43.923V15h3a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-
1h3v-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-12-
12-.708.708z"/>
</svg>
</button>
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");
};


To handle the logic part, use the below code.


// javascript/packs/video_call.js
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.
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="video-
disable-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.111-
1.382A2 2 0 0 1 9.5 13H2a2 2 0 0 1-2-2V5z"/>
</svg>
</button>
<button class="btn btn-danger p-3 rounded-
circle 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-.913l-
3.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-10-
14 .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("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.
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="screen-
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-.5v-
7a.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.5v-
7A1.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="stop-
screen-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-.5v-
7a.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.5v-
7A1.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>
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]);
});
}


Use the below code to capture your screen.
// javascript/packs/video_call.js
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-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(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-share-
btn").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("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
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

More Related Content

Similar to Create a video chat app with twilio, rails, and js tutorial (part 2) (20)

https12.doc
https12.dochttps12.doc
https12.doc
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow(1).txt
slowslow(1).txtslowslow(1).txt
slowslow(1).txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
slowslow.txt
slowslow.txtslowslow.txt
slowslow.txt
 
6. Vectors – Data Frames
6. Vectors – Data Frames6. Vectors – Data Frames
6. Vectors – Data Frames
 
Featured posts
Featured postsFeatured posts
Featured posts
 
Push notification salesforce
Push notification salesforcePush notification salesforce
Push notification salesforce
 
Getting to Know Bootstrap for Rapid Web Development
Getting to Know Bootstrap for Rapid Web DevelopmentGetting to Know Bootstrap for Rapid Web Development
Getting to Know Bootstrap for Rapid Web Development
 
Siempre e..
Siempre e..Siempre e..
Siempre e..
 

More from Katy Slemon

More from Katy Slemon (20)

React Alternatives Frameworks- Lightweight Javascript Libraries.pdf
React Alternatives Frameworks- Lightweight Javascript Libraries.pdfReact Alternatives Frameworks- Lightweight Javascript Libraries.pdf
React Alternatives Frameworks- Lightweight Javascript Libraries.pdf
 
Data Science Use Cases in Retail & Healthcare Industries.pdf
Data Science Use Cases in Retail & Healthcare Industries.pdfData Science Use Cases in Retail & Healthcare Industries.pdf
Data Science Use Cases in Retail & Healthcare Industries.pdf
 
How Much Does It Cost To Hire Golang Developer.pdf
How Much Does It Cost To Hire Golang Developer.pdfHow Much Does It Cost To Hire Golang Developer.pdf
How Much Does It Cost To Hire Golang Developer.pdf
 
What’s New in Flutter 3.pdf
What’s New in Flutter 3.pdfWhat’s New in Flutter 3.pdf
What’s New in Flutter 3.pdf
 
Why Use Ruby On Rails.pdf
Why Use Ruby On Rails.pdfWhy Use Ruby On Rails.pdf
Why Use Ruby On Rails.pdf
 
How Much Does It Cost To Hire Full Stack Developer In 2022.pdf
How Much Does It Cost To Hire Full Stack Developer In 2022.pdfHow Much Does It Cost To Hire Full Stack Developer In 2022.pdf
How Much Does It Cost To Hire Full Stack Developer In 2022.pdf
 
How to Implement Middleware Pipeline in VueJS.pdf
How to Implement Middleware Pipeline in VueJS.pdfHow to Implement Middleware Pipeline in VueJS.pdf
How to Implement Middleware Pipeline in VueJS.pdf
 
How to Build Laravel Package Using Composer.pdf
How to Build Laravel Package Using Composer.pdfHow to Build Laravel Package Using Composer.pdf
How to Build Laravel Package Using Composer.pdf
 
Sure Shot Ways To Improve And Scale Your Node js Performance.pdf
Sure Shot Ways To Improve And Scale Your Node js Performance.pdfSure Shot Ways To Improve And Scale Your Node js Performance.pdf
Sure Shot Ways To Improve And Scale Your Node js Performance.pdf
 
How to Develop Slack Bot Using Golang.pdf
How to Develop Slack Bot Using Golang.pdfHow to Develop Slack Bot Using Golang.pdf
How to Develop Slack Bot Using Golang.pdf
 
IoT Based Battery Management System in Electric Vehicles.pdf
IoT Based Battery Management System in Electric Vehicles.pdfIoT Based Battery Management System in Electric Vehicles.pdf
IoT Based Battery Management System in Electric Vehicles.pdf
 
Understanding Flexbox Layout in React Native.pdf
Understanding Flexbox Layout in React Native.pdfUnderstanding Flexbox Layout in React Native.pdf
Understanding Flexbox Layout in React Native.pdf
 
The Ultimate Guide to Laravel Performance Optimization in 2022.pdf
The Ultimate Guide to Laravel Performance Optimization in 2022.pdfThe Ultimate Guide to Laravel Performance Optimization in 2022.pdf
The Ultimate Guide to Laravel Performance Optimization in 2022.pdf
 
New Features in iOS 15 and Swift 5.5.pdf
New Features in iOS 15 and Swift 5.5.pdfNew Features in iOS 15 and Swift 5.5.pdf
New Features in iOS 15 and Swift 5.5.pdf
 
How to Hire & Manage Dedicated Team For Your Next Product Development.pdf
How to Hire & Manage Dedicated Team For Your Next Product Development.pdfHow to Hire & Manage Dedicated Team For Your Next Product Development.pdf
How to Hire & Manage Dedicated Team For Your Next Product Development.pdf
 
Choose the Right Battery Management System for Lithium Ion Batteries.pdf
Choose the Right Battery Management System for Lithium Ion Batteries.pdfChoose the Right Battery Management System for Lithium Ion Batteries.pdf
Choose the Right Battery Management System for Lithium Ion Batteries.pdf
 
Flutter Performance Tuning Best Practices From the Pros.pdf
Flutter Performance Tuning Best Practices From the Pros.pdfFlutter Performance Tuning Best Practices From the Pros.pdf
Flutter Performance Tuning Best Practices From the Pros.pdf
 
Angular Universal How to Build Angular SEO Friendly App.pdf
Angular Universal How to Build Angular SEO Friendly App.pdfAngular Universal How to Build Angular SEO Friendly App.pdf
Angular Universal How to Build Angular SEO Friendly App.pdf
 
How to Set Up and Send Mails Using SendGrid in NodeJs App.pdf
How to Set Up and Send Mails Using SendGrid in NodeJs App.pdfHow to Set Up and Send Mails Using SendGrid in NodeJs App.pdf
How to Set Up and Send Mails Using SendGrid in NodeJs App.pdf
 
Ruby On Rails Performance Tuning Guide.pdf
Ruby On Rails Performance Tuning Guide.pdfRuby On Rails Performance Tuning Guide.pdf
Ruby On Rails Performance Tuning Guide.pdf
 

Recently uploaded

CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)
Wonjun Hwang
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
FIDO Alliance
 

Recently uploaded (20)

Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdf
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
الأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهالأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهله
 
Design Guidelines for Passkeys 2024.pptx
Design Guidelines for Passkeys 2024.pptxDesign Guidelines for Passkeys 2024.pptx
Design Guidelines for Passkeys 2024.pptx
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps Productivity
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Vector Search @ sw2con for slideshare.pptx
Vector Search @ sw2con for slideshare.pptxVector Search @ sw2con for slideshare.pptx
Vector Search @ sw2con for slideshare.pptx
 
Frisco Automating Purchase Orders with MuleSoft IDP- May 10th, 2024.pptx.pdf
Frisco Automating Purchase Orders with MuleSoft IDP- May 10th, 2024.pptx.pdfFrisco Automating Purchase Orders with MuleSoft IDP- May 10th, 2024.pptx.pdf
Frisco Automating Purchase Orders with MuleSoft IDP- May 10th, 2024.pptx.pdf
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptx
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overview
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and Insight
 
CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 

Create a video chat app with twilio, rails, and js tutorial (part 2)

  • 1. Create a Video Chat App with Twilio, Rails, and JS Tutorial (Part 2) www.bacancytechnology.com
  • 3. 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.
  • 4. Tutorial Goal: Build Video Chat App with Twilio, Rails, and JS
  • 5. Audio mute and unmute Video on and off Screen sharing 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.
  • 6. How to Mute and Unmute Audio in Video Chat App with Twilio?
  • 7. 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-mute- btn"> <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-1h3v- 2.025A5 5 0 0 1 3 8V7a.5.5 0 0 1 .5-.5z"/> </svg>
  • 8. </button> <button class="btn btn-danger p-3 rounded-circle d-none m-3" id="call- unmute-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 1- 2.43.923V15h3a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0- 1h3v-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-12- 12-.708.708z"/> </svg> </button>
  • 9. 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"); }; To handle the logic part, use the below code. // javascript/packs/video_call.js
  • 10. 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); })
  • 11. 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.
  • 13. 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="video- disable-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.111- 1.382A2 2 0 0 1 9.5 13H2a2 2 0 0 1-2-2V5z"/> </svg> </button>
  • 14. <button class="btn btn-danger p-3 rounded- circle 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-.913l- 3.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-10- 14 .814-.58 10 14-.814.58z"/> </svg> </button> For handling business logic, add this code in javascript/packs/video_call.js
  • 15. // 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"); };
  • 16. 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); })
  • 17. 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"); } });
  • 18. So, this was about the Video On and Off functionality. Go to the show page of the room and test it out.
  • 19. Add Screen Sharing to Twilio Video Chat Application
  • 20. 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="screen- 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"/>
  • 21. <path d="M11.414 11H14.5a.5.5 0 0 0 .5-.5v- 7a.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.5v- 7A1.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="stop- screen-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-.5v- 7a.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.5v- 7A1.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>
  • 22. 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]); }); } Use the below code to capture your screen. // javascript/packs/video_call.js
  • 23. 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-share- btn").on("click",function() { onStopScreenShareButton(room,track); }) } The below function will stop publishing your captured screen. And will remove your screen share preview.
  • 24. 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.
  • 25. 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 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"); }
  • 26. 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.
  • 27. $("#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.
  • 28. 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
  • 30. 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.