پخش زنده با میزبان های متعدد از طریق یک مرورگر با آمازون IVS

در آخرین پست ما [todo: link]، ما یاد گرفتیم که چگونه یک “مرحله” مجازی برای ایجاد یک تجربه چت ویدیویی در زمان واقعی برای حداکثر 12 شرکت کننده با سرویس ویدئوی تعاملی آمازون (Amazon IVS) ایجاد کنیم. به عنوان یک ویژگی مستقل، بسیار قدرتمند است و ما را قادر می سازد تا همکاری بلادرنگ را به برنامه های خود اضافه کنیم. با این حال، این ویژگی برای توانمندسازی توسعه دهندگان ایجاد شده است تا به راحتی تجربیات پخش زنده مشترکی شبیه به ویژگی «ستاره مهمان» در Twitch ایجاد کنند. در این پست، ما از نسخه آزمایشی قبلی استفاده میکنیم تا فیدهای صوتی و تصویری همه شرکتکنندگان را در یک فید واحد ترکیب کنیم و آن را در یک کانال IVS آمازون پخش کنیم.
اگر هنوز پست قبلی را نخوانده اید، باید قبل از ادامه این پست این کار را انجام دهید. برای جمع بندی، در آن پست یاد گرفتیم که چگونه:
- یک منبع مرحله با AWS SDK برای جاوا اسکریپت (v3) ایجاد کنید
- با AWS SDK برای جاوا اسکریپت (v3) توکنهای شرکتکننده در مرحله ایجاد کنید.
- از Web Broadcast SDK برای اتصال به مرحله مجازی برای چت ویدیویی بیدرنگ بین شرکتکنندگان استفاده کنید
گام بعدی برای ایجاد یک تجربه پخش زنده مشترک، ترکیب (یا “ترکیب”) هر دو شرکت کننده محلی و راه دور در یک جریان واحد است که می تواند در یک کانال IVS آمازون منتشر شود. برای این ما همچنین می توانیم از Web Broadcast SDK استفاده کنیم، بنابراین بیایید ببینیم چگونه انجام می شود.
ایجاد یک سرویس گیرنده پخش
اگر به خاطر داشته باشید، در آخرین پست ما چندین توابع به نام داخل a داشتیم DOMContentLoaded
کنترل کننده ای که مجوزها را فعال می کند، دستگاه ها را به دست می آورد، پیکربندی می کند Stage
به عنوان مثال، و با پیوستن به صحنه. یک روش دیگر به این جریان اضافه می کنیم که نام دارد initBroadcastClient()
که می توانیم برای ایجاد یک نمونه از آن استفاده کنیم IVSBroadcastClient
. ما به a نیاز خواهیم داشت <canvas>
عنصری در نشانه گذاری ما برای جریان ترکیبی به طوری که شرکت کنندگان ما بتوانند پیش نمایش آنچه در نهایت در کانال 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 });
};
برای اینکه چیزها از نظر بصری کمی جذاب تر شوند، از آن استفاده کرده ام addImageSource()
برای اضافه کردن یک تصویر پس زمینه به جریان. را addImageSource()
متد سه آرگومان دریافت می کند: تصویر، یک نام منحصر به فرد برای منبع، و a VideoComposition
شی که برای تعریف استفاده می شود index
(یا “لایه”) برای منبع. اگر اسناد را برای VideoComposition
، همچنین توجه داشته باشید که می تواند حاوی مقادیری باشد height
، width
، x
، و y
موقعیت برای منبع زمانی که لایههای ویدیویی خود را برای هر شرکتکننده اضافه میکنیم، در مدت کوتاهی از آن ویژگیها استفاده خواهیم کرد.
افزودن صدا و تصویر مشارکت کننده به مشتری پخش
در مرحله بعد، ما می خواهیم صدا و تصویر را برای هر شرکت کننده به سرویس گیرنده پخش اضافه کنیم. ما این کار را در داخل StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED
هندلری که در پست قبل تعریف کردیم. برای افزودن تماس به دو عملکرد جدید، آن عملکرد را تغییر دهید.
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));
});
حالا بیایید ایجاد کنیم renderVideosToClient()
تابع. در اینجا، من در حال کدگذاری سخت هستم VideoComposition
به مقادیر مناسب برای یک شرکت کننده واحد. در برنامه خود، باید به صورت پویا محاسبه کنید height
، width
، x
، و y
مقادیر بسته به تعداد کاربرانی که در حال حاضر در گفتگو شرکت می کنند.
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);
};
را renderAudioToClient()
تابع به نظر شبیه است، اما از آن استفاده می کند addAudioInputDevice()
روش SDK برای افزودن تراک صوتی.
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)
};
در این مرحله استیج با تماس آماده پخش برای یک کانال است broadcastClient.startBroadcast('[YOUR STREAM KEY]')
. ما همچنین باید حذف شرکتکنندگان را از آن انجام دهیم broadcastClient
وقتی صحنه ای را ترک می کنند برای این کار، کنترل کننده را به روز کنید 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
});
در اینجا نحوه اجرا با یک شرکتکننده به نظر میرسد. توجه داشته باشید که هر شرکت کننده مرحله در صفحه پایین نشان داده می شود، و نمای ترکیبی برای پخش در بالا نشان داده شده است.
و زمانی که چندین شرکتکننده به مرحله مجازی ملحق شدند، برنامه طرحبندی را طوری تنظیم میکند که هر شرکتکننده را در خود جای دهد.
وقتی شرکتکننده «میزبان» روی دکمه «پخش» کلیک میکند، مکالمه ترکیبی به کانال IVS آمازون بهعنوان یک نمای ترکیبی با همه شرکتکنندگان صدا و ویدیو در یک جریان واحد پخش میشود.
خلاصه
در این پست، نحوه ایجاد یک پخش زنده با صدا و تصویر از چندین شرکت کننده از راه دور را یاد گرفتیم. در یک پست آینده، گزینه های جایگزین برای ایجاد جریان ترکیبی و پخش آن به یک کانال IVS آمازون را بررسی خواهیم کرد.