AWS IVS의 장점이라고 생각되는 부분은 Player, Chat, Broadcast가 각각 독립적이라는 점이다.
우리는 AWS IVS가 제공하는 SDK를 보면 다음과 같다.

크게 3가지 SDK 를 제공하는데 Player, Chat, Broadcast 이다. 사용해보면 각각 SDK 가 독립적이라 만약 aws ivs의 Player만 사용하고 Chat은 다른 플랫폼을 사용할거야! 라고 해도 문제가 되지 않는다.
우리 서비스는 모두 aws ivs를 사용했다. 다른 chat 플랫폼을 사용했을 때 이점을 찾지 못했기 때문이다.
하나씩 구현과정을 살펴보자.
이번 포스팅에서는 Broadcast를 구현해보자!!
공식홈페이지를 기준으로 설명하겠다.
npm install amazon-ivs-web-broadcast
먼저 sdk를 설치해준다.
const client = IVSBroadcastClient.create({
// Enter the desired stream configuration
streamConfig: IVSBroadcastClient.BASIC_LANDSCAPE,
// Enter the ingest endpoint from the AWS console or CreateChannel API
ingestEndpoint: 'UNIQUE_ID.global-contribute.live-video.net',
});
Stream에 연결하는건 간단하다. 다음과 같이 streamConfig와 ingestEndpoint를 넣어주면된다.
streamConfig는 stream에 관련된 설정사항을, ingestEndpoint에는 해당 스트리밍 채널의 엔드포인트 값을 넣어주면된다.
const client = IVSBroadcastClient.create({
// Enter the custom stream configuration
streamConfig: {
maxResolution: {
width: 1080,
height: 1920,
},
maxFramerate: 30,
/**
* maxBitrate is measured in kbps
*/
maxBitrate: 3500,
},
// Other configuration . . .
});
디테일한 스트리밍 설정이 가능하다.
일단 방송을 하려는 디바이스에 audio와 video에 대한 허용이 필요하다.
async function handlePermissions() {
let permissions = {
audio: false,
video: false,
};
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
for (const track of stream.getTracks()) {
track.stop();
}
permissions = { video: true, audio: true };
} catch (err) {
permissions = { video: false, audio: false };
console.error(err.message);
}
// If we still don't have permissions after requesting them display the error message
if (!permissions.video) {
console.error('Failed to get video permissions.');
} else if (!permissions.audio) {
console.error('Failed to get audio permissions.');
}
}
그리고 방송을 시작하는 코드는 아까 전에 생성한 client를 가지고 방송을 시작하자
client
.startBroadcast(streamKey)
.then((result) => {
console.log('I am successfully broadcasting!');
})
.catch((error) => {
console.error('Something drastically failed while broadcasting!', error);
});
// 일부코드
const [facingMode, setFacingMode] = React.useState<'user' | 'enviroment'>('user');
// 카메라 오디오 허용
async function handlePermissions() {
let permissions = {
audio: false,
video: false,
};
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
for (const track of stream.getTracks()) {
track.stop();
}
permissions = { video: true, audio: true };
} catch (err: any) {
permissions = { video: false, audio: false };
console.error(err.message);
}
if (!permissions.video) {
console.error('Failed to get video permissions.');
} else if (!permissions.audio) {
console.error('Failed to get audio permissions.');
}
}
useEffect(() => {
handlePermissions();
const setupBroadcast = async () => {
if (typeof window === 'undefined') return;
const { default: IVSBroadcastClient }: any = await import('amazon-ivs-web-broadcast');
const client = IVSBroadcastClient.create({
streamConfig: IVSBroadcastClient.BASIC_LANDSCAPE,
ingestEndpoint: '엔드포인트',
});
const previewEl = document.getElementById('preview') as HTMLCanvasElement;
if (previewEl) {
client.attachPreview(previewEl);
}
const devices = await navigator.mediaDevices.enumerateDevices();
let stream;
if (!isMobile) {
// 💻 PC에서는 DroidCam 사용
const videoDevices = devices.filter(d => d.label === 'DroidCam Video');
if (videoDevices.length > 0) {
stream = await navigator.mediaDevices.getUserMedia({
video: { deviceId: { exact: videoDevices[0].deviceId } },
audio: true,
});
client.addVideoInputDevice(stream, 'camera', { index: 0 });
} else {
console.warn('DroidCam not found, using default camera');
}
} else {
// 📱 모바일에서는 기본 전면 카메라 사용
stream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: { ideal: facingMode } },
audio: true,
});
client.addVideoInputDevice(stream, 'camera', { index: 0 });
}
startBroadcastRef.current = () => {
client
.startBroadcast('스트림 키')
.then(() => {
console.log('I am successfully broadcasting!');
})
.catch(error => {
console.error('Broadcast failed!', error);
});
};
stopBroadcastRef.current = () => {
client.stopBroadcast();
console.log('방송 멈춤!');
};
};
setupBroadcast();
}, []);

결과적으로 이런 캠을 띄우고 방송을 시작하고 멈출 수 있다.