I would like to create an app that enables users to make video calls. I found some insight here, but unfortunately, the answer doesn't explain neither what third party services can be used, nor any meaningful insight on integrating WebRTC.
I have managed to create a Django WebSocket based live chat using Channels, and I figured the "get user media". But I was totally overwhelmed by Peer2Peer connection.
How can I integrate the WebRTC over Django Channels? Or is there a simpler way/third party service I could use?
my consumers.py:
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.consumer import AsyncConsumer
import json
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.room_name
self.user = self.scope["user"].username
# Join room group
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
# Leave room group
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
# Receive message from WebSocket
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
user = text_data_json['user']
# Send message to room group
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message',
'message': message,
'user': user
}
)
# Receive message from room group
async def chat_message(self, event):
message = event['message'],
user = event['user']
# Send message to WebSocket
await self.send(text_data=json.dumps({
'message': message,
'user': user
}))
my chat room:
{% extends 'main/header.html' %}
{% block content %}
<!-- chat/templates/chat/room.html -->
<!DOCTYPE html>
<body>
<div class="container">
<textarea id="chat-log" class="materialize-textarea" ></textarea><br/>
<div class="input-field col s12 ">
<input id="chat-message-input" type="text" />
<a class="waves-effect waves-light btn prefix" id="chat-message-submit"><i class="material-icons right">send</i></a>
</div>
</div>
</body>
<script>
var roomName = "{{ room_name|escapejs }}";
var chatSocket = new WebSocket(
'ws://' + window.location.host +
'/ws/chat/' + roomName + '/');
chatSocket.onmessage = function(e) {
var data = JSON.parse(e.data);
console.info(e)
var message = data['message'];
var user = data['user'];
document.querySelector('#chat-log').value += (user +": " + message + '\n');
elem = document.getElementById("chat-log")
M.textareaAutoResize(elem);
};
chatSocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
document.querySelector('#chat-message-input').focus();
document.querySelector('#chat-message-input').onkeyup = function(e) {
if (e.keyCode === 13) { // enter, return
document.querySelector('#chat-message-submit').click();
}
};
document.querySelector('#chat-message-submit').onclick = function(e) {
var messageInputDom = document.querySelector('#chat-message-input');
var message = messageInputDom.value;
var user = "{{user.username}}"
chatSocket.send(JSON.stringify({
'message': message,
'user': user
}));
messageInputDom.value = '';
};
</script>
{% endblock %}
my client.js:
window.onload = function () {
var constraints = { audio: true, video: { width: 1280, height: 720 } };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
var video = document.querySelector('video');
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
};
})
.catch(function(err) { console.log(err.name + ": " + err.message); });
};
my video vindow:
<html>
{% load static %}
<head>
<meta charset = "utf-8">
<script src = "{% static 'main/js/client.js' %}"></script>
</head>
<body>
<video controls="" id = 'video-player' name = 'video-player' autoplay></video>
</body>
</html>
A simple realtime-chat application with no media transfer can be implemented using just WebSockets whereas a realtime media transfer (audio, video) needs different protocol altogether.
WebRTC is natively supported by all modern browsers and can be used for realtime media transfer.
While webRTC can be used to transfer media, the handshaking between devices has to happen outside of this.
Even though an api/http request of any sort is plausible for this, the realtime data-transfer ability of websockets are a good to have.
Enough of that being said, since you have already chosen django-channels, you can use that to make the handshake.
To establish a WebRTC connection, the client-A needs to generate an offer with its SDP (Session Description Protocol) and send it over to Client-B, to which the Client-B has to send back its SDP as an answer.
At this point both clients will be aware of what codecs and codec-parameters are to be used while transferring the data. However, both the clients are not aware or sure of what network settings needs to be used or how the data itself needs to be transmitted.
That is where the ICE (Interactive Connectivity Establishment) negotiations comes into picture. Both the clients will send back and forth the higher to lower negotiations until they agree upon one. And that is where the media stream starts to flow.
The above is just a drop from the ocean, however, it is not hard to get a working prototype if you follow through MDN's topic on signalling and video calling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With