paint-brush
Cách tạo bố cục động cho truyền phát nhiều máy chủ với Amazon IVStừ tác giả@amazonivs
2,313 lượt đọc
2,313 lượt đọc

Cách tạo bố cục động cho truyền phát nhiều máy chủ với Amazon IVS

từ tác giả Amazon Interactive Video Service (IVS) 6m2023/06/27
Read on Terminal Reader

dài quá đọc không nổi

Trong bài đăng trước, chúng ta đã xem cách tạo ứng dụng trò chuyện trực tiếp nhiều máy chủ với Amazon Interactive Video Service (Amazon IVS) Trong bài đăng đó, tôi đã gian lận một chút và mã hóa cứng các giá trị cho ứng dụng khách phát sóng biết kích thước và vị trí của người tham gia video trên máy khách. Chúng ta sẽ xem xét một cách tiếp cận mà bạn có thể sử dụng để tạo bố cục động dễ dàng hơn một chút.
featured image - Cách tạo bố cục động cho truyền phát nhiều máy chủ với Amazon IVS
Amazon Interactive Video Service (IVS)  HackerNoon profile picture

Gần đây, tôi đã viết một số bài đăng về luồng trực tiếp nhiều máy chủ với Dịch vụ video tương tác của Amazon (Amazon IVS). Đây là một tính năng thú vị giúp mở ra nhiều khả năng mà mãi đến gần đây mới có. Đầu tiên chúng ta xem cách tạo ứng dụng trò chuyện trực tiếp nhiều máy chủ .


Tiếp theo, chúng ta đã xem cách phát phiên trò chuyện trực tiếp đó tới kênh Amazon IVS.


Khi chúng tôi xem xét việc thêm người tham gia trò chuyện vào ứng dụng khách phát sóng trong bài đăng cuối cùng đó, bạn có thể nhận thấy rằng tôi đã gian lận một chút và mã hóa cứng các giá trị VideoComposition cho ứng dụng khách phát sóng biết kích thước và vị trí của video của người tham gia trên ứng dụng khách.


Chà - bị lừa là một từ mạnh - giả sử rằng tôi cố ý đơn giản hóa mã để tập trung vào quá trình phát một phiên trò chuyện trực tiếp.


Về cơ bản, những gì chúng tôi đang tìm kiếm ở đây là sửa đổi kích thước và vị trí của video của người tham gia trong chương trình phát sóng để khi có một video, bố cục sẽ giống như sau:



Nhưng khi có hai video, bố cục sẽ thay đổi thành như thế này:



Và khi có năm:



Bạn có ý tưởng - bố cục động thay đổi dựa trên số lượng người tham gia.


Trong bài đăng này, chúng ta sẽ xem xét một cách tiếp cận mà bạn có thể sử dụng để tạo bố cục động dễ dàng hơn một chút. Chúng tôi sẽ xây dựng giải pháp trong bài đăng trước, vì vậy nếu bạn chưa đọc bài đăng đó, có lẽ bạn nên làm điều đó ngay bây giờ.


Trong bài đăng trước, chúng tôi đã theo dõi sự kiện có tên STAGE_PARTICIPANT_STREAMS_ADDED . Trong trình xử lý sự kiện cho sự kiện đó, chúng tôi đã thêm người tham gia vào DOM và hiển thị âm thanh và video cho phiên bản IVSBroadcastClient .


Để hiển thị bố cục động, chúng tôi sẽ cần theo dõi có bao nhiêu người tham gia hiện đang tham gia phiên, vì vậy chúng tôi sẽ thêm một mảng có tên là participantIds làm biến toàn cục. Hãy sửa đổi trình xử lý sự kiện để đẩy id người tham gia hiện tại vào mảng đó.


 stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED, (participant, streams) => { //add participant id to array participantIds.push(participant.id); renderParticipant(participant, streams); renderVideosToClient(participant, streams.find(s => s.streamType === StreamType.VIDEO)); renderAudioToClient(participant, streams.find(s => s.streamType === StreamType.AUDIO)); updateVideoCompositions(); });


Trong bài đăng trước, tôi đã đề cập rằng phương thức updateVideoCompositions() không được hiển thị vì cách triển khai sẽ thay đổi. Chúng ta sẽ nói về một triển khai khả thi trong giây lát.


Bây giờ, chúng ta hãy xem làm thế nào chúng ta có thể có được một cấu hình bố cục động thay vì mã hóa cứng nó như chúng ta đã làm trong bài đăng trước.


Một cách để có được kích thước và vị trí động là lặp qua mảng người tham gia và tính toán chúng dựa trên số lượng người tham gia, kích thước của <canvas> và số lượng hàng, cột và phần đệm mong muốn. Nhưng, tại sao ?


Điều đó nghe có vẻ giống như rất nhiều mã khó và công việc không cần thiết khi bạn nhận ra rằng những giá trị này không bao giờ thay đổi. Nếu bạn có một người tham gia, video sẽ có kích thước cố định và được căn giữa trong <canvas> .


Việc thêm bao nhiêu người tham gia không quan trọng - bố cục cho mỗi video sẽ luôn giống nhau đối với một số lượng người tham gia nhất định. Vậy tại sao phải lãng phí thời gian và chu kỳ CPU khi chúng ta có thể tính toán trước các giá trị này và lưu trữ chúng trong một mảng các mảng?


Đối với bản trình diễn của mình, tôi đã dành một chút thời gian để xác định các giá trị tốt nhất trong 30 phút chuyên sâu bằng bút, giấy và máy tính để xác định các giá trị bố cục cho từng bố cục có thể. Xin lưu ý: Tôi không phải là sinh viên chuyên ngành toán học hay nghệ thuật, bằng chứng là bản phác thảo sau đây.



Đối với bản demo này, tôi đã giới hạn luồng trực tiếp của mình khi chỉ hiển thị video cho 6 người tham gia đầu tiên. Trường hợp sử dụng của bạn có thể quyết định điều gì đó khác biệt, nhưng theo kinh nghiệm của tôi, việc có nhiều hơn 6 video của người tham gia trong một luồng trực tiếp trở nên quá bận rộn.


Đây là kết quả tính toán của tôi:


 const layouts = [ [{ height: 720, width: 1280, x: 320, y: 180 }], [{ height: 450, width: 800, x: 80, y: 315 }, { height: 450, width: 800, x: 1040, y: 315 }], [{ height: 450, width: 800, x: 80, y: 45 }, { height: 450, width: 800, x: 1040, y: 45 }, { height: 450, width: 800, x: 560, y: 585 }], [{ height: 450, width: 800, x: 80, y: 45 }, { height: 450, width: 800, x: 1040, y: 45 }, { height: 450, width: 800, x: 80, y: 585 }, { height: 450, width: 800, x: 1040, y: 585 }], [{ height: 337, width: 600, x: 20, y: 100 }, { height: 337, width: 600, x: 650, y: 100 }, { height: 337, width: 600, x: 1280, y: 100 }, { height: 337, width: 600, x: 340, y: 640 }, { height: 337, width: 600, x: 980, y: 640 }], [{ height: 337, width: 600, x: 20, y: 100 }, { height: 337, width: 600, x: 650, y: 100 }, { height: 337, width: 600, x: 1280, y: 100 }, { height: 337, width: 600, x: 20, y: 640 }, { height: 337, width: 600, x: 650, y: 640 }, { height: 337, width: 600, x: 1280, y: 640 }] ];


Điều đó có vẻ quá sức, nhưng hãy cân nhắc rằng mỗi phần tử trong phần tử mảng bên ngoài chứa một mảng bố cục cho mỗi video.


Nếu có 3 người tham gia, chúng tôi có thể tham chiếu phần tử thứ ba trong mảng bên ngoài và vị trí của id người tham gia trong mảng participantIds sẽ xác định bố cục nào sẽ áp dụng cho video đó.


Chúng tôi có thể sửa đổi hàm renderVideosToClient() của mình để lấy thành phần phù hợp và sử dụng các giá trị đó khi chúng tôi thêm video vào ứng dụng khách phát sóng.


 const renderVideosToClient = async (participant, stream) => { const participantId = participant.id; const videoId = `video-${participantId}`; // get the index of this participantId const pIdx = participantIds.indexOf(participantId); let composition = layouts[participantIds.length - 1][pIdx]; config.index = 2; const mediaStream = new MediaStream(); mediaStream.addTrack(stream.mediaStreamTrack); broadcastClient.addVideoInputDevice(mediaStream, videoId, composition); };


Nhưng hãy nhớ - nếu chúng tôi chỉ làm điều này khi một người tham gia được thêm vào, các bố cục video trước đó sẽ vẫn phản ánh bố cục được áp dụng khi chúng được thêm vào. Đó là nơi hàm updateVideoCompositions() xuất hiện.


Ở đây, chúng tôi lặp lại mảng participantIds , lấy thành phần phù hợp từ layouts và sử dụng updateVideoDeviceComposition() ( tài liệu ) phương thức của broadcastClient .


 const updateVideoCompositions = async () => { let idx = 0; for (const p of participantIds) { const videoId = `video-${p}`; let config = layouts[filteredParticipantIds.length - 1][idx]; config.index = 2; broadcastClient.updateVideoDeviceComposition(videoId, config); idx = idx + 1; } };


Chúng tôi cũng nên đảm bảo rằng khi một người tham gia rời khỏi sân khấu, chúng tôi sẽ xóa id người tham gia khỏi mảng và cập nhật lại bố cục cho tất cả các video.


 stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_REMOVED, (participant, streams) => { const participantId = participant.id; // remove participant id from array const pIdx = participantIds.findIndex(id => id === participantId); participantIds.splice(pIdx, 1); const videoTrackId = `video-${participantId}`; const audioTrackId = `audio-${participantId}`; if (broadcastClient.getVideoInputDevice(videoTrackId)) broadcastClient.removeVideoInputDevice(videoTrackId); if (broadcastClient.getAudioInputDevice(audioTrackId)) broadcastClient.removeAudioInputDevice(audioTrackId); const videoId = `${participantId}-video`; document.getElementById(videoId).closest('.participant-col').remove(); updateVideoCompositions(); });


Như đã đề cập ở trên, rất có thể bạn sẽ muốn giới hạn số lượng video được thêm vào luồng trực tiếp thông qua ứng dụng phát sóng. Bạn có thể muốn thêm một hình ảnh tĩnh thay vì video cuối cùng để cho thấy rằng có nhiều người tham gia hơn những gì được hiển thị:


Bản tóm tắt

Trong bài đăng này, chúng ta đã học được một cách tiếp cận bố cục động khi phát giai đoạn nhiều máy chủ với Amazon IVS. Trong một bài đăng trong tương lai, chúng tôi sẽ xem xét các tùy chọn bổ sung để phát sóng với nhiều máy chủ. Như mọi khi, nếu bạn có bất kỳ câu hỏi hoặc nhận xét nào, vui lòng để lại bên dưới.


Cũng được xuất bản ở đây