Trong bài đăng trước, chúng ta đã học cách tạo một "sân khấu" ảo để tạo trải nghiệm trò chuyện video thời gian thực cho tối đa 12 người tham gia với Amazon Interactive Video Service (Amazon IVS). Là một tính năng độc lập, tính năng này khá mạnh mẽ và cho phép chúng tôi thêm tính năng cộng tác theo thời gian thực vào các ứng dụng của mình. Tuy nhiên, tính năng này được tạo để trao quyền cho các nhà phát triển dễ dàng tạo trải nghiệm phát trực tiếp cộng tác tương tự như tính năng "Ngôi sao khách" trên Twitch. Trong bài đăng này, chúng tôi sẽ xây dựng dựa trên bản demo trước để kết hợp nguồn cấp dữ liệu âm thanh và video từ tất cả những người tham gia vào một nguồn cấp dữ liệu duy nhất và phát nguồn cấp dữ liệu đó tới kênh Amazon IVS.
Nếu bạn chưa đọc bài đăng trước, bạn nên làm điều đó trước khi tiếp tục với bài đăng này. Tóm lại, trong bài đăng đó, chúng ta đã học cách:
Tạo tài nguyên giai đoạn với AWS SDK dành cho JavaScript (v3)
Tạo mã thông báo của người tham gia giai đoạn với AWS SDK cho JavaScript (v3)
Sử dụng Web Broadcast SDK để kết nối với sân khấu ảo để trò chuyện video theo thời gian thực giữa những người tham gia
Bước tiếp theo để tạo trải nghiệm phát trực tuyến cộng tác là kết hợp (hoặc "tổng hợp") cả người tham gia cục bộ và từ xa vào một luồng duy nhất có thể xuất bản lên kênh Amazon IVS. Đối với điều này, chúng tôi cũng có thể sử dụng Web Broadcast SDK, vì vậy hãy xem nó được thực hiện như thế nào.
Nếu bạn nhớ lại, trong bài đăng trước, chúng tôi đã có một số hàm được gọi bên trong trình xử lý DOMContentLoaded
cho phép cấp quyền, nhận thiết bị, định cấu hình phiên bản Stage
và xử lý việc tham gia giai đoạn. Chúng ta sẽ thêm một phương thức khác vào luồng này có tên là initBroadcastClient()
mà chúng ta có thể sử dụng để tạo một phiên bản của IVSBroadcastClient
. Chúng ta sẽ cần một phần tử <canvas>
trong phần đánh dấu của mình cho luồng kết hợp để những người tham gia có thể xem trước nội dung cuối cùng sẽ được phát lên kênh Amazon IVS.
const initBroadcastClient = async () => { broadcastClient = IVSBroadcastClient.create({ streamConfig: IVSBroadcastClient.STANDARD_LANDSCAPE, ingestEndpoint: '[YOUR INGEST ENDPOINT]', }); const previewEl = document.getElementById('broadcast-preview'); broadcastClient.attachPreview(previewEl); const bgImage = new Image(); bgImage.src = '/images/stage_bg.png'; broadcastClient.addImageSource(bgImage, 'bg-image', { index: 0 }); };
Để làm cho mọi thứ trông hấp dẫn hơn một chút, tôi đã sử dụng addImageSource()
để thêm hình nền vào luồng. Phương thức addImageSource()
nhận ba đối số: hình ảnh, tên duy nhất cho nguồn và đối tượng VideoComposition
được sử dụng để xác định index
(hoặc 'lớp') cho nguồn. Nếu bạn kiểm traVideoComposition
, bạn cũng sẽ lưu ý rằng nó có thể chứa các giá trị cho vị trí height
, width
, x
và y
của nguồn. Chúng tôi sẽ tận dụng các thuộc tính đó chỉ trong chốc lát khi chúng tôi thêm các lớp video của mình cho mỗi người tham gia.
Tiếp theo, chúng tôi sẽ thêm âm thanh và video cho từng người tham gia vào ứng dụng khách phát sóng. Chúng tôi sẽ thực hiện việc này bên trong trình xử lý StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED
mà chúng tôi đã xác định trong bài viết trước. Sửa đổi chức năng đó để thêm các cuộc gọi đến hai chức năng mới.
stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED, (participant, streams) => { renderParticipant(participant, streams); renderVideosToClient(participant, streams.find(s => s.streamType === StreamType.VIDEO)); renderAudioToClient(participant, streams.find(s => s.streamType === StreamType.AUDIO)); });
Bây giờ, hãy tạo hàm renderVideosToClient()
. Ở đây, tôi đang mã hóa VideoComposition
thành các giá trị thích hợp cho một người tham gia. Trong ứng dụng của mình, bạn sẽ muốn tính toán động các giá trị height
, width
, x
và y
tùy thuộc vào số lượng người dùng hiện đang tham gia vào cuộc trò chuyện.
const renderVideosToClient = async (participant, stream) => { const participantId = participant.id; const videoId = `video-${participantId}`; const composition = { index: 1, height: 984, width: 1750, x: 85, y: 48 }; const mediaStream = new MediaStream(); mediaStream.addTrack(stream.mediaStreamTrack); broadcastClient.addVideoInputDevice(mediaStream, videoId, composition); };
Hàm renderAudioToClient()
trông tương tự, nhưng sử dụng phương thức addAudioInputDevice()
của SDK để thêm rãnh âm thanh.
const renderAudioToClient = async (participant, stream) => { const participantId = participant.id; const audioTrackId = `audio-${participantId}`; const mediaStream = new MediaStream(); mediaStream.addTrack(stream.mediaStreamTrack); broadcastClient.addAudioInputDevice(mediaStream, audioTrackId) };
Tại thời điểm này, giai đoạn đã sẵn sàng để được phát tới một kênh bằng cách gọi broadcastClient.startBroadcast('[YOUR STREAM KEY]')
. Chúng tôi cũng sẽ cần xử lý việc xóa người tham gia khỏi broadcastClient
khi họ rời khỏi sân khấu. Đối với điều này, hãy cập nhật trình xử lý cho StageEvents.STAGE_PARTICIPANT_STREAMS_REMOVED
.
stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_REMOVED, (participant, streams) => { const videoTrackId = `video-${participant.id}`; const audioTrackId = `audio-${participant.id}`; if (broadcastClient.getVideoInputDevice(videoTrackId)) broadcastClient.removeVideoInputDevice(videoTrackId); if (broadcastClient.getAudioInputDevice(audioTrackId)) broadcastClient.removeAudioInputDevice(audioTrackId); const videoId = `${participant.id}-video` document.getElementById(videoId).closest('.participant-col').remove(); updateVideoCompositions(); // function not defined in demo, implementation will vary });
Đây là cách triển khai có thể trông như thế nào với một người tham gia. Lưu ý rằng mỗi người tham gia giai đoạn sẽ được hiển thị ở màn hình dưới cùng và chế độ xem tổng hợp sẽ được phát sóng được hiển thị ở trên.
Và khi nhiều người tham gia đã tham gia sân khấu ảo, ứng dụng sẽ điều chỉnh bố cục để phù hợp với từng người tham gia.
Khi người tham gia 'chủ nhà' nhấp vào nút 'Phát', cuộc trò chuyện được kết hợp sẽ được phát tới kênh Amazon IVS dưới dạng chế độ xem tổng hợp với tất cả âm thanh và video của người tham gia được kết hợp thành một luồng duy nhất.
Trong bài đăng này, chúng tôi đã tìm hiểu cách tạo luồng phát trực tiếp với âm thanh và video từ nhiều người tham gia từ xa. Trong một bài đăng trong tương lai, chúng ta sẽ kiểm tra các tùy chọn thay thế để tạo luồng tổng hợp và phát luồng đó tới kênh Amazon IVS.