diff --git a/base/__pycache__/__init__.cpython-313.pyc b/base/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..aab3819 Binary files /dev/null and b/base/__pycache__/__init__.cpython-313.pyc differ diff --git a/base/__pycache__/admin.cpython-313.pyc b/base/__pycache__/admin.cpython-313.pyc new file mode 100644 index 0000000..10e0cd0 Binary files /dev/null and b/base/__pycache__/admin.cpython-313.pyc differ diff --git a/base/__pycache__/apps.cpython-313.pyc b/base/__pycache__/apps.cpython-313.pyc new file mode 100644 index 0000000..42ce66b Binary files /dev/null and b/base/__pycache__/apps.cpython-313.pyc differ diff --git a/base/__pycache__/models.cpython-313.pyc b/base/__pycache__/models.cpython-313.pyc new file mode 100644 index 0000000..97fb24b Binary files /dev/null and b/base/__pycache__/models.cpython-313.pyc differ diff --git a/base/__pycache__/urls.cpython-313.pyc b/base/__pycache__/urls.cpython-313.pyc new file mode 100644 index 0000000..9ebec5d Binary files /dev/null and b/base/__pycache__/urls.cpython-313.pyc differ diff --git a/base/__pycache__/views.cpython-313.pyc b/base/__pycache__/views.cpython-313.pyc new file mode 100644 index 0000000..8a8322c Binary files /dev/null and b/base/__pycache__/views.cpython-313.pyc differ diff --git a/base/migrations/__pycache__/__init__.cpython-313.pyc b/base/migrations/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..4280a65 Binary files /dev/null and b/base/migrations/__pycache__/__init__.cpython-313.pyc differ diff --git a/base/templates/base/lobby.html b/base/templates/base/lobby.html index a390c32..2dce955 100644 --- a/base/templates/base/lobby.html +++ b/base/templates/base/lobby.html @@ -1,7 +1,7 @@ {% extends 'base/main.html' %} {% load static %} - {% block content %} +
@@ -9,6 +9,39 @@

Welcome to MyChart

A group calling application for you

+ +
+
+ +
+
+ +
+
-{% endblock content %} \ No newline at end of file + + + +{% endblock content %} diff --git a/base/templates/base/room.html b/base/templates/base/room.html index 2061dec..fbf8a58 100644 --- a/base/templates/base/room.html +++ b/base/templates/base/room.html @@ -1,18 +1,19 @@ {% extends 'base/main.html' %} - {% block content %}
-
-

Room Name:

+
+

Room Name:

-
-
-
My Name
-
-
+
+ +
+ + +
{% endblock content %} + diff --git a/base/urls.py b/base/urls.py index eee9bea..9dbd17b 100644 --- a/base/urls.py +++ b/base/urls.py @@ -1,7 +1,8 @@ -from django.urls import path -from . import views +from django.urls import path +from . import views urlpatterns = [ - path("", views.lobby), - path("room/", views.room), + path('', views.lobby), + path('room/', views.room), + path('get_token/', views.getToken), ] diff --git a/base/views.py b/base/views.py index bf673c6..0ff600a 100644 --- a/base/views.py +++ b/base/views.py @@ -1,7 +1,25 @@ from django.shortcuts import render +from django.http import JsonResponse +import random +import time +from agora_token_builder import RtcTokenBuilder def lobby(request): return render(request, 'base/lobby.html') def room(request): return render(request, 'base/room.html') + +def getToken(request): + appId = 'YOUR_AGORA_APP_ID' + appCertificate = 'YOUR_AGORA_APP_CERTIFICATE' + channelName = request.GET.get('channel') + uid = random.randint(1, 230) + expirationTimeInSeconds = 3600 * 24 + currentTimeStamp = int(time.time()) + privilegeExpiredTs = currentTimeStamp + expirationTimeInSeconds + role = 1 + + token = RtcTokenBuilder.buildTokenWithUid(appId, appCertificate, channelName, uid, role, privilegeExpiredTs) + + return JsonResponse({'token': token, 'uid': uid}, safe=False) diff --git a/mychart/__pycache__/__init__.cpython-313.pyc b/mychart/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..292ca43 Binary files /dev/null and b/mychart/__pycache__/__init__.cpython-313.pyc differ diff --git a/mychart/__pycache__/settings.cpython-313.pyc b/mychart/__pycache__/settings.cpython-313.pyc new file mode 100644 index 0000000..7242c19 Binary files /dev/null and b/mychart/__pycache__/settings.cpython-313.pyc differ diff --git a/mychart/__pycache__/urls.cpython-313.pyc b/mychart/__pycache__/urls.cpython-313.pyc new file mode 100644 index 0000000..fdff78a Binary files /dev/null and b/mychart/__pycache__/urls.cpython-313.pyc differ diff --git a/mychart/__pycache__/wsgi.cpython-313.pyc b/mychart/__pycache__/wsgi.cpython-313.pyc new file mode 100644 index 0000000..6748f49 Binary files /dev/null and b/mychart/__pycache__/wsgi.cpython-313.pyc differ diff --git a/static/js/stream.js b/static/js/stream.js index e69de29..4b7ea00 100644 --- a/static/js/stream.js +++ b/static/js/stream.js @@ -0,0 +1,98 @@ +const APP_ID = 'YOUR_AGORA_APP_ID' +const CHANNEL = sessionStorage.getItem('room') +const TOKEN = sessionStorage.getItem('token') +let UID = Number(sessionStorage.getItem('uid')) + +const client = AgoraRTC.createClient({mode:'rtc', codec:'vp8'}) + +let localTracks = [] +let remoteUsers = {} + +let joinAndDisplayLocalStream = async () => { + document.getElementById('room-name-wrapper').innerText = CHANNEL + + client.on('user-published', handleUserJoined) + client.on('user-left', handleUserLeft) + + try{ + await client.join(APP_ID, CHANNEL, TOKEN, UID) + }catch(error){ + console.error(error) + window.open('/', '_self') + } + + localTracks = await AgoraRTC.createMicrophoneAndCameraTracks() + + let player = `
+
My Stream
+
+
` + document.getElementById('video-streams').insertAdjacentHTML('beforeend', player) + + localTracks[1].play(`user-${UID}`) + await client.publish([localTracks[0], localTracks[1]]) +} + +let handleUserJoined = async (user, mediaType) => { + remoteUsers[user.uid] = user + await client.subscribe(user, mediaType) + + if (mediaType === 'video'){ + let player = document.getElementById(`user-container-${user.uid}`) + if (player != null){ + player.remove() + } + + player = `
+
User ${user.uid}
+
+
` + document.getElementById('video-streams').insertAdjacentHTML('beforeend', player) + user.videoTrack.play(`user-${user.uid}`) + } + + if (mediaType === 'audio'){ + user.audioTrack.play() + } +} + +let handleUserLeft = async (user) => { + delete remoteUsers[user.uid] + document.getElementById(`user-container-${user.uid}`).remove() +} + +let leaveAndRemoveLocalStream = async () => { + for(let i = 0; localTracks.length > i; i++){ + localTracks[i].stop() + localTracks[i].close() + } + + await client.leave() + window.open('/', '_self') +} + +let toggleMic = async (e) => { + if (localTracks[0].muted){ + await localTracks[0].setMuted(false) + e.target.innerText = 'Mute Mic' + }else{ + await localTracks[0].setMuted(true) + e.target.innerText = 'Unmute Mic' + } +} + +let toggleCamera = async (e) => { + if (localTracks[1].muted){ + await localTracks[1].setMuted(false) + e.target.innerText = 'Turn Off Camera' + }else{ + await localTracks[1].setMuted(true) + e.target.innerText = 'Turn On Camera' + } +} + +joinAndDisplayLocalStream() + +document.getElementById('leave-btn').addEventListener('click', leaveAndRemoveLocalStream) +document.getElementById('mic-btn').addEventListener('click', toggleMic) +document.getElementById('camera-btn').addEventListener('click', toggleCamera)