Open
Description
音频房间创建及连接说明
声网开源通话代码
API-Examples-Web/Demo/selfRendering at main · AgoraIO/API-Examples-Web
UI
CSS
.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;
}
.player-name {
margin: 8px 0;
}
#success-alert, #success-alert-with-token {
display: none;
}
@media (max-width: 640px) {
.player {
width: 320px;
height: 240px;
}
}
HTML
<!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>Video Self-Rendering -- 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">Video Self-Rendering</p>
<a style="color: rgb(255, 255, 255);fill: rgb(255, 255, 255);fill-rule: evenodd; position: absolute; right: 10px; top: 4px;"
class="Header-link " href="https://github.com/AgoraIO/API-Examples-Web/tree/main/Demo">
<svg class="octicon octicon-mark-github v-align-middle" height="32" viewBox="0 0 16 16" version="1.1" width="32" aria-hidden="true"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg>
</a>
</div>
<div id="success-alert" class="alert alert-success alert-dismissible fade show" role="alert">
<strong>Congratulations!</strong><span> You can invite others to watch your live by click </span><a href="" target=&am
6293
p;quot;_blank">here</a>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="container">
<form id="join-form" name="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 class="col-sm">
<p class="join-info-text">User ID(optional)</p>
<input id="uid" type="text" placeholder="Enter the user ID">
</div>
</div>
<div class="button-group">
<button id="host-join" type="submit" class="btn btn-primary btn-sm">Join as host</button>
<div class="btn-group">
<button id="audience-join" type="button" class="btn btn-primary btn-sm" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Join as audience
</button>
<div class="audience dropdown-menu">
<a id="lowLatency" class="dropdown-item" label="Interactive Live Streaming Standard" href="#">Interactive Live Streaming Standard</a>
<a id="ultraLowLatency" class="dropdown-item" label="Interactive Live Streaming Premium" href="#">Interactive Live Streaming Premium</a>
</div>
</div>
<button id="leave" type="button" class="btn btn-primary btn-sm" disabled>Leave</button>
</div>
</form>
<!-- Single button -->
<div class="row video-group">
<div class="col">
<p id="local-player-name" class="player-name"></p>
<div id="local-player" class="player"></div>
<div id="local-player-mirror-area" class="player video-mirror" title="Video Mirror" style="display: none; border: 2px dashed red ;">
<div id="local-player-mirror" style="width: 100%; height: 100%; position: relative; overflow: hidden; background-color: black;">
<video id="local-player-mirror-video-track" class="agora_video_player" playsinline="" muted="" style="width: 100%; height: 100%; position: absolute; left: 0px; top: 0px; transform: rotateY(180deg); object-fit: cover;">
</video>
</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.agora.io/sdk/release/AgoraRTC_N.js"></script>
<script src="./index.js"></script>
</body>
</html>
通话逻辑
// create Agora client
var client = AgoraRTC.createClient({mode: "live", codec: "vp8"});
AgoraRTC.enableLogUpload();
var localTracks = {
videoTrack: null,
audioTrack: null
};
var remoteUsers = {};
// Agora client options
var options = {
appid: null,
channel: null,
uid: null,
token: null,
role: "audience", // host or audience
audienceLatency: 2
};
// 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");
options.uid = urlParams.get("uid");
if (options.appid && options.channel) {
$("#uid").val(options.uid);
$("#appid").val(options.appid);
$("#token").val(options.token);
$("#channel").val(options.channel);
$("#join-form").submit();
}
})
$("#host-join").click(function (e) {
options.role = "host"
})
$("#lowLatency").click
A935
(function (e) {
options.role = "audience"
options.audienceLatency = 1
$("#join-form").submit()
})
$("#ultraLowLatency").click(function (e) {
options.role = "audience"
options.audienceLatency = 2
$("#join-form").submit()
})
$("#join-form").submit(async function (e) {
e.preventDefault();
$("#host-join").attr("disabled", true);
$("#audience-join").attr("disabled", true);
try {
options.appid = $("#appid").val();
options.token = $("#token").val();
options.channel = $("#channel").val();
options.uid = Number($("#uid").val());
await join();
if (options.role === "host") {
$("#success-alert a").attr("href", `index.html?appid=${options.appid}&channel=${options.channel}&token=${options.token}`);
if (options.token) {
$("#success-alert-with-token").css("display", "block");
} else {
$("#success-alert a").attr("href", `index.html?appid=${options.appid}&channel=${options.channel}&token=${options.token}`);
$("#success-alert").css("display", "block");
}
}
} catch (error) {
console.error(error);
} finally {
$("#leave").attr("disabled", false);
}
})
$("#leave").click(function (e) {
leave();
})
async function join() {
// create Agora client
if (options.role === "audience") {
client.setClientRole(options.role, {level: options.audienceLatency});
// add event listener to play remote tracks when remote user publishs.
client.on("user-published", handleUserPublished);
client.on("user-unpublished", handleUserUnpublished);
}
else{
client.setClientRole(options.role);
}
// join the channel
options.uid = await client.join(options.appid, options.channel, options.token || null, options.uid || null);
if (options.role === "host") {
// create local audio and video tracks
localTracks.audioTrack = await AgoraRTC.createMicrophoneAudioTrack();
localTracks.videoTrack = await AgoraRTC.createCameraVideoTrack();
// play local video track
localTracks.videoTrack.play("local-player");
$("#local-player-name").text(`localTrack(${options.uid})`);
//create the mirror of local player
$("#local-player-mirror-area").show();
var mirrorPlayer = document.getElementById("local-player-mirror-video-track");
//get browser-native object MediaStreamTrack from WebRTC SDK
const msTrack = localTracks.videoTrack.getMediaStreamTrack();
//generate browser-native object MediaStream with above video track
const ms = new MediaStream([msTrack])
mirrorPlayer.srcObject = ms;
mirrorPlayer.play();
// publish local tracks to channel
await client.publish(Object.values(localTracks));
console.log("publish success");
}
}
async function leave() {
for (trackName in localTracks) {
var track = localTracks[trackName];
if (track) {
track.stop();
track.close();
localTracks[trackName] = undefined;
}
}
// remove remote users and player views
remoteUsers = {};
$("#remote-playerlist").html("");
// leave the channel
await client.leave();
$("#local-player-name").text("");
$("#host-join").attr("disabled", false);
$("#audience-join").attr("disabled", false);
$("#leave").attr("disabled", true);
$(".video-mirror").hide();
console.log("client leaves channel success");
}
async function subscribe(user, mediaType) {
const uid = user.uid;
// subscribe to a remote user
await client.subscribe(user, mediaType);
console.log("subscribe success");
if (mediaType === 'video') {
const player = $(`
<div id="player-wrapper-${uid}">
<p class="player-name">remoteUser(${uid})</p>
<div id="player-${uid}" class="player"></div>
<p class="player-name">Video Mirror</p>
<div id="player-${uid}-mirror-area" class="player" style="border: 2px dashed red ;">
<div style="width: 100%; height: 100%; position: relative; overflow: hidden; background-color: black;">
<video id="video_track-video-${uid}-mirror"
class="agora_video_player" playsinline="" muted=""
style="width: 100%; height: 100%; position: absolute; left: 0px; top: 0px; object-fit: contain;">
</video>
</div>
</div>
</div>
`);
$("#remote-playerlist").append(player);
user.videoTrack.play(`player-${uid}`, {fit:"contain"});
//handling the mirror video
$(`#player-${uid}-mirror-area`).show();
var mirrorRemotePlayer = document.getElementById(`video_track-video-${uid}-mirror`);
//get browser-native object MediaStreamTrack from WebRTC SDK
const msTrack = user.videoTrack.getMediaStreamTrack();
//generate browser-native object MediaStream with above video track
const ms = new MediaStream([msTrack])
mirrorRemotePlayer.srcObject = ms;
mirrorRemotePlayer.play();
}
if (mediaType === 'audio') {
user.audioTrack.play();
}
}
function handleUserPublished(user, mediaType) {
const id = user.uid;
remoteUsers[id] = user;
subscribe(user, mediaType);
}
function handleUserUnpublished(user, mediaType) {
if (mediaType === 'video') {
const id = user.uid;
delete remoteUsers[id];
$(`#player-wrapper-${id}`).remove();
}
}
改动点
新建一个配置页面,由用户进入房间时填写 AppId
,token
,channel
等
js
代码改动点:
options.appid = $("#appid").val();
options.token = $("#token").val();
options.channel = $("#channel").val();
options.uid = Number($("#uid").val());
blog link 音频房间创建及连接说明
Metadata
Metadata
Assignees
Labels
No labels