使用 IVS Web 廣播 SDK 發布和訂閱 - Amazon IVS

使用 IVS Web 廣播 SDK 發布和訂閱

本節將引導您完成使用 Web 應用程式發布和訂閱階段的相關步驟。

建立 HTML 樣板

首先,建立 HTML 樣板並將程式庫匯入為指令碼標籤:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <!-- Import the SDK --> <script src="https://web-broadcast.live-video.net/1.21.0/amazon-ivs-web-broadcast.js"></script> </head> <body> <!-- TODO - fill in with next sections --> <script src="./app.js"></script> </body> </html>

接受權杖輸入並新增加入/離開按鈕

在這裡用輸入控制填寫內文。這些做為輸入權杖,然後設定加入離開按鈕。通常,應用程式會透過您的應用程式 API 請求權杖,但在本範例中,您將複製權杖並將其貼至權杖輸入。

<h1>IVS Real-Time Streaming</h1> <hr /> <label for="token">Token</label> <input type="text" id="token" name="token" /> <button class="button" id="join-button">Join</button> <button class="button" id="leave-button" style="display: none;">Leave</button> <hr />

新增媒體容器元素

這些元素將為本機和遠端參與者保留媒體。新增了一個指令碼標籤,來載入 app.js 中定義的應用程式邏輯。

<!-- Local Participant --> <div id="local-media"></div> <!-- Remote Participants --> <div id="remote-media"></div> <!-- Load Script --> <script src="./app.js"></script>

這樣就完成了 HTML 頁面,並且您應在瀏覽器中載入 index.html 時看到此頁面:

在瀏覽器中檢視即時串流:HTML 設定完成。

建立 app.js

繼續來定義 app.js 檔案的內容。首先,透過 SDK 的全域匯入所有必要的屬性:

const { Stage, LocalStageStream, SubscribeType, StageEvents, ConnectionState, StreamType } = IVSBroadcastClient;

建立應用程式變數

建立變數來保留加入離開按鈕 HTML 元素的參考,以及存放應用程式的狀態:

let joinButton = document.getElementById("join-button"); let leaveButton = document.getElementById("leave-button"); // Stage management let stage; let joining = false; let connected = false; let localCamera; let localMic; let cameraStageStream; let micStageStream;

建立 joinStage 1:定義函數並驗證輸入

joinStage 函數採用輸入權杖,建立與階段的連線,並開始發布從 getUserMedia 中擷取的影片和音訊。

首先,定義函數並驗證狀態和權杖輸入。我們將在接下來的幾個部分完善此功能。

const joinStage = async () => { if (connected || joining) { return; } joining = true; const token = document.getElementById("token").value; if (!token) { window.alert("Please enter a participant token"); joining = false; return; } // Fill in with the next sections };

建立 JoinSage 2:取得要發布的媒體

以下是將在階段上發布的媒體:

async function getCamera() { // Use Max Width and Height return navigator.mediaDevices.getUserMedia({ video: true, audio: false }); } async function getMic() { return navigator.mediaDevices.getUserMedia({ video: false, audio: true }); } // Retrieve the User Media currently set on the page localCamera = await getCamera(); localMic = await getMic(); // Create StageStreams for Audio and Video cameraStageStream = new LocalStageStream(localCamera.getVideoTracks()[0]); micStageStream = new LocalStageStream(localMic.getAudioTracks()[0]);

建立 JoinSage 3:定義階段策略並建立階段

此階段策略是 SDK 用於決定發布內容,以及要訂閱哪些參與者的決策邏輯核心。如需函數用途的詳細資訊,請參閱策略

這項策略很簡單。加入階段後,發布剛剛擷取的串流,並訂閱每個遠端參與者的音訊和影片:

const strategy = { stageStreamsToPublish() { return [cameraStageStream, micStageStream]; }, shouldPublishParticipant() { return true; }, shouldSubscribeToParticipant() { return SubscribeType.AUDIO_VIDEO; } }; stage = new Stage(token, strategy);

建立 JoinSage 4:處理階段事件並轉譯媒體

階段會發出許多事件。我們需要監聽 STAGE_PARTICIPANT_STREAMS_ADDED 和 STAGE_PARTICIPANT_LEFT 來回轉譯和移除頁面中的媒體。更詳盡的事件集列於活動中。

請注意,我們在這裡建立了四個協助程式函數,來協助管理必要的 DOM 元素:setupParticipantteardownParticipantcreateVideoEl 和 createContainer

stage.on(StageEvents.STAGE_CONNECTION_STATE_CHANGED, (state) => { connected = state === ConnectionState.CONNECTED; if (connected) { joining = false; joinButton.style = "display: none"; leaveButton.style = "display: inline-block"; } }); stage.on( StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED, (participant, streams) => { console.log("Participant Media Added: ", participant, streams); let streamsToDisplay = streams; if (participant.isLocal) { // Ensure to exclude local audio streams, otherwise echo will occur streamsToDisplay = streams.filter( (stream) => stream.streamType === StreamType.VIDEO ); } const videoEl = setupParticipant(participant); streamsToDisplay.forEach((stream) => videoEl.srcObject.addTrack(stream.mediaStreamTrack) ); } ); stage.on(StageEvents.STAGE_PARTICIPANT_LEFT, (participant) => { console.log("Participant Left: ", participant); teardownParticipant(participant); }); // Helper functions for managing DOM function setupParticipant({ isLocal, id }) { const groupId = isLocal ? "local-media" : "remote-media"; const groupContainer = document.getElementById(groupId); const participantContainerId = isLocal ? "local" : id; const participantContainer = createContainer(participantContainerId); const videoEl = createVideoEl(participantContainerId); participantContainer.appendChild(videoEl); groupContainer.appendChild(participantContainer); return videoEl; } function teardownParticipant({ isLocal, id }) { const groupId = isLocal ? "local-media" : "remote-media"; const groupContainer = document.getElementById(groupId); const participantContainerId = isLocal ? "local" : id; const participantDiv = document.getElementById( participantContainerId + "-container" ); if (!participantDiv) { return; } groupContainer.removeChild(participantDiv); } function createVideoEl(id) { const videoEl = document.createElement("video"); videoEl.id = id; videoEl.autoplay = true; videoEl.playsInline = true; videoEl.srcObject = new MediaStream(); return videoEl; } function createContainer(id) { const participantContainer = document.createElement("div"); participantContainer.classList = "participant-container"; participantContainer.id = id + "-container"; return participantContainer; }

建立 JoinSage 5:加入階段

最終加入階段以完成 joinStage 函數!

try { await stage.join(); } catch (err) { joining = false; connected = false; console.error(err.message); }

建立 leaveStage

定義 leaveStage 離開按鈕將調用的函數。

const leaveStage = async () => { stage.leave(); joining = false; connected = false; };

初始化輸入事件處理常式

將新增一個最後的函數至 app.js 檔案。當載入頁面並建立事件處理常式以加入和離開階段時,會立即調用此函數。

const init = async () => { try { // Prevents issues on Safari/FF so devices are not blank await navigator.mediaDevices.getUserMedia({ video: true, audio: true }); } catch (e) { alert( "Problem retrieving media! Enable camera and microphone permissions." ); } joinButton.addEventListener("click", () => { joinStage(); }); leaveButton.addEventListener("click", () => { leaveStage(); joinButton.style = "display: inline-block"; leaveButton.style = "display: none"; }); }; init(); // call the function

執行應用程式並提供權杖

此時,您可以在本地或與其他人分享網頁,打開頁面,然後輸入參與者權杖並加入階段。

後續步驟?

有關 npm、React 等的更詳細範例,請參閱 IVS 廣播 SDK:網絡指南(即時串流指南)