Diff
checker
Texte
Texte
Images
Documents
Excel
Dossiers
Legal
Enterprise
Application de bureau
Prix
Se connecter
Télécharger Diffchecker Desktop
Comparer le texte
Trouver la différence entre deux fichiers texte
Outils
Historique
Éditeur live
Cacher identiques
Sans retour à la ligne
Vue
Divisé
Unifié
Niveau de précision
Intelligent
Mot
Caractère
Coloration syntaxique
Choisir la syntaxe
Ignorer
Transformer le texte
Aller au premier écart
Modifier l'entrée
Diffchecker Desktop
La façon la plus sécurisée d'utiliser Diffchecker. Obtenez l'application Diffchecker Desktop : vos diffs ne quittent jamais votre ordinateur !
Obtenir Desktop
index.html comms-getting-started
Créé
il y a 3 ans
Le diff n'expire jamais
Effacer
Exporter
Partager
Expliquer
49 suppressions
Lignes
Total
Supprimé
Caractères
Total
Supprimé
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
287 lignes
Copier tout
81 ajouts
Lignes
Total
Ajouté
Caractères
Total
Ajouté
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
301 lignes
Copier tout
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<html lang="en">
<head>
<head>
<meta charset="utf-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Dolby.io Getting Started with Video Calls</title>
<title>Dolby.io Getting Started with Video Calls</title>
<link rel="shortcut icon" href="https://go.dolby.io/hubfs/Dolby_April2021/images/favicon-32x32.png">
<link rel="shortcut icon" href="https://go.dolby.io/hubfs/Dolby_April2021/images/favicon-32x32.png">
<!-- Bootstrap Bundle -->
<!-- Bootstrap Bundle -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<!-- Dolby.io Web SDK -->
<!-- Dolby.io Web SDK -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@voxeet/voxeet-web-sdk/dist/voxeet-sdk.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@voxeet/voxeet-web-sdk/dist/voxeet-sdk.js"></script>
Copier
Copié
Copier
Copié
<script type="text/javascript" src="
https://developer.dolby.io/demos/comms-sdk-web-getting-started
/util/dolbyio-auth-helper.js"></script>
<script type="text/javascript" src="
..
/util/dolbyio-auth-helper.js"></script>
<!-- Auth0 Single Page Application SDK -->
<script src="https://cdn.auth0.com/js/auth0-spa-js/1.2/auth0-spa-js.production.js"></script>
<script src="./app.js"></script>
</head>
</head>
<body>
<body>
<div class="container bg-dark text-white gx-4 px-4 py-4 mt-3 rounded">
<div class="container bg-dark text-white gx-4 px-4 py-4 mt-3 rounded">
Copier
Copié
Copier
Copié
<img src="https://go.dolby.io/hubfs/raw_assets/public/Dolby_April2021/images/dolby-io-logo.svg"
/>
<img src="https://go.dolby.io/hubfs/raw_assets/public/Dolby_April2021/images/dolby-io-logo.svg"
/>
<h1>Getting Started with
Video Calls
</h1>
<h1>Getting Started with
Auth0 User Authentication
</h1>
</div>
<div>
<style>
.hidden {
display: none;
}
label {
margin-bottom: 10px;
display: block;
}
</style>
<br>
<button id="btn-login" class="btn btn-dark" disabled="true">Log in</button>
<button id="btn-logout" class="btn btn-dark" disabled="true">Log out</button>
</div>
</div>
Copier
Copié
Copier
Copié
<!-- Video Call Elements Hidden Until the Users Logs in -->
<div class="hidden" id="gated-content">
<p>
You're seeing this content because you're currently
<strong>logged in</strong>.
</p>
Copier
Copié
Copier
Copié
<div class="container px-4 mt-4">
<div class="container px-4 mt-4">
<div class="row justify-content-around mt-3">
<div class="row justify-content-around mt-3">
<div class="col-4 shadow p-3 mb-5 bg-body rounded">
<div class="col-4 shadow p-3 mb-5 bg-body rounded">
<h2>Self-View</h2>
<h2>Self-View</h2>
<style>
<style>
#self-view video {
/* Flip the display of the local user in self view */
#self-view video {
/* Flip the display of the local user in self view */
-webkit-transform: rotateY(180deg); /* Safari, Chrome */
-webkit-transform: rotateY(180deg); /* Safari, Chrome */
-moz-transform: rotateY(180deg); /* Firefox */
-moz-transform: rotateY(180deg); /* Firefox */
transform: rotateY(180deg); /* Microsoft, etc. */
transform: rotateY(180deg); /* Microsoft, etc. */
Copier
Copié
Copier
Copié
}
}
</style>
</style>
<div id="self-view"> <!-- Container for the local participant media stream -->
<div id="self-view"> <!-- Container for the local participant media stream -->
<p id="self-view-username"></p>
<p id="self-view-username"></p>
<i class="display-1 bi bi-person-video position-relative"></i>
<i class="display-1 bi bi-person-video position-relative"></i>
</div>
<button type="button" class="btn btn-dark" id="btn-join">Join</button>
<button type="button" class="btn btn-dark" id="btn-leave">Leave</button>
</div>
</div>
Copier
Copié
Copier
Copié
<button type="button" class="btn btn-dark" id="btn-join">Join</button>
<div class="col-4 shadow p-3 mb-5 bg-body rounded">
<button type="button" class="btn btn-dark" id="btn-leave">Leave</button>
<h2>Remote-View</h2>
</div>
<div id="remote-view"> <!-- Container for the remote participant media stream -->
<p id="remote-view-username"></p>
<div class="col-4 shadow p-3 mb-5 bg-body rounded">
<i class="display-1 bi bi-person-video position-relative"></i>
<h2>Remote-View</h2>
</div>
<div id="remote-view"> <!-- Container for the remote participant media stream -->
<p id="remote-view-username"></p>
<button type="button" class="btn btn-dark" id="btn-invite"><i class="bi bi-clipboard2-plus-fill"></i> Invite</button>
<i class="display-1 bi bi-person-video position-relative"></i>
</div>
</div>
Copier
Copié
Copier
Copié
<button type="button" class="btn btn-dark" id="btn-invite"><i class="bi bi-clipboard2-plus-fill"></i> Invite</button>
</div>
</div>
</div>
</div>
Copier
Copié
Copier
Copié
</div>
<div class="container px-4 py-4 mt-3">
<p id="message"></p>
<p><a href="https://docs.dolby.io/communications-apis/docs/getting-started-with-the-javascript-sdk">Explore More Tutorials</a></p>
</div>
Copier
Copié
Copier
Copié
<!-- Prompt user for token and alias if not provided in URL -->
<div class="container px-4 py-4 mt-3">
<div class="modal fade" id="token-prompt" tabindex="-1" aria-labelledby="token-prompt-label" aria-hidden="true">
<
p
id="
message
"></
p
>
<div class="modal-dialog">
<p><a href="https://docs.dolby.io/communications-apis/docs/getting-started-with-the-javascript-sdk">Explore More Tutorials</a></p>
<div class="modal-content">
<div class="modal-header">
<
h5 class="modal-title"
id="
token-prompt-label">Dolby.io Dashboard</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close
"></
button
>
</div>
<div class="modal-body">
<label for="input-token" class="form-label">Demo Client Access Token:</label>
<input id="input-token" type="text" class="form-control">
</div>
<div class="modal-footer">
<button type="button" id="btn-token" class="btn btn-primary">Authenticate</button>
</div>
</div>
</div>
</div>
</div>
</div>
Copier
Copié
Copier
Copié
<!-- Bootstrap Bundle -->
<!-- Bootstrap Bundle -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<!-- Dolby.io Starter Application -->
<!-- Dolby.io Starter Application -->
<script type="text/javascript">
<script type="text/javascript">
const shareMessage = (message) => {
const shareMessage = (message) => {
document.getElementById("message").innerText = message;
document.getElementById("message").innerText = message;
}
}
/**
/**
* Start by initializing the Web SDK with an access token. This starter project
* Start by initializing the Web SDK with an access token. This starter project
Copier
Copié
Copier
Copié
* utilizes a helper function to
pull
the token
from the query parameters in the URL
.
* utilizes a helper function to
provide
the token
with an API call
.
*/
*/
Copier
Copié
Copier
Copié
const initializeToken =
() => {
const initializeToken =
async
() => {
console.group("Step 1: Initialize the SDK");
console.group("Step 1: Initialize the SDK");
Copier
Copié
Copier
Copié
const token =
dolbyio.getAccessToken();
const token =
await
dolbyio.getAccessToken();
VoxeetSDK.initializeToken(token, () => { console.log("Get a New Access Token"); });
VoxeetSDK.initializeToken(token, () => { console.log("Get a New Access Token"); });
shareMessage("Step 1: Web SDK initialized.");
shareMessage("Step 1: Web SDK initialized.");
console.groupEnd();
console.groupEnd();
return token;
return token;
}
}
/**
/**
* Start a session by establishing a communication link between this client application
* Start a session by establishing a communication link between this client application
* and the Dolby.io Platform. You need to provide the client name when establishing
* and the Dolby.io Platform. You need to provide the client name when establishing
* a new session, often this is the name that will be used by the participant.
* a new session, often this is the name that will be used by the participant.
*/
*/
const openSession = async (sessionName) => {
const openSession = async (sessionName) => {
console.group("Step 2: Open a Session");
console.group("Step 2: Open a Session");
console.log(`Session Name: ${sessionName}`);
console.log(`Session Name: ${sessionName}`);
try {
try {
await VoxeetSDK.session.open({ name: sessionName });
await VoxeetSDK.session.open({ name: sessionName });
shareMessage("Step 2: Session opened.");
shareMessage("Step 2: Session opened.");
} catch (error) {
} catch (error) {
console.error(error);
console.error(error);
shareMessage(`Error opening session: ${error}`);
shareMessage(`Error opening session: ${error}`);
}
}
console.groupEnd();
console.groupEnd();
}
}
/**
/**
* Bi-directional communications for multiple participants occurs in a conference. Initially,
* Bi-directional communications for multiple participants occurs in a conference. Initially,
* the conference must be created before it can be joined. The conference should be given a
* the conference must be created before it can be joined. The conference should be given a
* unique and meaningful alias to help identify it among multiple conferences in an account.
* unique and meaningful alias to help identify it among multiple conferences in an account.
*
*
* This should be in response to a user event so that they may approve media access to the
* This should be in response to a user event so that they may approve media access to the
* microphone and camera.
* microphone and camera.
*/
*/
const createAndJoinConference = async (conferenceAlias, participantName) => {
const createAndJoinConference = async (conferenceAlias, participantName) => {
if (!VoxeetSDK.session.isOpen()) { await openSession(participantName); };
if (!VoxeetSDK.session.isOpen()) { await openSession(participantName); };
console.group("Step 3: Create and Join a Conference");
console.group("Step 3: Create and Join a Conference");
console.log(`Conference Alias: ${conferenceAlias}`);
console.log(`Conference Alias: ${conferenceAlias}`);
const joinOptions = {
const joinOptions = {
constraints: { audio: true, video: true }
constraints: { audio: true, video: true }
};
};
const conferenceOptions = {
const conferenceOptions = {
alias: conferenceAlias
alias: conferenceAlias
}
}
try {
try {
const conference = await VoxeetSDK.conference.create(conferenceOptions);
const conference = await VoxeetSDK.conference.create(conferenceOptions);
await VoxeetSDK.conference.join(conference, joinOptions);
await VoxeetSDK.conference.join(conference, joinOptions);
shareMessage(`Step 3: Conference '${conferenceAlias}' created and joined.`)
shareMessage(`Step 3: Conference '${conferenceAlias}' created and joined.`)
} catch (error) {
} catch (error) {
console.error(error);
console.error(error);
}
}
console.groupEnd();
console.groupEnd();
};
};
/**
/**
* The SDK will trigger server-generated events which we can respond to
* The SDK will trigger server-generated events which we can respond to
* for intended functionality.
* for intended functionality.
*/
*/
const handleConferenceFlow = () => {
const handleConferenceFlow = () => {
// Custom behavior for when there is a media stream added
// Custom behavior for when there is a media stream added
VoxeetSDK.conference.on("streamAdded", (participant, stream) => {
VoxeetSDK.conference.on("streamAdded", (participant, stream) => {
console.log(`Stream Added for ${participant.info.name}`);
console.log(`Stream Added for ${participant.info.name}`);
console.log(` Type: ${stream.type}`);
console.log(` Type: ${stream.type}`);
console.log(` Video Tracks: ${stream.getVideoTracks().length}`);
console.log(` Video Tracks: ${stream.getVideoTracks().length}`);
if (stream.type === "Camera") {
if (stream.type === "Camera") {
shareVideo(participant, stream);
shareVideo(participant, stream);
}
}
});
});
// Custom behavior for when there is a media stream updated which happens once an attendee starts sharing video
// Custom behavior for when there is a media stream updated which happens once an attendee starts sharing video
VoxeetSDK.conference.on("streamUpdated", (participant, stream) => {
VoxeetSDK.conference.on("streamUpdated", (participant, stream) => {
console.log(`Stream Updated for ${participant.info.name}`);
console.log(`Stream Updated for ${participant.info.name}`);
console.log(` Type: ${stream.type}`);
console.log(` Type: ${stream.type}`);
console.log(` Video Tracks: ${stream.getVideoTracks().length}`);
console.log(` Video Tracks: ${stream.getVideoTracks().length}`);
if (stream.type === "Camera" && stream.getVideoTracks().length) {
if (stream.type === "Camera" && stream.getVideoTracks().length) {
shareVideo(participant, stream);
shareVideo(participant, stream);
}
}
});
});
// Custom behavior for when the app stops receiving a media stream for remote participants
// Custom behavior for when the app stops receiving a media stream for remote participants
VoxeetSDK.conference.on("streamRemoved", (participant, stream) => {
VoxeetSDK.conference.on("streamRemoved", (participant, stream) => {
console.log(`Stream Removed for ${participant.info.name}`);
console.log(`Stream Removed for ${participant.info.name}`);
const videoNode = document.getElementById(`video-${participant.id}`);
const videoNode = document.getElementById(`video-${participant.id}`);
if (videoNode) {
if (videoNode) {
videoNode.parentNode.removeChild(videoNode);
videoNode.parentNode.removeChild(videoNode);
}
}
});
});
// Custom behavior for when the participant has left the conference
// Custom behavior for when the participant has left the conference
VoxeetSDK.conference.on("left", async () => {
VoxeetSDK.conference.on("left", async () => {
await VoxeetSDK.session.close();
await VoxeetSDK.session.close();
console.log("Session closed.");
console.log("Session closed.");
});
});
}
}
/**
/**
* When a new participant camera media stream is detected, we determine which
* When a new participant camera media stream is detected, we determine which
* part of the user interface to update and create a video element that will
* part of the user interface to update and create a video element that will
* display the incoming stream.
* display the incoming stream.
*/
*/
const shareVideo = (participant, stream) => {
const shareVideo = (participant, stream) => {
console.group("Step 4: Start and Share Video");
console.group("Step 4: Start and Share Video");
let perspective = "self-view";
let perspective = "self-view";
if (VoxeetSDK.session.participant.id !== participant.id) {
if (VoxeetSDK.session.participant.id !== participant.id) {
console.log("Adding media stream for remote user.");
console.log("Adding media stream for remote user.");
perspective = "remote-view";
perspective = "remote-view";
}
}
let videoNode = document.getElementById(`video-${participant.id}`);
let videoNode = document.getElementById(`video-${participant.id}`);
if (videoNode) {
if (videoNode) {
console.log("Video node already created");
console.log("Video node already created");
} else {
} else {
console.log(`Creating a video node: video-${participant.id}`);
console.log(`Creating a video node: video-${participant.id}`);
videoNode = document.createElement("video");
videoNode = document.createElement("video");
videoNode.setAttribute("id", `video-${participant.id}`);
videoNode.setAttribute("id", `video-${participant.id}`);
videoNode.setAttribute("height", "100%");
videoNode.setAttribute("height", "100%");
videoNode.setAttribute("width", "100%");
videoNode.setAttribute("width", "100%");
videoNode.muted = true; // Don't echo local audio
videoNode.muted = true; // Don't echo local audio
videoNode.autoplay = true; // Start right away
videoNode.autoplay = true; // Start right away
videoNode.playsinline = true; // Not full screen
videoNode.playsinline = true; // Not full screen
const videoContainer = document.getElementById(perspective);
const videoContainer = document.getElementById(perspective);
videoContainer.lastElementChild.replaceWith(videoNode);
videoContainer.lastElementChild.replaceWith(videoNode);
videoContainer.firstElementChild.innerText = participant.info.name;
videoContainer.firstElementChild.innerText = participant.info.name;
}
}
navigator.attachMediaStream(videoNode, stream);
navigator.attachMediaStream(videoNode, stream);
shareMessage(`Step 4: Video of participant '${participant.info.name}' started.`);
shareMessage(`Step 4: Video of participant '${participant.info.name}' started.`);
console.groupEnd();
console.groupEnd();
}
}
/**
/**
* When the user decides to leave the conference you should stop sending the audio/video
* When the user decides to leave the conference you should stop sending the audio/video
* stream.
* stream.
*/
*/
const leaveConference = async () => {
const leaveConference = async () => {
console.group("Final Step: Leave the Conference");
console.group("Final Step: Leave the Conference");
try {
try {
await VoxeetSDK.conference.leave();
await VoxeetSDK.conference.leave();
shareMessage("Getting Started Success: Conference has ended.")
shareMessage("Getting Started Success: Conference has ended.")
} catch (error) {
} catch (error) {
console.error(error);
console.error(error);
}
}
console.groupEnd();
console.groupEnd();
}
}
const main = async () => {
const main = async () => {
Copier
Copié
Copier
Copié
// Configure the
application
from query parameter values
// When the web page has finished loading, configure Auth0 client, check the user's login state, and update the UI accordingly.
window.onload = async () => {
await configureClient();
await processLoginState();
// Function below will use initializeToken and openSession functions as callbacks in it after authentication.
await updateUI(initializeToken, openSession);
};
// When user clicks the Log in button, redirect user to Auth0 to access the conference only after authentication
document.getElementById("btn-login").onclick = async () => {
await login();
};
// When user clicks the Log out button, log out and clean Auht0 browser cookies
document.getElementById("btn-logout").onclick = async () => {
await logout();
};
// Configure the
conference alias
from query parameter values
const queryParams = new URLSearchParams(window.location.search);
const queryParams = new URLSearchParams(window.location.search);
Copier
Copié
Copier
Copié
const name = queryParams.get("name") || "developer";
const alias = queryParams.get("alias") || "web-sdk-starter";
const alias = queryParams.get("alias") || "web-sdk-starter";
Copier
Copié
Copier
Copié
// Establish Real-time Communications by first initializing the Dolby.io Web SDK with credentials
const token = await initializeToken();
// Start a new session and connect to the Dolby.io platform establishing a client-server link
await openSession(name);
// When user clicks the Join button, start and join a conference for the given alias
// When user clicks the Join button, start and join a conference for the given alias
document.getElementById("btn-join").onclick = async () => {
document.getElementById("btn-join").onclick = async () => {
Copier
Copié
Copier
Copié
await createAndJoinConference(alias
, name
);
await createAndJoinConference(alias
);
};
};
// Define custom behavior for activity that occurs during a video call
// Define custom behavior for activity that occurs during a video call
handleConferenceFlow();
handleConferenceFlow();
// When user clicks the Invite button, generate a url to join the same conference
// When user clicks the Invite button, generate a url to join the same conference
document.getElementById("btn-invite").onclick = () => {
document.getElementById("btn-invite").onclick = () => {
console.group("Step 5: Invite a remote participant")
console.group("Step 5: Invite a remote participant")
Copier
Copié
Copier
Copié
let url = `http
s
://
developer.dolby.io/demos/comms-sdk-web-getting-started/index.html?token=${token}&
alias=${alias}
&name=guest
`;
let url = `http
://
localhost:3000/?
alias=${alias}
`;
console.log(`Invite a guest with URL: ${url}`);
console.log(`Invite a guest with URL: ${url}`);
shareMessage(`Share the URL copied to your browser clipboard: ${url}`);
shareMessage(`Share the URL copied to your browser clipboard: ${url}`);
navigator.clipboard.writeText(url);
navigator.clipboard.writeText(url);
console.groupEnd();
console.groupEnd();
}
}
// When user clicks the Leave button, end the conference
// When user clicks the Leave button, end the conference
document.getElementById("btn-leave").onclick = async () => {
document.getElementById("btn-leave").onclick = async () => {
await leaveConference();
await leaveConference();
console.log("Getting Started Guide complete, congratulations!");
console.log("Getting Started Guide complete, congratulations!");
};
};
};
};
main();
main();
</script>
</script>
</body>
</body>
</html>
</html>
Différences enregistrées
Texte d'origine
Ouvrir un fichier
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"> <title>Dolby.io Getting Started with Video Calls</title> <link rel="shortcut icon" href="https://go.dolby.io/hubfs/Dolby_April2021/images/favicon-32x32.png"> <!-- Bootstrap Bundle --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css"> <!-- Dolby.io Web SDK --> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@voxeet/voxeet-web-sdk/dist/voxeet-sdk.js"></script> <script type="text/javascript" src="https://developer.dolby.io/demos/comms-sdk-web-getting-started/util/dolbyio-auth-helper.js"></script> </head> <body> <div class="container bg-dark text-white gx-4 px-4 py-4 mt-3 rounded"> <img src="https://go.dolby.io/hubfs/raw_assets/public/Dolby_April2021/images/dolby-io-logo.svg"/> <h1>Getting Started with Video Calls</h1> </div> <div class="container px-4 mt-4"> <div class="row justify-content-around mt-3"> <div class="col-4 shadow p-3 mb-5 bg-body rounded"> <h2>Self-View</h2> <style> #self-view video { /* Flip the display of the local user in self view */ -webkit-transform: rotateY(180deg); /* Safari, Chrome */ -moz-transform: rotateY(180deg); /* Firefox */ transform: rotateY(180deg); /* Microsoft, etc. */ } </style> <div id="self-view"> <!-- Container for the local participant media stream --> <p id="self-view-username"></p> <i class="display-1 bi bi-person-video position-relative"></i> </div> <button type="button" class="btn btn-dark" id="btn-join">Join</button> <button type="button" class="btn btn-dark" id="btn-leave">Leave</button> </div> <div class="col-4 shadow p-3 mb-5 bg-body rounded"> <h2>Remote-View</h2> <div id="remote-view"> <!-- Container for the remote participant media stream --> <p id="remote-view-username"></p> <i class="display-1 bi bi-person-video position-relative"></i> </div> <button type="button" class="btn btn-dark" id="btn-invite"><i class="bi bi-clipboard2-plus-fill"></i> Invite</button> </div> </div> </div> <div class="container px-4 py-4 mt-3"> <p id="message"></p> <p><a href="https://docs.dolby.io/communications-apis/docs/getting-started-with-the-javascript-sdk">Explore More Tutorials</a></p> </div> <!-- Prompt user for token and alias if not provided in URL --> <div class="modal fade" id="token-prompt" tabindex="-1" aria-labelledby="token-prompt-label" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="token-prompt-label">Dolby.io Dashboard</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <label for="input-token" class="form-label">Demo Client Access Token:</label> <input id="input-token" type="text" class="form-control"> </div> <div class="modal-footer"> <button type="button" id="btn-token" class="btn btn-primary">Authenticate</button> </div> </div> </div> </div> <!-- Bootstrap Bundle --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script> <!-- Dolby.io Starter Application --> <script type="text/javascript"> const shareMessage = (message) => { document.getElementById("message").innerText = message; } /** * Start by initializing the Web SDK with an access token. This starter project * utilizes a helper function to pull the token from the query parameters in the URL. */ const initializeToken = () => { console.group("Step 1: Initialize the SDK"); const token = dolbyio.getAccessToken(); VoxeetSDK.initializeToken(token, () => { console.log("Get a New Access Token"); }); shareMessage("Step 1: Web SDK initialized."); console.groupEnd(); return token; } /** * Start a session by establishing a communication link between this client application * and the Dolby.io Platform. You need to provide the client name when establishing * a new session, often this is the name that will be used by the participant. */ const openSession = async (sessionName) => { console.group("Step 2: Open a Session"); console.log(`Session Name: ${sessionName}`); try { await VoxeetSDK.session.open({ name: sessionName }); shareMessage("Step 2: Session opened."); } catch (error) { console.error(error); shareMessage(`Error opening session: ${error}`); } console.groupEnd(); } /** * Bi-directional communications for multiple participants occurs in a conference. Initially, * the conference must be created before it can be joined. The conference should be given a * unique and meaningful alias to help identify it among multiple conferences in an account. * * This should be in response to a user event so that they may approve media access to the * microphone and camera. */ const createAndJoinConference = async (conferenceAlias, participantName) => { if (!VoxeetSDK.session.isOpen()) { await openSession(participantName); }; console.group("Step 3: Create and Join a Conference"); console.log(`Conference Alias: ${conferenceAlias}`); const joinOptions = { constraints: { audio: true, video: true } }; const conferenceOptions = { alias: conferenceAlias } try { const conference = await VoxeetSDK.conference.create(conferenceOptions); await VoxeetSDK.conference.join(conference, joinOptions); shareMessage(`Step 3: Conference '${conferenceAlias}' created and joined.`) } catch (error) { console.error(error); } console.groupEnd(); }; /** * The SDK will trigger server-generated events which we can respond to * for intended functionality. */ const handleConferenceFlow = () => { // Custom behavior for when there is a media stream added VoxeetSDK.conference.on("streamAdded", (participant, stream) => { console.log(`Stream Added for ${participant.info.name}`); console.log(` Type: ${stream.type}`); console.log(` Video Tracks: ${stream.getVideoTracks().length}`); if (stream.type === "Camera") { shareVideo(participant, stream); } }); // Custom behavior for when there is a media stream updated which happens once an attendee starts sharing video VoxeetSDK.conference.on("streamUpdated", (participant, stream) => { console.log(`Stream Updated for ${participant.info.name}`); console.log(` Type: ${stream.type}`); console.log(` Video Tracks: ${stream.getVideoTracks().length}`); if (stream.type === "Camera" && stream.getVideoTracks().length) { shareVideo(participant, stream); } }); // Custom behavior for when the app stops receiving a media stream for remote participants VoxeetSDK.conference.on("streamRemoved", (participant, stream) => { console.log(`Stream Removed for ${participant.info.name}`); const videoNode = document.getElementById(`video-${participant.id}`); if (videoNode) { videoNode.parentNode.removeChild(videoNode); } }); // Custom behavior for when the participant has left the conference VoxeetSDK.conference.on("left", async () => { await VoxeetSDK.session.close(); console.log("Session closed."); }); } /** * When a new participant camera media stream is detected, we determine which * part of the user interface to update and create a video element that will * display the incoming stream. */ const shareVideo = (participant, stream) => { console.group("Step 4: Start and Share Video"); let perspective = "self-view"; if (VoxeetSDK.session.participant.id !== participant.id) { console.log("Adding media stream for remote user."); perspective = "remote-view"; } let videoNode = document.getElementById(`video-${participant.id}`); if (videoNode) { console.log("Video node already created"); } else { console.log(`Creating a video node: video-${participant.id}`); videoNode = document.createElement("video"); videoNode.setAttribute("id", `video-${participant.id}`); videoNode.setAttribute("height", "100%"); videoNode.setAttribute("width", "100%"); videoNode.muted = true; // Don't echo local audio videoNode.autoplay = true; // Start right away videoNode.playsinline = true; // Not full screen const videoContainer = document.getElementById(perspective); videoContainer.lastElementChild.replaceWith(videoNode); videoContainer.firstElementChild.innerText = participant.info.name; } navigator.attachMediaStream(videoNode, stream); shareMessage(`Step 4: Video of participant '${participant.info.name}' started.`); console.groupEnd(); } /** * When the user decides to leave the conference you should stop sending the audio/video * stream. */ const leaveConference = async () => { console.group("Final Step: Leave the Conference"); try { await VoxeetSDK.conference.leave(); shareMessage("Getting Started Success: Conference has ended.") } catch (error) { console.error(error); } console.groupEnd(); } const main = async () => { // Configure the application from query parameter values const queryParams = new URLSearchParams(window.location.search); const name = queryParams.get("name") || "developer"; const alias = queryParams.get("alias") || "web-sdk-starter"; // Establish Real-time Communications by first initializing the Dolby.io Web SDK with credentials const token = await initializeToken(); // Start a new session and connect to the Dolby.io platform establishing a client-server link await openSession(name); // When user clicks the Join button, start and join a conference for the given alias document.getElementById("btn-join").onclick = async () => { await createAndJoinConference(alias, name); }; // Define custom behavior for activity that occurs during a video call handleConferenceFlow(); // When user clicks the Invite button, generate a url to join the same conference document.getElementById("btn-invite").onclick = () => { console.group("Step 5: Invite a remote participant") let url = `https://developer.dolby.io/demos/comms-sdk-web-getting-started/index.html?token=${token}&alias=${alias}&name=guest`; console.log(`Invite a guest with URL: ${url}`); shareMessage(`Share the URL copied to your browser clipboard: ${url}`); navigator.clipboard.writeText(url); console.groupEnd(); } // When user clicks the Leave button, end the conference document.getElementById("btn-leave").onclick = async () => { await leaveConference(); console.log("Getting Started Guide complete, congratulations!"); }; }; main(); </script> </body> </html>
Texte modifié
Ouvrir un fichier
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"> <title>Dolby.io Getting Started with Video Calls</title> <link rel="shortcut icon" href="https://go.dolby.io/hubfs/Dolby_April2021/images/favicon-32x32.png"> <!-- Bootstrap Bundle --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css"> <!-- Dolby.io Web SDK --> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@voxeet/voxeet-web-sdk/dist/voxeet-sdk.js"></script> <script type="text/javascript" src="../util/dolbyio-auth-helper.js"></script> <!-- Auth0 Single Page Application SDK --> <script src="https://cdn.auth0.com/js/auth0-spa-js/1.2/auth0-spa-js.production.js"></script> <script src="./app.js"></script> </head> <body> <div class="container bg-dark text-white gx-4 px-4 py-4 mt-3 rounded"> <img src="https://go.dolby.io/hubfs/raw_assets/public/Dolby_April2021/images/dolby-io-logo.svg" /> <h1>Getting Started with Auth0 User Authentication </h1> </div> <div> <style> .hidden { display: none; } label { margin-bottom: 10px; display: block; } </style> <br> <button id="btn-login" class="btn btn-dark" disabled="true">Log in</button> <button id="btn-logout" class="btn btn-dark" disabled="true">Log out</button> </div> <!-- Video Call Elements Hidden Until the Users Logs in --> <div class="hidden" id="gated-content"> <p> You're seeing this content because you're currently <strong>logged in</strong>. </p> <div class="container px-4 mt-4"> <div class="row justify-content-around mt-3"> <div class="col-4 shadow p-3 mb-5 bg-body rounded"> <h2>Self-View</h2> <style> #self-view video { /* Flip the display of the local user in self view */ -webkit-transform: rotateY(180deg); /* Safari, Chrome */ -moz-transform: rotateY(180deg); /* Firefox */ transform: rotateY(180deg); /* Microsoft, etc. */ } </style> <div id="self-view"> <!-- Container for the local participant media stream --> <p id="self-view-username"></p> <i class="display-1 bi bi-person-video position-relative"></i> </div> <button type="button" class="btn btn-dark" id="btn-join">Join</button> <button type="button" class="btn btn-dark" id="btn-leave">Leave</button> </div> <div class="col-4 shadow p-3 mb-5 bg-body rounded"> <h2>Remote-View</h2> <div id="remote-view"> <!-- Container for the remote participant media stream --> <p id="remote-view-username"></p> <i class="display-1 bi bi-person-video position-relative"></i> </div> <button type="button" class="btn btn-dark" id="btn-invite"><i class="bi bi-clipboard2-plus-fill"></i> Invite</button> </div> </div> </div> <div class="container px-4 py-4 mt-3"> <p id="message"></p> <p><a href="https://docs.dolby.io/communications-apis/docs/getting-started-with-the-javascript-sdk">Explore More Tutorials</a></p> </div> </div> <!-- Bootstrap Bundle --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script> <!-- Dolby.io Starter Application --> <script type="text/javascript"> const shareMessage = (message) => { document.getElementById("message").innerText = message; } /** * Start by initializing the Web SDK with an access token. This starter project * utilizes a helper function to provide the token with an API call. */ const initializeToken = async () => { console.group("Step 1: Initialize the SDK"); const token = await dolbyio.getAccessToken(); VoxeetSDK.initializeToken(token, () => { console.log("Get a New Access Token"); }); shareMessage("Step 1: Web SDK initialized."); console.groupEnd(); return token; } /** * Start a session by establishing a communication link between this client application * and the Dolby.io Platform. You need to provide the client name when establishing * a new session, often this is the name that will be used by the participant. */ const openSession = async (sessionName) => { console.group("Step 2: Open a Session"); console.log(`Session Name: ${sessionName}`); try { await VoxeetSDK.session.open({ name: sessionName }); shareMessage("Step 2: Session opened."); } catch (error) { console.error(error); shareMessage(`Error opening session: ${error}`); } console.groupEnd(); } /** * Bi-directional communications for multiple participants occurs in a conference. Initially, * the conference must be created before it can be joined. The conference should be given a * unique and meaningful alias to help identify it among multiple conferences in an account. * * This should be in response to a user event so that they may approve media access to the * microphone and camera. */ const createAndJoinConference = async (conferenceAlias, participantName) => { if (!VoxeetSDK.session.isOpen()) { await openSession(participantName); }; console.group("Step 3: Create and Join a Conference"); console.log(`Conference Alias: ${conferenceAlias}`); const joinOptions = { constraints: { audio: true, video: true } }; const conferenceOptions = { alias: conferenceAlias } try { const conference = await VoxeetSDK.conference.create(conferenceOptions); await VoxeetSDK.conference.join(conference, joinOptions); shareMessage(`Step 3: Conference '${conferenceAlias}' created and joined.`) } catch (error) { console.error(error); } console.groupEnd(); }; /** * The SDK will trigger server-generated events which we can respond to * for intended functionality. */ const handleConferenceFlow = () => { // Custom behavior for when there is a media stream added VoxeetSDK.conference.on("streamAdded", (participant, stream) => { console.log(`Stream Added for ${participant.info.name}`); console.log(` Type: ${stream.type}`); console.log(` Video Tracks: ${stream.getVideoTracks().length}`); if (stream.type === "Camera") { shareVideo(participant, stream); } }); // Custom behavior for when there is a media stream updated which happens once an attendee starts sharing video VoxeetSDK.conference.on("streamUpdated", (participant, stream) => { console.log(`Stream Updated for ${participant.info.name}`); console.log(` Type: ${stream.type}`); console.log(` Video Tracks: ${stream.getVideoTracks().length}`); if (stream.type === "Camera" && stream.getVideoTracks().length) { shareVideo(participant, stream); } }); // Custom behavior for when the app stops receiving a media stream for remote participants VoxeetSDK.conference.on("streamRemoved", (participant, stream) => { console.log(`Stream Removed for ${participant.info.name}`); const videoNode = document.getElementById(`video-${participant.id}`); if (videoNode) { videoNode.parentNode.removeChild(videoNode); } }); // Custom behavior for when the participant has left the conference VoxeetSDK.conference.on("left", async () => { await VoxeetSDK.session.close(); console.log("Session closed."); }); } /** * When a new participant camera media stream is detected, we determine which * part of the user interface to update and create a video element that will * display the incoming stream. */ const shareVideo = (participant, stream) => { console.group("Step 4: Start and Share Video"); let perspective = "self-view"; if (VoxeetSDK.session.participant.id !== participant.id) { console.log("Adding media stream for remote user."); perspective = "remote-view"; } let videoNode = document.getElementById(`video-${participant.id}`); if (videoNode) { console.log("Video node already created"); } else { console.log(`Creating a video node: video-${participant.id}`); videoNode = document.createElement("video"); videoNode.setAttribute("id", `video-${participant.id}`); videoNode.setAttribute("height", "100%"); videoNode.setAttribute("width", "100%"); videoNode.muted = true; // Don't echo local audio videoNode.autoplay = true; // Start right away videoNode.playsinline = true; // Not full screen const videoContainer = document.getElementById(perspective); videoContainer.lastElementChild.replaceWith(videoNode); videoContainer.firstElementChild.innerText = participant.info.name; } navigator.attachMediaStream(videoNode, stream); shareMessage(`Step 4: Video of participant '${participant.info.name}' started.`); console.groupEnd(); } /** * When the user decides to leave the conference you should stop sending the audio/video * stream. */ const leaveConference = async () => { console.group("Final Step: Leave the Conference"); try { await VoxeetSDK.conference.leave(); shareMessage("Getting Started Success: Conference has ended.") } catch (error) { console.error(error); } console.groupEnd(); } const main = async () => { // When the web page has finished loading, configure Auth0 client, check the user's login state, and update the UI accordingly. window.onload = async () => { await configureClient(); await processLoginState(); // Function below will use initializeToken and openSession functions as callbacks in it after authentication. await updateUI(initializeToken, openSession); }; // When user clicks the Log in button, redirect user to Auth0 to access the conference only after authentication document.getElementById("btn-login").onclick = async () => { await login(); }; // When user clicks the Log out button, log out and clean Auht0 browser cookies document.getElementById("btn-logout").onclick = async () => { await logout(); }; // Configure the conference alias from query parameter values const queryParams = new URLSearchParams(window.location.search); const alias = queryParams.get("alias") || "web-sdk-starter"; // When user clicks the Join button, start and join a conference for the given alias document.getElementById("btn-join").onclick = async () => { await createAndJoinConference(alias); }; // Define custom behavior for activity that occurs during a video call handleConferenceFlow(); // When user clicks the Invite button, generate a url to join the same conference document.getElementById("btn-invite").onclick = () => { console.group("Step 5: Invite a remote participant") let url = `http://localhost:3000/?alias=${alias}`; console.log(`Invite a guest with URL: ${url}`); shareMessage(`Share the URL copied to your browser clipboard: ${url}`); navigator.clipboard.writeText(url); console.groupEnd(); } // When user clicks the Leave button, end the conference document.getElementById("btn-leave").onclick = async () => { await leaveConference(); console.log("Getting Started Guide complete, congratulations!"); }; }; main(); </script> </body> </html>
Trouver la différence