-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of https://github.com/anyRTC/ArRTCWebSDK
# Conflicts: # .gitignore # Demo/assets/bootstrap.bundle.min.js # Demo/assets/bootstrap.min.css # Demo/assets/index.css # Demo/assets/jquery-3.4.1.min.js # Demo/audioMixingAndAudioEffect/HeroicAdventure.mp3 # Demo/audioMixingAndAudioEffect/audio.mp3 # Demo/audioMixingAndAudioEffect/audioMixingAndAudioEffect.js # Demo/audioMixingAndAudioEffect/index.css # Demo/audioMixingAndAudioEffect/index.html # Demo/basicLive/basicLive.js # Demo/basicLive/index.css # Demo/basicLive/index.html # Demo/basicVideoCall/basicVideoCall.js # Demo/basicVideoCall/index.css # Demo/basicVideoCall/index.html # Demo/index.html # Demo/recordingDeviceControl/index.css # Demo/recordingDeviceControl/index.html # Demo/recordingDeviceControl/recordingDeviceControl.js # Demo/shareTheScreen/index.css # Demo/shareTheScreen/index.html # Demo/shareTheScreen/shareTheScreen.js # README.cn.md # README.md add displayCallStats demo, update SDK
- Loading branch information
Showing
10 changed files
with
367 additions
and
5 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
var client; // ArRTC client | ||
var localTracks = { | ||
videoTrack: null, | ||
audioTrack: null | ||
}; | ||
var remoteUsers = {}; | ||
// ArRTC client options | ||
var options = { | ||
appid: null, | ||
channel: null, | ||
uid: null, | ||
token: null | ||
}; | ||
|
||
let statsInterval; | ||
|
||
// the demo can auto join channel with params in url | ||
$(() => { | ||
var urlParams = new URL(location.href).searchParams; | ||
options.appid = urlParams.get("appid"); | ||
options.channel = urlParams.get("channel"); | ||
options.token = urlParams.get("token"); | ||
if (options.appid && options.channel) { | ||
$("#appid").val(options.appid); | ||
$("#token").val(options.token); | ||
$("#channel").val(options.channel); | ||
$("#join-form").submit(); | ||
} | ||
}) | ||
|
||
$("#join-form").submit(async function (e) { | ||
e.preventDefault(); | ||
$("#join").attr("disabled", true); | ||
try { | ||
options.appid = $("#appid").val(); | ||
options.token = $("#token").val(); | ||
options.channel = $("#channel").val(); | ||
await join(); | ||
} catch (error) { | ||
console.error(error); | ||
} finally { | ||
$("#success-alert a").attr("href", `index.html?appid=${options.appid}&channel=${options.channel}&token=${options.token}`); | ||
$("#success-alert").css("display", "block"); | ||
$("#leave").attr("disabled", false); | ||
} | ||
}) | ||
|
||
$("#leave").click(function (e) { | ||
leave(); | ||
}) | ||
|
||
async function join() { | ||
// create ArRTC client | ||
client = ArRTC.createClient({ mode: "rtc", codec: "h264" }); | ||
|
||
// add event listener to play remote tracks when remote user publishs. | ||
client.on("user-published", handleUserPublished); | ||
client.on("user-unpublished", handleUserUnpublished); | ||
|
||
// join a channel and create local tracks, we can use Promise.all to run them concurrently | ||
[ options.uid, localTracks.audioTrack, localTracks.videoTrack ] = await Promise.all([ | ||
// join the channel | ||
client.join(options.appid, options.channel, options.token || null), | ||
// create local tracks, using microphone and camera | ||
ArRTC.createMicrophoneAudioTrack(), | ||
ArRTC.createCameraVideoTrack() | ||
]); | ||
|
||
// play local video track | ||
localTracks.videoTrack.play("local-player"); | ||
$("#local-player-name").text(`localVideo(${options.uid})`); | ||
|
||
// publish local tracks to channel | ||
await client.publish(Object.values(localTracks)); | ||
console.log("publish success"); | ||
|
||
initStats(); | ||
} | ||
|
||
async function leave() { | ||
for (trackName in localTracks) { | ||
var track = localTracks[trackName]; | ||
if(track) { | ||
track.stop(); | ||
track.close(); | ||
localTracks[trackName] = undefined; | ||
} | ||
} | ||
|
||
destructStats(); | ||
|
||
// remove remote users and player views | ||
remoteUsers = {}; | ||
$("#remote-playerlist").html(""); | ||
|
||
// leave the channel | ||
await client.leave(); | ||
|
||
$("#local-player-name").text(""); | ||
$("#join").attr("disabled", false); | ||
$("#leave").attr("disabled", true); | ||
console.log("client leaves channel success"); | ||
} | ||
|
||
|
||
async function subscribe(user) { | ||
const uid = user.uid; | ||
// subscribe to a remote user | ||
await client.subscribe(user, "all"); | ||
console.log("subscribe success"); | ||
const player = $(` | ||
<div id="player-wrapper-${uid}"> | ||
<p class="player-name">remoteUser(${uid})</p> | ||
<div class="player-with-stats"> | ||
<div id="player-${uid}" class="player"></div> | ||
<div class="track-stats stats"></div> | ||
</div> | ||
</div> | ||
`); | ||
$("#remote-playerlist").append(player); | ||
user.videoTrack.play(`player-${uid}`); | ||
user.audioTrack.play(); | ||
} | ||
|
||
function handleUserPublished(user) { | ||
const id = user.uid; | ||
remoteUsers[id] = user; | ||
subscribe(user); | ||
} | ||
|
||
function handleUserUnpublished(user) { | ||
const id = user.uid; | ||
delete remoteUsers[id]; | ||
$(`#player-wrapper-${id}`).remove(); | ||
} | ||
|
||
// start collect and show stats information | ||
function initStats() { | ||
statsInterval = setInterval(flushStats, 1000); | ||
} | ||
|
||
// stop collect and show stats information | ||
function destructStats() { | ||
clearInterval(statsInterval); | ||
$("#session-stats").html(""); | ||
$("#transport-stats").html(""); | ||
$("#local-stats").html(""); | ||
} | ||
|
||
// flush stats views | ||
function flushStats() { | ||
// get the client stats message | ||
const clientStats = client.getRTCStats(); | ||
const clientStatsList = [ | ||
{ description: "Number of users in channel", value: clientStats.UserCount, unit: "" }, | ||
{ description: "Duration in channel", value: clientStats.Duration, unit: "s" }, | ||
{ description: "Bit rate receiving", value:clientStats.RecvBitrate, unit: "bps" }, | ||
{ description: "Bit rate being sent", value:clientStats.SendBitrate, unit: "bps" }, | ||
{ description: "Total bytes received", value:clientStats.RecvBytes, unit: "bytes" }, | ||
{ description: "Total bytes sent", value:clientStats.SendBytes, unit: "bytes" }, | ||
{ description: "Outgoing available bandwidth", value: clientStats.OutgoingAvailableBandwidth.toFixed(3), unit: "kbps" }, | ||
{ description: "RTT from SDK to SD-RTN access node", value: clientStats.RTT, unit: "ms" }, | ||
] | ||
$("#client-stats").html(` | ||
${clientStatsList.map(stat => `<p class="stats-row">${stat.description}: ${stat.value} ${stat.unit}</p>`).join("")} | ||
`) | ||
|
||
// get the local track stats message | ||
const localStats = { video: localTracks.videoTrack.getStats(), audio: localTracks.audioTrack.getStats() }; | ||
const localStatsList = [ | ||
{ description: "Send audio bit rate", value: localStats.audio.sendBitrate, unit: "bps" }, | ||
{ description: "Total audio bytes sent", value: localStats.audio.sendBytes, unit: "bytes" }, | ||
{ description: "Total audio packets sent", value: localStats.audio.sendPackets, unit: "" }, | ||
{ description: "Total audio packets loss", value: localStats.audio.sendPacketsLost, unit: "" }, | ||
{ description: "Video capture resolution height", value: localStats.video.captureResolutionHeight, unit: "" }, | ||
{ description: "Video capture resolution width", value: localStats.video.captureResolutionWidth, unit: "" }, | ||
{ description: "Video send resolution height", value: localStats.video.sendResolutionHeight, unit: "" }, | ||
{ description: "Video send resolution width", value: localStats.video.sendResolutionWidth, unit: "" }, | ||
{ description: "video encode delay", value: Number(localStats.video.encodeDelay).toFixed(2), unit: "ms" }, | ||
{ description: "Send video bit rate", value: localStats.video.sendBitrate, unit: "bps" }, | ||
{ description: "Total video bytes sent", value: localStats.video.sendBytes, unit: "bytes" }, | ||
{ description: "Total video packets sent", value: localStats.video.sendPackets, unit: "" }, | ||
{ description: "Total video packets loss", value: localStats.video.sendPacketsLost, unit: "" }, | ||
{ description: "Video duration", value: localStats.video.totalDuration, unit: "s" }, | ||
{ description: "Total video freeze time", value: localStats.video.totalFreezeTime, unit: "s" }, | ||
]; | ||
$("#local-stats").html(` | ||
${localStatsList.map(stat => `<p class="stats-row">${stat.description}: ${stat.value} ${stat.unit}</p>`).join("")} | ||
`); | ||
|
||
Object.keys(remoteUsers).forEach(uid => { | ||
// get the remote track stats message | ||
const remoteTracksStats = { video: remoteUsers[uid].videoTrack.getStats(), audio: remoteUsers[uid].audioTrack.getStats()}; | ||
const remoteTracksStatsList = [ | ||
{ description: "Delay of audio from sending to receiving", value: Number(remoteTracksStats.audio.receiveDelay).toFixed(2), unit: "ms" }, | ||
{ description: "Delay of video from sending to receiving", value: Number(remoteTracksStats.video.receiveDelay).toFixed(2), unit: "ms" }, | ||
{ description: "Total audio bytes received", value: remoteTracksStats.audio.receiveBytes, unit: "bytes" }, | ||
{ description: "Total audio packets received", value: remoteTracksStats.audio.receivePackets, unit: "" }, | ||
{ description: "Total audio packets loss", value: remoteTracksStats.audio.receivePacketsLost, unit: "" }, | ||
{ description: "Total audio packets loss rate", value: Number(remoteTracksStats.audio.packetLossRate).toFixed(3), unit: "%" }, | ||
{ description: "Video received resolution height", value: remoteTracksStats.video.receiveResolutionHeight, unit: "" }, | ||
{ description: "Video received resolution width", value: remoteTracksStats.video.receiveResolutionWidth, unit: "" }, | ||
{ description: "Receiving video bit rate", value: remoteTracksStats.video.receiveBitrate, unit: "bps" }, | ||
{ description: "Total video bytes received", value: remoteTracksStats.video.receiveBytes, unit: "bytes" }, | ||
{ description: "Total video packets received", value: remoteTracksStats.video.receivePackets, unit: "" }, | ||
{ description: "Total video packets loss", value: remoteTracksStats.video.receivePacketsLost, unit: "" }, | ||
{ description: "Total video packets loss rate", value: Number(remoteTracksStats.video.receivePacketsLost).toFixed(3), unit: "%" }, | ||
{ description: "Video duration", value: remoteTracksStats.video.totalDuration, unit: "s" }, | ||
{ description: "Total video freeze time", value: remoteTracksStats.video.totalFreezeTime, unit: "s" }, | ||
{ description: "video freeze rate", value: Number(remoteTracksStats.video.freezeRate).toFixed(3), unit: "%" }, | ||
]; | ||
$(`#player-wrapper-${uid} .track-stats`).html(` | ||
${remoteTracksStatsList.map(stat => `<p class="stats-row">${stat.description}: ${stat.value} ${stat.unit}</p>`).join("")} | ||
`); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
.banner { | ||
padding: 0; | ||
background-color: #52575c; | ||
color: white; | ||
} | ||
|
||
.banner-text { | ||
padding: 8px 20px; | ||
margin: 0; | ||
} | ||
|
||
|
||
#join-form { | ||
margin-top: 10px; | ||
} | ||
|
||
.tips { | ||
font-size: 12px; | ||
margin-bottom: 2px; | ||
color: gray; | ||
} | ||
|
||
.join-info-text { | ||
margin-bottom: 2px; | ||
} | ||
|
||
input { | ||
width: 100%; | ||
margin-bottom: 2px; | ||
} | ||
|
||
.player { | ||
width: 480px; | ||
height: 320px; | ||
margin-right: 10px; | ||
} | ||
|
||
.player-name { | ||
margin: 8px 0; | ||
} | ||
|
||
#success-alert { | ||
display: none; | ||
} | ||
|
||
#client-stats { | ||
margin-top: 10px; | ||
} | ||
|
||
.stats { | ||
color: gray; | ||
} | ||
|
||
.stats-row { | ||
font-size: 12px; | ||
margin-bottom: 2px; | ||
} | ||
|
||
.player-with-stats { | ||
display: flex; | ||
} | ||
|
||
.stream-stats { | ||
min-width: 260px; | ||
} | ||
|
||
@media (max-width: 640px) { | ||
.player { | ||
width: 320px; | ||
height: 240px; | ||
} | ||
.player-with-stats { | ||
display: block; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
<title>Display Call Stats -- Agora</title> | ||
<link rel="stylesheet" href="../assets/bootstrap.min.css"> | ||
<link rel="stylesheet" href="./index.css"> | ||
</head> | ||
<body> | ||
<div class="container-fluid banner"> | ||
<p class="banner-text">Display Call Stats</p> | ||
</div> | ||
|
||
<div id="success-alert" class="alert alert-success alert-dismissible fade show" role="alert"> | ||
<strong>Congratulations!</strong><span> You can invite others join this channel by click </span><a href="" target="_blank">here</a> | ||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
</div> | ||
|
||
<div class="container"> | ||
<form id="join-form"> | ||
<div class="row join-info-group"> | ||
<div class="col-sm"> | ||
<p class="join-info-text">AppID</p> | ||
<input id="appid" type="text" placeholder="enter appid" required> | ||
<p class="tips">If you don`t know what is your appid, checkout <a href="https://docs.agora.io/en/Agora%20Platform/terms?platform=All%20Platforms#a-nameappidaapp-id">this</a></p> | ||
</div> | ||
<div class="col-sm"> | ||
<p class="join-info-text">Token(optional)</p> | ||
<input id="token" type="text" placeholder="enter token"> | ||
<p class="tips">If you don`t know what is your token, checkout <a href="https://docs.agora.io/en/Agora%20Platform/terms?platform=All%20Platforms#a-namekeyadynamic-key">this</a></p> | ||
</div> | ||
<div class="col-sm"> | ||
<p class="join-info-text">Channel</p> | ||
<input id="channel" type="text" placeholder="enter channel name" required> | ||
<p class="tips">If you don`t know what is your channel, checkout <a href="https://docs.agora.io/en/Agora%20Platform/terms?platform=All%20Platforms#channel">this</a></p> | ||
</div> | ||
</div> | ||
|
||
<div class="button-group"> | ||
<button id="join" type="submit" class="btn btn-primary btn-sm">Join</button> | ||
<button id="leave" type="button" class="btn btn-primary btn-sm" disabled>Leave</button> | ||
</div> | ||
</form> | ||
|
||
<div id="client-stats" class="stats"></div> | ||
|
||
<div class="row video-group"> | ||
<div class="col"> | ||
<p id="local-player-name" class="player-name"></p> | ||
<div class="player-with-stats"> | ||
<div id="local-player" class="player"></div> | ||
<div id="local-stats" class="stream-stats stats"></div> | ||
</div> | ||
</div> | ||
<div class="w-100"></div> | ||
<div class="col"> | ||
<div id="remote-playerlist"></div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<script src="../assets/jquery-3.4.1.min.js"></script> | ||
<script src="../assets/bootstrap.bundle.min.js"></script> | ||
<script src="https://download.anyrtc.io/sdk/web/ArRTC@latest.js"></script> | ||
<script src="./displayCallStats.js"></script> | ||
</body> | ||
</html> |
Oops, something went wrong.