Quick Start

Omnitalk SDK๋Š” ์‰ฝ๊ณ  ๊ฐ„ํŽธํ•˜๊ฒŒ webrtc ๊ธฐ์ˆ ์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ง„ ํŒจํ‚ค์ง€์ž…๋‹ˆ๋‹ค. Omnitalk SDK์˜ ๋ชจ๋“  API๋Š” async ~ await ๊ตฌ์กฐ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์š”์ฒญ์ด ์‹คํŒจํ•˜๋ฉด ์—๋Ÿฌ๋ฅผ throw ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ธ API ์‚ฌ์šฉ๋ฒ•์€ FLUTTER API Reference๋ฅผ ์ฐธ์กฐ๋ฐ”๋ž๋‹ˆ๋‹ค. 1:1 ํ†ตํ™”๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝœ ๊ธฐ๋Šฅ๊ณผ ๋‹ค์ž๊ฐ„ ํšŒ์˜์‹ค์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฃธ์„ ๊ตฌ๋ถ„ํ•˜์—ฌ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

1:1 ์Œ์„ฑ/์˜์ƒ ํ†ตํ™”

1. ์˜ด๋‹ˆํ†ก ๊ฐ์ฒด ์ƒ์„ฑ

๋ฐœ๊ธ‰๋ฐ›์€ Service Id์™€ Service Key๋กœ omnitalk ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. (Service Id์™€ Service Key๋Š” console ํŽ˜์ด์ง€์—์„œ ๋ฐœ๊ธ‰ ๊ฐ€๋Šฅํ•˜๋ฉฐ ๋…ธ์ถœ๋˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.)

import 'package:omnitalk_sdk/omnitalk_sdk.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';

Omnitalk.sdkInit(
        serviceId: 'Service ID', serviceKey: 'Service KEY');
Omnitalk sdk = Omnitalk.getInstance();

2. ์„ธ์…˜ ์ƒ์„ฑ

์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ user_id์˜ ์„ธ์…˜์„ ์ƒ์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. user_id ์ƒ๋žต์‹œ Omnitalk ์„œ๋ฒ„์—์„œ ์ž„์˜์˜ id๋ฅผ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.

await sdk.createSession();

3. 1:1 ์Œ์„ฑ ํ†ตํ™”

1:1 ์Œ์„ฑ ํ†ตํ™”๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐœ์‹  ๊ธฐ๋Šฅ์€ offerCall API๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์˜ˆ์‹œ๋Š” Dev guide์˜ audio call ํ•ญ๋ชฉ์„ ์ฐธ์กฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. call flow๋Š” ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐ๋ฐ”๋ž๋‹ˆ๋‹ค.

3.1 ๋ฐœ์‹ 

์„ธ์…˜์ด ๋งŒ๋“ค์–ด์ง„ ์ƒํƒœ์—์„œ call type๊ณผ ์ฐฉ์‹  ์ƒ๋Œ€๋ฐฉ์ธ callee์˜ user_id๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. offerCall ํ˜ธ์ถœ์ด ์„ฑ๊ณตํ•˜๋ฉด caller์—๊ฒŒ๋Š” RINGBACK_EVENT๊ฐ€, callee์—๊ฒŒ๋Š” RINGING_EVENT๊ฐ€ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

String callee = '[email protected]';
await sdk.offerCall(
    callType: CallType.audiocall, 
    callee : callee); //๋ฐœ์‹ ์ธก

3.2 ์ˆ˜์‹ 

callee์ธก์ด answerCall์„ ํ˜ธ์ถœํ•˜๋ฉด caller, caller ์–‘์ธก์€ CONNECTED_EVENT๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ์Œ์„ฑํ†ตํ™”๊ฐ€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. callee๋Š” leave API๋ฅผ ์ด์šฉํ•˜์—ฌ ์ˆ˜์‹ ๊ฑฐ์ ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

String callerSession = '';

sdk.on('event', (dynamic msg) async {
       switch (msg["cmd"]) {
        case "RINGING_EVENT":
          callerSession = msg['session']
          break;
      }
    }
  );

await sdk.answerCall();  // ์ฐฉ์‹ ์ธก

await sdk.leave(session: callerSession); // ์ˆ˜์‹  ๊ฑฐ์ ˆ

4. 1:1 ์˜์ƒ ํ†ตํ™”

1:1 ์˜์ƒ ํ†ตํ™”๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐœ์‹  ๊ธฐ๋Šฅ์€ offerCall API๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์˜ˆ์‹œ๋Š” Dev guide์˜ video call ํ•ญ๋ชฉ์„ ์ฐธ์กฐ ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. call flow๋Š” ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐ ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์„ธ์…˜์ด ๋งŒ๋“ค์–ด์ง„ ์ƒํƒœ์—์„œ call type๊ณผ ์ฐฉ์‹  ์ƒ๋Œ€๋ฐฉ์ธ callee์˜ user_id, ๊ทธ๋ฆฌ๊ณ  caller, callee์˜ ์˜์ƒ์„ ๋‹ด์„ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. offerCall ํ˜ธ์ถœ์ด ์„ฑ๊ณตํ•˜๋ฉด caller์—๊ฒŒ๋Š” RINGBACK_EVENT๊ฐ€, callee์—๊ฒŒ๋Š” RINGING_EVENT๊ฐ€ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

String callee = '[email protected]'
RTCVideoRenderer localvideo = RTCVideoRenderer();
RTCVIdeoRenderer remotevideo = RTCVideoRenderer();

await sdk.offerCall(
    callType:  CallType.videocall, 
    callee: callee, 
    record: false, 
    localRenderer: localVideo, 
    remoteRenderer: remoteVideo
    );

์ฐฉ์‹ ์ธก์€ RINGING_EVENT๋ฅผ ๋ฐ›๊ณ  answerCall API๋ฅผ ์ด์šฉํ•ด ํ†ตํ™”๋ฅผ ์ˆ˜๋ฝํ•˜๊ฑฐ๋‚˜ leave API๋ฅผ ์ด์šฉํ•ด ๊ฑฐ์ ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

String caller = '';
String callerSession = '';
RTCVideoRenderer localvideo = RTCVideoRenderer();
RTCVIdeoRenderer remotevideo = RTCVideoRenderer();

sdk.on('event', (dynamic msg) async {
       switch (msg["cmd"]) {
        case "RINGING_EVENT":
          callerSession = msg['session']
          caller = msg['caller']
          break;
      }
    }
  );

await sdk.answerCall(
    callType: CallType.videocall, 
    caller: caller, 
    localRenderer: localVideo, 
    remoteRenderer: remoteVideo
    );

๋‹ค์ž๊ฐ„ ํšŒ์˜

1. ์˜ด๋‹ˆํ†ก ๊ฐ์ฒด ์ƒ์„ฑ

๋ฐœ๊ธ‰๋ฐ›์€ Service Id์™€ Service Key๋กœ omnitalk ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. (Service Id์™€ Service Key๋Š” console ํŽ˜์ด์ง€์—์„œ ๋ฐœ๊ธ‰ ๊ฐ€๋Šฅํ•˜๋ฉฐ ๋…ธ์ถœ๋˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.)

import 'package:omnitalk_sdk/omnitalk_sdk.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';

Omnitalk.sdkInit(
        serviceId: 'Service ID', serviceKey: 'Service KEY');
Omnitalk sdk = Omnitalk.getInstance();

2. ์„ธ์…˜ ์ƒ์„ฑ

์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ user_id์˜ ์„ธ์…˜์„ ์ƒ์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. user_id ์ƒ๋žต์‹œ Omnitalk ์„œ๋ฒ„์—์„œ ์ž„์˜์˜ id๋ฅผ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.

await sdk.createSession();

3. ๋ฃธ ์ƒ์„ฑ

์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ ๋ฃธ ํƒ€์ž…์˜ ๋ฐฉ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. (RoomType.videoroom | RoomType.audioroom)

var roomResult = await sdk.createRoom(roomType: RoomType.videoroom);

4. ๋ฃธ ์ฐธ์—ฌ

๋ฃธ์— ์ฐธ์—ฌํ•˜๊ฒŒ ๋˜๋ฉด ์ž๋™์œผ๋กœ ์˜ค๋””์˜ค ๋ฐฉ์†ก์„ ์‹œ์ž‘ํ•˜๊ณ  ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

String roomId = roomResult['room_id'];
await sdk.joinRoom(roomId :roomId);

5. ๋ฐฉ์†ก ์‹œ์ž‘ (video)

์˜ค๋””์˜ค ๋ฐฉ์†ก์€ ๋ฃธ์— ์ฐธ์—ฌํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ์‹œ์ž‘ ๊ฐ€๋Šฅํ•˜๋ฉฐ ์˜์ƒ ๋ฐฉ์†ก์€ ์ž์‹ ์˜ ๋ฐฉ์†ก ์˜์ƒ ์ŠคํŠธ๋ฆผ์„ ๋‹ด์„ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•ด ๋ฐฉ์†ก์„ ๋ฐœํ–‰ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. publish APIํ˜ธ์ถœ์ด ์„ฑ๊ณตํ•˜๋ฉด ํ•ด๋‹น ๋ฐฉ์†ก์˜ ์„ธ์…˜ id๊ฐ€ ๋‹ด๊ธด ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ด ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

RTCVideoRenderer localvideo = RTCVideoRenderer();

await sdk.publish(localRenderer: localVideo);

6. ๋ฐฉ์†ก ๊ตฌ๋…(video)

๊ตฌ๋…ํ•˜๊ณ ์ž๋Š” ๋ฐฉ์†ก์˜ session์„ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋ฉด ํ•ด๋‹น ๋ฐฉ์†ก์„ ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฃธ์—์„œ ๋ฐฉ์†ก์„ ๊ฐœ์‹œํ•œ ์‚ฌ์šฉ์ž์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์กฐํšŒ(publishList API)ํ•˜๊ฑฐ๋‚˜ BROADCASTING_EVENT์˜ ์ด๋ฒคํŠธ ๋ฉ”์‹œ์ง€์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

await sdk.subscribe(
    publisherSession: publisherSession, 
    remoteRenderer: remoteVideo);

7. ์ด๋ฒคํŠธ ๋ฉ”์‹œ์ง€ ์ˆ˜์‹ 

์˜ด๋‹ˆํ†ก SDK์—์„œ ์ „๋‹ฌํ•˜๋Š” ์ด๋ฒคํŠธ ๋ฉ”์‹œ์ง€ ๊ทœ๊ฒฉ๊ณผ ๋ฉ”์‹œ์ง€ ์ˆ˜์‹  ๋ฐฉ๋ฒ•์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋ฐฉ์†ก ์ด๋ฒคํŠธ ๋ฐœ์ƒ์‹œ ๋ฐฉ์†ก ์„ธ์…˜์„ ์ €์žฅํ•˜๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

sdk.on('event', (dynamic event) async {
      var msg = event;
      switch (msg["cmd"]) {
        case "BROADCASTING_EVENT":
          setState(() {
            publisherSession = msg['session'];
          });
          print('publisherSession : $publisherSession');
          break;
        case "CONNECTED_EVENT":
          print('Audio Connected');
          break;
        case "LEAVE_EVENT":
          print('${msg['session']} has left');
          break;
      }
    });

8. ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€

์–ด๋–ค ํƒ€์ž…์ด๋“  ๋ฃธ์— ์ฐธ์—ฌํ•˜๊ฒŒ ๋˜๋ฉด ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. sendMessage API๋ฅผ ์ด์šฉํ•˜์—ฌ action type์„ ๋ช…์‹œํ•˜๋ฉด ๋ฃธ ์ „์ฒด์— ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก ๋ฐ ํŠน์ • ์ƒ๋Œ€๋กœ์˜ ๊ท“์†๋ง ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ท“์†๋ง์€ ์ƒ๋Œ€์˜ session id๋ฅผ target ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

await sdk.sendMessage(action: MessageAction.send, message: msg); // ๋ฃธ ์ „์ฒด ๋ฉ”์‹œ์ง€ ์ „์†ก
await sdk.sendMessage(
   action : MessageAction.whisper,
   message : whispermsg,
   target : target,
   );  // ํŠน์ • ์ƒ๋Œ€์— ๊ท“์†๋ง ๋ฉ”์‹œ์ง€ ์ „์†ก

9. ๋ฐฉ์†ก ์ข…๋ฃŒ

๋ฐฉ์†ก์„ ์ข…๋ฃŒํ•˜๋Š” API์ž…๋‹ˆ๋‹ค. ์ข…๋ฃŒ์‹œํ‚ค๊ณ  ์‹ถ์€ session id๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ์ˆ˜์‹  ๊ฑฐ์ ˆ์ด๋‚˜ ๊ฐ•์ œ ํ‡ด์žฅ ๋“ฑ์˜ ๊ธฐ๋Šฅ์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. session์„ ์ „๋‹ฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ž์‹ ์˜ ๋ฐฉ์†ก์„ ์ข…๋ฃŒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

await sdk.leave();

Last updated