Diff
checker
テキスト
テキスト
画像
ドキュメント
Excel
フォルダ
Legal
Enterprise
デスクトップ
料金
ログイン
Diffchecker デスクトップのダウンロード
テキスト比較
2 つのテキスト ファイルの違いを見つける
ツール
履歴
ライブエディター
未変更行を折りたたむ
折り返しなし
レイアウト
分割
統合
比較精度
スマート
単語
文字
シンタックスハイライト
構文を選択
無視
テキスト変換
最初の差分へ移動
入力を編集
Diffchecker Desktop
Diffcheckerを実行する最も安全な方法。Diffchecker Desktopアプリを入手:あなたの差分はコンピューターから出ることはありません!
Desktopを入手
index.html comms-getting-started
作成日
3 年前
差分は期限切れになりません
クリア
エクスポート
共有
説明
49 削除
行
合計
削除
文字
合計
削除
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
287 行
すべてコピー
81 追加
行
合計
追加
文字
合計
追加
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
301 行
すべてコピー
<!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>
コピー
コピー済み
コピー
コピー済み
<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">
コピー
コピー済み
コピー
コピー済み
<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>
コピー
コピー済み
コピー
コピー済み
<!-- 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="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. */
コピー
コピー済み
コピー
コピー済み
}
}
</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>
コピー
コピー済み
コピー
コピー済み
<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>
コピー
コピー済み
コピー
コピー済み
<button type="button" class="btn btn-dark" id="btn-invite"><i class="bi bi-clipboard2-plus-fill"></i> Invite</button>
</div>
</div>
</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="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>
コピー
コピー済み
コピー
コピー済み
<!-- 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
コピー
コピー済み
コピー
コピー済み
* 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
.
*/
*/
コピー
コピー済み
コピー
コピー済み
const initializeToken =
() => {
const initializeToken =
async
() => {
console.group("Step 1: Initialize the SDK");
console.group("Step 1: Initialize the SDK");
コピー
コピー済み
コピー
コピー済み
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 () => {
コピー
コピー済み
コピー
コピー済み
// 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);
コピー
コピー済み
コピー
コピー済み
const name = queryParams.get("name") || "developer";
const alias = queryParams.get("alias") || "web-sdk-starter";
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
// 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 () => {
コピー
コピー済み
コピー
コピー済み
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")
コピー
コピー済み
コピー
コピー済み
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>
保存された差分
原文
ファイルを開く
<!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>
変更されたテキスト
ファイルを開く
<!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>
違いを見つける