# Omnitalk SDK

환영합니다. Omnitalk SDK의 문서 페이지입니다.

모든 언어에 공통으로 적용되는 부분은 [**Commons**](/commons/precondition)에서 확인 할 수 있습니다.

언어별 레퍼런스는 해당 언어의 섹션을 참고해 주세요.&#x20;

#### ✔️ Javascript

&#x20;   \- [API Reference ](/javascript/api-reference)| [github repository](https://github.com/omnistory-labs/omnitalk.sdk)

#### ✔️ Typescript

&#x20;   \- [API Reference](https://docs.omnitalk.io/typescript/api-reference) | [github repository](https://github.com/omnistory-labs/omnitalk.sdk)

#### ✔️ iOS

&#x20;   \- [API Reference](/ios/api-reference) | [github repository](https://github.com/omnistory-labs/omnitalk.ios.sdk)

#### ✔️ Android

&#x20;   -[ API Reference](https://docs.omnitalk.io/android/api-reference) | [github repository](https://github.com/omnistory-labs/omnitalk.android.sdk)

#### ✔️ Flutter

&#x20;   \- [API Reference](/react-native/api-reference) | [github repository](https://github.com/omnistory-labs/omnitalk.flutter.sdk)

#### ✔️ React-native

&#x20;   \- [API Reference](/react-native/api-reference)[ ](/react-native/api-reference)| [github repository](https://github.com/omnistory-labs/omnitalk.react-native.sdk)


# Precondition

옴니톡 SDK 개발을 진행하기 위해서는 아래 선행 작업을 수행해야 합니다.

### 회원 가입

<table><thead><tr><th width="145">구분</th><th>설명</th></tr></thead><tbody><tr><td>가입요건</td><td>기업,스타트업 또는 예비창업자</td></tr><tr><td>승인절차</td><td>증빙 서류 확인 및 필요시 상담 후 승인</td></tr><tr><td>승인기간</td><td>영업일 기준 최대 2일 이내</td></tr></tbody></table>

### **Service ID 및 Key 발급**

<table><thead><tr><th width="146">구분</th><th>설명</th></tr></thead><tbody><tr><td>발급 방법</td><td>회원 승인 후 관리자 메뉴에서 발급 가능</td></tr><tr><td>Service ID</td><td>ABCD-1234-EFGH-5678</td></tr><tr><td>Service Key</td><td>(APP) 123456789abcdefg</td></tr><tr><td>Web</td><td>도메인 인증 방식 (KEY 미발급)</td></tr><tr><td>App</td><td>SERVICE ID, KEY 인증 방식</td></tr><tr><td>용도</td><td>인증, 서비스 제품 구분 및 ID별 과금 산정</td></tr><tr><td>보안</td><td>APP 서비스인 경우 Service Key는 외부에 노출이 되지 않도록 주의해야 하며, 사용하지 않는 Service ID는 삭제 요함</td></tr></tbody></table>

##


# Call Flow

videocall과 audiocall의 흐름을 sequence diagram으로 보여줍니다. Caller는 발신자를 의미하고 Callee는 수신자를 의미합니다. 자세한 내용은 각 플랫폼별 문서를 참조 바랍니다.

### Caller와 Callee가 미리 Session을 생성한 상태에서 offerCall을 호출할 때

<figure><img src="https://784183326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaPg0bJkhusp9D4dvlOo2%2Fuploads%2FgQSUGyGwpNILe6Gs3JdD%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202023-07-20%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.47.26.png?alt=media&amp;token=5881903b-3b31-4f17-a137-69c11a968eed" alt=""><figcaption></figcaption></figure>

### Caller가 offerCall 호출 이후에 Callee가 Session을 생성할 때

<figure><img src="https://784183326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaPg0bJkhusp9D4dvlOo2%2Fuploads%2FV3Hk12m0OlxvXkdi7xZp%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202023-07-20%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.47.52.png?alt=media&amp;token=127e25d9-6d64-41f5-8e36-044b130dd718" alt=""><figcaption></figcaption></figure>


# Event Message

옴니톡 SDK에서 제공하는 이벤트는 다음과 같으며 필요에 따라 자유롭게 활용하시면 됩니다.&#x20;

해당 페이지에서는 Event Message 이름과 각각의 예시를 보여 줍니다.

플랫폼별 이벤트 메시지 수신 방법은 각 API Reference 본문을 참조 바랍니다.

## 플랫폼별 API Reference 링크

* [Javascript API](/javascript/api-reference)
* [Typescript API](https://docs.omnitalk.io/typescript/api-reference)
* [React-Native API](/react-native/api-reference)
* [Flutter API](/flutter/api-reference)
* [iOS API](/ios/api-reference)

<table><thead><tr><th width="281">Event Name</th><th>Description</th></tr></thead><tbody><tr><td>RINGBACK_EVENT</td><td>offerCall() 호출 성공 시</td></tr><tr><td>RINGING_EVENT</td><td>offerCall( ) 수신 시</td></tr><tr><td>BROADCASTING_EVENT</td><td>영상 회의 publish() 성공 시</td></tr><tr><td>CONNECTED_EVENT</td><td><p>통화 - 상대방과 연결 성공 시</p><p>회의 - 새로운 참가자 입장 시</p></td></tr><tr><td>MUTE_EVENT</td><td>음소거 / 로컬 비디오 화면 송출 off 시</td></tr><tr><td>UNMUTE_EVENT</td><td>음소거 해제 / 로컬 비디오 화면 송출 on 시</td></tr><tr><td>SCREEN_SHARE_EVENT</td><td>screenShare() 호출 성공 시</td></tr><tr><td>SCREEN_UNSHARE_EVENT</td><td>screenUnshare() 호출 시</td></tr><tr><td>MESSAGE_EVENT</td><td>채팅 메시지 이벤트 수신 시</td></tr><tr><td>LEAVE_EVENT</td><td>참가자 퇴장 시</td></tr><tr><td>KICKOUT_EVENT</td><td>참가자 강제 퇴장 시</td></tr><tr><td></td><td></td></tr></tbody></table>

### RINGBACK\_EVENT

* caller(발신자)가 offerCall() 호출에 성공 했을 때, **발신자 본인에게 발생**하는 이벤트 메세지

```jsx
{
"cmd" : "RINGBACK_EVENT",
"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",
"caller": "alice",
"callee": "bob",
"call_type": "audiocall"
}
```

### RINGING\_EVENT

* caller(발신자)가 offerCall() 호출에 성공 했을 때, **callee(수신자)에게 발생**하는 이벤트 메세지

```jsx
{
"cmd" : "RINGBACK_EVENT",
"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",
"user_id":"gOEEdpqGJP",
"caller": "alice",
"callee": "bob",
"room_type": "audiocall",
"call_type": "audiocall",
}
```

### BROADCASTING\_EVENT

* 영상 회의(videoroom) 에서만 발생하는 이벤트 메세지.
* 특정 **참가자가 방송을 송출** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지

```jsx
{
"cmd" : "BROADCASTING_EVENT",
"session": "YzMyYWE1YTA3MmJhMTY4NjE0MDAwNTcyNi01MzM=",
"user_id" : "gOEEdpqGJP",
"room_type": "audiocall",
"call_type": "audiocall",
}                                        
```

### CONNECTED\_EVENT

* (음성, 영상) **통화일 경우**는 상대방과 연결이 성공 했을 때, **caller와 callee 모두에게 발생**하는 이벤트 메세지
* (음성, 영상) **회의일 경우**는 새로운 참가자가 입장 했을 때, **기존 참가자들에게 발생**하는 이벤트 메세지

```jsx
{
"cmd" : "CONNECTED_EVENT",
"session": "YjQ1ZGUzYzA3MmJhMTY4NjE0MzU0NjI1My01MDM=",
"user_id": "AaalBCeHdL",
"room_type": "videoroom",
"call_type": "audiocall",
}

```

### MUTE\_EVENT

* 특정 참가자가 **음성 또는 영상을 mute** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지

```javascript
{
"cmd" : "MUTE_EVENT",
"session": "YjQ1ZGUzYzA3MmJhMTY4Njgy",
"track":"audio"
}
```

### UNMUTE\_EVENT

* 특정 참가자가 **음성 또는 영상을 unmute** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지

```javascript
{
"cmd" : "UNMUTE_EVENT",
"session": "YjQ1ZGUzYzA3MmJhMTY4Njgy",
"track":"audio"
}
```

### SCREEN\_SHARE\_EVENT

* 특정 참가자가 **화면 공유**를 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지

```javascript
{
"cmd" : "SCREEN_SHARE_EVENT",
"session": "YjQ1ZGUzYzA3MmJhMTY4Njgy",
"user_id": "gOEEdpqGJP",
"room_type": "videoroom",
"call_type": "videocall"
}
```

### SCREEN\_UNSHARE\_EVENT

* 특정 참가자가 **화면 공유를 취소** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지

```javascript
{
"cmd" : "SCREEN_UNSHARE_EVENT",
"session": "YjQ1ZGUzYzA3MmJhMTY4Njgy",
"user_id": "gOEEdpqGJP",
"room_type": "videoroom",
"call_type": "videocall"
}
```

### MESSAGE\_EVENT

* message action은 4가지로 구분됩니다.
  * send: 특정 참가자가 **채팅 메세지를 전송** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지
  * whisper: 특정 참가자가 다른 참가자에게 **귓속말을 전송** 했을때, **귓속말 대상자에게 발생**하는 이벤트 메세지
  * join: 새로운 **참가자가 입장** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지
  * leave: **참가자가 퇴장** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지

```javascript
{
"cmd" : "MESSAGE_EVENT",
"action": "join", 
"session": "aGZTTUpDVG1JSDE2ODg4OTE4MDMtNA==", 
"timestamp": 1688891816, 
"user_id": "11", 
"user_name": "mXPkkkEOgQ"
}
```

### LEAVE\_EVENT

* 특정 참가자가 **퇴장** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지

```jsx
{
"cmd" : "LEAVE_EVENT",
"session": "YzMyYWE1YTA3MmJhMTY4NjE0MzUzOTMxNS01Mzg=",
}
```

### KICKOUT\_EVENT

* 특정 참가자를 강제 **퇴장**시켰을 때, **다른 참가자들에게 발생**하는 이벤트 메세지

```jsx
{
"cmd" : "KICKOUT_EVENT",
"session": "YjQ1ZGUzYzA3MmJhMTY4Njgy",
"room_type" : "videoroom"
}
```

###


# SDK State

Omnitalk SDK는 내부적으로 사용자의 상태를 관리하고 있습니다. 각 상태별로 호출 가능한 API가 제한되며, 이 상태는 호출하는 API에 따라서 변하게 됩니다.

아래에서는 각 상태에 대한 설명과 상태별로 호출할 수 있는 API 목록을 보여줍니다.

## NULL\_STATE

세션 생성을 하지 않았거나 leave()를 호출하여 세션이 없는 상태를 의미합니다. 호출 가능한 API 목록은 아래와 같습니다.

* createSession

## SESSION\_STATE

createSession 호출을 성공하여 세션이 생성된 상태입니다. 이 상태에서는 회의실 등의 목록 조회가 가능하며 전화를 걸거나 받을 수 있고, 회의실에 참가 할 수 있습니다. 호출 가능한 API 목록은 아래와 같습니다.

* ~~sessionList (deprecated)~~
* roomList
* callList
* createRoom
* joinRoom
* offerCall
* answerCall
* makeSipNumber
* destroyRoom

## ACTIVE\_STATE

joinRoom 호출을 성공하여 회의실에 참가하여 음성 회의가 시작된 상태입니다. 이 상태에서는 회의실 참가자 목록 등의 목록 조회가 가능하며 다른 참가자의 영상을 송출하거나 구독할 수 있습니다. ( 영상 송출은 video room 타입에서만 가능 ) 호출 가능한 API 목록은 아래와 같습니다.

* partiList
* publishList
* screenList
* publish
* screenShare ( 회의실당 1명만 화면 공유 가능 )
* screenUnshare
* subscribe
* unsubscribe
* leave
* kickout
* sendMessage

## CONNECT\_STATE

publish 호출을 성공하여 영상을 송출하고 있는 상태입니다. 이 상태에서는 영상 회의실 참가자 목록 등의 목록 조회가 가능하며 다른 참가자의 영상을 구독할 수 있습니다. 호출 가능한 API 목록은 아래와 같습니다.

* partiList
* publishList
* screenList
* screenShare ( 회의실당 1명만 화면 공유 가능 )
* screenUnshare
* subscribe
* unsubscribe
* leave
* kickout
* sendMessage
* recordingStart
* recordingStop


# Installation

## NPM

1. npm을 사용하여 설치합니다.

```jsx
$ npm install omnitalk-ts-sdk
```

1. JavaScript파일에서 호출합니다.

```jsx
import Omnitalk from "onmitalk-ts-sdk";
```

## CDN

HTML 파일 하단에 다음 태그를 추가하여 설치합니다.

```html
<script src="https://cdn.jsdelivr.net/npm/omnitalk-ts-sdk@latest">
```


# Quick Start

Omnitalk SDK를 어떻게 활용할 수 있는지에 대한 간단한 예시입니다. (음성,영상)

## **1. 객체 및 세션 생성**

발급된 Service ID로 Omnitalk 객체와 세션을 생성하는 초기화 과정을 수행합니다. 세션이 정상적으로 생성되면 방 리스트를 조회하거나 방 생성, 방송 개시 및 시청이 가능합니다.

```jsx
Omnitalk.sdkInit("YN3F-GE3M-4CW2-FDLZ");
const sdk = Omnitalk.getInstance();
const session = await sdk.createSession();
```

<table><thead><tr><th width="153">Function</th><th width="152">Description</th><th width="122">Parameter</th><th width="340">Value</th><th>Return</th></tr></thead><tbody><tr><td>sdkInit( )</td><td>sdk 객체 초기화</td><td>service_id</td><td>"YN3F-GE3M-4CW2-FDLZ"</td><td></td></tr><tr><td>getInstance()</td><td>sdk 객체 생성</td><td>-</td><td>-</td><td>Object</td></tr><tr><td>createSession( )</td><td>옴니톡 세션 생성</td><td>-</td><td>-</td><td>Object</td></tr></tbody></table>

## 2. 방 생성

생성된 세션을 바탕으로 방을 만들 수 있습니다. 음성은 "audioroom" 영상은 "videoroom"을 parameter에 전달합니다. 방의 정보가 담긴 JSON Object를 리턴합니다.

```jsx
const roomId = await sdk.createRoom(room_type);
```

<table><thead><tr><th width="161">Function</th><th width="129">Description</th><th>Parameter</th><th>Value</th><th>Return</th></tr></thead><tbody><tr><td>createRoom( )</td><td>방송 생성</td><td>room_type</td><td><p>"audioroom",</p><p>"videoroom"</p></td><td>JSON Object</td></tr></tbody></table>

## 3. 방 목록 조회 및 참여

방 목록을 조회하거나 참여할 수 있습니다. 참여할 방의 room\_id는 방 목록을 조회하여 알 수 있습니다.

```jsx
const roomList = await sdk.roomList(room_type);
const joinResult = await sdk.joinRoom(room_id);
```

<table><thead><tr><th>Function</th><th width="112">Description</th><th width="119">Parameter</th><th>Value</th><th>Return</th></tr></thead><tbody><tr><td>roomList( )</td><td>방송 조회</td><td>room_type</td><td><p>"audioroom",</p><p>"videoroom"</p></td><td>JSON Array</td></tr><tr><td>joinRoom( )</td><td>방송 참여</td><td>room_id</td><td>"b45de3c0167"</td><td>JSON Object</td></tr></tbody></table>

## 4. 방송 개시

로컬의 음성이나 영상을 송출하기 위해서 필요한 과정입니다. call\_type에 송출하고 싶은 종류의 값을 전달 합니다. publish를 수행한 결과를 JSON Object로 리턴합니다.

```jsx
const publishResult = await sdk.publish(call_type);
```

<table><thead><tr><th>Function</th><th>Description</th><th width="147">Parameter</th><th>Value</th><th>Return</th></tr></thead><tbody><tr><td>publish( )</td><td>방송 조회</td><td>call_type</td><td>"videocall", "audiocall"</td><td>JSON Object</td></tr></tbody></table>

## 5. 방송 중인 참여자 조회 및 시청

방에 참여하면 방송 중인 참여자의 목록을 조회하고 시청할 수 있습니다. Subscribe는 영상을 시청할 경우에만 필요하며 특정 사용자의 publish\_idx는 참여자 목록을 조회하면 알 수 있습니다.

```jsx
const publishList = await sdk.publishList(room_id);
const subscribeResult = await sdk.subscribe(publish_idx);
```

<table><thead><tr><th>Function</th><th>Description</th><th width="144">Parameter</th><th>Value</th><th>Return</th></tr></thead><tbody><tr><td>publishList( )</td><td>방송중인 참여자 조회</td><td>room_id</td><td>"b45de3c0167"</td><td>JSON Array</td></tr><tr><td>subscribe( )</td><td>방송 중인 특정 사용자의 영상 시청</td><td>publish_idx</td><td>27</td><td>JSON Object</td></tr></tbody></table>

## 6. 시청 종료 및 세션 종료

특정 사용자의 영상 시청을 종료하거나 방을 나갈 수 있습니다. leave의 parameter로 특정 사용자의 session\_id를 전달하면 방 안에서 특정 사용자의 영상 시청이 종료됩니다. leave의 parameter에 아무것도 전달하지 않으면 로컬의 세션 연결이 종료됩니다.

```jsx
await sdk.leave(session_id);
```

<table><thead><tr><th>Function</th><th>Description</th><th width="187">Parameter</th><th>Value</th><th>Return</th></tr></thead><tbody><tr><td>leave( )</td><td>특정 사용자의 영상 시청 종료 혹은 로컬의 세션 연결 종료</td><td>session_id</td><td>"YjQ1ZGUzYzA3M"</td><td>-</td></tr></tbody></table>


# API Reference

⚠️ SDK 2.0.x 버전과 2.1.x 이후 버전간 호환 불가

## **Synchronization**

Omnitalk SDK는 통신 서비스를 제공하기 위해 Offer-Answer 구조로 설계되어 있으며, 이를 위해 반드시 async, await 비동기 처리를 지원해야 합니다.

## **Global Module**

sdk 객체를 생성합니다. 생성된 객체는 이후 모든 메서드 호출에 사용됩니다. Service Id와 Service Key는 [console 페이지](https://omnitalk.io/console/service/service-id)에서 발급 가능하며 노출되지 않도록 주의하여야 합니다.

```javascript
Omnitalk.sdkInit(service_id, service_key);
const sdk = Omnitalk.getInstance();
```

<details>

<summary>cdn import 시 객체 생성</summary>

Omnitalk.Omnitalk.sdkInit(service\_id, service\_key);\
const sdk = Omnitalk.getInstance();

</details>

*<mark style="color:red;">\*O = Optional, M = Mandatory</mark>*

<table><thead><tr><th>Parameter</th><th width="131">Mandatory</th><th width="163">Type</th><th>Description</th></tr></thead><tbody><tr><td>service_id</td><td>M</td><td>String</td><td>발급받은 Service ID</td></tr><tr><td>service_key</td><td>O</td><td>String</td><td>APP 서비스인 경우 KEY 필수</td></tr></tbody></table>

## Audio/Video Tag Rule

음성을 입출력하기 위한 Audio 태그는 옴니톡 SDK에서 자동으로 생성하며, Video 입출력을 위한 Tag ID는 아래의 규칙이 적용됩니다.

<table><thead><tr><th width="137">DOM</th><th width="208">ID</th><th>Attribute</th><th>Use For</th><th>Creator</th></tr></thead><tbody><tr><td>audio</td><td>Omnitalk-Audio-0</td><td>autoplay</td><td>-</td><td>SDK</td></tr><tr><td>video</td><td>Omnitalk-LocalVideo-0</td><td>autoplay, playinline</td><td><a href="#publish">publish()</a></td><td>Customer</td></tr><tr><td>video</td><td>Omnitalk-RemoteVideo-0<br>...<br>Omnitalk-RemoteVideo-31</td><td>autoplay, playinline</td><td><a href="#subscribe">subscribe()</a></td><td>Customer</td></tr></tbody></table>

## EVENT\_MESSAGE

## on

이벤트 메시지는 [여기](https://docs.omnitalk.io/commons/event-message)를 참고하시면 됩니다. 이벤트 메시지를 수신하기 위해서는 옴니톡의 이벤트 리스너 API를 이용하시면 됩니다.

```javascript
sdk.on('event', ()=>{})
```

leave 이벤트로 서버와의 연결이 끊기거나 사용자 인터넷 환경 불안정 등으로 인터넷 연결이 끊길 때 발생하는 close 메시지입니다.

```jsx
sdk.on('close', ()=>{})
```

##

## createSession

사용자의 세션을 생성하기 위해 서버와 연결하고 그 결과로 세션 아이디, 유저 아이디 등을 포함한 객체를 리턴합니다.

```javascript
const sessionInfo = await sdk.createSession(user_id);
```

<table><thead><tr><th width="139">Parameter</th><th width="137">Mandatory</th><th width="107">Type</th><th>Description</th></tr></thead><tbody><tr><td>user_id</td><td>O</td><td>String</td><td>사용자별 과금 정보, 통화 기능등에 사용되며, 미입력시 임의의 ID 정보를 자동으로 할당</td></tr></tbody></table>

<details>

<summary><strong>리턴 객체 예시 | createSession</strong></summary>

{

"result": "success",

"session": "YjQ1ZGUzYzA3MmJhLTM0",

"user\_id": "KclCDjtcOn"

}

</details>

## ~~sessionList(deprecated)~~

세션 생성 후 같은 Service Id 및 Key를 사용하는 모든 사용자를 조회합니다.

```javascript
await sdk.sessionList();
```

<table><thead><tr><th width="162">Parameter</th><th>Mandatory/Optional</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>page</td><td>O</td><td>Number</td><td>default = 1, per page = 10</td></tr></tbody></table>

<details>

<summary><strong>리턴 객체 | sessionList</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

"page": 1,&#x20;

"count": 1,&#x20;

"list": \[&#x20;

&#x20;           { "user\_id": "omnitalk",&#x20;

&#x20;             "call\_type": "videocall",&#x20;

&#x20;             "state": "busy",&#x20;

&#x20;           }&#x20;

&#x20;         ]

}

</details>

## createRoom

모든 방송은 룸에서 이루어집니다. 방송을 시작할 룸 타입을 전달해 룸을 생성합니다. 방 주제나 방의 비밀 번호를 설정할 수 있습니다. start\_date 및 end\_date는 룸 생성 및 종료 예상 시간을 설정할 때 이용합니다.&#x20;

```javascript
const roomInfo = await sdk.createRoom(room_type);
```

| Parameter   | Mandatory/Optional | Type   | Description |
| ----------- | ------------------ | ------ | ----------- |
| room\_type  | M                  | String |             |
| subject     | O                  | String |             |
| secret      | O                  | Number | max 6       |
| start\_date | O                  | Number | Date 객체     |
| end\_date   | O                  | Number | Date 객체     |

<details>

<summary><strong>리턴 객체 예시 | createRoom</strong></summary>

{

"room\_id": "b45de3c016739550222295",

"session": "YjQ1ZGUzYzA3MmJhLTM0"

}

</details>

## **roomList**

인수로 전달한 룸타입에 해당하는 모든 룸을 조회해 리스트로 반환합니다. default인 "all"은 룸타입에 관계없이 전체 룸을 조회합니다.

```javascript
const roomList = await sdk.roomList(room_type);
```

| Parameter  | Mandatory/Optional | Type   | Description                |
| ---------- | ------------------ | ------ | -------------------------- |
| room\_type | O                  | String | "all"(default)             |
| page       | O                  | Number | default = 1, per page = 10 |

<details>

<summary><strong>리턴 객체 예시 | roomList</strong></summary>

{

&#x20; "session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

&#x20;  "count": 1,&#x20;

&#x20;  "page": 1,&#x20;

&#x20;  "room\_type": "all",&#x20;

&#x20;  "list":&#x20;

&#x20;        \[&#x20;

&#x20;          {&#x20;

&#x20;             "room\_id": "8a1086680e47261208eeff87000b",&#x20;

&#x20;              "room\_type": "videoroom",&#x20;

&#x20;              "count": 0,&#x20;

&#x20;              "secret": true,&#x20;

&#x20;              "sip\_support": true,&#x20;

&#x20;              "sip\_number": "991000"  (optional)

&#x20;              "start\_date": 1686816051,&#x20;

&#x20;              "end\_date": 1686819651,&#x20;

&#x20;              "reg\_date": 1686816051,&#x20;

&#x20;              "subject": "fish"&#x20;

&#x20;         }    &#x20;

&#x20;      ]

}

</details>

## joinRoom

방송을 시작하거나 다른 방송을 시청하기 위해서는 반드시 룸 참여 과정이 필요합니다.&#x20;

```javascript
const joinResult = await sdk.joinRoom(room_id);
```

| Parameter  | Mandatory/Optional | Type   | Description      |
| ---------- | ------------------ | ------ | ---------------- |
| room\_id   | M                  | String |                  |
| secret     | O                  | Number | max 6            |
| user\_name | O                  | String | max 32, nickname |

<details>

<summary><strong>리턴 객체 예시 | joinRoom</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

"room\_id": "8a1086680e47261208eeff87000b",&#x20;

"room\_type": "videoroom"

}

</details>

## partiList

해당 룸에 참여한 모든 사용자(방송 개시 여부와 무관)를 조회합니다. room\_id를 전달하지 않으면 자신이 참여한 룸의 참여자 리스트를 조회합니다.&#x20;

```javascript
const partiListResult = await sdk.partiList(room_id);
```

| Parameter | Mandatory/Optional | Type   | Description                |
| --------- | ------------------ | ------ | -------------------------- |
| room\_id  | O                  | String |                            |
| page      | O                  | Number | default = 1, per page = 10 |

<details>

<summary><strong>리턴 객체 예시 | partiList</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

"page": 1,&#x20;

"count": 1,&#x20;

"list":&#x20;

\[ {&#x20;

"session": "YzMyYWE1YTA3MmJhMTY4",&#x20;

"user\_id": "<jason@omnistory.net>",&#x20;

"user\_name": "jason",&#x20;

"audio\_mute": false,

"video\_mute": false

} ]

}

</details>

## publish

영상 방송을 개시하고 방송 세션 id가 담긴 객체를 리턴받습니다. 사용자 지정 Tag ID를 전달하지 않으면 옴니톡 SDK에서 발급한 [Tag Rule](#audio-video-tag-rule)에 따른 Tag ID를 이용하시면 됩니다. 같은 룸의 다른 사용자가 join하거나 publish를 하게 되면 `CONNECTED_EVENT`를 받게 됩니다. 이는 각 사용자(peer)의 오디오가 연결되어 방송을 구독할 수 있는 상태가 되었음을 의미합니다. publish한 방송의 영상을 보고 싶은 사용자는 구독 [subscribe API](#subscribe)를 이용하면 됩니다.&#x20;

```javascript
const publishResult = await sdk.publish(tag_id);
```

<table><thead><tr><th width="153">Paremeter</th><th width="132">Mandatory</th><th width="144">Type</th><th>Description</th></tr></thead><tbody><tr><td>tag_id</td><td>O</td><td>String</td><td>Video 입출력을 위한  사용자 지정 Tag ID</td></tr></tbody></table>

<details>

<summary><strong>리턴 객체 예시 | publish</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhLTIz",

}

</details>

## subscribe

구독할 방송의 세션 번호를 전달하면 해당 방송을 구독할 수 있습니다. tag id를 별도로 전달하지 않으면 옴니톡의 [Tag Rule](#audio-video-tag-rule)에 따른 id를 이용하시면 됩니다. subscribe 호출이 성공하면 자신의 세션, 구독하는 세션, 화면 공유 여부에 대한 boolean 값을 리턴 객체로 받게 됩니다.

```javascript
const subscribeResult = await sdk.subscribe(publish_idx);
```

<table><thead><tr><th width="142">Paremeter</th><th width="132">Mandatory</th><th width="132">Type</th><th>Description</th></tr></thead><tbody><tr><td>publisherSession</td><td>M</td><td>String</td><td></td></tr><tr><td>tag_id</td><td>O</td><td>String</td><td></td></tr></tbody></table>

<details>

<summary><strong>리턴 객체 | subscribe</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Nj",  // 자신의 세션

"subscribe": "YzMyYWE1YTA3MmJhMTY4Njg"  // 구독하는 상대의 세션

"screen": false // 화면 공유 여부에 대한 boolean 값

</details>

## unsubscribe

구독 중인 방송의 구독을 취소할 수 있습니다.

```javascript
await sdk.unsubscribe(publisherSession);
```

| Parameter        | Mandatory/Optional | Type   | Description |
| ---------------- | ------------------ | ------ | ----------- |
| publisherSession | M                  | String |             |

<details>

<summary><strong>리턴 객체 | unsubscribe</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Nj", // 자신의 세션

"subscribe": "YzMyYWE1YTA3MmJhMTY4Njg"  // 구독취소한 세션

}

</details>

## screenShare

화면 공유 기능을 수행하기 위한 API입니다. tag id를 별도로 전달하지 않으면 옴니톡의 [Tag Rule](#audio-video-tag-rule)에 따른 id를 이용하시면 됩니다. screenShare 호출 성공시 화면 공유에 대한 session id가 담긴 리턴 객체를 받게 되며 동일 방의 다른 사용자들에게 `SCREEEN_SHARE_EVENT`가 전달됩니다. 공유 화면을 보고 싶은 사용자는 이벤트 메시지에서 전달하는 세션id를 구독하면 됩니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message#screen_share_event))

```javascript
await sdk.screenShare(tag_id);
```

| Parameter | Mandatory/Optional | Type   | Description                 |
| --------- | ------------------ | ------ | --------------------------- |
| tag\_id   | O                  | String | Video 입출력을 위한 사용자 지정 Tag ID |

<details>

<summary><strong>리턴 객체 | screenShare</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

}

</details>

## screenUnshare

자신의 화면 공유를 취소합니다. 동일 방의 다른 사용자들에게 `SCREEEN_UNSHARE_EVENT`가 전달됩니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message#screen_unshare_event))

```javascript
await sdk.screenShare();
```

<details>

<summary><strong>리턴 객체 | screenUnshare</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

}

</details>

## screenList

룸에서 화면을 공유하고 있는 방송이 있다면 그 방송에 대한 정보를 조회하는 API입니다. 별도의 room\_id를 전달하지 않으면 자신이 참여하고 있는 룸의 화면 공유 리스트를 조회하게 됩니다.

```javascript
await sdk.screenList();
```

| Parameter | Mandatory/Optional | Type   | Description |
| --------- | ------------------ | ------ | ----------- |
| room\_id  | O                  | String |             |

<details>

<summary><strong>리턴 객체 | screenList</strong></summary>

{

&#x20; "session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

&#x20; "room\_id": "9389314d3cb1b92eeaa81b618e0f",&#x20;

&#x20; "count": 1,&#x20;

&#x20; "page": 1,&#x20;

&#x20; "list":&#x20;

&#x20;          \[&#x20;

&#x20;            {&#x20;

&#x20;               "session": "YzMyYWE1YTA3MmJhMTY4",&#x20;

&#x20;               "user\_id": "sADKOqOGBA",&#x20;

&#x20;               "user\_name": "kAIaDnhpPH",&#x20;

&#x20;               "call\_type": "videocall"&#x20;

&#x20;           }&#x20;

&#x20;         ]

}

</details>

## offerCall

음성 또는 영상 통화를 위한 발신 기능을 수행합니다. 첫 번째 파라미터인 call\_type이 음성 통화 요청인지, 영상 통화 요청인지 결정합니다. callee는 전화를 요청할 상대방의 user\_id를 전달해 주시면 됩니다. record 파라미터를 전달하지 않으면 default=false 입니다.

영상 통화의 경우 송출되는 영상을 재생하기 위해서는 video 태그가 필요합니다. Omnitalk SDK는 video 태그의 id를 기반으로 영상을 재생합니다. 파라미터로 사용자 지정 tag id를 전달할 수 있습니다. 사용자 지정 tag id를 전달하지 않으면 옴니톡 SDK에서 발급한 [Tag Rule](#audio-video-tag-rule)에 따라서 video 태그를 생성하시면 됩니다. 자신의 영상은 `Omnitalk-LocalVideo-0` 상대방 영상은 `Omnitalk-RemoteVideo-0` 입니다.

offerCall 호출이 성공하면 callee에게는 `RINGING_EVENT`가 전달됩니다. offerCall을 호출한 측은 `RINGBACK_EVENT`를 받게 됩니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message))

<mark style="color:orange;">⚠️</mark> 2.1.x 이후 버전부터 record 파라메터가 삭제되었습니다. 녹음은 [recordingStart](#recordingstart) 함수를 사용합니다. &#x20;

```javascript
await sdk.offerCall(call_type, callee, record);
```

| Parameter       | Mandatory/Optional | Type    | Description          |
| --------------- | ------------------ | ------- | -------------------- |
| call\_type      | M                  | String  |                      |
| callee          | M                  | String  | 이메일, 전화번호, 닉네임, id 등 |
| record          | O                  | Boolean | 2.1.x 버전부터 삭제        |
| local\_tag\_id  | O                  | String  |                      |
| remote\_tag\_id | O                  | String  |                      |

<details>

<summary>이벤트 메시지 <strong>예시 | RINGBACK_EVENT</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"caller": "alice",&#x20;

"callee": "bob",&#x20;

"call\_type": "audiocall"

}

</details>

<details>

<summary>이벤트 메시지 <strong>예시 | RINGING_EVENT</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"room\_id": "9389314d3cb1b92eeaa81b618e0f",&#x20;

"room\_type": "audiocall",&#x20;

"call\_type": "audiocall",

"caller": "alice",&#x20;

"callee": "bob",&#x20;

"track": "audio",

}

</details>

## answerCall

음성 또는 영상 통화를 위한 착신 기능을 수행합니다. answerCall 호출이 성공하면 caller, callee 양측 모두 `CONNECTED_EVENT`를 받습니다.

```javascript
await sdk.answerCall(call_type, caller);
```

| Parameter       | Mandatory/Optional | Type   | Description |
| --------------- | ------------------ | ------ | ----------- |
| call\_type      | O                  | String |             |
| caller          | O                  | String |             |
| local\_tag\_id  | O                  | String |             |
| remote\_tag\_id | O                  | String |             |

## makeSipNumber

개인 또는 방송 룸에 일반 전화를 수신할 수 있는 번호를 부여합니다. 만약 룸에 번호를 할당하면 룸의 참여자 모두에게 전화를 걸 수 있습니다.&#x20;

```javascript
await sdk.makeSipNumber();
```

| Parameter    | Mandatory/Optional | Type   | Description |
| ------------ | ------------------ | ------ | ----------- |
| call\_number | O                  | String |             |
| room\_id     | O                  | String |             |

## mute/unmute

mute할 track을 인자로 넘겨주면 음소거 및 음소거 해제 기능을 수행할 수 있습니다. 비디오 mute는 로컬의 화면 송출을 off 시키는 기능입니다. mute/unmute API를 호출하면 룸의 다른 사용자들에게 `MUTE_EVENT` 또는 `UNMUTE_EVENT`가 전달됩니다.

```javascript
await sdk.setMute(track);
await sdk.setUnmute(track);
```

| Parameter | Mandatory/Optional | Type   | Description      |
| --------- | ------------------ | ------ | ---------------- |
| track     | M                  | String | "audio", "video" |

## getDeviceList

해당 장치의 모든 오디오, 비디오 장치를 조회할 수 있는 API 입니다.

```javascript
await sdk.getDeviceList();
```

<details>

<summary><strong>리턴 객체 예시 | getDeviceList</strong></summary>

{&#x20;

"videoinput":

&#x20;                   \[\
&#x20;                      {&#x20;

&#x20;                         "kind":"videoinput",&#x20;

&#x20;                          "label":"Logitech BRIO (046d:085e)",&#x20;

&#x20;                           "deviceId": "33fb0bfdda06b8815f94baa46d3965\
&#x20;                                                211b5476825021ac91578280a5d7c05b94",&#x20;

&#x20;                           "groupId":"cbc0be3ca9648a43fa29e144e1460bb6\
&#x20;                                             df916243eea817625a4700b2cf910654 ",&#x20;

&#x20;                      }, \
&#x20;                     {&#x20;

&#x20;                         "kind":"videoinput",&#x20;

&#x20;                          "label":"FaceTime HD 카메라 (3A71:F4B5)",&#x20;

&#x20;                           "deviceId": "9e82b7ecc5f2844f1109f31ac47b\
&#x20;                                                b1c5fc1d9d13d7f627e4f1db3fd0132bf9be",&#x20;

&#x20;                           "groupId":"5ccd5bf9211dfd080cfcc6f8187f486c9a1\
&#x20;                                             02e579a4d9e3f4e22cdfecb732cf7 ",&#x20;

&#x20;                      },&#x20;

&#x20;                     ], \
"audioinput":

&#x20;                   \[\
&#x20;                      {&#x20;

&#x20;                         "kind":"audioinput",&#x20;

&#x20;                          "label":"Logitech BRIO (046d:085e)",&#x20;

&#x20;                           "deviceId": "5f9715786e17b339dfdfabfd65fc0a5b5\
&#x20;                                                850ec11fc6509085c4a13b5fa760bef",&#x20;

&#x20;                           "groupId":"2479fd4c965cadd52de1d9dd54debbcdb0\
&#x20;                                             caf370a2c0b916f13554d9eaec782d ",&#x20;

&#x20;                      }, \
&#x20;                     {&#x20;

&#x20;                         "kind":"audioinput",&#x20;

&#x20;                          "label":"MacBook Pro 마이크 (Built-in)",&#x20;

&#x20;                           "deviceId": "1a825a6af6bb985db3dbcdedf67cfad\
&#x20;                                                0d2b850f892a4dbd049fa01f140c2a972",&#x20;

&#x20;                           "groupId":"dbec76dc0e283229718a34a2a07de4\
&#x20;                                             e98bb5987fb5db535affb6428c6b0f1339 ",&#x20;

&#x20;                      },&#x20;

&#x20;                     ],&#x20;

}

</details>

## setAudioDevice

제어하고 싶은 장치의 device id를 인수로 전달하면 됩니다.

```jsx
await sdk.setAudioDevice(device_id);
```

| Parameter  | Mandatory/Optional | Type   | Description |
| ---------- | ------------------ | ------ | ----------- |
| device\_id | M                  | String |             |

## setVideoDevice

제어하고 싶은 장치의 device id를 인수로 전달하면 됩니다.

```jsx
await sdk.setAudioDevice(device_id);
```

| Parameter  | Mandatory/Optional | Type   | Description |
| ---------- | ------------------ | ------ | ----------- |
| device\_id | M                  | String |             |

## setResolution

송출할 비디오 영상의 해상도를 설정하는 API입니다.&#x20;

```jsx
await sdk.setResolution(resolution);
```

| resolution | width \* height |
| ---------- | --------------- |
| QVGA       | 320 \* 240      |
| VGA        | 640 \* 480      |
| SD         | 720 \* 480      |
| HD         | 1280 \* 720     |
| FHD        | 1920 \* 1080    |
| 2k         | 2560 \* 1440    |
| 4k         | 1840 \* 2160    |

## destroyRoom

룸 삭제 기능을 수행하는 API 입니다. 룸에 어떤 참여자도 없으면 Omnitalk SDK에서 일정 시간 이후 자동으로 룸을 제거합니다. 만약 명시적으로 룸을 삭제하거나 추가 사용자의 룸 참여를 막고 싶다면 해당 room\_id를 전달하여 기능을 수행할 수 있습니다. 자신이 참여하고 있는 룸을 삭제할 수는 없습니다. 방송 중인 참여자가 있는 룸을 삭제하게 되면 방송 중인 참여자들은 계속 방송할 수 있고 룸 리스트 조회도 가능하지만 추가적인 룸 참여는 불가능합니다.

```javascript
await sdk.destroyRoom(room_id);
```

| Parameter | Mandatory/Optional | Type   | Description |
| --------- | ------------------ | ------ | ----------- |
| room\_id  | M                  | String |             |

<details>

<summary><strong>리턴 객체 | destroyRoom</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"room\_id":"8a1086680e47261208eeff87000b",

}

</details>

## leave

방송을 종료하는 API입니다. 통화 또는 회의에 참여한 상태일 경우, session을 전달하지 않으면 자신의 방송을 종료하고 퇴장(통화 종료)하게 됩니다. 퇴장시, 다른 참가자들은 LEAVE\_EVENT 를 수신 합니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message))

파라미터에 session를 전달하면 해당 session을 가진 사용자가 퇴장(통화 종료) 하게 됩니다. 해당 상황은 수신 거절이나 강제 퇴장 등의 기능으로 활용할 수 있습니다.&#x20;

<mark style="color:orange;">⚠️</mark> 2.1.x 이후 버전에서 leave는 본인의 퇴장만 가능합니다. 상대방의 강제 종료는 [kickout](#kickout)을 사용해 주세요.

```javascript
await sdk.leave();
```

| Parameter   | Mandatory/Optional | Type   | Description   |
| ----------- | ------------------ | ------ | ------------- |
| session\_id | O                  | String | 2.1.x 버전부터 삭제 |

***

{% hint style="info" %}
**sdk 2.1.x 이후 버전부터 사용 가능**
{% endhint %}

## kickOut

사용자가 룸에 참여해 방송을 개시한 이후에 다른 사용자를 강제퇴장 시키는 기능입니다. 인수로 전달하는 session은 룸에서 강제 퇴장되며 세션이 끊어지게 됩니다. 룸의 다른 참여자들에게는 KICKOUT\_EVENT가 발생합니다.

```javascript
await sdk.kickOut(target)
```

| Parameter | Mandatory/Optional | Type   | Description        |
| --------- | ------------------ | ------ | ------------------ |
| target    | M                  | string | 강제 종료할 상대의 session |

## recordingStart

음성 녹음을 시작하는 API입니다. 모든 call\_type에서 호출할 수 있습니다. 단, 녹음 시작 API 호출은 call/room에 참여한 사용자별로 한 번만 호출할 수 있습니다.  recordingStop()을 호출하지 않고 leave()를 호출 하거나 연결이 끊어져도 해당 시점까지 녹음은 마무리됩니다.

```javascript
await sdk.recordingStart();
```

## recordingStop

음성 녹음을 종료하는 API입니다. 녹음 완료 시 옴니톡 콘솔에 등록한 Webhook URL로 콜백을 받을 수 있습니다.

```javascript
await sdk.recordingStop();
```


# Installation

공식 패키지 저장소(npmjs.com)에서 Typescript용 [옴니톡SDK](https://www.npmjs.com/package/omnitalk-ts-sdk)를 다운받아 설치할 수 있습니다.&#x20;

```
npm i omnitalk-ts-sdk
```


# Quick Start

Omnitalk SDK는 쉽고 간편하게 WebRTC 기술을 이용할 수 있도록 만들어진 패키지입니다. Omnitalk SDK의 모든 API는 async \~ await 구조로 작성되었습니다. 요청이 실패하면 에러를 throw 합니다. 상세 API 사용법은[Typescript API ](/typescript/api-reference)를 참조 바랍니다.

## 1:1 영상 통화

### 1. 옴니톡 객체 생성

[콘솔](https://omnitalk.io/console/service/service-id)에서 발급받은 Service ID로 Omnitalk 객체를 생성합니다.

```typescript
import { Omnitalk } from "omnitalk-ts-sdk";

const SERVICE_ID = '발급받은 service id';
const SERVICE_KEY = '발급받은 service key';

Omnitalk.sdkInit(SERVICE_ID, SERVICE_KEY);
const sdk = Omnitalk.getInstance();
```

### 2. 세션 생성

인수로 전달한 user\_id로 세션을 생성하게 됩니다. user\_id 생략시 Omnitalk 서버에서 임의의 ID를 부여합니다.

```typescript
const sessionResult = await sdk.createSession('alice');
const session = sessionResult.session
```

### 3. 발신

1:1 영상 통화를 구현하기 위한 발신 기능은 offerCall API를 이용합니다. 영상을 화면에 재생하기 위해서 caller 및 callee의 영상을 담을 사용자 지정 tag id를 전달할 수 있습니다(미지정시 옴니톡 [Tag Rule](/typescript/api-reference#audio-video-tag-rule)에 따른 id를 사용하시면 됩니다).

offerCall 호출이 성공하면 caller에게는 `RINGBACK_EVENT`가, callee에게는 `RINGING_EVENT`가 전달됩니다.

```typescript
import { CALL_TYPE } from "omnitalk-ts-sdk/dist/public-types/common";

const localVideo = 'videotag1';
const remoteVideo = 'videotag2'; 
const callee = 'test@omnistory.net';

await sdk.offerCall(CALL_TYPE.VIDEO_CALL, callee, true, localVideo, remoteVideo);
```

### 4. 수신

callee측에서는 `RINGING_EVENT`를 받고 통화를 수락하거나 거절할 수 있습니다. 통화 수락은 [answerCall API](/typescript/api-reference#answercall)를 이용합니다. 영상을 화면에 재생하기 위해서 caller 및 callee의 영상을 담을 사용자 지정 tag id를 전달할 수 있습니다(미지정시 옴니톡 [Tag Rule](/typescript/api-reference#audio-video-tag-rule)에 따른 id를 사용하시면 됩니다).

answerCall이 정상적으로 수행되면 caller, callee 양측은 `CONNECTED_EVENT`를 받습니다. 수신 거절은[ leave API](/typescript/api-reference#leave)를 이용하시면 됩니다.

```typescript
import { OmniEvent } from "omnitalk-ts-sdk/dist/public-types/common"

sdk.on('event', async(msg) => {
    if (msg.cmd == OmniEvent.RINGING_EVENT) {
        const ringingMsg = msg as EventRinging;
        await omnitalk.answerCall();
    } else if (msg.cmd == OmniEvent.CONNECTED_EVENT) {
	console.log(msg.session);
    }
});
```

## 영상 회의

### 1. 옴니톡 객체 생성

[콘솔](https://omnitalk.io/console/service/service-id)에서 발급받은 Service ID로 Omnitalk 객체를 생성합니다.

```typescript
import { Omnitalk } from "omnitalk-ts-sdk";

const SERVICE_ID = '발급받은 service id';
const SERVICE_KEY = '발급받은 service key';

Omnitalk.sdkInit(SERVICE_ID, SERVICE_KEY);
const sdk = Omnitalk.getInstance();
```

### 2. 세션 생성

인수로 전달한 user\_id로 세션을 생성하게 됩니다. user\_id 생략시 Omnitalk 서버에서 임의의 ID를 부여합니다.

```typescript
const sessionResult = await sdk.createSession('alice');
const session = sessionResult.session
```

### 3. 룸 생성

영상 회의를 위한 룸을 생성합니다.

```typescript
import { VIDEOROOM_TYPE } from "omnitalk-ts-sdk/dist/public-types/common"

const roomResult = await sdk.createRoom(VIDEOROOM_TYPE.VIDEO_ROOM);
```

### 4. 룸 참여

룸에 참여하게 되면 음성과 채팅 메시지를 주고 받을 수 있는 상태가 됩니다.

```typescript
const roomId = roomResult.room_id;
await sdk.joinRoom(roomId);
```

### 5. 방송 시작

publish API 호출시 방송을 시작합니다. 영상을 화면에 재생하기 사용자 지정 tag id를 전달할 수 있습니다(미지정시 옴니톡 [Tag Rule](/typescript/api-reference#audio-video-tag-rule)에 따른 id를 사용하시면 됩니다).

```typescript
cosnt pubResult = await sdk.publish('Omnitalk-LocalVideo-0');
```

### 6. 방송 구독

구독하고자는 방송의 session을 인수로 전달하면 해당 방송을 구독할 수 있습니다. 영상을 화면에 재생하기 사용자 지정 tag id를 전달할 수 있습니다(미지정시 옴니톡 [Tag Rule](/typescript/api-reference#audio-video-tag-rule)에 따른 id를 사용하시면 됩니다).

```typescript
const pubSession = pubResult.session;
await sdk.subscribe(pubSession, 'Omnitalk-RemoteVideo-0');
```


# API Reference

⚠️ SDK 2.0.x 버전과 2.1.x 이후 버전간 호환 불가

## Synchronization

Omnitalk SDK는 통신 서비스를 제공하기 위해 Offer-Answer 구조로 설계되어 있으며, 이를 위해 반드시 async, await 비동기 처리를 지원해야 합니다.

## Global Module

Omnitalk SDK 객체를 생성합니다. Omnitalk SDK는 싱글톤 패턴으로 제공됩니다. 초기화된 객체는 이후 모든 메서드 호출에 사용됩니다. Service Id와 Service Key는 [console 페이지](https://omnitalk.io/console/service/service-id)에서 발급 가능하며 노출되지 않도록 주의하여야 합니다.

```javascript
import { Omnitalk } from "omnitalk-ts-sdk";

const SERVICE_ID = '발급받은 service id';
const SERVICE_KEY = '발급받은 service key';

Omnitalk.sdkInit(SERVICE_ID, SERVICE_KEY);
const sdk = Omnitalk.getInstance();
```

<table><thead><tr><th width="178">Parameter</th><th width="148">Mandatory</th><th width="156">Type</th><th>Description</th></tr></thead><tbody><tr><td>service_id</td><td>M</td><td>String</td><td>발급받은 Service ID</td></tr><tr><td>service_key</td><td>O</td><td>String</td><td>APP 서비스인 경우 KEY 필수</td></tr></tbody></table>

## Audio/Video Tag Rule

음성을 입출력하기 위한 Audio 태그는 옴니톡 SDK에서 자동으로 생성하며, Video 입출력을 위한 Tag ID는 아래의 규칙이 적용됩니다.

<table><thead><tr><th width="137">DOM</th><th width="208">ID</th><th>Attribute</th><th width="144">Use For</th><th>Creator</th></tr></thead><tbody><tr><td>audio</td><td>Omnitalk-Audio-0</td><td>autoplay</td><td>-</td><td>SDK</td></tr><tr><td>video</td><td>Omnitalk-LocalVideo-0</td><td>autoplay, playinline</td><td><a href="#publish">publish( )</a>,<br><a href="#offercall">offerCall()</a>,<br><a href="#answercall">answerCall()</a></td><td>Customer</td></tr><tr><td>video</td><td>Omnitalk-RemoteVideo-0<br>...<br>Omnitalk-RemoteVideo-31</td><td>autoplay, playinline</td><td><a href="#subscribe">subscribe( )</a>,<br><a href="#offercall">offerCall()</a>,<br><a href="#answercall">answerCall()</a></td><td>Customer</td></tr><tr><td>video</td><td>Omnitalk-LocalScreen-0</td><td>autoplay, playinline</td><td><a href="#screenshare">screenShare()</a>,<br><a href="#subscribe">subscribe()</a></td><td>Customer</td></tr></tbody></table>

### EVENT\_MESSAGE

전체 이벤트 메시지 내용은 [여기](https://docs.omnitalk.io/commons/event-message)를 참고하시면 됩니다. 이벤트 메시지를 수신하기 위해서는 이벤트 리스너를 이용하시면 됩니다.

```javascript
sdk.on('event', ()=>{})
```

leave 이벤트로 서버와의 연결이 끊기거나 사용자 인터넷 환경 불안정 등으로 인터넷 연결이 끊길 때 발생하는 close 메시지입니다.

```jsx
sdk.on('close', ()=>{})
```

### createSession

사용자의 세션을 생성하기 위해 서버와 연결하고 그 결과로 session, user\_id가 담긴 객체를 리턴합니다. user\_id 생략시 Omnitalk 서버에서 임의의 id를 부여합니다.&#x20;

```jsx
await sdk.createSession(user_id);
```

| Parameter | Mandatory/Optional | Type   | Description |
| --------- | ------------------ | ------ | ----------- |
| user\_id  | O                  | String | \* max 64   |

* 리턴 객체 | CreateSessionResult

```json
{
  "session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD", 
  "user_id":"omnitalk",
}
```

### ~~sessionList(deprecated)~~

세션 생성 후 같은 Service Id 및 Key를 사용하는 모든 사용자를 조회합니다.

```jsx
await sdk.sessionList();
```

<table><thead><tr><th width="162">Parameter</th><th>Mandatory/Optional</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>page</td><td>O</td><td>Number</td><td>default = 1, per page = 10</td></tr></tbody></table>

* 리턴 객체 | SessionListResult

```json
{
  "page": 1,
  "count": 1,
  "list": [
    {
      "user_id": "omnitalk",
      "call_type": "videocall",
      "state": "busy",
    }
  ]
}
```

### createRoom

모든 방송은 룸에서 이루어집니다. 방송을 시작할 룸 타입을 전달해 룸을 생성합니다. 룸 주제나 방의 비밀 번호를 설정할 수 있습니다. start\_date 및 end\_date는 룸 생성 및 종료 예상 시간을 설정할 때 이용합니다.

```jsx
await sdk.createRoom(room_type);
```

| Parameter   | Mandatory/Optional | Type   | Description |
| ----------- | ------------------ | ------ | ----------- |
| room\_type  | M                  | String |             |
| subject     | O                  | String |             |
| secret      | O                  | Number | max 6       |
| start\_date | O                  | Number | Date 객체     |
| end\_date   | O                  | Number | Date 객체     |

* 리턴 객체 | CreateRoomResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4NjcxMD",
  "room_id": "8a1086680e47261208eeff87000b"
}
```

### roomList

인수로 전달한 룸타입에 해당하는 모든 룸을 조회해 리스트로 반환합니다. default인 "all"은 룸타입에 관계없이 전체 룸을 조회합니다.

```jsx
await sdk.roomList(room_type);
```

| Parameter  | Mandatory/Optional | Type   | Description                |
| ---------- | ------------------ | ------ | -------------------------- |
| room\_type | O                  | String | "all"(default)             |
| page       | O                  | Number | default = 1, per page = 10 |

* 리턴 객체 | RoomListResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4NjcxMD",
  "count": 1,
  "page": 1,
  "room_type": "all",
  "list": [
    {
      "room_id": "8a1086680e47261208eeff87000b",
      "room_type": "videoroom",
      "count": 0, // 해당 룸의 참여자 수
      "secret": true,
      "sip_support": true,
      "start_date": 1686816051,
      "end_date": 1686819651,
      "reg_date": 1686816051,
      "subject": "fish"
    }
  ]
}
```

### joinRoom

영상 회의에서 방송을 시작하거나 다른 방송을 시청하기 위해서는 반드시 룸 참여 과정이 필요합니다. 회의실에 참여하게 되면 별도의 작업 없이 참여자들과 음성 회의를 할 수 있게 되며 회의실에 관련된 이벤트 메세지를 수신할 수 있습니다. 이벤트에 대한 자세한 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

```jsx
await sdk.joinRoom(room_id);
```

| Parameter  | Mandatory/Optional | Type   | Description      |
| ---------- | ------------------ | ------ | ---------------- |
| room\_id   | M                  | String |                  |
| secret     | O                  | Number | max 6            |
| user\_name | O                  | String | max 32, nickname |

* 리턴 객체 | JoinRoomResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",
  "room_id": "8a1086680e47261208eeff87000b",
  "room_type": "videoroom",
  "screen": false // 참여한 룸의 화면 공유 여부
}
```

### partiList

해당 룸에 참여한 모든 사용자(방송 개시 여부와 무관)를 조회합니다. room\_id를 전달하지 않으면 자신이 참여한 룸의 참여자 리스트를 조회합니다.&#x20;

```jsx
await sdk.partiList(room_id);
```

| Parameter | Mandatory/Optional | Type   | Description                |
| --------- | ------------------ | ------ | -------------------------- |
| room\_id  | O                  | String |                            |
| page      | O                  | Number | default = 1, per page = 10 |

* 리턴 객체 | PartiListResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",
  "room_id": "8a1086680e47261208eeff87000b",
  "page": 1,
  "count": 1,
  "list": [
    {
      "session": "YzMyYWE1YTA3MmJhMTY4",
      "user_id": "jason@omnistory.net",
      "user_name": "jason",
      "audio_mute": false,
      "audio_mute": false
    }
  ]
}
```

### publish

사용자의 영상을 송출합니다. 송출되는 영상을 재생하기 위해서는 video 태그가 필요합니다. Omnitalk SDK는 video 태그의 id를 기반으로 영상을 재생합니다. 파라미터로 사용자 지정 tag id를 전달할 수 있습니다. 사용자 지정 tag id를 전달하지 않으면 옴니톡 SDK에서 발급한 [Tag Rule](#audio-video-tag-rule)에 따라서 video 태그를 생성하시면 됩니다.

같은 룸의 다른 사용자가 publish를 하게 되면 `BROADCASTING_EVENT` 를 받게 됩니다. publish한 방송의 영상을 보고 싶은 사용자는 구독 [subscribe API](#subscribe)를 이용하면 됩니다.&#x20;

```jsx
await sdk.publish(tag_id);
```

| Parameter | Mandatory/Optional | Type   | Description                  |
| --------- | ------------------ | ------ | ---------------------------- |
| tag\_id   | O                  | String | Video 입출력을 위한  사용자 지정 Tag ID |

* 리턴 객체 | PublishResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4Njcx"
}
```

### publishList

참여한 룸에서 방송 중인 사용자 리스트를 조회합니다. room\_id를 전달하지 않으면 자신이 참여한 룸의 참여자 리스트를 조회합니다.&#x20;

```jsx
await sdk.publishList();
```

| Parameter | Mandatory/Optional | Type   | Description                |
| --------- | ------------------ | ------ | -------------------------- |
| room\_id  | O                  | String |                            |
| page      | O                  | Number | default = 1, per page = 10 |

* 리턴 객체 | PublishListResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",
  "room_id": "9389314d3cb1b92eeaa81b618e0f",
  "page": 1,
  "count": 1,
  "list": [
    {
      "session": "YzMyYWE1YTA3MmJhMTY4",
      "user_id": "sADKOqOGBA",
      "user_name": "kAIaDnhpPH",
      "call_type": "videocall"
    }
  ]
}
```

### subscribe

구독할 방송의 session을 전달하면 해당 방송을 구독할 수 있습니다. 송출되는 영상을 재생하기 위해서는 video 태그가 필요합니다. Omnitalk SDK는 video 태그의 id를 기반으로 영상을 재생합니다. 파라미터로 사용자 지정 tag id를 전달할 수 있습니다. 사용자 지정 tag id를 전달하지 않으면 옴니톡 SDK에서 발급한 [Tag Rule](#audio-video-tag-rule)에 따라서 video 태그를 생성하시면 됩니다.

```jsx
await sdk.subscribe(publisher_session);
```

| Parameter          | Mandatory/Optional | Type   | Description |
| ------------------ | ------------------ | ------ | ----------- |
| publisher\_session | M                  | String |             |
| tag\_id            | O                  | String |             |

* 리턴 객체 | SubscribeResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4Nj", // 자신의 session
  "publisher_session": "YzMyYWE1YTA3MmJhMTY4Njg", // 송출자의 session
  "screen": false // 화면 공유 여부에 대한 boolean 값
}
```

### unsubscribe

구독 중인 방송의 구독을 취소할 수 있습니다.

<pre class="language-jsx"><code class="lang-jsx"><strong>await sdk.unSubscribe(publisher_session);
</strong></code></pre>

| Parameter          | Mandatory/Optional | Type   | Description |
| ------------------ | ------------------ | ------ | ----------- |
| publisher\_session | M                  | String |             |

* 리턴 객체 | UnsubscribeResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4Nj",
  "publisher_session": "YzMyYWE1YTA3MmJhMTY4Njg"
}
```

### screenShare

화면 공유 기능을 수행하기 위한 API입니다. 화면 공유는 룸당 하나의 영상만 송출 가능합니다. 송출되는 영상을 재생하기 위해서는 video 태그가 필요합니다. Omnitalk SDK는 video 태그의 id를 기반으로 영상을 재생합니다. 파라미터로 사용자 지정 tag id를 전달할 수 있습니다. 사용자 지정 tag id를 전달하지 않으면 옴니톡 SDK에서 발급한 [Tag Rule](#audio-video-tag-rule)에 따라서 video 태그를 생성하시면 됩니다.

screenShare 호출 성공시 동일 방의 다른 사용자들에게 `SCREEEN_SHARE_EVENT`가 전달됩니다. 공유 화면을 보고 싶은 사용자는 이벤트 메시지에서 전달하는 session을 구독하면 됩니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message#screen_share_event))

```jsx
await sdk.screenShare(tag_id);
```

| Parameter | Mandatory/Optional | Type   | Description                 |
| --------- | ------------------ | ------ | --------------------------- |
| tag\_id   | O                  | String | Video 입출력을 위한 사용자 지정 Tag ID |

* 리턴 객체 | ScreenShareResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4Nj"
}
```

### screenUnshare

자신의 화면 공유를 취소합니다. 동일 방의 다른 사용자들에게 `SCREEEN_UNSHARE_EVENT`가 전달됩니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message#screen_unshare_event))

```jsx
await sdk.screenUnshare();
```

* 리턴 객체 | ScreenUnshareResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4Nj"
}
```

### screenList

룸에서 화면을 공유하고 있는 방송이 있다면 그 방송에 대한 정보를 조회하는 API입니다. 별도의 room\_id를 전달하지 않으면 자신이 참여하고 있는 룸의 화면 공유 정보를 조회하게 됩니다.

```jsx
await sdk.screenList();
```

| Parameter | Mandatory/Optional | Type   | Description |
| --------- | ------------------ | ------ | ----------- |
| room\_id  | O                  | String |             |

* 리턴 객체 | ScreenListResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",
  "room_id": "9389314d3cb1b92eeaa81b618e0f",
  "count": 1,
  "page": 1,
  "list": [
    {
      "session": "YzMyYWE1YTA3MmJhMTY4",
      "user_id": "sADKOqOGBA",
      "user_name": "kAIaDnhpPH",
      "call_type": "videocall"
    }
  ]
}
```

### offerCall

음성 또는 영상 통화를 위한 발신 기능을 수행합니다. 첫 번째 파라미터인 call\_type이 음성 통화 요청인지, 영상 통화 요청인지 결정합니다. callee는 전화를 요청할 상대방의 user\_id를 전달해 주시면 됩니다. record 파라미터를 전달하지 않으면 default=false 입니다.

영상 통화의 경우 송출되는 영상을 재생하기 위해서는 video 태그가 필요합니다. Omnitalk SDK는 video 태그의 id를 기반으로 영상을 재생합니다. 파라미터로 사용자 지정 tag id를 전달할 수 있습니다. 사용자 지정 tag id를 전달하지 않으면 옴니톡 SDK에서 발급한 [Tag Rule](#audio-video-tag-rule)에 따라서 video 태그를 생성하시면 됩니다. 자신의 영상은 `Omnitalk-LocalVideo-0` 상대방 영상은 `Omnitalk-RemoteVideo-0` 입니다.

offerCall 호출이 성공하면 callee에게는 `RINGING_EVENT`가 전달됩니다. offerCall을 호출한 측은 `RINGBACK_EVENT`를 받게 됩니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message))

<mark style="color:orange;">⚠️</mark> 2.1.x 이후 버전부터 record 파라메터가 삭제되었습니다. 녹음은 [recordingStart](#recordingstart) 함수를 사용합니다.&#x20;

```jsx
await sdk.offerCall(call_type, callee);
```

| Parameter       | Mandatory/Optional | Type    | Description          |
| --------------- | ------------------ | ------- | -------------------- |
| call\_type      | M                  | String  |                      |
| callee          | M                  | String  | 이메일, 전화번호, 닉네임, id 등 |
| record          | O                  | Boolean | 2.1.x 버전부터 삭제        |
| local\_tag\_id  | O                  | String  |                      |
| remote\_tag\_id | O                  | String  |                      |

### answerCall

음성 또는 영상 통화를 위한 착신 기능을 수행합니다. answerCall 호출이 성공하면 caller, callee 양측 모두 `CONNECTED_EVENT`를 받습니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message))

```jsx
await sdk.answerCall(call_type, caller);
```

| Parameter       | Mandatory/Optional | Type   | Description |
| --------------- | ------------------ | ------ | ----------- |
| call\_type      | O                  | String |             |
| caller          | O                  | String |             |
| local\_tag\_id  | O                  | String |             |
| remote\_tag\_id | O                  | String |             |

### makeSipNumber

애플리케이션에서 일반 전화와 통화할 수 있는 번호를 발급 받습니다. 파라미터에 call\_number를 전달하지 않으면 서버에서 임의의 6자리 번호를 발급합니다.

애플리케이션에서 call\_number 발급 이후에 일반 전화로 옴니톡 070 번호로 전화를 걸고, 발급받은 6자리 call\_number를 입력하면 일반 전화에서 애플리케이션으로 통화 요청이 이루어 집니다. 이 때, 애플리케이션에서는 `RINGING_EVENT`를 받게 됩니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message)) 전화 수신을 위해서는 [answerCall()](#answercall)를 호출하시면 됩니다.

```jsx
await sdk.makeSipNumber();
```

| Parameter    | Mandatory/Optional | Type   | Description |
| ------------ | ------------------ | ------ | ----------- |
| call\_number | O                  | String |             |
| room\_id     | O                  | String |             |

* 리턴 객체 | MakeSipNumberResult

```json
{
  "call_number": "123456"
}
```

### mute/unmute

mute할 track을 인자로 넘겨주면 음소거 및 음소거 해제 기능을 수행할 수 있습니다. 비디오 mute는 로컬의 화면 송출을 off 시키는 기능입니다. mute/unmute API를 호출하면 룸의 다른 사용자들에게 `MUTE_EVENT` 또는 `UNMUTE_EVENT`가 전달됩니다.

```jsx
await sdk.setMute(track);
await sdk.setUnmute(track);
```

| Parameter | Mandatory/Optional | Type   | Description      |
| --------- | ------------------ | ------ | ---------------- |
| track     | M                  | String | "audio", "video" |

### getDeviceList

해당 장치의 모든 오디오, 비디오 장치를 조회할 수 있는 API 입니다.

```jsx
await sdk.getDeviceList();
```

* 리턴 객체 | DeviceList

```json
{
  "videoinput": [
    {
      "kind": "videoinput",
      "label": "Logitech BRIO (046d:085e)",
      "deviceId": "33fb0bfdda06b8815f94baa46d3965211b5476825021ac91578280a5d7c05b94",
      "groupId": "cbc0be3ca9648a43fa29e144e1460bb6df916243eea817625a4700b2cf910654"
    },
    {
      "kind": "videoinput",
      "label": "FaceTime HD 카메라 (3A71:F4B5)",
      "deviceId": "9e82b7ecc5f2844f1109f31ac47bb1c5fc1d9d13d7f627e4f1db3fd0132bf9be",
      "groupId": "5ccd5bf9211dfd080cfcc6f8187f486c9a102e579a4d9e3f4e22cdfecb732cf7"
    }
  ],
  "audioinput": [
    {
      "kind": "audioinput",
      "label": "Logitech BRIO (046d:085e)",
      "deviceId": "5f9715786e17b339dfdfabfd65fc0a5b5850ec11fc6509085c4a13b5fa760bef",
      "groupId": "2479fd4c965cadd52de1d9dd54debbcdb0caf370a2c0b916f13554d9eaec782d"
    },
    {
      "kind": "audioinput",
      "label": "MacBook Pro 마이크 (Built-in)",
      "deviceId": "1a825a6af6bb985db3dbcdedf67cfad0d2b850f892a4dbd049fa01f140c2a972",
      "groupId": "dbec76dc0e283229718a34a2a07de4e98bb5987fb5db535affb6428c6b0f1339"
    }
  ]
}
```

### setAudioDevice

사용하고 싶은 마이크 장치의 device id를 인수로 전달하면 됩니다. device id는 [getDeviceList()](#getdevicelist) 에서 참조 바랍니다. 이미 통화 또는 회의에 참여 중일 때 호출할 경우, 송출되는 장치가 변경되어 송출 됩니다.

```jsx
await sdk.setAudioDevice(device_id);
```

| Parameter  | Mandatory/Optional | Type   | Description |
| ---------- | ------------------ | ------ | ----------- |
| device\_id | M                  | String |             |

### setVideoDevice

사용하고 싶은 카메라 장치의 device id를 인수로 전달하면 됩니다. device id는 [getDeviceList()](#getdevicelist) 에서 참조 바랍니다. 이미 통화 또는 회의에 참여 중일 때 호출할 경우, 송출되는 장치가 변경되어 송출 됩니다.

```jsx
await sdk.setVideoDevice(device_id);
```

| Parameter  | Mandatory/Optional | Type   | Description |
| ---------- | ------------------ | ------ | ----------- |
| device\_id | M                  | String |             |

### destroyRoom

룸 삭제 기능을 수행하는 API 입니다. 룸에 어떤 참여자도 없으면 Omnitalk SDK에서 일정 시간 이후 자동으로 룸을 제거합니다. 만약 명시적으로 룸을 삭제하거나 추가 사용자의 룸 참여를 막고 싶다면 room\_id를 전달하여 기능을 수행할 수 있습니다.

자신이 참여하고 있는 룸을 삭제할 수는 없습니다. 방송 중인 참여자가 있는 룸을 삭제하게 되면 방송 중인 참여자들은 계속 방송할 수 있지만 추가적인 룸 참여는 불가능한 상태가 됩니다.

```jsx
await sdk.destroyRoom(room_id);
```

| Parameter | Mandatory/Optional | Type   | Description |
| --------- | ------------------ | ------ | ----------- |
| room\_id  | M                  | String |             |

* 리턴 객체 | DestroyRoomResult

```json
1
  "session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",
  "room_id":"8a1086680e47261208eeff87000b"
}
```

### leave

방송을 종료하는 API입니다. 통화 또는 회의에 참여한 상태일 경우, session을 전달하지 않으면 자신의 방송을 종료하고 퇴장(통화 종료)하게 됩니다. 퇴장시, 다른 참가자들은 LEAVE\_EVENT 를 수신 합니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message))

파라미터에 session를 전달하면 해당 session을 가진 사용자가 퇴장(통화 종료) 하게 됩니다. 해당 상황은 수신 거절이나 강제 퇴장 등의 기능으로 활용할 수 있습니다.&#x20;

<mark style="color:orange;">⚠️</mark> 2.1.x 이후 버전에서 leave는 본인의 퇴장만 가능합니다. 상대방의 강제 종료는[ kickout](#kickout)을 사용해 주세요.

```jsx
await sdk.leave();
```

| Parameter   | Mandatory/Optional | Type   | Description   |
| ----------- | ------------------ | ------ | ------------- |
| session\_id | O                  | String | 2.1.x 버전부터 삭제 |

### sendMessage

채팅 기능을 사용할 수 있는 API 입니다. 같은방에 참여한 사용자들에게는 MESSAGE\_EVENT 이벤트가 발생합니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message))

```jsx
await sdk.sendMessage(message);
```

| Parameter | Mandatory/Optional | Type   | Description     |
| --------- | ------------------ | ------ | --------------- |
| message   | M                  | String | max length 2048 |

### sendWhisper

귓속말 기능을 사용할 수 있는 API 입니다. target에 다른 참여자 session을 전달 해야하며, 해당 session을 가진 참여자 에게만 MESSAGE\_EVENT 이벤트가 발생합니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message))

```jsx
await sdk.sendWhisper(message, target);
```

<table><thead><tr><th>Parameter</th><th>Mandatory/Optional</th><th width="173">Type</th><th>Description</th></tr></thead><tbody><tr><td>message</td><td>M</td><td>String</td><td></td></tr><tr><td>target</td><td>M</td><td>String</td><td>귓속말을 보낼 상대의 session</td></tr></tbody></table>

### messageList

입장한 방의 채팅 참여자 목록을 조회하고 MessageListResult 객체를 리턴합니다.

```jsx
await sdk.messageList();
```

* 리턴 객체 | MessageListResult

```json
{
  "session": "YjQ1ZGUzYzA3MmJhMTY4NjcxMD",
  "count": 1,
  "page": 1,
  "list": [
    {
      "call_type": "audiocall",
      "session": "Z1RWVnJRZGp1YTE2ODk3MzU1NzMtMTE3",
      "user_id": "gKodyLVKll",
      "user_name": "pVtOlFfxfO"
    }
  ]
}
```

***

{% hint style="info" %}
**sdk 2.1.x 이후 버전부터 사용 가능**
{% endhint %}

### kickOut

사용자가 룸에 참여해 방송을 개시한 이후에 다른 사용자를 강제퇴장 시키는 기능입니다. 인수로 전달하는 session은 룸에서 강제 퇴장되며 세션이 끊어지게 됩니다. 룸의 다른 참여자들에게는 KICKOUT\_EVENT가 발생합니다.

```javascript
await sdk.kickOut(target)
```

| Parameter | Mandatory/Optional | Type   | Description        |
| --------- | ------------------ | ------ | ------------------ |
| target    | M                  | string | 강제 종료할 상대의 session |

### recordingStart

음성 녹음을 시작하는 API입니다. 모든 call\_type에서 호출할 수 있습니다. 단, 녹음 시작 API 호출은 call/room에 참여한 사용자별로 한 번만 호출할 수 있습니다.  recordingStop()을 호출하지 않고 leave()를 호출 하거나 연결이 끊어져도 해당 시점까지 녹음은 마무리됩니다.

```javascript
await sdk.recordingStart();
```

### recordingStop

음성 녹음을 종료하는 API입니다. 녹음 완료 시 옴니톡 콘솔에 등록한 Webhook URL로 콜백을 받을 수 있습니다.

```javascript
await sdk.recordingStop();
```


# Developer's Guide


# Pre-requisite

해당 페이지에서는 Omnitalk SDK를 사용하기 위해서 공통적으로 필요한 내용에 대해서 설명합니다.&#x20;

## 1. SDK 객체 초기화

[콘솔](https://omnitalk.io/console/service/service-id)에서 발급받은 Service Id와 Service Key로 SDK를 초기화 합니다. 해당 정보는 노출되지 않도록 주의하여야 합니다. 초기화된 SDK 객체는 이후 모든 메서드 호출에 사용됩니다.&#x20;

Omnitalk SDK는 싱글톤 패턴으로 제공됩니다. 아래 방법으로 SDK 초기화 및 객체를 얻을 수 있습니다.

```typescript
import { Omnitalk } from "omnitalk-ts-sdk";

const SERVICE_ID = '발급받은 service id';
const SERVICE_KEY = '발급받은 service key';

Omnitalk.sdkInit(SERVICE_ID, SERVICE_KEY);
const sdk = Omnitalk.getInstance();
```

## 2. 이벤트 리스너 등록

Omnitalk SDK에서 발생하는 이벤트를 수신하기 위해서 이벤트 리스너를 등록합니다. 이벤트 메세지의 상세 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

이벤트 메세지의 cmd 필드로 어떤 이벤트인지 확인할 수 있습니다. 해당 내용은 enum type `OmniEvent를`참조할 수 있습니다. 이벤트 메세지 내용도 아래와 같이 캐스팅하여 사용할 수 있습니다. 아래에서 간단한 예시를 보여 드립니다.

```typescript
sdk.on('event', msg => {
  switch(msg.cmd) {
    case OmniEvent.RINGBACK_EVENT:
      const ringbackMsg = msg as EventRingBack;
      break;
    case OmniEvent.RINGING_EVENT:
      const ringingMsg = msg as EventRinging;
      break;
  }
});
```


# Audio Call

audiocall은 1:1 전화 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 사용하여 offerCall(), answerCall()을 각각 호출하고 해당 이벤트 메시지에 대응하는 것으로 전화 기능을 간단히 구현할 수 있습니다.

[Call Flow](/commons/call-flow) 에서는 audiocall의 흐름을 sequence diagram으로 보여줍니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 user\_id는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. user\_id는 Optional 이며, 생략시 Omnitalk 서버에서 임의의 id를 부여합니다.

```typescript
await sdk.createSession(user_id);
```

## Step 2. 발신

동일한 Service Id로  세션을 생성한 사용자 중  idle state의 사용자에게 전화 요청을 할 수 있습니다.

offerCall() API로 전화 요청을 할 수 있습니다. 파라미터로 call\_type, callee의 user\_id, 녹음 여부를 전달하면 됩니다.

* call\_type: 전화 타입을 의미합니다. CALL\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 음성 통화를 위해서는 `audiocall` 을 전달하시면 됩니다.&#x20;
* callee:  callee의 user\_id를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. defalut = false

```typescript
await sdk.offerCall(CALL_TYPE.AUDIO_CALL, callee, true);
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 `RINGING_EVENT`를 수신합니다.

## Step 3. 수신

### callee가 RINGING\_EVENT를 받은 경우

callee가 세션을 생성한 상태에서 caller가 offerCall(전화 요청)을 하여`RINGING_EVENT`를 받은 경우, callee는 별도의 파라미터를 전달하지 않고 answerCall()을 호출하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 leave()를 호출하시면 됩니다.

```typescript
await sdk.answerCall();
```

### callee가 전화 요청(offerCall) 이후에 session을 생성한 경우

callee가 세션을 생성하기 전 caller가 offerCall(전화 요청)을 하여 `RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터에 call\_type과 caller를 전달하여 전화를 수신할 수 있습니다. 이 경우, 애플리케이션에서 callee 에게 call\_type과 caller를 전달해 주어야 합니다.

* call\_type: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 때와 동일하게 `audiocall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 user\_id를 전달하시면 됩니다.

```typescript
await sdk.answerCall(CALL_TYPE.AUDIO_CALL, caller);
```

## Step 4. 연결 성공

음성 통화 연결이 성공하면 caller, callee 양측 모두 `CONNECTED_EVENT` 를 수신합니다.

## Step 5. 전화 끊기

[leave()](/typescript/api-reference#leave) API를 통해서 전화 연결을 끊을 수 있습니다.

```typescript
await sdk.leave();
```

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 track type은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```typescript
await sdk.setMute(TRACK_TYPE.AUDIO);
```

### 입력 장치 변경

전화 연결 전, 또는 전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 API를 제공합니다.&#x20;

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. [setAudioDevice()](/typescript/api-reference#setaudiodevice) 파라미터로 deviceId를 전달하여 입력 장치를 변경할 수 있습니다.


# Video Call

videocall은 1:1 영상 통화 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 사용하여 offerCall(), answerCall()을 각각 호출하고 해당 이벤트 메시지에 대응하는 것으로 전화 기능을 간단히 구현할 수 있습니다.

[Call Flow](/commons/call-flow) 에서는 audiocall의 흐름을 sequence diagram으로 보여줍니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 user\_id는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. user\_id는 Optional 이며, 생략시 Omnitalk 서버에서 임의의 id를 부여합니다.

```typescript
await sdk.createSession(user_id);
```

## Step 2. 발신

동일한 Service Id로  세션을 생성한 사용자 중  idle state의 사용자에게 전화 요청을 할 수 있습니다.

offerCall() API로 전화 요청을 할 수 있습니다. 파라미터로 call\_type, callee의 user\_id, 녹음 여부를 전달하면 됩니다.

* call\_type: 전화 타입을 의미합니다. CALL\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 1:1 영상 통화를 위해서는 `videocall` 을 전달하시면 됩니다.&#x20;
* callee: callee의 user\_id를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. defalut = false

```typescript
await sdk.offerCall(CALL_TYPE.VIDEO_CALL, callee, true);
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 `RINGING_EVENT`를 수신합니다.

## Step 3. 수신

### callee가 RINGING\_EVENT를 받은 경우

callee가 세션을 생성한 상태에서 caller가 offerCall(전화 요청)을 하여`RINGING_EVENT`를 받은 경우, callee는 별도의 파라미터를 전달하지 않고 answerCall()을 호출하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 leave()를 호출하시면 됩니다.

```typescript
await sdk.answerCall();
```

### callee가 전화 요청(offerCall) 이후에 session을 생성한 경우

callee가 세션을 생성하기 전 caller가 offerCall(전화 요청)을 하여 `RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터에 call\_type과 caller를 전달하여 전화를 수신할 수 있습니다. 이 경우, 애플리케이션에서 callee 에게 call\_type과 caller를 전달해 주어야 합니다.

* call\_type: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 떄와 동일하게 `videocall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 user\_id를 전달하시면 됩니다.

```typescript
await sdk.answerCall(CALL_TYPE.VIDEO_CALL, caller);
```

## Step 4. 연결 성공

1:1 영상 통화 연결이 성공하면 caller, callee 양측 모두 `CONNECTED_EVENT` 를 수신합니다.

## Step 5. 전화 끊기

[leave()](/typescript/api-reference#leave) API를 통해서 전화 연결을 끊을 수 있습니다.

```typescript
await sdk.leave();
```

## 비디오 장치 제어

### mute/unmute

영상 전화중에 영상 송출을 중단할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 track type은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```typescript
await sdk.setMute(TRACK_TYPE.VIDEO);
```

### 입력 장치 변경

전화 연결 전, 또는 영상 전화 통화중에 입력(카메라) 장치를 변경할 수 있도록 API를 제공합니다.&#x20;

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. [setVideoDevice()](/typescript/api-reference#setvideodevice) 파라미터로 deviceId를 전달하여 입력 장치를 변경할 수 있습니다.

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 track type은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```typescript
await sdk.setMute(TRACK_TYPE.AUDIO);
```

### 입력 장치 변경

전화 연결 전, 또는 전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 API를 제공합니다.&#x20;

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. [setAudioDevice()](/typescript/api-reference#setaudiodevice) 파라미터로 deviceId를 전달하여 입력 장치를 변경할 수 있습니다.


# SIP Call

sipcall은 애플리케이션과 일반 전화 간 전화를 연결 할 수 있도록 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 사용하여 offerCall(), answerCall()을 호출하고 해당 이벤트 메시지에 대응하는 것으로 애플리케이션과 일반 전화 간 전화 연결을 간단히 구현할 수 있습니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 user\_id는 사용자를 구분하기 위한 고유한 id입니다. user\_id는 Optional 이며, 생략시 Omnitalk 서버에서 임의의 id를 부여합니다.

```typescript
await sdk.createSession(user_id);
```

## Step 2. 발신

offerCall() API로 애플리케이션에서 일반 전화로 전화 요청을 할 수 있습니다. 파라미터로 call\_type, callee의 전화번호, 녹음 여부를 전달하면 됩니다.

* call\_type: 전화 타입을 의미합니다. CALL\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 일반 전화와 음성 통화를 위해서는 `sipcall` 을 전달하시면 됩니다.
* callee: 전화를 걸고자 하는 수신자의 전화 번호를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. defalut = false

```typescript
await sdk.offerCall(CALL_TYPE.SIP_CALL, '01012345678', true);
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 전화 요청이 울리게 됩니다. 이 때, callee에게 보여지는 발신자 정보는 옴니톡에서 발급받은 번호 입니다.

## Step 3. 수신

일반 전화에서 애플리케이션으로 전화 요청을 할 경우에는 [makeSipNumber()](/typescript/api-reference#makesipnumber) API를 통해서 6자리의 call\_number를 발급 받아야합니다. 일반 전화 -> 애플리케이션 발신 Call Flow는 아래와 같습니다.

1. 애플리케이션에서 makeSipNumber() API 통해서 call\_number 발급 ( 4번 다음 순서로 변경 가능 )
2. 일반 전화로 옴니톡에서 발급받은 번호로 전화
3. 전화를 요청하고자 하는 6자리 call\_number(PIN Number) 입력
4. 해당 call\_number로 발신 요청

애플리케이션으로 전화 요청이 왔을때, 수신하는 방법은 아래와 같습니다.

### callee가 call\_number를 생성한 상태에서 전화 요청이 왔을때

callee(애플리케이션)가 call\_number를 생성한 상태에서 caller(일반 전화)가 전화를 걸어`RINGING_EVENT`를 받은 경우, callee는 별도의 파라미터를 전달하지 않고 answerCall()을 호출하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 leave()를 호출하시면 됩니다.

```typescript
await sdk.answerCall();
```

### callee가 call\_number를 생성하기 전 전화 요청이 왔을때

callee(애플리케이션)가 call\_number를 생성하기 전에 caller(일반 전화)가 전화를 걸어`RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터에 call\_type과 caller의 전화번호를 전달하여 전화를 수신할 수 있습니다. 이 경우, 옴니톡 서버에서 별도의 이벤트로 call\_type과 caller의 정보를 제공드릴 예정입니다.

* call\_type: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 떄와 동일하게 `sipcall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 전화번호를 전달하시면 됩니다.

```typescript
await sdk.answerCall(CALL_TYPE.SIPCALL, '01012345678);
```

## Step 4. 연결 성공

음성 통화 연결이 성공하면 callee(애플리케이션)는 `CONNECTED_EVENT` 를 수신합니다.

## Step 5. 전화 끊기

[leave()](/typescript/api-reference#leave) API를 통해서 전화 연결을 끊을 수 있습니다.

```typescript
await sdk.leave();
```

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 track type은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```typescript
await sdk.setMute(TRACK_TYPE.AUDIO);
```

### 입력 장치 변경

전화 연결 전, 또는 전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 API를 제공합니다.&#x20;

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. [setAudioDevice()](/typescript/api-reference#setaudiodevice) 파라미터로 deviceId를 전달하여 입력 장치를 변경할 수 있습니다.


# Audio Room

audioroom은 음성 회의 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. Omnitalk SDK를 사용하여 회의실(룸) 생성 및 참여, 이벤트 메시지에 대응하는 것으로 음성 회의 기능을 간단히 구현할 수 있습니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 user\_id는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. user\_id는 Optional 이며, 생략시 Omnitalk 서버에서 임의의 id를 부여합니다.

```typescript
await sdk.createSession(user_id);
```

## Step 2. 회의실 생성 / 조회

[createRoom()](/typescript/api-reference#createroom) API 를 사용하여 사람들이 입장 할 수 있는 회의실(룸)을 생성합니다. createRoom()의 필수 파라미터은 room\_type은 Omnitalk SDK에서 enum type으로 제공합니다. 음성 회의의 경우는 AUDIO\_ROOM 을 사용하시면 됩니다. createRoom() API 리턴 객체에 room\_id 로 회의실에 참여할 수 있습니다.

```typescript
await sdk.createRoom(VIDEOROOM_TYPE.AUDIO_ROOM, "subject", "123456")
```

이미 다른 사용자가 회의실을 생성 했다면 [roomList()](/typescript/api-reference#roomlist) API 를 사용하여 현재 생성된 회의실 목록을 조회할 수 있습니다. 음성 회의실 목록만 조회하고 싶은 경우 room\_type 을 AUDIO\_ROOM 으로 전달하시면 됩니다. 조회한 목록 결과에 room\_id 로 회의실에 참여할 수 있습니다.

```typescript
await sdk.roomList(VIDEOROOM_TYPE.AUDIO_ROOM);
```

## Step 3. 회의실 참여

[joinRoom()](/typescript/api-reference#joinroom) API 를 사용하여 회의실에 참여할 수 있습니다. 회의실에 참여하게 되면 별도의 작업 없이 참여자들과 음성 회의를 할 수 있게 되며, 회의실에 관련된 이벤트 메세지를 수신할 수 있습니다. 음성 회의실에서 수신 가능한 이벤트는 아래와 같습니다. 자세한 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

* CONNECTED\_EVENT - 새로운 참가자 입장했을 때
* LEAVE\_EVENT - 다른 참가자가 퇴장 했을 때
* MUTE\_EVENT - 다른 참가자가 mute 했을 때
* UNMUTE\_EVENT - 다른 참가자가 unmute 했을 때
* MESSAGE\_EVENT - 채팅 메세지 수신 이벤트, 회의실 입장시 채팅 기능을 사용할 수 있는 상태가 됩니다. 채팅기능 사용법은 [Chatting](/typescript/developers-guide/chatting) 문서를 참조 바랍니다.

```typescript
await sdk.joinRoom(room_id);
```

## Step 4. 회의실 퇴장

[leave()](/typescript/api-reference#leave) API를 통해서 전화 연결을 끊을 수 있습니다. 파라미터에 session을 전달하지 않으면 자신의 방송을 종료하고 퇴장(통화 종료)하게 됩니다. session를 전달하면 해당 session을 가진 사용자가 퇴장(통화 종료) 하게 됩니다. 해당 상황은 수신 거절이나 강제 퇴장 등의 기능으로 활용할 수 있습니다.&#x20;

```typescript
await sdk.leave();
```

## 참여자 목록 조회

[partiList()](/typescript/api-reference#partilist) API 를 사용하여 입장한 회의실에 참여한 사용자 목록을 조회할 수 있습니다.

* 추가 예정 - partiList의 결과에 다른 참가자의 mute 여부를 알 수 있습니다.

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 track type은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```typescript
await sdk.setMute(TRACK_TYPE.AUDIO);
```

### 입력 장치 변경

전화 연결 전, 또는 전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 API를 제공합니다.&#x20;

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. [setAudioDevice()](/typescript/api-reference#setaudiodevice) 파라미터로 deviceId를 전달하여 입력 장치를 변경할 수 있습니다.

## 룸 삭제

현재 참여중이지 않은 회의실은 [destroyRoom()](/typescript/api-reference#destroyroom) API 를 사용하여 회의실을 삭제할 수 있습니다.


# Video Room

videoroom은 영상 회의 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. Omnitalk SDK를 사용하여 회의실(룸) 생성 및 참여, 이벤트 메시지에 대응하는 것으로 음성 회의 기능을 간단히 구현할 수 있습니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 user\_id는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. user\_id는 Optional 이며, 생략시 Omnitalk 서버에서 임의의 id를 부여합니다.

```typescript
await sdk.createSession(user_id);
```

## Step 2. 회의실 생성 / 조회

[createRoom()](/typescript/api-reference#createroom) API 를 사용하여 사람들이 입장 할 수 있는 회의실(룸)을 생성합니다. createRoom()의 필수 파라미터은 room\_type은 Omnitalk SDK에서 enum type으로 제공합니다. 영상 회의의 경우는 `VIDEO_ROOM` 을 사용하시면 됩니다. createRoom() API 리턴 객체에 room\_id 로 회의실에 참여할 수 있습니다.

```typescript
await sdk.createRoom(VIDEOROOM_TYPE.VIDEO_ROOM, "subject", "123456")
```

이미 다른 사용자가 회의실을 생성 했다면 [roomList()](/typescript/api-reference#roomlist) API 를 사용하여 현재 생성된 회의실 목록을 조회할 수 있습니다. 음성 회의실 목록만 조회하고 싶은 경우 room\_type 을 `VIDEO_ROOM` 으로 전달하시면 됩니다. 조회한 목록 결과에 room\_id 로 회의실에 참여할 수 있습니다.

```typescript
await sdk.roomList(VIDEOROOM_TYPE.VIDEO_ROOM);
```

## Step 3. 회의실 참여

[joinRoom()](/typescript/api-reference#joinroom) API 를 사용하여 회의실에 참여할 수 있습니다. 회의실에 참여하게 되면 별도의 작업 없이 참여자들과 음성 회의를 할 수 있게 되며, 영상 송출은 다음 스텝을 참고 바랍니다. 회의실에 관련된 이벤트 메세지를 수신할 수 있습니다. 영상 회의에서 수신 가능한 이벤트는 아래와 같습니다. 자세한 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

* CONNECTED\_EVENT - 새로운 참가자 입장했을 때
* BROADCASTING\_EVENT - 다른 참가자가 영상을 송출했을 때
* LEAVE\_EVENT - 다른 참가자가 퇴장 했을 때
* MUTE\_EVENT - 다른 참가자가 mute 했을 때
* UNMUTE\_EVENT - 다른 참가자가 unmute 했을 때
* SCREEN\_SHARE\_EVENT - 화면 공유 발생 이벤트
* SCREEN\_UNSHARE\_EVENT - 화면 공유 종료 이벤트
* MESSAGE\_EVENT - 채팅 메세지 수신 이벤트, 회의실 입장시 채팅 기능을 사용할 수 있는 상태가 됩니다. 채팅기능 사용법은 [Chatting](/typescript/developers-guide/chatting) 문서를 참조 바랍니다.

```typescript
await sdk.joinRoom(room_id);
```

## Step 4. 영상 송출

### 카메라 영상

[publish()](/typescript/api-reference#publish) API 를 사용하여 카메라 영상을 송출할 수 있습니다. 송출되는 영상을 재생하기 위해서는 video 태그가 필요합니다. Omnitalk SDK는 video 태그의 id를 기반으로 영상을 재생합니다. 파라미터로 사용자 지정 tag id를 전달할 수 있습니다. 사용자 지정 tag id를 전달하지 않으면 옴니톡 SDK에서 발급한 [Tag Rule](#audio-video-tag-rule)에 따라서 video 태그를 생성하시면 됩니다.

publish를 하게 되면 다른 참가자들은 `BROADCASTING_EVENT` 이벤트 메세지를 받게 됩니다. 방송 구독은 다음 스텝을 참고 바랍니다.

```typescript
await sdk.publish(tag_id);
```

### 화면 공유

[screenShare()](/typescript/api-reference#screenshare) API 를 사용하여 사용자의 화면을 공유할 수 있습니다. 송출되는 영상을 재생하기 위해서는 video 태그가 필요합니다. Omnitalk SDK는 video 태그의 id를 기반으로 영상을 재생합니다. 파라미터로 사용자 지정 tag id를 전달할 수 있습니다. 사용자 지정 tag id를 전달하지 않으면 옴니톡 SDK에서 발급한 [Tag Rule](#audio-video-tag-rule)에 따라서 video 태그를 생성하시면 됩니다.

screenShare를 하게 되면 다른 참가자들은 `SCREEN_SHARE_EVENT` 이벤트 메세지를 받게 됩니다. 방송 구독은 다음 스텝을 참고 바랍니다.

```typescript
await sdk.screenShare(tag_id);
```

### 화면 공유 취소

screenUnshare를 하게 되면 화면 공유를 중단합니다. 다른 참가자들은 `SCREEN_UNSHARE_EVENT` 이벤트 메세지를 받게 됩니다.&#x20;

```typescript
await sdk.screenUnshare();
```

## Step 5. 영상 구독

[subscribe()](/typescript/api-reference#subscribe) API 를 사용하여 송출된 영상을 구독할 수 있습니다. 파라미터에 영상 송출자의 session 을 전달하시면 됩니다. session은 partiList() API 또는 `BROADCASTING_EVENT` 또는 `SCREEN_SHARE_EVENT` 에서 확인 하실 수 있습니다.

송출되는 영상을 재생하기 위해서는 video 태그가 필요합니다. Omnitalk SDK는 video 태그의 id를 기반으로 영상을 재생합니다. 파라미터로 사용자 지정 tag id를 전달할 수 있습니다. 사용자 지정 tag id를 전달하지 않으면 옴니톡 SDK에서 발급한 [Tag Rule](#audio-video-tag-rule)에 따라서 video 태그를 생성하시면 됩니다.

```typescript
await sdk.subscribe(publisher_session);
```

### 영상 구독 취소

[unsubscribe()](/typescript/api-reference#unsubscribe) API 를 사용하여 구독중이던 영상을 구독 취소 할 수 있습니다.

```typescript
await sdk.unsubscribe(publisher_session);
```

## Step 6. 회의실 퇴장

[leave()](/typescript/api-reference#leave) API를 통해서 회의실에서 퇴장 할 수 있습니다. 파라미터에 session을 전달하지 않으면 자신의 방송을 종료하고 퇴장하게 됩니다. session를 전달하면 해당 session을 가진 사용자가 퇴장 하게 됩니다. 해당 상황은 수신 거절이나 강제 퇴장 등의 기능으로 활용할 수 있습니다.&#x20;

```typescript
await sdk.leave();
```

## 목록 조회

### 참여자 목록 조회

[partiList()](/typescript/api-reference#partilist) API 를 사용하여 입장한 회의실에 참여한 사용자 목록을 조회할 수 있습니다.

* 추가 예정 - partiList의 결과에 다른 참가자의 mute 여부를 알 수 있습니다.

### 방송 목록 조회

[publishList()](/typescript/api-reference#publishlist) API 를 사용하여 입장한 회의실에 송출중인 방송 목록을 조회할 수 있습니다.

### 화면공유 정보 조회

[screenList()](/typescript/api-reference#screenlist) API 를 사용하여 입장한 회의실에 송출중인 화면 공유 정보를 조회할 수 있습니다.&#x20;

## 비디오 장치 제어

### mute/unmute

영상 송출을 중단할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 track type은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```typescript
await sdk.setMute(TRACK_TYPE.VIDEO);
```

### 입력 장치 변경

전화 연결 전, 또는 영상 전화 통화중에 입력(카메라) 장치를 변경할 수 있도록 API를 제공합니다.&#x20;

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. [setVideoDevice()](/typescript/api-reference#setvideodevice) 파라미터로 deviceId를 전달하여 입력 장치를 변경할 수 있습니다.

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 track type은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```typescript
await sdk.setMute(TRACK_TYPE.AUDIO);
```

### 입력 장치 변경

전화 연결 전, 또는 전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 API를 제공합니다.&#x20;

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. [setAudioDevice()](/typescript/api-reference#setaudiodevice) 파라미터로 deviceId를 전달하여 입력 장치를 변경할 수 있습니다.

## 룸 삭제

현재 참여중이지 않은 회의실은 [destroyRoom()](/typescript/api-reference#destroyroom) API 를 사용하여 회의실을 삭제할 수 있습니다.


# Chatting

옴니톡 SDK가 제공하는 채팅 기능은 모든 room\_type에서 기본으로 제공됩니다. 상대방과 음성이 연결되는 시점부터 채팅 기능을 사용할 수 있습니다.

## 메세지 전송

[sendMessage()](/typescript/api-reference#sendmessage) API 를 사용하여 같은 룸에 참여한 모든 사용자에게 채팅 메세지를 전달할 수 있습니다. message의 최대 길이는 2048자 입니다.

```typescript
await sdk.sendMessage(message);
```

## 귓속말 전송

[sendWhisper()](/typescript/api-reference#sendwhisper) API 를 사용하여 특정 사용자에게 귓속말 메세지를 전달할 수 있습니다. 첫번째 파라미터인 message의 최대 길이는 2048자 입니다. 두번째 파라미터는 귓속말을 보내고자 하는 대상의 session을 전달하시면 됩니다.

```typescript
await sdk.sendWhisper(message, target_session);
```

## 이벤트 수신

이벤트 메세지 수신 방법은 [이벤트 리스너 등록](https://docs.omnitalk.io/typescript/developers-guide/pages/w8ACkJxajWMoTKkdX6Xw#2.) 를 참고 바랍니다. 채팅 메세지의 이벤트 이름은 `MESSAGE_EVENT` 입니다. 채팅 이벤트 메세지의 종류는 4가지로, message action으로 구분됩니다.

* send: 특정 참가자가 **채팅 메세지를 전송** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지
* whisper: 특정 참가자가 다른 참가자에게 **귓속말을 전송** 했을때, **귓속말 대상자에게 발생**하는 이벤트 메세지
* join: 새로운 **참가자가 입장** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지
* leave: **참가자가 퇴장** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지


# Installation

## 지원 환경

* iOS Version 13.0 이상
* 지원 언어: Swift5
* 배포방식: Swift Package Manager

## 설치

1. Xcode > File > Add Packages
2. <https://github.com/omnistory-labs/omnitalk.ios.sdk> 입력
3. Dependency Rule: Branch - main
4. Add Package 선택

## 권한 설정

Omnitalk SDK를 사용하기 위해서는 카메라와 마이크 권한이 필요합니다. 앱 info에 아래 두 권한을 설정합니다.

* Privacy - Camera Usage Description
* Privacy - Microphone Usage Description


# Quick Start

Omnitalk SDK를 어떻게 활용할 수 있는지에 대한 간단한 예시입니다. 기본적으로 모든 API는 async, await로 작성 되었으며, 요청이 실패한 경우 에러를 throw 합니다. API들의 자세한 사용법은 [iOS API Reference](/ios/api-reference)를 참조 바랍니다.

데모 앱 소스코드: <https://github.com/omnistory-labs/omnitalk.ios.sdk/tree/demo>

## 1:1 영상 통화

### 1. 옴니톡 객체 생성

[콘솔](https://omnitalk.io/console/service/service-id)에서 발급받은 Service ID와 Service KEY로 Omnitalk 객체를 생성합니다.

```swift
import OmnitalkSdk

try OmniTalk.sdkInit(serviceId: "YOUR_SERVICE_ID", serviceKey: "YOUR_SERVICE_KEY")
let sdk = OmniTalk.getInstance()
```

### 2. 세션 생성

인수로 전달한 userId로 세션을 생성하게 됩니다. userId는 Optional이며, nil일 경우 서버에서 임의의 userId를 생성합니다.

```swift
let createSessionResult = try await sdk.createSession(userId: "alice")
```

### 3. 발신

1:1 영상 통화를 구현하기 위한 발신 기능은 [offerCall()](/ios/api-reference#offercall) API를 이용합니다. 자신과 상대방의 영상을 화면에 재생하기 위해서 파라미터에 영상을 출력할 `RTCMTLVideoView` 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

offerCall 호출이 성공하면 caller에게는 `RINGBACK_EVENT`가, callee에게는 `RINGING_EVENT`가 전달됩니다.

```swift
import WebRTC

let callee = "test@omnistory.net"
let localView = await RTCMTLVideoView()
let remoteView = await RTCMTLVideoView()
try await sdk.offerCall(callType: .VIDEO_CALL, callee: callee, record: true, localView: localView, remoteView: remoteView)
```

### 4. 수신

callee측에서는 `RINGING_EVENT`를 받고 통화를 수락하거나 거절할 수 있습니다. 통화 수락은 [answerCall()](/ios/api-reference#answercall) API를 이용합니다. 자신과 상대방의 영상을 화면에 재생하기 위해서 파라미터에 영상을 출력할 `RTCMTLVideoView` 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

answerCall이 정상적으로 수행되면 caller, callee 양측은 `CONNECTED_EVENT`를 받습니다. 수신 거절은 [leave()](/ios/api-reference#leave) API를 이용하시면 됩니다.

```swift
func onEvent(eventName: OmniEvent, message: Any) {
    switch eventName {
        case .RINGING_EVENT:
            try await sdk.answerCall(localView: localView, remoteView: remoteView)
        case .CONNECTED_EVENT:
            ...
    }
}
```

## 영상 회의

### 1. 옴니톡 객체 생성

[콘솔](https://omnitalk.io/console/service/service-id)에서 발급받은 Service ID로 Omnitalk 객체를 생성합니다.

```swift
import OmnitalkSdk

try OmniTalk.sdkInit(serviceId: "YOUR_SERVICE_ID", serviceKey: "YOUR_SERVICE_KEY")
let sdk = OmniTalk.getInstance()
```

### 2. 세션 생성

인수로 전달한 user\_id로 세션을 생성하게 됩니다. userId는 Optional이며, nil일 경우 서버에서 임의의 userId를 생성합니다.

```swift
let createSessionResult = try await sdk.createSession(userId: "alice")
```

### 3. 룸 생성

영상 회의를 위한 룸을 생성합니다. roomType을 제외한 나머지 파라미터는 Optional 입니다.

```swift
let createRoomResult = try await sdk?.createRoom(roomType: .VIDEO_ROOM, subject: "subject", secret: "secret", startDate: nil, endDate: nil)
```

### 4. 룸 참여

룸에 참여하게 되면 음성과 채팅 메시지를 주고 받을 수 있는 상태가 됩니다. roomId을 제외한 나머지 파라미터는 Optional 입니다.

```jsx
let roomId = createRoomResult.roomId
try await sdk.joinRoom(roomId: roomId, secret: "secret", userName: "userName")
```

### 5. 방송 시작

로컬의 영상을 송출합니다. publish API는 roomType `VIDEO_ROOM` 또는 `WEBINAR` 에서만 필요한 기능입니다.

파라미터에 로컬의 영상을 출력할 `RTCMTLVideoView` 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

```swift
let localView = await RTCMTLVideoView()
try await sdk.publish(view: localView)
```

### 6. 방송 구독

구독하고자는 방송의 session을 인수로 전달하면 해당 방송을 구독할 수 있습니다. 상대방 영상을 화면에 재생하기 위해서 파라미터에 영상을 출력할 `RTCMTLVideoView` 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

```swift
let remoteView = await RTCMTLVideoView()
await sdk.subscribe(publisherSession: "PUBLISHER_SESSION", view: remoteView)
```


# API Reference

⚠️ SDK 2.0.x 버전과 2.1.x 이후 버전간 호환 불가

옴니톡의 이벤트 목록은[ Event Message](/commons/event-message)를 확인해 주세요. Omnitalk iOS Demo앱 소스 코드는 [이곳](https://github.com/omnistory-labs/omnitalk.ios.sdk/tree/demo) 에서 확인 하실 수 있습니다.&#x20;

## View

영상을 송출하는 videoroom, videocall의 경우 로컬의 영상을 출력할 `RTCMTLVideoView`가 필요합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

Omnitalk iOS SDK는 SwiftUI를 사용하여 영상을 렌더링 합니다. `OmnitalkSdk.WebRTCVideoView` 을 사용하여 영상을 화면에 표현할 수 있습니다. WebRTCVIdeoView의 인자로 RTCMTLVideoView를 전달해 주시면 됩니다.

## Event 수신 방법

Event를 수신할 class에서 OmnitalkSdk의 `OmniEventDelegate`를 채택합니다. OmniEventDelegate의 onEvent로 이벤트 메세지를 수신할 수 있습니다. 이벤트 메세지 내용은 [Event Message](/commons/event-message)를 참조 바랍니다.

`OmniEventDeleagte` protocol의 내용은 두 가지 입니다.&#x20;

* `onEvent(eventName: OmniEvent, message: Any)`
* `onClose()`

이벤트 메세지는 Omnitalk SDK에서 제공하는 타입으로 캐스팅하여 사용할 수 있습니다. 다음은 onEvent 이벤트 처리 예시입니다.

```swift
import OmnitalkSdk

class Test: OmnitalkSdk.OmniEventDelegate {
    func onEvent(eventName: OmniEvent, message: Any) {
    switch eventName {
        case .LEAVE:
            let leaveEventMsg = message as! EventLeave
            ...
    }
    func onClose() {
        ...
    }
}
```

## **Global Module**

Omnitalk sdkInit API를 통해서 객체를 초기화 합니다. 초기화 이후에는 `getInstance()` 를 통해서 객체를 반환 받을 수 있습니다. SDK 객체는 이후 모든 메서드 호출에 사용됩니다. Service Id와 Service Key는 [console 페이지](https://omnitalk.io/console/service/service-id)에서 발급 가능하며 노출되지 않도록 주의하여야 합니다.

```swift
try OmniTalk.sdkInit(serviceId: "YOUR_SERVICE_ID", serviceKey: "YOUR_SERVICE_KEY")
let sdk = OmniTalk.getInstance()
```

## createSession

사용자의 세션을 생성하기 위해 서버와 연결하고 그 결과로 세션 아이디, 유저 아이디 등을 포함한 CreateSessionResult 객체를 리턴합니다. userId를 nil로 전달하면 임의의 ID 정보를 자동으로 할당합니다.

```swift
let createSessionResult = await sdk.createSession(userId: "omnitalk")
```

## makeSipNumber

SIP 전화에 필요한 number를 생성하는 API 입니다. MakeSipNumberResult 객체를 리턴합니다.

```swift
let makeSipNumberResult = await sdk.makeSipNumber(callNumber: "123456", roomId: nil)
```

## ~~sessionList(deprecated)~~

세션 생성 후 같은 Service Id 및 Key를 사용하는 모든 사용자를 조회하고 SessionListResult 객체를 리턴합니다.

```swift
let sessionListResult = await sdk.sessionList(page: 1)
```

## createRoom

방송할 수 있는 방을 만들고 roomId를 포함한 CreateRoomResult 객체를 리턴합니다. roomType를 제외한 나머지 인자는 Optional 입니다.

```swift
let createRoomResult = try await sdk.createRoom(roomType: .VIDEO_ROOM, subject: "subject", secret: "secret", startDate: nil, endDate: nil)
```

## destroyRoom

생성되어 있는 방을 삭제하고 DestroyRoomResult 객체를 리턴합니다.

```swift
let destroyRoomResult = try await sdk.destroyRoom(roomId: "ABC123=")
```

## **roomList**

이미 생성된 방 목록을 조회하고 RoomListResult 객체를 리턴합니다. 방 목록 조회는 roomType별로 가능합니다.

roomType: .ALL 로 적용하면 모든 roomType 목록을 조회할 수 있습니다.

```swift
let roomListResult = try await sdk.roomList(roomType: .VIDEO_ROOM, page: 1)
```

## joinRoom

방에 참여하고 JoinRoomResult 객체를 리턴합니다. 방송을 시작하거나 다른 방송을 시청하기 위해 반드시 참여 과정을 수행해야 합니다. roomId를 제외한 나머지 인자는 Optional 입니다.

JoinRoomResult에 screen 필드는 참여한 방에 화면 공유 진행 여부를 나타냅니다.

```swift
let joinRoomResult = try await sdk.joinRoom(roomId: roomId, secret: "secret", userName: "userName")
```

## partiList

입장한 방의 참여자 목록을 조회하고 PartiListResult 객체를 리턴합니다. roomId를 nil로 전달하면 현재 참여중인 방의 참여자 목록을 조회합니다.

```swift
let partiList = try await sdk.partiList(roomId: nil, page: 1)
```

## publishList

입장한 방의 송출자 목록을 조회하고 PublishListResult 객체를 리턴합니다. roomId를 nil로 전달하면 현재 참여중인 방의 송출자 목록을 조회합니다.

```swift
let publishListResult = try await sdk.publishList(roomId: nil, page: 1)
```

## screenList

입장한 방의 화면공유 목록을 조회하고 ScreenListResult 객체를 리턴합니다. roomId를 nil로 전달하면 현재 참여중인 방의 화면 공유 목록을 조회합니다.

```swift
let screenListResult = try await sdk.screenList(roomId: nil)
```

## publish

방송을 개시하고 자신의 방송 번호를 포함한 PublishResult 객체를 리턴합니다. publish API는 roomType `VIDEO_ROOM` 또는 `WEBINAR` 에서 요구되는 기능입니다.

파라미터에 로컬의 영상을 출력할 RTCMTLVideoView 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

```swift
import WebRTC

let view = await RTCMTLVideoView()
let publishResult = try await sdk.publish(view: view)
```

## subscribe

방송 중인 사용자의 영상을 시청합니다. subscribe API는 roomType `VIDEO_ROOM` 또는 `WEBINAR` 에서 요구되는 기능입니다. 영상을 시청하기 위한 publisherSession 정보는 publishList API를 통해 조회할 수 있습니다. subscribe()를 호출하면 상대방의 영상을 구독하고 구독 정보에 대한 SubscribeResult 객체를 리턴합니다.

subscribe의 경우 송출자의 영상을 출력할 RTCMTLVideoView 객체가 필요합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )&#x20;

```swift
import WebRTC

let subscribeView = await RTCMTLVideoView()
let subscribeResult = try await sdk.subscribe(publisherSession: "PUBLISHER_SESSION", view: subscribeView)
```

## unsubscribe

구독중인 사용자의 영상을 구독 중지하고 UnsubscribeResult 객체를 리턴합니다.

```swift
let unsubscribeResult = try await unsubscribe(publisherSession: "PUBLISHER_SESSION")
```

## offerCall

1:1 음성 또는 영상 발신 기능을 수행하고 OfferCallResult 객체를 리턴합니다. offerCall 호출이 성공하면 수신자는 RINGING\_EVENT 를 받습니다. ( 발신자는 RINGBACK\_EVENT를 수신합니다. )

callType과 calleeId는 필수값이며 녹화 여부에 대한 record는 Optional 입니다. ( 기본값 false )

<mark style="color:orange;">⚠️</mark> 2.1.x 이후 버전부터 record 파라메터가 삭제되었습니다. 녹음은 [recordingStart](#recordingstart) 함수를 사용합니다.&#x20;

callType이 VIDEO\_CALL 인 경우 영상을 표현할 RTCMTLVideoView 타입의 localView와 remoteView는 인자로 전달 해야합니다. AUDIO\_CALL과 SIP\_CALL 의 경우 nil로 전달하시면 됩니다.

offerCall은 수신자가 존재하지 않아도 요청 가능합니다. 수신자가 RINGING\_EVENT를 받지 못했을 경우 offerCall의 리턴 데이터(call\_type, caller)를 수신자의 answerCall 인수로 전달하면 전화를 연결할 수 있습니다. 전체 흐름은 [Call Flow](/commons/call-flow)에서 그림으로 확인할 수 있습니다.

```swift
// videocall의 경우
import WebRTC

let localView = await RTCMTLVideoView()
let remoteView = await RTCMTLVideoView()
let offerCallResult = try await sdk.offerCall(callType: .VIDEO_CALL, callee: "CALLEE_ID", record: true, localView: localView , remoteView: remoteView)

// audiocall의 경우
let offerCallResult = try await sdk.offerCall(callType: .AUDIO_CALL, callee: "CALLEE_ID", record: true, localView: nil, remoteView: nil)
```

## answerCall

발신자가 offerCall을 호출하면 수신자에게는 RINGING\_EVENT가 발생합니다. 수신자가 answerCall을 호출하면 전화를 연결할 수 있습니다. (이 경우에는 answerCall에 인자를 전달하지 않아도 됩니다.) 발신자와 수신자가 연결되면 CONNECTED\_EVENT가 발생합니다.

offerCall은 수신자가 존재하지 않아도 요청 가능합니다. 수신자가 RINGING\_EVENT를 받지 못했을 경우 offerCall의 리턴 데이터(call\_type, caller)를 수신자의 answerCall 인수로 전달하면 전화를 연결할 수 있습니다. 전체 흐름은 [Call Flow](/commons/call-flow)에서 그림으로 확인할 수 있습니다.

iOS SDK에서는 두 상황별로 API를 오버로딩하여 별도로 제공합니다. 예시는 아래와 같습니다.

```swift
// 수신자가 RINGING_EVENT를 받고 answerCall을 호출하는 경우
try await sdk.answerCall(localView: localView, remoteView: remoteView) // videocall
try await sdk.answerCall(localView: nil, remoteView: nil) // audiocall


// 수신자가 RINGING_EVENT를 받지 않은 경우
try await sdk.answerCall(callType: .VIDEO_CALL, caller: "CALLER_ID", localView: localView, remoteView: remoteView) // videocall
try await sdk.answerCall(callType: .AUDIO_CALL, caller: "CALLER_ID", localView: nil, remoteView: nil) // audiocall
```

## leave

구독중인 사용자의 방송 시청을 종료하거나 로컬의 방송을 종료합니다. leave에 종료하고 싶은 sessionId를 넘겨줍니다. sessionId를 전달하지 않는 경우 로컬의 방송이 종료됩니다.

<mark style="color:orange;">⚠️</mark> 2.1.x 이후 버전에서 leave는 본인의 퇴장만 가능합니다. 상대방의 강제 종료는 [kickout](#kickout)을 사용해 주세요.

```swift
try await sdk.leave(sessionId: nil) // default: 자기 자신 퇴장
```

## setVideoDevice

송출중인 카메라 장치를 변경합니다. 인자는 CAM\_TYPE으로 front와 back 모드가 있습니다.

```swift
try await sdk.setVideoDevice(type: .front)
```

## setAudioDevice

송출중인 오디오 장치를 변경합니다. 인자는 MIC\_TYPE으로 defaultInEar와 speaker 모드가 있습니다.

```swift
try await sdk.setAudioDevice(type: .speaker)
```

## setMute

영상 또는 음성의 출력 상태를 mute 상태로 변경합니다. setMute 호출시 다른 참가자들에게 MUTE\_EVENT 이벤트가 발생합니다.

```swift
try await sdk.setMute(track: .VIDEO)
```

## setUnmute

영상 또는 음성의 출력 상태를 mute 상태로 변경합니다. setMute 호출시 다른 참가자들에게 UNMUTE\_EVENT 이벤트가 발생합니다.

```swift
try await sdk.setUnmute(track: .VIDEO)
```

## sendMessage

채팅 기능을 사용할 수 있는 API 입니다. 같은방에 참여한 사용자들에게는 MESSAGE\_EVENT 이벤트가 발생합니다.

```swift
try await sdk.sendMessage(message: "MESSAGE")
```

## sendWhisper

귓속말 기능을 사용할 수 있는 API 입니다. target에 참여자 session을 전달 해야하며, 해당 session을 가진 참여자 에게만 MESSAGE\_EVENT 이벤트가 발생합니다.

```swift
try await sdk.sendWhisper(message: "MESSAGE", target: "ABC123=")
```

## messageList

입장한 방의 채팅 참여자 목록을 조회하고 MessageListResult 객체를 리턴합니다.

```swift
let messageListReulst = try await sdk.messageList()
```

## kickOut

사용자가 룸에 참여해 방송을 개시한 이후에 다른 사용자를 강제퇴장 시키는 기능입니다. 인수로 전달하는 session은 룸에서 강제 퇴장되며 세션이 끊어지게 됩니다. 룸의 다른 참여자들에게는 KICKOUT\_EVENT가 발생합니다.

```javascript
try await sdk.kickOut(target: "ABC123=")
```

***

{% hint style="info" %}
**sdk 2.1.x 이후 버전부터 사용 가능**
{% endhint %}

## recordingStart

음성 녹음을 시작하는 API입니다. 모든 call\_type에서 호출할 수 있습니다. 단, 녹음 시작 API 호출은 call/room에 참여한 사용자별로 한 번만 호출할 수 있습니다.  recordingStop()을 호출하지 않고 leave()를 호출 하거나 연결이 끊어져도 해당 시점까지 녹음은 마무리됩니다.

```javascript
try await sdk.recordingStart();
```

## recordingStop

음성 녹음을 종료하는 API입니다. 녹음 완료 시 옴니톡 콘솔에 등록한 Webhook URL로 콜백을 받을 수 있습니다.

```javascript
try await sdk.recordingStop();
```


# Developer's Guide


# Pre-requisite

해당 페이지에서는 Omnitalk SDK를 사용하기 위해서 공통적으로 필요한 내용에 대해서 설명합니다.&#x20;

## 1. SDK 객체 초기화

[콘솔](https://omnitalk.io/console/service/service-id)에서 발급받은 Service Id와 Service Key로 SDK를 초기화 합니다. 해당 정보는 노출되지 않도록 주의하여야 합니다. 초기화된 SDK 객체는 이후 모든 메서드 호출에 사용됩니다.&#x20;

Omnitalk SDK는 싱글톤 패턴으로 제공됩니다. 아래 방법으로 SDK 초기화 및 객체를 얻을 수 있습니다.

```typescript
import OmnitalkSdk

try OmniTalk.sdkInit(serviceId: "YOUR_SERVICE_ID", serviceKey: "YOUR_SERVICE_KEY")
let sdk = OmniTalk.getInstance()
```

## 2. 이벤트 메세지 수신

Event를 수신할 class에서 OmnitalkSdk의 `OmniEventDelegate`를 채택합니다. OmniEventDelegate의 onEvent로 이벤트 메세지를 수신할 수 있습니다. 이벤트 메세지 내용은 [Event Message](/commons/event-message)를 참조 바랍니다.

`OmniEventDeleagte` protocol의 내용은 두 가지 입니다.&#x20;

* `onEvent(eventName: OmniEvent, message: Any)`
* `onClose()`

이벤트 메세지는 Omnitalk SDK에서 제공하는 타입으로 캐스팅하여 사용할 수 있습니다. 다음은 onEvent 이벤트 처리 예시입니다.

```swift
func onEvent(eventName: OmniEvent, message: Any) {
    switch eventName {
        case .LEAVE:
            let leaveEventMsg = message as! EventLeave
            ...
    }    
}
func onClose() {
    ...
}
```


# Audio Call

audiocall은 1:1 전화 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 사용하여 offerCall(), answerCall()을 각각 호출하고 해당 이벤트 메시지에 대응하는 것으로 전화 기능을 간단히 구현할 수 있습니다.

[Call Flow](/commons/call-flow) 에서는 audiocall의 흐름을 sequence diagram으로 보여줍니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 userId는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. userId는 Optional 이며, nil로 전달할 경우 Omnitalk 서버에서 임의의 id를 부여합니다.

```swift
try await sdk.createSession(userId: "USER_ID")
```

## Step 2. 발신

동일한 Service Id로  세션을 생성한 사용자 중  idle state의 사용자에게 전화 요청을 할 수 있습니다.

offerCall() API로 전화 요청을 할 수 있습니다. 파라미터로 callType, callee의 userId, 녹음 여부를 전달하면 됩니다.

* callType: 전화 타입을 의미합니다. CALL\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 음성 통화를 위해서는 `.AUDIO_CALL` 을 전달하시면 됩니다.&#x20;
* callee: callee의 userId를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. defalut = false
* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. 1:1 전화 기능에서는 nil로 적용하시면 됩니다.

```swift
try await sdk.offerCall(
    callType: .AUDIO_CALL,
    callee: calleeId,
    record: true,
    localView: nil,
    remoteView: nil
)
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 `RINGING_EVENT`를 수신합니다.

## Step 3. 수신

iOS SDK 에서는 아래 두 상황에 대해서 answerCall() API를 오버로딩하여 각각 제공합니다.

### callee가 RINGING\_EVENT를 받은 경우

callee가 세션을 생성한 상태에서 caller가 offerCall(전화 요청)을 하여`RINGING_EVENT`를 받은 경우, callee는 별도의 파라미터를 전달하지 않고 answerCall()을 호출하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 leave()를 호출하시면 됩니다.

* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. 1:1 전화 기능에서는 nil로 적용하시면 됩니다.

```swift
try await sdk.answerCall(localView: nil, remoteView: nil)
```

### callee가 전화 요청(offerCall) 이후에 session을 생성한 경우

callee가 세션을 생성하기 전 caller가 offerCall(전화 요청)을 하여 `RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터에 callType과 caller를 전달하여 전화를 수신할 수 있습니다. 이 경우, 애플리케이션에서 callee 에게 callType과 caller를 전달해 주어야 합니다.

* callType: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 때와 동일하게 `.AUDIO_CALL` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 userId를 전달하시면 됩니다.
* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. 1:1 전화 기능에서는 nil로 적용하시면 됩니다.

```swift
try await sdk.answerCall(
    callType: .AUDIO_CALL,
    caller: callerId,
    localView: nil,
    remoteView: nil
)
```

## Step 4. 연결 성공

음성 통화 연결이 성공하면 caller, callee 양측 모두 `CONNECTED_EVENT` 를 수신합니다.

## Step 5. 전화 끊기

leave() API를 통해서 전화 연결을 끊을 수 있습니다.

```swift
try await sdk.leave()
```

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/ios/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```swift
try await sdk.setMute(track: .AUDIO)
```

### 입력 장치 변경

전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 [setAudioDevice()](/ios/api-reference#setaudiodevice) API를 제공합니다. 파라미터인 MIC\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 귀에 대어 전화받는 `defaultInEar` 타입과 스피커폰 모드인 `speaker` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
try await sdk.setAudioDevice(type: .speaker)
```


# Video Call

videocall은 1:1 영상 통화 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 사용하여 offerCall(), answerCall()을 각각 호출하고 해당 이벤트 메시지에 대응하는 것으로 전화 기능을 간단히 구현할 수 있습니다.

[Call Flow](/commons/call-flow) 에서는 videocall의 흐름을 sequence diagram으로 보여줍니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 userId는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. userId는 Optional 이며, nil로 전달할 경우 Omnitalk 서버에서 임의의 id를 부여합니다.

```swift
try await sdk.createSession(userId: "USER_ID")
```

## Step 2. 발신

동일한 Service Id로  세션을 생성한 사용자 중  idle state의 사용자에게 전화 요청을 할 수 있습니다.

offerCall() API로 전화 요청을 할 수 있습니다. 파라미터로 callType, callee의 userId, 녹음 여부 및 자신과 상대방의 영상을 화면에 재생하기 위해서 영상을 출력할 `RTCMTLVideoView` 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

* call\_type: 전화 타입을 의미합니다. CALL\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 1:1 영상 통화를 위해서는 `.VIDEO_CALL` 을 전달하시면 됩니다.&#x20;
* callee: callee의 userId를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. defalut = false
* localView: 자신의 영상을 재생할 `RTCMTLVideoView` 객체
* remoteView: 상대방의 영상을 재생할 `RTCMTLVideoView` 객체

```swift
import WebRTC

let localView = await RTCMTLVideoView()
let remoteView = await RTCMTLVideoView()

try await sdk.offerCall(
    callType: .VIDEO_CALL,
    callee: calleeId,
    record: true,
    localView: localView,
    remoteView: remoteView
)
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 `RINGING_EVENT`를 수신합니다.

## Step 3. 수신

iOS SDK 에서는 아래 두 상황에 대해서 answerCall() API를 오버로딩하여 각각 제공합니다.

### callee가 RINGING\_EVENT를 받은 경우

callee가 세션을 생성한 상태에서 caller가 offerCall(전화 요청)을 하여`RINGING_EVENT`를 받은 경우, 영상을 재생할 객체만 answerCall() API의 파라미터로 전달하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 leave()를 호출하시면 됩니다.

* localView: 자신의 영상을 재생할 `RTCMTLVideoView` 객체
* remoteView: 상대방의 영상을 재생할 `RTCMTLVideoView` 객체

```swift
import WebRTC

let localView = await RTCMTLVideoView()
let remoteView = await RTCMTLVideoView()
try await sdk.answerCall(localView: localView, remoteView: remoteView)
```

### callee가 전화 요청(offerCall) 이후에 session을 생성한 경우

callee가 세션을 생성하기 전 caller가 offerCall(전화 요청)을 하여 `RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터에 callType과 caller를 전달하여 전화를 수신할 수 있습니다. 이 경우, 애플리케이션에서 callee 에게 callType과 caller를 전달해 주어야 합니다.

* call\_type: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 때와 동일하게 `videocall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 userId를 전달하시면 됩니다.
* localView: 자신의 영상을 재생할 `RTCMTLVideoView` 객체
* remoteView: 상대방의 영상을 재생할 `RTCMTLVideoView` 객체

```typescript
import WebRTC

let localView = await RTCMTLVideoView()
let remoteView = await RTCMTLVideoView()
await sdk.answerCall(
    callType: .VIDEO_CALL,
    caller: callerId,
    localView: localView,
    remoteView: remoteView
)
```

## Step 4. 연결 성공

1:1 영상 통화 연결이 성공하면 caller, callee 양측 모두 `CONNECTED_EVENT` 를 수신합니다.

## Step 5. 전화 끊기

[leave()](/typescript/api-reference#leave) API를 통해서 전화 연결을 끊을 수 있습니다.

```typescript
await sdk.leave()
```

## 비디오 장치 제어

### mute/unmute

영상 전화중에 영상 송출을 중단할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/ios/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```typescript
try await sdk.setMute(track: .VIDEO)
```

### 입력 장치 변경

전화 통화중에 입력(카메라) 장치를 변경할 수 있도록 [setVideoDevice()](/ios/api-reference#setvideodevice) API를 제공합니다. 파라미터인 CAM\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 후면 카메라인 `back` 타입과 전면 카메라인 `front` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
try await sdk.setVideoDevice(type: .back)
```

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/ios/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```swift
try await sdk.setMute(track: .AUDIO)
```

### 입력 장치 변경

전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 [setAudioDevice()](/ios/api-reference#setaudiodevice) API를 제공합니다. 파라미터인 MIC\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 귀에 대어 전화받는 `defaultInEar` 타입과 스피커폰 모드인 `speaker` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
try await sdk.setAudioDevice(type: .speaker)
```


# SIP Call

sipcall은 애플리케이션과 일반 전화 간 전화를 연결 할 수 있도록 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 사용하여 offerCall(), answerCall()을 호출하고 해당 이벤트 메시지에 대응하는 것으로 애플리케이션과 일반 전화 간 전화 연결을 간단히 구현할 수 있습니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 userId는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. userId는 Optional 이며, nil로 전달할 경우 Omnitalk 서버에서 임의의 id를 부여합니다.

```swift
try await sdk.createSession(userId: "USER_ID")
```

## Step 2. 발신

offerCall() API로 애플리케이션에서 일반 전화로 전화 요청을 할 수 있습니다. 파라미터로 callType, callee의 전화번호, 녹음 여부를 전달하면 됩니다.

* callType: 전화 타입을 의미합니다. CALL\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 일반 전화와 음성 통화를 위해서는 `SIP_CALL` 을 전달하시면 됩니다.
* callee: 전화를 걸고자 하는 수신자의 전화 번호를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. defalut = false
* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. SIP 전화 기능에서는 nil로 적용하시면 됩니다.

```swift
try await sdk.offerCall(
    callType: .SIP_CALL,
    callee: "01012345678",
    record: true,
    localView: nil,
    remoteView: nil
)
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 전화 요청이 울리게 됩니다. 이 때, callee에게 보여지는 발신자 정보는 옴니톡에서 발급받은 번호 입니다.

## Step 3. 수신

일반 전화에서 애플리케이션으로 전화 요청을 할 경우에는 [makeSipNumber()](/ios/api-reference#makesipnumber) API를 통해서 6자리의 callNumber를 발급 받아야합니다. 일반 전화 -> 애플리케이션 발신 Call Flow는 아래와 같습니다.

1. 애플리케이션에서 makeSipNumber() API 통해서 callNumber 발급 ( 4번 다음 순서로 변경 가능 )
2. 일반 전화로 옴니톡에서 발급받은 번호로 전화
3. 전화를 요청하고자 하는 6자리 callNumber(PIN Number) 입력
4. 해당 callNumber로 발신 요청

애플리케이션으로 전화 요청이 왔을때, 수신하는 방법은 아래와 같습니다.

iOS SDK 에서는 아래 두 상황에 대해서 answerCall() API를 오버로딩하여 각각 제공합니다.

### callee가 callNumber를 생성한 상태에서 전화 요청이 왔을때

callee(애플리케이션)가 callNumber를 생성한 상태에서 caller(일반 전화)가 전화를 걸어`RINGING_EVENT`를 받은 경우, callee는 별도의 파라미터를 전달하지 않고 answerCall()을 호출하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 leave()를 호출하시면 됩니다.

* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. 1:1 전화 기능에서는 nil로 적용하시면 됩니다.

```swift
try await sdk.answerCall(localView: nil, remoteView: nil)
```

### callee가 callNumber를 생성하기 전 전화 요청이 왔을때

callee(애플리케이션)가 callNumber를 생성하기 전에 caller(일반 전화)가 전화를 걸어`RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터에 callType과 caller의 전화번호를 전달하여 전화를 수신할 수 있습니다. 이 경우, 옴니톡 서버에서 별도의 이벤트로 callType과 caller의 정보를 제공드릴 예정입니다.

* callType: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 때와 동일하게 `SIP_CALL` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 전화번호를 전달하시면 됩니다.
* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. 1:1 전화 기능에서는 nil로 적용하시면 됩니다.

```swift
try await sdk.answerCall(
    callType: .SIPCALL,
    caller: "01012345678",
    localView: nil,
    remoteView: nil
)
```

## Step 4. 연결 성공

음성 통화 연결이 성공하면 callee(애플리케이션)는 `CONNECTED_EVENT` 를 수신합니다.

## Step 5. 전화 끊기

[leave()](/typescript/api-reference#leave) API를 통해서 전화 연결을 끊을 수 있습니다.

```typescript
await sdk.leave()
```

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/ios/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```swift
try await sdk.setMute(track: .AUDIO)
```

### 입력 장치 변경

전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 [setAudioDevice()](/ios/api-reference#setaudiodevice) API를 제공합니다. 파라미터인 MIC\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 귀에 대어 전화받는 `defaultInEar` 타입과 스피커폰 모드인 `speaker` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
try await sdk.setAudioDevice(type: .speaker)
```


# Audio Room

audioroom은 음성 회의 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. Omnitalk SDK를 사용하여 회의실(룸) 생성 및 참여, 이벤트 메시지에 대응하는 것으로 음성 회의 기능을 간단히 구현할 수 있습니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 userId는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. userId는 Optional 이며, nil로 전달할 경우 Omnitalk 서버에서 임의의 id를 부여합니다.

```swift
try await sdk.createSession(userId: "USER_ID")
```

## Step 2. 회의실 생성 / 조회

[createRoom()](/ios/api-reference#createroom) API 를 사용하여 사람들이 입장 할 수 있는 회의실(룸)을 생성합니다. createRoom()의 필수 파라미터은 roomType은 Omnitalk SDK에서 enum type으로 제공합니다. 음성 회의의 경우는 `AUDIO_ROOM` 을 사용하시면 됩니다. createRoom() API 리턴 객체에 roomId 로 회의실에 참여할 수 있습니다. roomType을 제외한 나머지 파라미터는 Optional 입니다.

```swift
try await sdk.createRoom(
    roomType: .AUDIO_ROOM,
    subject: "subject",
    secret: "secret",
    startDate: nil,
    endDate: nil
)
```

이미 다른 사용자가 회의실을 생성 했다면 [roomList()](/ios/api-reference#roomlist) API 를 사용하여 현재 생성된 회의실 목록을 조회할 수 있습니다. 음성 회의실 목록만 조회하고 싶은 경우 roomType 을 `AUDIO_ROOM` 으로 전달하시면 됩니다. 조회한 목록 결과에 roomId 로 회의실에 참여할 수 있습니다.

```swift
try await sdk.roomList(roomType: .AUDIO_ROOM, page: nil)
```

## Step 3. 회의실 참여

[joinRoom()](/ios/api-reference#joinroom) API 를 사용하여 회의실에 참여할 수 있습니다. 회의실에 참여하게 되면 별도의 작업 없이 참여자들과 음성 회의를 할 수 있게 되며, 회의실에 관련된 이벤트 메세지를 수신할 수 있습니다. 음성 회의실에서 수신 가능한 이벤트는 아래와 같습니다. 자세한 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

* CONNECTED\_EVENT - 새로운 참가자 입장했을 때
* LEAVE\_EVENT - 다른 참가자가 퇴장 했을 때
* MUTE\_EVENT - 다른 참가자가 mute 했을 때
* UNMUTE\_EVENT - 다른 참가자가 unmute 했을 때
* MESSAGE\_EVENT - 채팅 메세지 수신 이벤트, 회의실 입장시 채팅 기능을 사용할 수 있는 상태가 됩니다. 채팅기능 사용법은 [Chatting](/ios/developers-guide/chatting) 문서를 참조 바랍니다.

```swift
try await sdk.joinRoom(roomId: roomId, secret: "secret", userName: "userName")
```

## Step 4. 회의실 퇴장

[leave()](/ios/api-reference#leave) API를 통해서 회의실에서 퇴장 할 수 있습니다. 파라미터에 session을 전달하지 않으면 자신의 방송을 종료하고 퇴장(통화 종료)하게 됩니다. session를 전달하면 해당 session을 가진 사용자가 퇴장(통화 종료) 하게 됩니다. 해당 상황은 수신 거절이나 강제 퇴장 등의 기능으로 활용할 수 있습니다.&#x20;

```typescript
try await sdk.leave()
```

## 참여자 목록 조회

[partiList()](/ios/api-reference#partilist) API 를 사용하여 입장한 회의실에 참여한 사용자 목록을 조회할 수 있습니다.

* 추가 예정 - partiList의 결과에 다른 참가자의 mute 여부를 알 수 있습니다.

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/ios/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```swift
try await sdk.setMute(track: .AUDIO)
```

### 입력 장치 변경

전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 [setAudioDevice()](/ios/api-reference#setaudiodevice) API를 제공합니다. 파라미터인 MIC\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 귀에 대어 전화받는 `defaultInEar` 타입과 스피커폰 모드인 `speaker` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
try await sdk.setAudioDevice(type: .speaker)
```

## 룸 삭제

현재 참여중이지 않은 회의실은 [destroyRoom()](/ios/api-reference#destroyroom) API 를 사용하여 회의실을 삭제할 수 있습니다.


# Video Room

videoroom은 영상 회의 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. Omnitalk SDK를 사용하여 회의실(룸) 생성 및 참여, 이벤트 메시지에 대응하는 것으로 음성 회의 기능을 간단히 구현할 수 있습니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 userId는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. userId는 Optional 이며, nil로 전달할 경우 Omnitalk 서버에서 임의의 id를 부여합니다.

```swift
try await sdk.createSession(userId: "USER_ID")
```

## Step 2. 회의실 생성 / 조회

[createRoom()](/ios/api-reference#createroom) API 를 사용하여 사람들이 입장 할 수 있는 회의실(룸)을 생성합니다. createRoom()의 필수 파라미터은 roomType은 Omnitalk SDK에서 enum type으로 제공합니다. 음성 회의의 경우는 `VIDEO_ROOM` 을 사용하시면 됩니다. createRoom() API 리턴 객체에 roomId 로 회의실에 참여할 수 있습니다. roomType을 제외한 나머지 파라미터는 Optional 입니다.

```swift
try await sdk.createRoom(
    roomType: .VIDEO_ROOM,
    subject: "subject",
    secret: "secret",
    startDate: nil,
    endDate: nil
)
```

이미 다른 사용자가 회의실을 생성 했다면 [roomList()](/ios/api-reference#roomlist) API 를 사용하여 현재 생성된 회의실 목록을 조회할 수 있습니다. 음성 회의실 목록만 조회하고 싶은 경우 roomType 을 `VIDEO_ROOM` 으로 전달하시면 됩니다. 조회한 목록 결과에 roomId 로 회의실에 참여할 수 있습니다.

```swift
try await sdk.roomList(roomType: .VIDEO_ROOM, page: nil)
```

## Step 3. 회의실 참여

[joinRoom()](/ios/api-reference#joinroom) API 를 사용하여 회의실에 참여할 수 있습니다. 회의실에 참여하게 되면 별도의 작업 없이 참여자들과 음성 회의를 할 수 있게 되며, 영상 송출은 다음 스텝을 참고 바랍니다. 회의실에 관련된 이벤트 메세지를 수신할 수 있습니다. 영상 회의에서 수신 가능한 이벤트는 아래와 같습니다. 자세한 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

* CONNECTED\_EVENT - 새로운 참가자 입장했을 때
* BROADCASTING\_EVENT - 다른 참가자가 영상을 송출했을 때
* LEAVE\_EVENT - 다른 참가자가 퇴장 했을 때
* MUTE\_EVENT - 다른 참가자가 mute 했을 때
* UNMUTE\_EVENT - 다른 참가자가 unmute 했을 때
* SCREEN\_SHARE\_EVENT - 화면 공유 발생 이벤트
* SCREEN\_UNSHARE\_EVENT - 화면 공유 종료 이벤트
* MESSAGE\_EVENT - 채팅 메세지 수신 이벤트, 회의실 입장시 채팅 기능을 사용할 수 있는 상태가 됩니다. 채팅기능 사용법은 [Chatting](/ios/developers-guide/chatting) 문서를 참조 바랍니다.

```swift
try await sdk.joinRoom(roomId: roomId, secret: "secret", userName: "userName")
```

## Step 4. 영상 송출

[publish()](/ios/api-reference#publish) API 를 사용하여 카메라 영상을 송출할 수 있습니다. 송출되는 영상을 화면에 재생하기 위해서 영상을 출력할 `RTCMTLVideoView` 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

publish를 하게 되면 다른 참가자들은 `BROADCASTING_EVENT` 이벤트 메세지를 받게 됩니다. 방송 구독은 다음 스텝을 참고 바랍니다.

```swift
import WebRTC

let localView = await RTCMTLVideoView()
try await sdk.publish(view: localView)
```

## Step 5. 영상 구독

[subscribe()](/ios/api-reference#subscribe) API 를 사용하여 송출된 영상을 구독할 수 있습니다. 파라미터에 영상 송출자의 session 을 전달하시면 됩니다. session은 partiList() API 또는 `BROADCASTING_EVENT` 또는 `SCREEN_SHARE_EVENT` 에서 확인 하실 수 있습니다.

송출되는 영상을 화면에 재생하기 위해서 영상을 출력할 `RTCMTLVideoView` 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

```swift
import WebRTC

let remoteView = await RTCMTLVideoView()
try await sdk.subscribe(
    publisherSession: publisherSession,
    view: remoteView
)
```

### 영상 구독 취소

[unsubscribe()](/ios/api-reference#unsubscribe) API 를 사용하여 구독중이던 영상을 구독 취소 할 수 있습니다.

```swift
try await sdk.unsubscribe(publisherSession: publisherSession)
```

## Step 6. 회의실 퇴장

[leave()](/ios/api-reference#leave) API를 통해서 회의실에서 퇴장 할 수 있습니다. 파라미터에 session을 전달하지 않으면 자신의 방송을 종료하고 퇴장하게 됩니다. session를 전달하면 해당 session을 가진 사용자가 퇴장 하게 됩니다. 해당 상황은 수신 거절이나 강제 퇴장 등의 기능으로 활용할 수 있습니다.&#x20;

```swift
try await sdk.leave()
```

## 목록 조회

### 참여자 목록 조회

[partiList()](/ios/api-reference#partilist) API 를 사용하여 입장한 회의실에 참여한 사용자 목록을 조회할 수 있습니다.

* 추가 예정 - partiList의 결과에 다른 참가자의 mute 여부를 알 수 있습니다.

### 방송 목록 조회

[publishList()](/ios/api-reference#publishlist) API 를 사용하여 입장한 회의실에 송출중인 방송 목록을 조회할 수 있습니다.

### 화면공유 정보 조회

[screenList()](/ios/api-reference#screenlist) API 를 사용하여 입장한 회의실에 송출중인 화면 공유 정보를 조회할 수 있습니다.&#x20;

## 비디오 장치 제어

### mute/unmute

영상 전화중에 영상 송출을 중단할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/ios/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```typescript
try await sdk.setMute(track: .VIDEO)
```

### 입력 장치 변경

전화 통화중에 입력(카메라) 장치를 변경할 수 있도록 [setVideoDevice()](/ios/api-reference#setvideodevice) API를 제공합니다. 파라미터인 CAM\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 후면 카메라인 `back` 타입과 전면 카메라인 `front` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
try await sdk.setVideoDevice(type: .back)
```

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/ios/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```swift
try await sdk.setMute(track: .AUDIO)
```

### 입력 장치 변경

전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 [setAudioDevice()](/ios/api-reference#setaudiodevice) API를 제공합니다. 파라미터인 MIC\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 귀에 대어 전화받는 `defaultInEar` 타입과 스피커폰 모드인 `speaker` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
try await sdk.setAudioDevice(type: .speaker)
```

## 룸 삭제

현재 참여중이지 않은 회의실은 [destroyRoom()](/ios/api-reference#destroyroom) API 를 사용하여 회의실을 삭제할 수 있습니다.


# Chatting

옴니톡 SDK가 제공하는 채팅 기능은 모든 VIDEOROOM\_TYPE 에서 기본으로 제공됩니다. 상대방과 음성이 연결되는 시점부터 채팅 기능을 사용할 수 있습니다.

## 메세지 전송

[sendMessage()](/ios/api-reference#sendmessage) API 를 사용하여 같은 룸에 참여한 모든 사용자에게 채팅 메세지를 전달할 수 있습니다. message의 최대 길이는 2048자 입니다.

```swift
try await sdk.sendMessage(message: message)
```

## 귓속말 전송

[sendWhisper()](/ios/api-reference#sendwhisper) API 를 사용하여 특정 사용자에게 귓속말 메세지를 전달할 수 있습니다. 첫번째 파라미터인 message의 최대 길이는 2048자 입니다. 두번째 파라미터는 귓속말을 보내고자 하는 대상의 session을 전달하시면 됩니다.

```swift
try await sdk.sendWhisper(message: message, target: targetSession)
```

## 이벤트 수신

이벤트 메세지 수신 방법은 [이벤트 메세지 수신](https://docs.omnitalk.io/ios/developers-guide/pages/aRIWYjXzko4i7tlrdKy5#2.)을 참고 바랍니다. 채팅 메세지의 이벤트 이름은 `MESSAGE_EVENT` 입니다. 채팅 이벤트 메세지의 종류는 4가지로, message action으로 구분됩니다.

* send: 특정 참가자가 **채팅 메세지를 전송** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지
* whisper: 특정 참가자가 다른 참가자에게 **귓속말을 전송** 했을때, **귓속말 대상자에게 발생**하는 이벤트 메세지
* join: 새로운 **참가자가 입장** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지
* leave: **참가자가 퇴장** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지


# Installation

## 지원 환경

* Android OS: SDK 24 이상
* Kotlin: 17 이상 (또는 Java 17 이상)

## 설치

Omnitalk Android SDK는 maven repository에 배포되어 있습니다. build.gradle 파일에 아래와 같이 설정하여 SDK dependency를 추가 합니다. 최신 버전 정보는 <https://central.sonatype.com/artifact/io.omnitalk/omnitalksdk> 에서 확인할 수 있습니다.

```
implementation 'io.omnitalk:omnitalksdk:2.0.2'
```

## 권한 설정

* SDK 사용에 필요한 권한을 획득하기 위해서 Android Manifest 설정합니다.
* 기본적으로 `CAMERA`, `RECORD_AUDIO` 등 일부 권한을 필요로 합니다.
* 아래의 사용자 권한들을 추가해 줍니다.

| 파라미터                    |            설명           |
| ----------------------- | :---------------------: |
| INTERNET                |   네트워크 통신을 위해서 필요한 권한   |
| CAMERA                  | 카메라 영상을 송출하기 위해서 필요한 권한 |
| RECORD\_AUDIO           | 오디오 음성을 송출하기 위해서 필요한 권한 |
| MODIFY\_AUDIO\_SETTINGS |  오디오 장치 관리를 위해서 필요한 권한  |

<br>


# Quick Start

Omnitalk SDK를 어떻게 활용할 수 있는지에 대한 간단한 예시입니다. 자세한 사용법은 [Android API Reference](/android/api-reference)를 참조 바랍니다.

기본적으로 모든 API는 suspend fun 으로 작성 되었으며, 요청이 실패한 경우 에러를 throw 합니다. 예시와 데모에서는 CoroutineScope를 사용합니다.

데모 앱 소스코드: <https://github.com/omnistory-labs/omnitalk.android.sdk/tree/demo>

## 1:1 영상 통화

### 1. 옴니톡 객체 생성

[콘솔](https://omnitalk.io/console/service/service-id)에서 발급받은 Service ID와 Service KEY로 Omnitalk 객체를 생성합니다.

```kotlin
import io.omnitalk.sdk.Omnitalk

Omnitalk.sdkInit(
    serviceId = "YOUR_SERVICE_ID",
    serviceKey = "YOUR_SERVICE_KEY",
    applicationContext = applicationContext
)

val sdk = Omnitalk.getInstance()
```

### 2. 세션 생성

인수로 전달한 userId로 세션을 생성하게 됩니다. userId는 Optional이며, null일 경우 서버에서 임의의 userId를 생성합니다.

```kotlin
val createSessionResult = sdk.createSession(userId = "alice")
```

### 3. 발신

1:1 영상 통화를 구현하기 위한 발신 기능은 [offerCall()](/android/api-reference#offercall) API를 이용합니다. 자신과 상대방의 영상을 화면에 재생하기 위해서 파라미터에 영상을 출력할 `SurfaceViewRenderer` 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 설치에 포함된 패키지 )

offerCall 호출이 성공하면 caller에게는 `RINGBACK_EVENT`가, callee에게는 `RINGING_EVENT`가 전달됩니다.

```kotlin
import org.webrtc.SurfaceViewRenderer
import io.omnitalk.sdk.types.PublicTypes

val callee = "test@omnistory.net"
val localView = findViewById<SurfaceViewRenderer>(R.id.localView)
val remoteView = findViewById<SurfaceViewRenderer>(R.id.remoteView)

sdk.offerCall(
    callType = PublicTypes.CALL_TYPE.videocall,
    callee = callee,
    record = true,
    localView = localView,
    remoteView = remoteView
)
```

### 4. 수신

callee측에서는 `RINGING_EVENT`를 받고 통화를 수락하거나 거절할 수 있습니다. 통화 수락은 [answerCall()](/android/api-reference#answercall) API를 이용합니다. 자신과 상대방의 영상을 재생하기 위해서 파라미터에 영상을 출력할 `SurfaceViewRenderer` 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 설치에 포함된 패키지 )

answerCall이 정상적으로 수행되면 caller, callee 양측은 `CONNECTED_EVENT`를 받습니다. 수신 거절은 [leave()](/android/api-reference#leave) API를 이용하시면 됩니다.

```kotlin
override fun onEvent(eventName: OmniEvent, message: Any) {
    when(eventName) {
        OmniEvent.RINGING_EVENT -> {
            sdk.answerCall(localView = localView, remoteView = remoteView)
        }
        OmniEvent.CONNECTED_EVENT -> {
            ...
        }            
    }
}
```

## 영상 회의

### 1. 옴니톡 객체 생성

[콘솔](https://omnitalk.io/console/service/service-id)에서 발급받은 Service ID와 Service KEY로 Omnitalk 객체를 생성합니다.

```kotlin
import io.omnitalk.sdk.Omnitalk

Omnitalk.sdkInit(
    serviceId = "YOUR_SERVICE_ID",
    serviceKey = "YOUR_SERVICE_KEY",
    applicationContext = applicationContext
)

val sdk = Omnitalk.getInstance()
```

### 2. 세션 생성

인수로 전달한 userId로 세션을 생성하게 됩니다. userId는 Optional이며, null일 경우 서버에서 임의의 userId를 생성합니다.

```kotlin
val createSessionResult = sdk.createSession(userId = "alice")
```

### 3. 룸 생성

영상 회의를 위한 룸을 생성합니다. roomType을 제외한 나머지 파라미터는 Optional 입니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

val createRoomResult = sdk.createRoom(
    roomType = PublicTypes.VIDEOROOM_TYPE.videoroom,
    subject = "subject",
    secret = "secret",
    startDate = null,
    endDate = null
)
```

### 4. 룸 참여

룸에 참여하게 되면 음성과 채팅 메시지를 주고 받을 수 있는 상태가 됩니다. roomId을 제외한 나머지 파라미터는 Optional 입니다.

```kotlin
val roomId = createRoomResult.roomId
sdk.joinRoom(roomId = roomId, secret = "secret", userName = "userName")
```

### 5. 방송 시작

로컬의 영상을 송출합니다. publish API는 roomType `VIDEO_ROOM` 또는 `WEBINAR` 에서만 필요한 기능입니다.

영상을 재생하기 위해서 파라미터에 영상을 출력할 `SurfaceViewRenderer` 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 설치에 포함된 패키지 )

```kotlin
import org.webrtc.SurfaceViewRenderer

val localView = findViewById<SurfaceViewRenderer>(R.id.localView)
sdk.publish(localView = localView)
```

### 6. 방송 구독

구독하고자는 방송의 session을 인수로 전달하면 해당 방송을 구독할 수 있습니다. 상대방 영상을 재생하기 위해서 파라미터에 영상을 출력할 `SurfaceViewRenderer` 객체를 전달합니다. 해당 객체를 생성하기 위해서 WebRTC 모듈을 import 해야 합니다. ( Omnitalk SDK 설치에 포함된 패키지 )

```kotlin
import org.webrtc.SurfaceViewRenderer

val remoteView = findViewById<SurfaceViewRenderer>(R.id.remoteView)
sdk.subscribe(publisherSession = publisherSession, remoteView = remoteView)
```


# API Reference

⚠️ SDK 2.0.x 버전과 2.1.x 이후 버전간 호환 불가

옴니톡의 이벤트 목록은[ Event Message](/commons/event-message)를 확인해 주세요. Omnitalk Android Demo앱 소스 코드는 [이곳](https://github.com/omnistory-labs/omnitalk.android.sdk/tree/demo) 에서 확인 하실 수 있습니다.&#x20;

## View

영상을 송출이 필요한 API는 영상을 출력할 SurfaceViewRenderer가 필요합니다. 해당 객체를 생성하기 위해서 org.webrtc 패키지를 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

API 호출 성공시 화면에 영상이 렌더링되기 때문에 예제에서는 CoroutineScope(Dispatchers.Main) 에서 코드를 실행 합니다. 만약 RecyclerView를 사용하려는 경우에는 onBindViewHolder 에서 sdk.bind 를 호출하여 영상을 바인딩 해주어야 합니다. 자세한 예시는 [Demo](https://github.com/omnistory-labs/omnitalk.android.sdk/tree/demo)를 참고 바랍니다.

## Event 수신 방법

sdk.setOnEventListener 를 호출하여 이벤트 리스너를 등록 합니다. onEvent와 onClose 함수를 override하여 이벤트 메세지를 수신할 수 있습니다. 이벤트 메세지 내용은 [Event Message](/commons/event-message)를 참조 바랍니다.

이벤트 메세지는 Omnitalk SDK에서 제공하는 타입으로 캐스팅하여 사용할 수 있습니다. 다음은 onEvent 이벤트 처리 예시입니다.&#x20;

```kotlin
sdk.setOnEventListener(object : OmniEventListener {
    override fun onEvent(eventName: OmniEvent, message: Any) {
        when(eventName) {
            OmniEvent.LEAVE_EVENT -> {
                val leaveMsg = message as EventLeave
                ...
            }
            ...
        }
    }
    override fun onClose() {
        ...
    }
})
```

## **Global Module**

Omnitalk sdkInit API를 통해서 객체를 초기화 합니다. 초기화 이후에는 `getInstance()` 를 통해서 객체를 반환 받을 수 있습니다. SDK 객체는 이후 모든 메서드 호출에 사용됩니다. Service Id와 Service Key는 [console 페이지](https://omnitalk.io/console/service/service-id)에서 발급 가능하며 노출되지 않도록 주의하여야 합니다.

```kotlin
import io.omnitalk.sdk.Omnitalk
...

Omnitalk.sdkInit(serviceId="YOUR_SERVICE_ID", serviceKey="YOUR_SERVICE_KEY", applicationContext=applicationContext)
val sdk = Omnitalk.getInstance()
```

## createSession

사용자의 세션을 생성하기 위해 서버와 연결하고 그 결과로 세션 아이디, 유저 아이디 등을 포함한 CreateSessionResult 객체를 리턴합니다. userId를 null로 전달하면 임의의 ID 정보를 자동으로 할당합니다.

```kotlin
CoroutineScope(Dispatchers.Default).launch {
    try {
        val createSessionResult = sdk.createSession(userId="omnitalk")
    } catch (err: Exception) {
        ...
    }
}

```

이후 API 설명부터는 `CoroutineScope(Dispatchers.Default).launch` 내용을 생략합니다.

## makeSipNumber

SIP 전화에 필요한 number를 생성하는 API 입니다. MakeSipNumberResult 객체를 리턴합니다.

```kotlin
val makeSipNumberResult = sdk.makeSipNumber(callNumber="123456", roomId=null)
```

## ~~sessionList(deprecated)~~

세션 생성 후 같은 Service Id 및 Key를 사용하는 모든 사용자를 조회하고 SessionListResult 객체를 리턴합니다.

```kotlin
val sessionListResult = sdk.sessionList(page: 1)
```

## createRoom

방송할 수 있는 방을 만들고 roomId를 포함한 CreateRoomResult 객체를 리턴합니다. roomType를 제외한 나머지 인자는 Optional 입니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

val createRoomResult = sdk.createRoom(
    roomType = PublicTypes.VIDEOROOM_TYPE.videoroom, 
    subject = "subject", 
    secrt = "secret", 
    startDate = null, 
    endDate = null
)
```

## destroyRoom

생성되어 있는 방을 삭제하고 DestroyRoomResult 객체를 리턴합니다.

```kotlin
val destroyRoomResult = sdk.destroyRoom(roomId="ABC123=")
```

## **roomList**

이미 생성된 방 목록을 조회하고 RoomListResult 객체를 리턴합니다. 방 목록 조회는 roomType별로 가능합니다.

roomType=PublicTypes.VIDEOROOM\_TYPE.all 로 적용하면 모든 roomType 목록을 조회할 수 있습니다.

```kotlin
val roomList = sdk.roomList(roomType=PublicTypes.VIDEOROOM_TYPE.videoroom, page=1)
```

## joinRoom

방에 참여하고 JoinRoomResult 객체를 리턴합니다. 방송을 시작하거나 다른 방송을 시청하기 위해 반드시 참여 과정을 수행해야 합니다. roomId를 제외한 나머지 인자는 Optional 입니다.

JoinRoomResult에 screen 필드는 참여한 방에 화면 공유 진행 여부를 나타냅니다.

```kotlin
val joinRoomResult = sdk.joinRoom(roomId=roomId, secret="secret", userName="userName")
```

## partiList

입장한 방의 참여자 목록을 조회하고 PartiListResult 객체를 리턴합니다. roomId를 null로 전달하면 현재 참여중인 방의 참여자 목록을 조회합니다.

```kotlin
val partiList = sdk.partiList(roomId=nil, page=1)
```

## publishList

입장한 방의 송출자 목록을 조회하고 PublishListResult 객체를 리턴합니다. roomId를 null로 전달하면 현재 참여중인 방의 송출자 목록을 조회합니다.

<pre class="language-kotlin"><code class="lang-kotlin"><strong>val publishListResult = sdk.publishList(roomId=nil, page=1)
</strong></code></pre>

## screenList

입장한 방의 화면공유 목록을 조회하고 ScreenListResult 객체를 리턴합니다. roomId를 null로 전달하면 현재 참여중인 방의 화면 공유 목록을 조회합니다.

```kotlin
val screenListResult = sdk.screenList(roomId=nil)
```

## publish

로컬의 영상을 송출합니다. publish API는 roomType `VIDEO_ROOM` 또는 `WEBINAR` 에서만 필요한 기능입니다.

파라미터에 로컬의 영상을 출력할 `SurfaceViewRenderer` 객체를 전달합니다. 해당 객체를 생성하기 위해서 org.webrtc 패키지를 import 해야 합니다. ( Omnitalk SDK 설치에 포함된 패키지 )

publish 성공시 화면에 영상이 렌더링되기 때문에 예제에서는 `CoroutineScope(Dispatchers.Main)` 에서 코드를 실행 합니다.

```kotlin
import org.webrtc.SurfaceViewRenderer

CoroutineScope(Dispatchers.Main).launch {
    try {
        val localView = findViewById<SurfaceViewRenderer>(R.id.localVideo)
        sdk.publish(localView=localView)
    } catch (err: Exception) {
        ...
    }
}
```

## subscribe

subscribe는 roomType `VIDEO_ROOM` 또는 `WEBINAR` 에서만 필요하며, 방에 참여하면 방송 중인 송출자의 목록을 조회하고 시청할 수 있습니다. 다른 송출자의 session은 송출자 목록을 조회하면 알 수 있습니다.

subscribe의 경우 송출자의 영상을 출력할 SurfaceViewRenderer 객체가 필요합니다. 해당 객체를 생성하기 위해서 org.webrtc 패키지를 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

subscribe 성공시 화면에 영상이 렌더링되기 때문에 예제에서는 `CoroutineScope(Dispatchers.Main)` 에서 코드를 실행 합니다. 만약 RecyclerView를 사용하려는 경우에는 `onBindViewHolder` 에서 `sdk.bind` 를 호출하여 영상을 바인딩 해주어야 합니다. 자세한 예시는 [Demo](https://github.com/omnistory-labs/omnitalk.android.sdk/tree/demo)를 참고 바랍니다.

```kotlin
import org.webrtc.SurfaceViewRenderer

CoroutineScope(Dispatchers.Main).launch {
    try {
        val remoteView = findViewById<SurfaceViewRenderer>(R.id.remoteView)
        sdk.subscribe(publisherSession="PUBLISHER_SESSION", remoteView=remoteView)
    } catch (err: Exception) {
        ...
    }
}
```

## unsubscribe

구독중인 사용자의 영상을 구독 중지하고 UnsubscribeResult 객체를 리턴합니다.

```kotlin
val unsubscribeResult = unsubscribe(publisherSession="PUBLISHER_SESSION")
```

## offerCall

1:1 음성 또는 영상 발신 기능을 수행하고 OfferCallResult 객체를 리턴합니다. offerCall 호출이 성공하면 수신자는 RINGING\_EVENT 를 받습니다. ( 발신자는 RINGBACK\_EVENT를 수신합니다. )

callType과 calleeId는 필수값이며 녹화 여부에 대한 record는 Optional 입니다. ( 기본값 false )

<mark style="color:orange;">⚠️</mark> 2.1.x 이후 버전부터 record 파라메터가 삭제되었습니다. 녹음은 [recordingStart](#recordingstart) 함수를 사용합니다.&#x20;

callType이 VIDEO\_CALL 인 경우 영상을 표현할 SurfaceViewRenderer 타입의 localView와 remoteView는 인자로 전달 해야합니다. AUDIO\_CALL과 SIP\_CALL 의 경우 null로 전달하시면 됩니다.

offerCall은 수신자가 존재하지 않아도 요청 가능합니다. 수신자가 RINGING\_EVENT를 받지 못했을 경우 offerCall의 리턴 데이터(call\_type, caller)를 수신자의 answerCall 인수로 전달하면 전화를 연결할 수 있습니다. 전체 흐름은 [Call Flow](/commons/call-flow)에서 그림으로 확인할 수 있습니다.

```kotlin
import org.webrtc.SurfaceViewRenderer

val localView = findViewById<SurfaceViewRenderer>(R.id.localView)
val remoteView = findViewById<SurfaceViewRenderer>(R.id.remoteView)

// videocall의 경우
CoroutineScope(Dispatchers.Main).launch {
    try {
        val offerCallResult = sdk.offerCall(
            callType= PublicTypes.CALL_TYPE.videocall,
            callee="CALLEE_ID",
            record=true,
            localView=localView,
            remoteView=remoteView
        )
    } catch (err: Exception) {
        ...
    }
}

// audiocall의 경우
val offerCallResult = sdk.offerCall(
    callType= PublicTypes.CALL_TYPE.audiocall,
    callee: "CALLEE_ID",
    record: true,
    localView: null,
    remoteView: null)
```

## answerCall

발신자가 offerCall을 호출하면 수신자에게는 RINGING\_EVENT가 발생합니다. 수신자가 answerCall을 호출하면 전화를 연결할 수 있습니다. (이 경우에는 answerCall에 인자를 전달하지 않아도 됩니다.) 발신자와 수신자가 연결되면 CONNECTED\_EVENT가 발생합니다.

offerCall은 수신자가 존재하지 않아도 요청 가능합니다. 수신자가 RINGING\_EVENT를 받지 못했을 경우 offerCall의 리턴 데이터(call\_type, caller)를 수신자의 answerCall 인수로 전달하면 전화를 연결할 수 있습니다. 전체 흐름은 [Call Flow](/commons/call-flow)에서 그림으로 확인할 수 있습니다.

iOS SDK에서는 두 상황별로 API를 오버로딩하여 별도로 제공합니다. 예시는 아래와 같습니다.

```kotlin
// 수신자가 RINGING_EVENT를 받고 answerCall을 호출하는 경우
sdk.answerCall(localView=localView, remoteView=remoteView) // videocall
sdk.answerCall(localView=null, remoteView=null) // audiocall

// 수신자가 RINGING_EVENT를 받지 않은 경우
sdk.answerCall(callType=PublicTypes.CALL_TYPE.videocall, caller="CALLER_ID", localView=localView, remoteView=remoteView) // videocall
sdk.answerCall(callType=PublicTypes.CALL_TYPE.audiocall, caller="CALLER_ID", localView=nil, remoteView=nil) // audiocall
```

## leave

자신의 방송을 종료합니다. 퇴장시, 다른 참가자들은 LEAVE\_EVENT 를 수신 합니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message))

```kotlin
sdk.leave()
```

## kickOut

사용자가 룸에 참여해 방송을 개시한 이후에 다른 사용자를 강제퇴장 시키는 기능입니다. 인수로 전달하는 session은 룸에서 강제 퇴장되며 세션이 끊어지게 됩니다. 룸의 다른 참여자들에게는 KICKOUT\_EVENT가 발생합니다.

```kotlin
sdk.kickOut(target="TARGET_SESSION")
```

## switchCameraDevice

송출중인 카메라 장치를 변경합니다. API를 호출하면 전면 카메라와 또는 후면 카메라로 전환 됩니다.

```kotlin
sdk.switchCameraDevice()
```

## setAudioDevice

송출중인 오디오 장치를 변경합니다. 인자는 MIC\_TYPE으로 defaultInEar와 speaker 모드가 있습니다.

```kotlin
sdk.setAudioDevice(type=PublicTypes.MIC_TYPE.defaultInEar)
```

## setMute

영상 또는 음성의 출력 상태를 mute 상태로 변경합니다. setMute 호출시 다른 참가자들에게 MUTE\_EVENT 이벤트가 발생합니다.

```kotlin
sdk.setMute(track=PublicTypes.TRACK_TYPE.video)
```

## setUnmute

영상 또는 음성의 출력 상태를 mute 상태로 변경합니다. setMute 호출시 다른 참가자들에게 UNMUTE\_EVENT 이벤트가 발생합니다.

```kotlin
sdk.setUnmute(track=PublicTypes.TRACK_TYPE.video)
```

## sendMessage

채팅 기능을 사용할 수 있는 API 입니다. 같은방에 참여한 사용자들에게는 MESSAGE\_EVENT 이벤트가 발생합니다.

```kotlin
sdk.sendMessage(message="MESSAGE")
```

## sendWhisper

귓속말 기능을 사용할 수 있는 API 입니다. target에 참여자 session을 전달 해야하며, 해당 session을 가진 참여자 에게만 MESSAGE\_EVENT 이벤트가 발생합니다.

```kotlin
sdk.sendWhisper(message="MESSAGE", target="ABC123=")
```

## messageList

입장한 방의 채팅 참여자 목록을 조회하고 MessageListResult 객체를 리턴합니다.

```kotlin
val messageListReulst = sdk.messageList()
```

***

{% hint style="info" %}
**sdk 2.1.x 이후 버전부터 사용 가능**
{% endhint %}

## recordingStart

음성 녹음을 시작하는 API입니다. 모든 call\_type에서 호출할 수 있습니다. 단, 녹음 시작 API 호출은 call/room에 참여한 사용자별로 한 번만 호출할 수 있습니다.  recordingStop()을 호출하지 않고 leave()를 호출 하거나 연결이 끊어져도 해당 시점까지 녹음은 마무리됩니다.

```javascript
sdk.recordingStart();
```

## recordingStop

음성 녹음을 종료하는 API입니다. 녹음 완료 시 옴니톡 콘솔에 등록한 Webhook URL로 콜백을 받을 수 있습니다.

```javascript
sdk.recordingStop();
```


# Developer's Guide


# Pre-requisite

해당 페이지에서는 Omnitalk SDK를 사용하기 위해서 공통적으로 필요한 내용에 대해서 설명합니다.&#x20;

## 1. SDK 객체 초기화

[콘솔](https://omnitalk.io/console/service/service-id)에서 발급받은 Service Id와 Service Key로 SDK를 초기화 합니다. 해당 정보는 노출되지 않도록 주의하여야 합니다. 초기화된 SDK 객체는 이후 모든 메서드 호출에 사용됩니다.&#x20;

Omnitalk SDK는 싱글톤 패턴으로 제공됩니다. 아래 방법으로 SDK 초기화 및 객체를 얻을 수 있습니다.

```kotlin
import io.omnitalk.sdk.Omnitalk

Omnitalk.sdkInit(
    serviceId = "YOUR_SERVICE_ID",
    serviceKey = "YOUR_SERVICE_KEY",
    applicationContext = applicationContext
)

val sdk = Omnitalk.getInstance()
```

## 2. 이벤트 리스너 등록

sdk.setOnEventListener 를 호출하여 이벤트 리스너를 등록 합니다. onEvent와 onClose 함수를 override하여 이벤트 메세지를 수신할 수 있습니다. 이벤트 메세지 내용은 [Event Message](/commons/event-message)를 참조 바랍니다.

이벤트 메세지는 Omnitalk SDK에서 제공하는 타입으로 캐스팅하여 사용할 수 있습니다. 다음은 onEvent 이벤트 처리 예시입니다.&#x20;

```kotlin
sdk.setOnEventListener(object : OmniEventListener 
    override fun onEvent(eventName: OmniEvent, message: Any) {
        when(eventName) {
            OmniEvent.LEAVE_EVENT -> {
                val leaveMsg = message as EventLeave
                ...
            }
            ...
        }
    }
    override fun onClose() {
        ...
    }
})
```

## OLD. 방송 개시

로컬의 영상을 송출합니다. publish API는 roomType `VIDEO_ROOM` 또는 `WEBINAR` 에서만 필요한 기능입니다.

파라미터에 로컬의 영상을 출력할 `SurfaceViewRenderer` 객체를 전달합니다. 해당 객체를 생성하기 위해서 org.webrtc 패키지를 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

publish 성공시 화면에 영상이 렌더링되기 때문에 예제에서는 `CoroutineScope(Dispatchers.Main)` 에서 코드를 실행 합니다.

```kotlin
import org.webrtc.SurfaceViewRenderer

CoroutineScope(Dispatchers.Main).launch {
    try {
        val localView = findViewById<SurfaceViewRenderer>(R.id.localVideo)
        sdk.publish(localView=localView)
    } catch (err: Exception) {
        ...
    }
}
```

## OLD. 방송 중인 참여자 조회 및 시청

subscribe는 roomType `VIDEO_ROOM` 또는 `WEBINAR` 에서만 필요하며, 방에 참여하면 방송 중인 송출자의 목록을 조회하고 시청할 수 있습니다. 다른 송출자의 session은 송출자 목록을 조회하면 알 수 있습니다.

subscribe의 경우 송출자의 영상을 출력할 SurfaceViewRenderer 객체가 필요합니다. 해당 객체를 생성하기 위해서 org.webrtc 패키지를 import 해야 합니다. ( Omnitalk SDK 패키지에 포함된 모듈 )

subscribe 성공시 화면에 영상이 렌더링되기 때문에 예제에서는 `CoroutineScope(Dispatchers.Main)` 에서 코드를 실행 합니다. 만약 RecyclerView를 사용하려는 경우에는 `onBindViewHolder` 에서 `sdk.bind` 를 호출하여 영상을 바인딩 해주어야 합니다. 자세한 예시는 [Demo](https://github.com/omnistory-labs/omnitalk.android.sdk/tree/demo)를 참고 바랍니다.

```kotlin
import org.webrtc.SurfaceViewRenderer

CoroutineScope(Dispatchers.Main).launch {
    try {
        val remoteView = findViewById<SurfaceViewRenderer>(R.id.remoteView)
        sdk.subscribe(publisherSession="PUBLISHER_SESSION", remoteView=remoteView)
    } catch (err: Exception) {
        ...
    }
} 
```


# Audio Call

audiocall은 1:1 전화 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 사용하여 offerCall(), answerCall()을 각각 호출하고 해당 이벤트 메시지에 대응하는 것으로 전화 기능을 간단히 구현할 수 있습니다.

[Call Flow](/commons/call-flow) 에서는 audiocall의 흐름을 sequence diagram으로 보여줍니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 userId는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. userId는 Optional 이며, null로 전달할 경우 Omnitalk 서버에서 임의의 id를 부여합니다.

```kotlin
sdk.createSession(userId = "USER_ID")
```

## Step 2. 발신

동일한 Service Id로  세션을 생성한 사용자 중  idle state의 사용자에게 전화 요청을 할 수 있습니다.

offerCall() API로 전화 요청을 할 수 있습니다. 파라미터로 callType, callee의 userId, 녹음 여부를 전달하면 됩니다.

* callType: 전화 타입을 의미합니다. CALL\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 음성 통화를 위해서는 `audiocall` 을 전달하시면 됩니다.&#x20;
* callee:  callee의 userId를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. defalut = false
* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. 1:1 전화 기능에서는 null로 적용하시면 됩니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

sdk.offerCall(
    callType = PublicTypes.CALL_TYPE.audiocall,
    callee = calleeId,
    record = true,
    localView = null,
    remoteView = null
)
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 `RINGING_EVENT`를 수신합니다.

## Step 3. 수신

Android SDK 에서는 아래 두 상황에 대해서 answerCall() API를 오버로딩하여 각각 제공합니다.

### callee가 RINGING\_EVENT를 받은 경우

callee가 세션을 생성한 상태에서 caller가 offerCall(전화 요청)을 하여`RINGING_EVENT`를 받은 경우, callee는 별도의 파라미터를 전달하지 않고 answerCall()을 호출하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 leave()를 호출하시면 됩니다.

* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. 1:1 전화 기능에서는 null로 적용하시면 됩니다.

```kotlin
sdk.answerCall(localView = null, remoteView = null)
```

### callee가 전화 요청(offerCall) 이후에 session을 생성한 경우

callee가 세션을 생성하기 전 caller가 offerCall(전화 요청)을 하여 `RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터에 callType과 caller를 전달하여 전화를 수신할 수 있습니다. 이 경우, 애플리케이션에서 callee 에게 callType과 caller를 전달해 주어야 합니다.

* callType: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 때와 동일하게 `audiocall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 userId를 전달하시면 됩니다.
* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. 1:1 전화 기능에서는 null로 적용하시면 됩니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

sdk.answerCall(
    callType = PublicTypes.CALL_TYPE.audiocall,
    caller: callerId,
    localView: null,
    remoteView: null
)
```

## Step 4. 연결 성공

음성 통화 연결이 성공하면 caller, callee 양측 모두 `CONNECTED_EVENT` 를 수신합니다.

## Step 5. 전화 끊기

leave() API를 통해서 전화 연결을 끊을 수 있습니다.

```kotlin
sdk.leave(session = null) // default: 본인 연결 끊기
```

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/android/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```swift
import io.omnitalk.sdk.types.PublicTypes

sdk.setMute(track = PublicTypes.TRACK_TYPE.audio)
```

### 입력 장치 변경

전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 [setAudioDevice()](/android/api-reference#setaudiodevice) API를 제공합니다. 파라미터인 MIC\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 귀에 대어 전화받는 `defaultInEar` 타입과 스피커폰 모드인 `speaker` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
import io.omnitalk.sdk.types.PublicTypes

sdk.setAudioDevice(type=PublicTypes.MIC_TYPE.speakr)
```


# Video Call

videocall은 1:1 영상 통화 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 사용하여 offerCall(), answerCall()을 각각 호출하고 해당 이벤트 메시지에 대응하는 것으로 전화 기능을 간단히 구현할 수 있습니다.

[Call Flow](/commons/call-flow) 에서는 videocall의 흐름을 sequence diagram으로 보여줍니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 userId는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. userId는 Optional 이며, null로 전달할 경우 Omnitalk 서버에서 임의의 id를 부여합니다.

```kotlin
sdk.createSession(userId = "USER_ID")
```

## Step 2. 발신

동일한 Service Id로  세션을 생성한 사용자 중  idle state의 사용자에게 전화 요청을 할 수 있습니다.

offerCall() API로 전화 요청을 할 수 있습니다. 파라미터로 callType, callee의 userId, 녹음 여부 및 자신과 상대방의 영상을 출력할 `SurfaceViewRenderer` 객체를 전달합니다. 해당 객체를 생성하기 위해서 org.webrtc 패키지를 import 해야 합니다. ( Omnitalk SDK 설치에 포함된 패키지 )

* callType: 전화 타입을 의미합니다. CALL\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 1:1 영상 통화를 위해서는 `videocall` 을 전달하시면 됩니다.&#x20;
* callee: callee의 userId를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. defalut = false
* localView: 자신의 영상을 재생할 `SurfaceViewRenderer` 객체
* remoteView: 상대방의 영상을 재생할 `SurfaceViewRenderer` 객체

```kotlin
import org.webrtc.SurfaceViewRenderer
import io.omnitalk.sdk.types.PublicTypes

val callee = "test@omnistory.net"
val localView = findViewById<SurfaceViewRenderer>(R.id.localView)
val remoteView = findViewById<SurfaceViewRenderer>(R.id.remoteView)

sdk.offerCall(
    callType = PublicTypes.CALL_TYPE.videocall,
    callee = callee,
    record = true,
    localView = localView,
    remoteView = remoteView
)
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 `RINGING_EVENT`를 수신합니다.

## Step 3. 수신

Android SDK 에서는 아래 두 상황에 대해서 answerCall() API를 오버로딩하여 각각 제공합니다.

### callee가 RINGING\_EVENT를 받은 경우

callee가 세션을 생성한 상태에서 caller가 offerCall(전화 요청)을 하여`RINGING_EVENT`를 받은 경우, 영상을 재생할 객체만 answerCall() API의 파라미터로 전달하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 leave()를 호출하시면 됩니다.

* localView: 자신의 영상을 재생할 `SurfaceViewRenderer` 객체
* remoteView: 상대방의 영상을 재생할 `SurfaceViewRenderer` 객체

```kotlin
import org.webrtc.SurfaceViewRenderer

val localView = findViewById<SurfaceViewRenderer>(R.id.localView)
val remoteView = findViewById<SurfaceViewRenderer>(R.id.remoteView)
sdk.answerCall(localView = localView, remoteView = remoteView)
```

### callee가 전화 요청(offerCall) 이후에 session을 생성한 경우

callee가 세션을 생성하기 전 caller가 offerCall(전화 요청)을 하여 `RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터에 callType과 caller를 전달하여 전화를 수신할 수 있습니다. 이 경우, 애플리케이션에서 callee 에게 callType과 caller를 전달해 주어야 합니다.

* callType: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 때와 동일하게 `videocall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 userId를 전달하시면 됩니다.
* localView: 자신의 영상을 재생할 `SurfaceViewRenderer` 객체
* remoteView: 상대방의 영상을 재생할 `SurfaceViewRenderer` 객체

```typescript
import org.webrtc.SurfaceViewRenderer
import io.omnitalk.sdk.types.PublicTypes

val localView = findViewById<SurfaceViewRenderer>(R.id.localView)
val remoteView = findViewById<SurfaceViewRenderer>(R.id.remoteView)
sdk.answerCall(
    callType = PublicTypes.CALL_TYPE.videocall,
    caller = callerId,
    localView = localView,
    remoteView = remoteView
)
```

## Step 4. 연결 성공

1:1 영상 통화 연결이 성공하면 caller, callee 양측 모두 `CONNECTED_EVENT` 를 수신합니다.

## Step 5. 전화 끊기

[leave()](/android/api-reference#leave) API를 통해서 전화 연결을 끊을 수 있습니다.

```kotlin
sdk.leave(session = null) // default: 본인 연결 끊기
```

## 비디오 장치 제어

### mute/unmute

영상 전화중에 영상 송출을 중단할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/android/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

sdk.setMute(track = PublicTypes.TRACK_TYPE.video)
```

### 입력 장치 변경

전화 통화중에 입력(카메라) 장치를 변경할 수 있도록 [switchCameraDevice()](/android/api-reference#switchcameradevice) API를 제공합니다. API 호출시 후면 카메라와 전면 카메라 간 전환이 이루어 집니다. 예시는 아래와 같습니다.

```kotlin
sdk.switchCameraDevice()
```

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/android/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```swift
import io.omnitalk.sdk.types.PublicTypes

sdk.setMute(track = PublicTypes.TRACK_TYPE.audio)
```

### 입력 장치 변경

전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 [setAudioDevice()](/android/api-reference#setaudiodevice) API를 제공합니다. 파라미터인 MIC\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 귀에 대어 전화받는 `defaultInEar` 타입과 스피커폰 모드인 `speaker` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
import io.omnitalk.sdk.types.PublicTypes

sdk.setAudioDevice(type=PublicTypes.MIC_TYPE.speakr)
```


# SIP Call

sipcall은 애플리케이션과 일반 전화 간 전화를 연결 할 수 있도록 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 사용하여 offerCall(), answerCall()을 호출하고 해당 이벤트 메시지에 대응하는 것으로 애플리케이션과 일반 전화 간 전화 연결을 간단히 구현할 수 있습니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 userId는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. userId는 Optional 이며, null로 전달할 경우 Omnitalk 서버에서 임의의 id를 부여합니다.

```kotlin
sdk.createSession(userId = "USER_ID")
```

## Step 2. 발신

offerCall() API로 애플리케이션에서 일반 전화로 전화 요청을 할 수 있습니다. 파라미터로 callType, callee의 전화번호, 녹음 여부를 전달하면 됩니다.

* callType: 전화 타입을 의미합니다. CALL\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 일반 전화와 음성 통화를 위해서는 `sipcall` 을 전달하시면 됩니다.
* callee: 전화를 걸고자 하는 수신자의 전화 번호를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. defalut = false
* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. SIP 전화 기능에서는 null로 적용하시면 됩니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

val callee = "test@omnistory.net"

sdk.offerCall(
    callType = PublicTypes.CALL_TYPE.sipcall,
    callee = "01012345678",
    record = true,
    localView = null,
    remoteView = null
)
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 전화 요청이 울리게 됩니다. 이 때, callee에게 보여지는 발신자 정보는 옴니톡에서 발급받은 번호 입니다.

## Step 3. 수신

일반 전화에서 애플리케이션으로 전화 요청을 할 경우에는 [makeSipNumber()](/android/api-reference#makesipnumber) API를 통해서 6자리의 callNumber를 발급 받아야합니다. 일반 전화 -> 애플리케이션 발신 Call Flow는 아래와 같습니다.

1. 애플리케이션에서 makeSipNumber() API 통해서 callNumber 발급 ( 4번 다음 순서로 변경 가능 )
2. 일반 전화로 옴니톡에서 발급받은 번호로 전화
3. 전화를 요청하고자 하는 6자리 callNumber(PIN Number) 입력
4. 해당 callNumber로 발신 요청

애플리케이션으로 전화 요청이 왔을때, 수신하는 방법은 아래와 같습니다.

Android SDK 에서는 아래 두 상황에 대해서 answerCall() API를 오버로딩하여 각각 제공합니다.

### callee가 callNumber를 생성한 상태에서 전화 요청이 왔을때

callee(애플리케이션)가 callNumber를 생성한 상태에서 caller(일반 전화)가 전화를 걸어`RINGING_EVENT`를 받은 경우, callee는 별도의 파라미터를 전달하지 않고 answerCall()을 호출하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 leave()를 호출하시면 됩니다.

* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. 1:1 전화 기능에서는 null로 적용하시면 됩니다.

```kotlin
sdk.answerCall(localView = null, remoteView = null)
```

### callee가 callNumber를 생성하기 전 전화 요청이 왔을때

callee(애플리케이션)가 callNumber를 생성하기 전에 caller(일반 전화)가 전화를 걸어`RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터에 callType과 caller의 전화번호를 전달하여 전화를 수신할 수 있습니다. 이 경우, 옴니톡 서버에서 별도의 이벤트로 callType과 caller의 정보를 제공드릴 예정입니다.

* callType: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 때와 동일하게 `sipcall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 전화번호를 전달하시면 됩니다.
* localView, remoteView: 영상 통화에 사용되는 파라미터입니다. 1:1 전화 기능에서는 null로 적용하시면 됩니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

sdk.offerCall(
    callType = PublicTypes.CALL_TYPE.sipcall,
    callee = "01012345678",
    record = true,
    localView = null,
    remoteView = null
)
```

## Step 4. 연결 성공

음성 통화 연결이 성공하면 callee(애플리케이션)는 `CONNECTED_EVENT` 를 수신합니다.

## Step 5. 전화 끊기

[leave()](/ios/api-reference#leave) API를 통해서 전화 연결을 끊을 수 있습니다.

```typescript
sdk.leave(session = null) // default: 본인 연결 끊기
```

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/android/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```swift
import io.omnitalk.sdk.types.PublicTypes

sdk.setMute(track = PublicTypes.TRACK_TYPE.audio)
```

### 입력 장치 변경

전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 [setAudioDevice()](/android/api-reference#setaudiodevice) API를 제공합니다. 파라미터인 MIC\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 귀에 대어 전화받는 `defaultInEar` 타입과 스피커폰 모드인 `speaker` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
import io.omnitalk.sdk.types.PublicTypes

sdk.setAudioDevice(type=PublicTypes.MIC_TYPE.speakr)
```


# Audio Room

audioroom은 음성 회의 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. Omnitalk SDK를 사용하여 회의실(룸) 생성 및 참여, 이벤트 메시지에 대응하는 것으로 음성 회의 기능을 간단히 구현할 수 있습니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 userId는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. userId는 Optional 이며, null로 전달할 경우 Omnitalk 서버에서 임의의 id를 부여합니다.

```kotlin
sdk.createSession(userId = "USER_ID")
```

## Step 2. 회의실 생성 / 조회

[createRoom()](/android/api-reference#createroom) API 를 사용하여 사람들이 입장 할 수 있는 회의실(룸)을 생성합니다. createRoom()의 필수 파라미터은 roomType은 Omnitalk SDK에서 enum type으로 제공합니다. 음성 회의의 경우는 `audioroom` 을 사용하시면 됩니다. createRoom() API 리턴 객체에 roomId 로 회의실에 참여할 수 있습니다. roomType을 제외한 나머지 파라미터는 Optional 입니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

val createRoomResult = sdk.createRoom(
    roomType = PublicTypes.VIDEOROOM_TYPE.audioroom,
    subject = "subject",
    secret = "secret",
    startDate = null,
    endDate = null
)
```

이미 다른 사용자가 회의실을 생성 했다면 [roomList()](/android/api-reference#roomlist) API 를 사용하여 현재 생성된 회의실 목록을 조회할 수 있습니다. 음성 회의실 목록만 조회하고 싶은 경우 roomType 을 `audioroom` 으로 전달하시면 됩니다. 조회한 목록 결과에 roomId 로 회의실에 참여할 수 있습니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

val roomList = sdk.roomList(
    roomType = PublicTypes.VIDEOROOM_TYPE.audioroom,
    page = null
)
```

## Step 3. 회의실 참여

[joinRoom()](/android/api-reference#joinroom) API 를 사용하여 회의실에 참여할 수 있습니다. 회의실에 참여하게 되면 별도의 작업 없이 참여자들과 음성 회의를 할 수 있게 되며, 회의실에 관련된 이벤트 메세지를 수신할 수 있습니다. 음성 회의실에서 수신 가능한 이벤트는 아래와 같습니다. 자세한 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

* CONNECTED\_EVENT - 새로운 참가자 입장했을 때
* LEAVE\_EVENT - 다른 참가자가 퇴장 했을 때
* MUTE\_EVENT - 다른 참가자가 mute 했을 때
* UNMUTE\_EVENT - 다른 참가자가 unmute 했을 때
* MESSAGE\_EVENT - 채팅 메세지 수신 이벤트, 회의실 입장시 채팅 기능을 사용할 수 있는 상태가 됩니다. 채팅기능 사용법은 [Chatting](/android/developers-guide/chatting) 문서를 참조 바랍니다.

```kotlin
sdk.joinRoom(roomId = roomId, secret = "secret", userName = "userName")
```

## Step 4. 회의실 퇴장

[leave()](/android/api-reference#leave) API를 통해서 회의실에서 퇴장할 수 있습니다. 파라미터에 session을 전달하지 않으면 자신의 방송을 종료하고 퇴장(통화 종료)하게 됩니다. session를 전달하면 해당 session을 가진 사용자가 퇴장(통화 종료) 하게 됩니다. 해당 상황은 수신 거절이나 강제 퇴장 등의 기능으로 활용할 수 있습니다.&#x20;

```typescript
sdk.leave(session = null) // default: 본인 퇴장
```

## 참여자 목록 조회

[partiList()](/android/api-reference#partilist) API 를 사용하여 입장한 회의실에 참여한 사용자 목록을 조회할 수 있습니다.

* 추가 예정 - partiList의 결과에 다른 참가자의 mute 여부를 알 수 있습니다.

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/android/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```swift
import io.omnitalk.sdk.types.PublicTypes

sdk.setMute(track = PublicTypes.TRACK_TYPE.audio)
```

### 입력 장치 변경

전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 [setAudioDevice()](/android/api-reference#setaudiodevice) API를 제공합니다. 파라미터인 MIC\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 귀에 대어 전화받는 `defaultInEar` 타입과 스피커폰 모드인 `speaker` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
import io.omnitalk.sdk.types.PublicTypes

sdk.setAudioDevice(type=PublicTypes.MIC_TYPE.speakr)
```

## 룸 삭제

현재 참여중이지 않은 회의실은 [destroyRoom()](/android/api-reference#destroyroom) API 를 사용하여 회의실을 삭제할 수 있습니다.


# Video Room

videoroom은 영상 회의 기능을 인터넷을 이용한 애플리케이션으로 구현한 것입니다. Omnitalk SDK를 사용하여 회의실(룸) 생성 및 참여, 이벤트 메시지에 대응하는 것으로 음성 회의 기능을 간단히 구현할 수 있습니다.

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 userId는 사용자를 구분하기 위한 고유한 id이며 audiocall 발신을 위한 offerCall() 호출에 사용됩니다. userId는 Optional 이며, null로 전달할 경우 Omnitalk 서버에서 임의의 id를 부여합니다.

```kotlin
sdk.createSession(userId = "USER_ID")
```

## Step 2. 회의실 생성 / 조회

[createRoom()](/android/api-reference#createroom) API 를 사용하여 사람들이 입장 할 수 있는 회의실(룸)을 생성합니다. createRoom()의 필수 파라미터은 roomType은 Omnitalk SDK에서 enum type으로 제공합니다. 음성 회의의 경우는 `videoroom` 을 사용하시면 됩니다. createRoom() API 리턴 객체에 roomId 로 회의실에 참여할 수 있습니다. roomType을 제외한 나머지 파라미터는 Optional 입니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

val createRoomResult = sdk.createRoom(
    roomType = PublicTypes.VIDEOROOM_TYPE.videoroom,
    subject = "subject",
    secret = "secret",
    startDate = null,
    endDate = null
)
```

이미 다른 사용자가 회의실을 생성 했다면 [roomList()](/android/api-reference#roomlist) API 를 사용하여 현재 생성된 회의실 목록을 조회할 수 있습니다. 음성 회의실 목록만 조회하고 싶은 경우 roomType 을 `videoroom` 으로 전달하시면 됩니다. 조회한 목록 결과에 roomId 로 회의실에 참여할 수 있습니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

val roomList = sdk.roomList(
    roomType = PublicTypes.VIDEOROOM_TYPE.videoroom,
    page = null
)
```

## Step 3. 회의실 참여

[joinRoom()](/android/api-reference#joinroom) API 를 사용하여 회의실에 참여할 수 있습니다. 회의실에 참여하게 되면 별도의 작업 없이 참여자들과 음성 회의를 할 수 있게 되며, 영상 송출은 다음 스텝을 참고 바랍니다. 회의실에 관련된 이벤트 메세지를 수신할 수 있습니다. 영상 회의에서 수신 가능한 이벤트는 아래와 같습니다. 자세한 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

* CONNECTED\_EVENT - 새로운 참가자 입장했을 때
* BROADCASTING\_EVENT - 다른 참가자가 영상을 송출했을 때
* LEAVE\_EVENT - 다른 참가자가 퇴장 했을 때
* MUTE\_EVENT - 다른 참가자가 mute 했을 때
* UNMUTE\_EVENT - 다른 참가자가 unmute 했을 때
* SCREEN\_SHARE\_EVENT - 화면 공유 발생 이벤트
* SCREEN\_UNSHARE\_EVENT - 화면 공유 종료 이벤트
* MESSAGE\_EVENT - 채팅 메세지 수신 이벤트, 회의실 입장시 채팅 기능을 사용할 수 있는 상태가 됩니다. 채팅기능 사용법은 [Chatting](/android/developers-guide/chatting) 문서를 참조 바랍니다.

```kotlin
sdk.joinRoom(roomId = roomId, secret = "secret", userName = "userName")
```

## Step 4. 영상 송출

[publish()](/android/api-reference#publish) API 를 사용하여 카메라 영상을 송출할 수 있습니다. 송출되는 영상을 출력할 `SurfaceViewRenderer` 객체를 전달합니다. 해당 객체를 생성하기 위해서 org.webrtc 패키지를 import 해야 합니다. ( Omnitalk SDK 설치에 포함된 패키지 )

publish를 하게 되면 다른 참가자들은 `BROADCASTING_EVENT` 이벤트 메세지를 받게 됩니다. 방송 구독은 다음 스텝을 참고 바랍니다.

```kotlin
import org.webrtc.SurfaceViewRenderer

val localView = findViewById<SurfaceViewRenderer>(R.id.localView)
sdk.publish(localView = localView)
```

## Step 5. 영상 구독

[subscribe()](/android/api-reference#subscribe) API 를 사용하여 송출된 영상을 구독할 수 있습니다. 파라미터에 영상 송출자의 session 을 전달하시면 됩니다. session은 partiList() API 또는 `BROADCASTING_EVENT` 또는 `SCREEN_SHARE_EVENT` 에서 확인 하실 수 있습니다.

송출되는 영상을 화면에 재생하기 위해서 영상을 출력할 `SurfaceViewRenderer` 객체를 전달합니다. 해당 객체를 생성하기 위해서 org.webrtc 패키지를 import 해야 합니다. ( Omnitalk SDK 설치에 포함된 패키지 )

```kotlin
import org.webrtc.SurfaceViewRenderer

val remoteView = findViewById<SurfaceViewRenderer>(R.id.remoteView)
sdk.subscribe(
    publisherSession = publisherSession,
    remoteView = remoteView
)
```

### 영상 구독 취소

[unsubscribe()](/android/api-reference#unsubscribe) API 를 사용하여 구독중이던 영상을 구독 취소 할 수 있습니다.

```kotlin
sdk.unsubscribe(publisherSession: publisherSession)
```

## Step 6. 회의실 퇴장

[leave()](/android/api-reference#leave) API를 통해서 회의실에서 퇴장할 수 있습니다. 파라미터에 session을 전달하지 않으면 자신의 방송을 종료하고 퇴장(통화 종료)하게 됩니다. session를 전달하면 해당 session을 가진 사용자가 퇴장(통화 종료) 하게 됩니다. 해당 상황은 수신 거절이나 강제 퇴장 등의 기능으로 활용할 수 있습니다.&#x20;

```typescript
sdk.leave(session = null) // default: 본인 퇴장
```

## 목록 조회

### 참여자 목록 조회

[partiList()](/android/api-reference#partilist) API 를 사용하여 입장한 회의실에 참여한 사용자 목록을 조회할 수 있습니다.

* 추가 예정 - partiList의 결과에 다른 참가자의 mute 여부를 알 수 있습니다.

### 방송 목록 조회

[publishList()](/android/api-reference#publishlist) API 를 사용하여 입장한 회의실에 송출중인 방송 목록을 조회할 수 있습니다.

### 화면공유 정보 조회

[screenList()](/android/api-reference#screenlist) API 를 사용하여 입장한 회의실에 송출중인 화면 공유 정보를 조회할 수 있습니다.&#x20;

## 비디오 장치 제어

### mute/unmute

영상 전화중에 영상 송출을 중단할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/android/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```kotlin
import io.omnitalk.sdk.types.PublicTypes

sdk.setMute(track = PublicTypes.TRACK_TYPE.video)
```

### 입력 장치 변경

전화 통화중에 입력(카메라) 장치를 변경할 수 있도록 [switchCameraDevice()](/android/api-reference#switchcameradevice) API를 제공합니다. API 호출시 후면 카메라와 전면 카메라 간 전환이 이루어 집니다. 예시는 아래와 같습니다.

```kotlin
sdk.switchCameraDevice()
```

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/android/api-reference#setmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 TRACK\_TYPE 은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```swift
import io.omnitalk.sdk.types.PublicTypes

sdk.setMute(track = PublicTypes.TRACK_TYPE.audio)
```

### 입력 장치 변경

전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 [setAudioDevice()](/android/api-reference#setaudiodevice) API를 제공합니다. 파라미터인 MIC\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 귀에 대어 전화받는 `defaultInEar` 타입과 스피커폰 모드인 `speaker` 두 가지로 제공 됩니다. 예시는 아래와 같습니다.

```swift
import io.omnitalk.sdk.types.PublicTypes

sdk.setAudioDevice(type=PublicTypes.MIC_TYPE.speakr)
```

## 룸 삭제

현재 참여중이지 않은 회의실은 [destroyRoom()](/android/api-reference#destroyroom) API 를 사용하여 회의실을 삭제할 수 있습니다.


# Chatting

옴니톡 SDK가 제공하는 채팅 기능은 모든 VIDEOROOM\_TYPE 에서 기본으로 제공됩니다. 상대방과 음성이 연결되는 시점부터 채팅 기능을 사용할 수 있습니다.

## 메세지 전송

[sendMessage()](/android/api-reference#sendmessage) API 를 사용하여 같은 룸에 참여한 모든 사용자에게 채팅 메세지를 전달할 수 있습니다. message의 최대 길이는 2048자 입니다.

```kotlin
sdk.sendMessage(message: message)
```

## 귓속말 전송

[sendWhisper()](/android/api-reference#sendwhisper) API 를 사용하여 특정 사용자에게 귓속말 메세지를 전달할 수 있습니다. 첫번째 파라미터인 message의 최대 길이는 2048자 입니다. 두번째 파라미터는 귓속말을 보내고자 하는 대상의 session을 전달하시면 됩니다.

```kotlin
sdk.sendWhisper(message: message, target: targetSession)
```

## 이벤트 수신

이벤트 메세지 수신 방법은 [이벤트 리스너 등록](https://docs.omnitalk.io/android/developers-guide/pages/aPU0PU1RaRESniRgQWlq#2.)을 참고 바랍니다. 채팅 메세지의 이벤트 이름은 `MESSAGE_EVENT` 입니다. 채팅 이벤트 메세지의 종류는 4가지로, message action으로 구분됩니다.

* send: 특정 참가자가 **채팅 메세지를 전송** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지
* whisper: 특정 참가자가 다른 참가자에게 **귓속말을 전송** 했을때, **귓속말 대상자에게 발생**하는 이벤트 메세지
* join: 새로운 **참가자가 입장** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지
* leave: **참가자가 퇴장** 했을 때, **다른 참가자들에게 발생**하는 이벤트 메세지


# Installation

### 방법 1.

Flutter, Dart용 공식 패키지 저장소 [pub.dev](https://pub.dev/)에서 Flutter용 [옴니톡SDK](https://pub.dev/packages/omnitalk_sdk)를 다운받아 설치할 수 있습니다.&#x20;

프로젝트 터미널에 다음 명령어를 실행합니다.

```dart
flutter pub add omnitalk_sdk
```

### 방법 2.

&#x20;프로젝트 pubspec.yaml파일의 dependencies 설정에서 다음 코드를 추가한 후,

```dart
dependencies:
	omnitalk_sdk: ^2.0.0
```

프로젝트 터미널에서 `flutter pub get` 명령어를 실행하거나 `Get Packages 버튼`(VSC) 혹은 `Packages get 버튼`(IntelliJ/Android Studio)을 클릭하여 설치를 마칩니다.


# Quick Start

Omnitalk SDK는 쉽고 간편하게 webrtc 기술을 이용할 수 있도록 만들어진 패키지입니다. Omnitalk SDK의 모든 API는 async \~ await 구조로 작성되었습니다. 요청이 실패하면 에러를 throw 합니다. 상세 API 사용법은 [FLUTTER API Reference](https://docs.omnitalk.io/flutter/api-reference)를 참조바랍니다. 1:1 통화를 구현할 수 있는 콜 기능과 다자간 회의실을 구현할 수 있는 룸을 구분하여 설명합니다.&#x20;

## 1:1 음성/영상 통화

### 1. 옴니톡 객체 생성

발급받은 Service Id와 Service Key로 omnitalk 객체를 생성합니다. (Service Id와 Service Key는 [console 페이지](https://omnitalk.io/console/service/service-id)에서 발급 가능하며 노출되지 않도록 주의하여야 합니다.)

```jsx
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를 부여합니다.

```jsx
await sdk.createSession();
```

### 3. 1:1 음성  통화

1:1 음성 통화를 구현하기 위한 발신 기능은 offerCall API를 호출하여 구현합니다. 상세 기능 구현 예시는 Dev guide의 [audio call](https://docs.omnitalk.io/react-native/developers-guide/audio-call-guide) 항목을 참조 바랍니다.  call flow는 [여기](https://docs.omnitalk.io/commons/call-flow)를 참조바랍니다.&#x20;

#### 3.1 발신

세션이 만들어진 상태에서 call type과 착신 상대방인 callee의 user\_id를 전달합니다. offerCall 호출이 성공하면 caller에게는 `RINGBACK_EVENT`가, callee에게는 `RINGING_EVENT`가 전달됩니다.&#x20;

```jsx
String callee = 'tester@omnistory.net';
await sdk.offerCall(
    callType: CallType.audiocall, 
    callee : callee); //발신측
```

#### 3.2 수신

callee측이 answerCall을 호출하면 caller, caller 양측은 `CONNECTED_EVENT`를 수신하고 음성통화가 연결됩니다. callee는 [ leave API](/typescript/api-reference#leave)를 이용하여 수신거절할 수 있습니다.&#x20;

```dart
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](https://docs.omnitalk.io/react-native/developers-guide/video-call-guide) 항목을 참조 하시기 바랍니다. call flow는 [여기](https://docs.omnitalk.io/commons/call-flow)를 참조 하시기 바랍니다.&#x20;

세션이 만들어진 상태에서 call type과 착신 상대방인 callee의 user\_id, 그리고 caller, callee의 영상을 담을 객체를 전달합니다. offerCall 호출이 성공하면 caller에게는 `RINGBACK_EVENT`가, callee에게는 `RINGING_EVENT`가 전달됩니다.&#x20;

```dart
String callee = 'tester@omnistroy.net'
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를 이용해 거절할 수 있습니다.

<pre class="language-dart"><code class="lang-dart">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(
<strong>    callType: CallType.videocall, 
</strong><strong>    caller: caller, 
</strong><strong>    localRenderer: localVideo, 
</strong><strong>    remoteRenderer: remoteVideo
</strong>    );
</code></pre>

###

## 다자간 회의

### 1. 옴니톡 객체 생성

발급받은 Service Id와 Service Key로 omnitalk 객체를 생성합니다. (Service Id와 Service Key는 [console 페이지](https://omnitalk.io/console/service/service-id)에서 발급 가능하며 노출되지 않도록 주의하여야 합니다.)

```jsx
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를 부여합니다.

```jsx
await sdk.createSession();
```

### 3. 룸 생성

인수로 전달한 룸 타입의 방을 생성합니다. (RoomType.videoroom | RoomType.audioroom)

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

### 4. 룸 참여

룸에 참여하게 되면 자동으로 오디오 방송을 시작하고 채팅 메시지를 주고 받을 수 있는 상태가 됩니다.

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

### 5. 방송 시작 (video)

오디오 방송은 룸에 참여하는 것만으로 시작 가능하며 영상 방송은 자신의 방송 영상 스트림을 담을 객체를 전달해 방송을 발행하는 것으로 시작합니다. publish API호출이 성공하면 해당 방송의 세션 id가 담긴 객체를 리턴 받게 됩니다.

```dart
RTCVideoRenderer localvideo = RTCVideoRenderer();

await sdk.publish(localRenderer: localVideo);
```

### 6. 방송 구독(video)

구독하고자는 방송의 session을 인수로 전달하면 해당 방송을 구독할 수 있습니다. 룸에서 방송을 개시한 사용자의 리스트를 조회(publishList API)하거나 `BROADCASTING_EVENT`의 [이벤트 메시지](/commons/event-message#broadcasting_event)에서 확인할 수 있습니다.

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

### 7. 이벤트 메시지 수신

옴니톡 SDK에서 전달하는 이벤트 메시지 규격과 메시지 수신 방법은 [여기](/commons/event-message)를 참고하시기 바랍니다. 다음은 방송 이벤트 발생시 방송 세션을 저장하는 예시입니다.

```jsx
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 인수로 전달하면 됩니다.

```dart
await sdk.sendMessage(action: MessageAction.send, message: msg); // 룸 전체 메시지 전송
await sdk.sendMessage(
   action : MessageAction.whisper,
   message : whispermsg,
   target : target,
   );  // 특정 상대에 귓속말 메시지 전송
```

### 9. 방송 종료

방송을 종료하는 API입니다. 종료시키고 싶은 session id를 전달하면 수신 거절이나 강제 퇴장 등의 기능으로 활용할 수 있습니다. session을 전달하지 않으면 자신의 방송을 종료하게 됩니다.

```jsx
await sdk.leave();
```


# API Reference

⚠️ SDK 2.0.x 버전과 2.1.x 이후 버전간 호환 불가

## Synchronization

Omnitalk SDK는 통신 서비스를 제공하기 위해 Offer-Answer 구조로 설계되어 있으며, 이를 위해 반드시 async, await 비동기 처리를 지원해야 합니다.

## **Global Module**

Omnitalk 객체를 생성합니다. 생성된 객체는 이후 모든 메서드 호출에 사용됩니다. Service Id와 Service Key는 [console 페이지](https://omnitalk.io/console/service/service-id)에서 발급 가능하며 노출되지 않도록 주의하여야 합니다.

```javascript
const SERVICE_ID = '발급받은 service id';
const SERVICE_KEY = '발급받은 service key';  // 앱

Omnitalk.sdkInit(SERVICE_ID, SERVICE_KEY);
Omnitalk sdk = Omnitalk.getInstance();
```

### EVENT\_MESSAGE

### on

이벤트 메시지는 [여기](https://docs.omnitalk.io/commons/event-message)를 참고하시면 됩니다. 이벤트 메시지를 수신하기 위해서는 옴니톡의 이벤트 리스너 API를 이용하시면 됩니다. (React-native는 screen share/unshare 기능을 제공하지 않습니다.)

```
sdk.on('event', ()=>{})
```

leave 이벤트로 서버와의 연결이 끊기거나 사용자 인터넷 환경 불안정 등으로 인터넷 연결이 끊길 때 발생하는 close 메시지입니다.

```
sdk.on('close', ()=>{})
```

### createSession

사용자의 세션을 생성하기 위해 서버와 연결하고 그 결과로 세션 id, 유저 id가 담긴 객체를 리턴합니다. userId 는 사용자를 구분하기 위한 고유한 id이며 생략시 Omnitalk 서버에서 임의의 id를 부여합니다.&#x20;

```jsx
await sdk.createSession(userId: );
```

| Parameter | Mandatory/Optional | Type   | Description |
| --------- | ------------------ | ------ | ----------- |
| userId    | O                  | String | max 64      |

<details>

<summary><strong>리턴 객체 | createSession</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"user\_id":"omnitalk",

}

</details>

### ~~sessionList(deprecated)~~

세션 생성 후 같은 Service Id 및 Key를 사용하는 모든 사용자를 조회합니다.

```jsx
await sdk.sessionList();
```

| Parameter | Mandatory/Optional | Type | Description                |
| --------- | ------------------ | ---- | -------------------------- |
| page      | O                  | int  | default = 1, per page = 10 |

<details>

<summary><strong>리턴 객체 | sessionList</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

"page": 1,&#x20;

"count": 1,&#x20;

"list": \[&#x20;

&#x20;           { "user\_id": "omnitalk",&#x20;

&#x20;             "call\_type": "videocall",&#x20;

&#x20;             "state": "busy",&#x20;

&#x20;           }&#x20;

&#x20;         ]

}

</details>

### createRoom

모든 방송은 룸에서 이루어집니다. 방송을 시작할 룸 타입을 전달해 룸을 생성합니다. 방 주제나 방의 비밀 번호를 설정할 수 있습니다. start\_date 및 end\_date는 룸 생성 및 종료 예상 시간을 설정할 때 이용합니다.&#x20;

```jsx
await sdk.createRoom(roomType: );
```

| Parameter | Mandatory/Optional | Type     | Description |
| --------- | ------------------ | -------- | ----------- |
| roomType  | M                  | RoomType | sdk 제공      |
| subject   | O                  | String   | max 128     |
| secret    | O                  | int      | 6 digits    |
| startDate | O                  | int      |             |
| endDate   | O                  | int      |             |

<details>

<summary><strong>리턴 객체 | createRoom</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"room\_id": "8a1086680e47261208eeff87000b"

}

</details>

### roomList

인수로 전달한 룸타입에 해당하는 모든 룸을 조회해 리스트로 반환합니다. 룸타입을 명시하지 않으면 룸타입에 관계없이 전체 룸을 조회합니다.

```jsx
await sdk.roomList(roomType: )
```

| Parameter | Mandatory/Optional | Type     | Description                |
| --------- | ------------------ | -------- | -------------------------- |
| roomType  | O                  | RoomType | sdk 제공                     |
| page      | O                  | int      | default = 1, per page = 10 |

<details>

<summary><strong>리턴 객체 | roomList</strong></summary>

{

&#x20; "session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

&#x20;  "count": 1,&#x20;

&#x20;  "page": 1,&#x20;

&#x20;  "room\_type": "all",&#x20;

&#x20;  "list":&#x20;

&#x20;        \[&#x20;

&#x20;          {&#x20;

&#x20;             "room\_id": "8a1086680e47261208eeff87000b",&#x20;

&#x20;              "room\_type": "videoroom",&#x20;

&#x20;              "count": 0,&#x20;

&#x20;              "secret": true,&#x20;

&#x20;              "sip\_support": true,&#x20;

&#x20;              "sip\_number": "991000"  (optional)

&#x20;              "start\_date": 1686816051,&#x20;

&#x20;              "end\_date": 1686819651,&#x20;

&#x20;              "reg\_date": 1686816051,&#x20;

&#x20;              "subject": "fish"&#x20;

&#x20;         }    &#x20;

&#x20;      ]

}

</details>

### joinRoom

방송을 시작하거나 다른 방송을 시청하기 위해서는 반드시 룸 참여 과정이 필요합니다.&#x20;

```jsx
await sdk.joinRoom(roomId : );
```

| Parameter | Mandatory/Optional | Type   | Description      |
| --------- | ------------------ | ------ | ---------------- |
| roomId    | M                  | String |                  |
| secret    | O                  | int    | 6 digits         |
| userName  | O                  | String | max 64, nickname |

<details>

<summary><strong>리턴 객체 | joinRoom</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

"room\_id": "8a1086680e47261208eeff87000b",&#x20;

"room\_type": "videoroom"

}

</details>

### partiList

해당 룸에 참여한 모든 사용자(방송 개시 여부와 무관)를 조회합니다. roomId를 전달하지 않으면 자신이 참여한 룸의 참여자 리스트를 조회합니다.&#x20;

```jsx
await sdk.partiList();
```

| Parameter | Mandatory/Optional | Type   | Description                |
| --------- | ------------------ | ------ | -------------------------- |
| roomId    | O                  | String |                            |
| page      | O                  | int    | default = 1, per page = 10 |

<details>

<summary><strong>리턴 객체 | partiList</strong></summary>

{

&#x20;   "session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

&#x20;   "page": 1,&#x20;

&#x20;   "count": 1,&#x20;

&#x20;   "list":&#x20;

&#x20;           \[&#x20;

&#x20;             {&#x20;

&#x20;                 "session": "YzMyYWE1YTA3MmJhMTY4",&#x20;

&#x20;                 "user\_id": "<jason@omnistory.net>",&#x20;

&#x20;                 "user\_name": "jason",&#x20;

&#x20;                 "call\_type": "videocall",&#x20;

&#x20;              }&#x20;

&#x20;           ]

}

</details>

### publish

API 호출 사용자의 영상을 송출하면서 영상 방송을 개시합니다. RTCVideoRenderer타입의 객체를 전달하면 됩니다. publish API 호출에 성공하면 자신의 방송 세션id가 담긴 객체를 리턴받습니다. 같은 룸의 다른 사용자가 publish를 하게 되면 룸의 다른 사용자들에게 `CONNECTEC_EVENT` 와 `BROADCASTING_EVENT`가 발생하며 그 방송을 구독할 수 있는 상태가 됩니다. publish한 방송의 영상을 보고 싶은 사용자는 구독 [subscribe API](https://app.gitbook.com/o/Kvp35YpCpS2xoh7EQYPA/s/aPg0bJkhusp9D4dvlOo2/~/changes/87/react-native/api-reference#subscribe)를 이용하면 됩니다.

```jsx
await sdk.publish(localRenderer: );
```

| Parameter     | Mandatory/Optional | Type             | Description                              |
| ------------- | ------------------ | ---------------- | ---------------------------------------- |
| localRenderer | M                  | RTCVideoRenderer | flutter\_webrtc의 RTCVideoRenderer 타입의 객체 |

<details>

<summary><strong>리턴 객체 | publish</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",

}

</details>

### publishList

참여한 룸에서 방송 중인 사용자 리스트를 조회합니다. roomId를 전달하지 않으면 자신이 참여한 룸의 참여자 리스트를 조회합니다.&#x20;

```jsx
await sdk.publishList();
```

| Parameter | Mandatory/Optional | Type   | Description                |
| --------- | ------------------ | ------ | -------------------------- |
| roomId    | O                  | String |                            |
| page      | O                  | int    | default = 1, per page = 10 |

<details>

<summary><strong>리턴 객체 | publishList</strong></summary>

{

&#x20;  "session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

&#x20;  "room\_id": "9389314d3cb1b92eeaa81b618e0f",

&#x20;  "page": 1,&#x20;

&#x20;  "count": 1,&#x20;

&#x20;  "list":&#x20;

&#x20;           \[&#x20;

&#x20;             {&#x20;

&#x20;              "session": "YzMyYWE1YTA3MmJhMTY4",&#x20;

&#x20;              "track": "video",&#x20;

&#x20;              "audio\_mute": false,&#x20;

&#x20;              "video\_mute": false,&#x20;

&#x20;              "user\_id": "sADKOqOGBA", &#x20;

&#x20;              "user\_name": "kAIaDnhpPH"&#x20;

&#x20;             }

&#x20;           ],

&#x20;}

</details>

### subscribe

구독할 방송의 session과 구독 영상을 담을 RTCVideoRenderer 타입의 객체를 전달하면 해당 방송을 구독할 수 있습니다. subscribe 호출이 성공하면 자신의 세션, 구독하는 세션, 화면 공유 여부에 대한 boolean 값을 리턴 객체로 받게 됩니다.

```jsx
await sdk.subscribe(publisherSession: , remoteRenderer: );
```

| Parameter        | Mandatory/Optional | Type             | Description                              |
| ---------------- | ------------------ | ---------------- | ---------------------------------------- |
| publisherSession | M                  | String           |                                          |
| remoteRenderer   | M                  | RTCVideoRenderer | flutter\_webrtc의 RTCVideoRenderer 타입의 객체 |

<details>

<summary><strong>리턴 객체 | subscribe</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Nj",  // 자신의 세션

"subscribe": "YzMyYWE1YTA3MmJhMTY4Njg"  // 구독하는 상대의 세션

"screen": false // 화면 공유 여부에 대한 boolean 값

}

</details>

### unsubscribe

구독 중인 방송의 구독을 취소할 수 있습니다.

```jsx
await sdk.unSubscribe(publisherSession);
```

| Parameter        | Mandatory/Optional | Type   | Description |
| ---------------- | ------------------ | ------ | ----------- |
| publisherSession | M                  | String |             |

<details>

<summary><strong>리턴 객체 | unsubscribe</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Nj", // 자신의 세션

"subscribe": "YzMyYWE1YTA3MmJhMTY4Njg"  // 구독취소한 세션

}

</details>

### offerCall

음성 또는 영상 통화를 위한 발신 기능을 수행합니다. 음성 통화는 callType과, 상대방 번호인 callee를 전달하고 영상 통화의 경우 caller 와 callee의 영상을 담을 객체도 전달해야 합니다. offerCall 호출이 성공하면 callee에게는 `RINGING_EVENT`가 전달됩니다. offerCall을 호출한 측은 `RINGBACK_EVENT`를 받게 됩니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message)) offerCall은 리턴값이 없습니다.

<mark style="color:orange;">⚠️</mark> 2.1.x 이후 버전부터 record 파라메터가 삭제되었습니다. 녹음은 [recordingStart](#recordingstart) 함수를 사용합니다.&#x20;

```jsx
await sdk.offerCall(callType, callee);
```

| Parameter      | Mandatory/Optional | Type             | Description                                         |
| -------------- | ------------------ | ---------------- | --------------------------------------------------- |
| callType       | M                  | CallType         | sdk 제공 (audiocall \| videocall)                     |
| callee         | M                  | String           | 착신 상대방의 userId                                      |
| record         | O                  | Boolean          | <p>audio call만 지원<br>2.1.x 버전부터 삭제</p>              |
| localRenderer  | \*O                | RTCVideoRenderer | flutter\_webrtc의 RTCVideoRenderer 타입 \*videocall 필수 |
| remoteRenderer | \*O                | RTCVideoRenderer | flutter\_webrtc의 RTCVideoRenderer 타입 \*videocall 필수 |

<details>

<summary>이벤트 메시지 <strong>예시 | RINGBACK_EVENT</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"caller": "alice",&#x20;

"callee": "bob",&#x20;

"call\_type": "audiocall"

}

</details>

<details>

<summary>이벤트 메시지 <strong>예시 | RINGING_EVENT</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"room\_id": "9389314d3cb1b92eeaa81b618e0f",&#x20;

"room\_type": "audiocall",&#x20;

"call\_type": "audiocall",

"caller": "alice",&#x20;

"callee": "bob",&#x20;

"track": "audio",

}

</details>

### answerCall

음성 또는 영상 통화를 위한 착신 기능을 수행합니다. 음성 통화의 경우 별도의 인수 전달없이 API호출만으로 통화 연결 가능합니다. 영상 통화의 경우 자신과 상대의 영상을 담을 객체를 전달해야 합니다. answerCall 호출이 성공하면 caller, callee 양측 모두 `CONNECTED_EVENT`를 받습니다.

```jsx
await sdk.answerCall(); 
```

| Parameter      | Mandatory/Optional | Type             | Description                                         |
| -------------- | ------------------ | ---------------- | --------------------------------------------------- |
| callType       | O                  | CallType         | sdk 제공                                              |
| caller         | O                  | String           | 발신상대방의 userId                                       |
| record         | O                  | Boolean          | audio call만 지원                                      |
| localRenderer  | \*O                | RTCVideoRenderer | flutter\_webrtc의 RTCVideoRenderer 타입 \*videocall 필수 |
| remoteRenderer | \*O                | RTCVideoRenderer | flutter\_webrtc의 RTCVideoRenderer 타입 \*videocall 필수 |

<details>

<summary>이벤트 메시지 예시 <strong>| CONNECTED_EVENT</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD"

}

</details>

### makeSipNumber

개인 또는 방송 룸에 일반 전화를 수신할 수 있는 번호를 발급받기 위한 API입니다. 만약 룸에 번호를 할당하면 룸의 참여자 모두에게 전화를 걸 수 있습니다. callNumber를 전달하지 않으면 서버에서 임의의 6자리 번호를 발급합니다.&#x20;

애플리케이션에서 callNumber 발급 이후 일반 전화로 옴니톡 070 번호로 전화를 걸고, 발급받은 6자리 callNumber를 입력하면 일반 전화에서 애플리케이션으로 통화 요청이 이루어 집니다. 이 때, 애플리케이션에서는 `RINGBACK_EVENT`를 받게 됩니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message)) 전화 수신을 위해서는 [answerCall()](#answercall)를 호출하시면 됩니다.

```jsx
await sdk.makeSipNumber();
```

| Parameter  | Mandatory/Optional | Type   | Description |
| ---------- | ------------------ | ------ | ----------- |
| callNumber | O                  | int    | 6 digits    |
| roomId     | O                  | String |             |

<details>

<summary><strong>리턴 객체 | makeSipNum</strong></summary>

{

"call\_number": "993627"

}

</details>

### mute/unmute

mute할 track을 인수로 넘겨주면 음소거 및 음소거 해제 기능을 수행할 수 있습니다. 비디오 mute는 로컬의 화면 송출을 off 시키는 기능입니다. mute/unmute API를 호출하면 룸의 다른 사용자들에게 `MUTE_EVENT` 또는 `UNMUTE_EVENT`가 전달됩니다.&#x20;

```jsx
await sdk.setMute(track : );
await sdk.setUnmute(track : );
```

| Parameter | Mandatory/Optional | Type      | Description              |
| --------- | ------------------ | --------- | ------------------------ |
| track     | M                  | TrackType | sdk 제공  (audio \| video) |

### sendMessage

채팅 기능 구현을 위한 메시지 전송 API입니다. 어떤 룸이든 입장하게 되면 기본적으로 채팅을 주고 받을 수 있는 상태가 됩니다. sendMessage API를 이용해 메시지를 발신하고, 옴니톡에서 전달하는 `MESSAGE_EVENT`로 메시지를 수신할 수 있습니다. 채팅 메시지는 룸의 모든 참여자에게 전송되며 특정 사용자에게 전달할 귓속말 메시지는 whisper action타입으로 보내면 됩니다.

| Parameter | Mandatory/Optional | Type          | Description                               |
| --------- | ------------------ | ------------- | ----------------------------------------- |
| action    | M                  | MessageAction | sdk 제공 (send \| whisper )                 |
| message   | M                  | String        | max 2048                                  |
| target    | \*O                | String        | 귓속말 상대방 session id. whisper action의 경우 필수 |

<details>

<summary>이벤트 메시지 예시 <strong>|</strong> MESSAGE_EVENT</summary>

{&#x20;

"action": "join",&#x20;

"cmd": "MESSAGE\_EVENT",&#x20;

"session": "U0lTUlpocVhOUTE2ODg3MDcxNjQtMzgy",&#x20;

"timestamp": 1688707215,&#x20;

"user\_id": "woo",&#x20;

"user\_name": "HJAhbndrmK"&#x20;

}

</details>

### getAvailableMessageUsers

현재 참여한 룸에서 채팅 가능한 사용자의 목록을 조회합니다.

```jsx
await sdk.getAvailableMessageUsers();
```

| Parameter | Mandatory/Optional | Type | Description |
| --------- | ------------------ | ---- | ----------- |
| -         | -                  | -    | -           |

<details>

<summary><strong>리턴 객체 |</strong> getAvailableMessageUsers</summary>

&#x20; {&#x20;

&#x20;  "session": "Smt1U29ncVRsSDE2ODg3MDcxMDctNTA0",&#x20;

&#x20;  "count": 3,&#x20;

&#x20;  "page": 1,&#x20;

&#x20; "list":&#x20;

&#x20;   \[&#x20;

&#x20;     {&#x20;

&#x20;        "call\_type": "audiocall",&#x20;

&#x20;        "session": "SHdyWlFMZEJ1VjE2ODg3MDc1MTYtNTA3",&#x20;

&#x20;        "user\_id": "222",

&#x20;        "user\_name": "TydFCkYSBL"&#x20;

&#x20;   },&#x20;

&#x20;   {

&#x20;       "call\_type": "audiocall",&#x20;

&#x20;       "session": "SWxJZ2tGcldNeDE2ODg3MDc4NTYtNTEw",&#x20;

&#x20;       "user\_id": "333",&#x20;

&#x20;       "user\_name": "ErKMqhVSzb"&#x20;

&#x20;   },&#x20;

&#x20;   {&#x20;

&#x20;     "call\_type": "audiocall",&#x20;

&#x20;     "session": "U0lTUlpocVhOUTE2ODg3MDcxNjQtMzgy",&#x20;

&#x20;     "user\_id": "woo",&#x20;

&#x20;     "user\_name": "HJAhbndrmK"

&#x20;   }&#x20;

&#x20; ]

&#x20;}

</details>

###

### getDeviceList

해당 장치의 모든 오디오, 비디오 장치를 조회할 수 있는 API 입니다.

```jsx
await sdk.getDeviceList();
```

<details>

<summary><strong>리턴 객체 예시 | getDeviceList</strong></summary>

{&#x20;

"videoinput":

&#x20;                   \[\
&#x20;                      {&#x20;

&#x20;                         "kind":"videoinput",&#x20;

&#x20;                          "label":"Logitech BRIO (046d:085e)",&#x20;

&#x20;                           "deviceId": "33fb0bfdda06b8815f94baa46d3965\
&#x20;                                                211b5476825021ac91578280a5d7c05b94",&#x20;

&#x20;                           "groupId":"cbc0be3ca9648a43fa29e144e1460bb6\
&#x20;                                             df916243eea817625a4700b2cf910654 ",&#x20;

&#x20;                      }, \
&#x20;                     {&#x20;

&#x20;                         "kind":"videoinput",&#x20;

&#x20;                          "label":"FaceTime HD 카메라 (3A71:F4B5)",&#x20;

&#x20;                           "deviceId": "9e82b7ecc5f2844f1109f31ac47b\
&#x20;                                                b1c5fc1d9d13d7f627e4f1db3fd0132bf9be",&#x20;

&#x20;                           "groupId":"5ccd5bf9211dfd080cfcc6f8187f486c9a1\
&#x20;                                             02e579a4d9e3f4e22cdfecb732cf7 ",&#x20;

&#x20;                      },&#x20;

&#x20;                     ], \
"audioinput":

&#x20;                   \[\
&#x20;                      {&#x20;

&#x20;                         "kind":"audioinput",&#x20;

&#x20;                          "label":"Logitech BRIO (046d:085e)",&#x20;

&#x20;                           "deviceId": "5f9715786e17b339dfdfabfd65fc0a5b5\
&#x20;                                                850ec11fc6509085c4a13b5fa760bef",&#x20;

&#x20;                           "groupId":"2479fd4c965cadd52de1d9dd54debbcdb0\
&#x20;                                             caf370a2c0b916f13554d9eaec782d ",&#x20;

&#x20;                      }, \
&#x20;                     {&#x20;

&#x20;                         "kind":"audioinput",&#x20;

&#x20;                          "label":"MacBook Pro 마이크 (Built-in)",&#x20;

&#x20;                           "deviceId": "1a825a6af6bb985db3dbcdedf67cfad\
&#x20;                                                0d2b850f892a4dbd049fa01f140c2a972",&#x20;

&#x20;                           "groupId":"dbec76dc0e283229718a34a2a07de4\
&#x20;                                             e98bb5987fb5db535affb6428c6b0f1339 ",&#x20;

&#x20;                      },&#x20;

&#x20;                     ],&#x20;

}

</details>

### setAudioInput

제어하고 싶은 장치의 device id를 인수로 전달하면 됩니다.

```jsx
await sdk.setAudioInput(deviceId: );

```

| Parameter  | Mandatory/Optional | Type   | Description |
| ---------- | ------------------ | ------ | ----------- |
| device\_id | M                  | String |             |

### SetAudioOutput

제어하고 싶은 장치의 device id를 인수로 전달하면 됩니다.

```
await sdk.setAudioOutput(deviceId : );
```

| Parameter  | Mandatory/Optional | Type   | Description |
| ---------- | ------------------ | ------ | ----------- |
| device\_id | M                  | String |             |

### setVideoDevice

모바일 디바이스의 전/후면 카메라 switching 기능입니다.&#x20;

```jsx
await sdk.setVideoDevice(deviceId : );

```

| Parameter | Mandatory/Optional | Type   | Description |
| --------- | ------------------ | ------ | ----------- |
| deviceId  | M                  | String |             |

### destroyRoom

룸 삭제 기능을 수행하는 API 입니다. 룸에 어떤 참여자도 없으면 Omnitalk SDK에서 일정 시간 이후 자동으로 룸을 제거합니다. 만약 명시적으로 룸을 삭제하거나 추가 사용자의 룸 참여를 막고 싶다면 해당 roomId를 전달하여 기능을 수행할 수 있습니다. 자신이 참여하고 있는 룸을 삭제할 수는 없습니다. 방송 중인 참여자가 있는 룸을 삭제하게 되면 방송 중인 참여자들은 계속 방송할 수 있지만 추가적인 룸 참여는 불가능하며 룸 리스트에 조회되지 않습니다.

```jsx
await sdk.destroyRoom(roomId);
```

| Parameter | Mandatory/Optional | Type   | Description |
| --------- | ------------------ | ------ | ----------- |
| roomId    | M                  | String |             |

<details>

<summary><strong>리턴 객체 | destroyRoom</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"room\_id":"8a1086680e47261208eeff87000b",

}

</details>

### leave

자신의 방송을 종료하는 API입니다.&#x20;

```jsx
await sdk.leave();
```

| Parameter | Mandatory/Optional | Type | Description |
| --------- | ------------------ | ---- | ----------- |
| -         | -                  | -    |             |

<details>

<summary><strong>리턴 객체 | leave</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

}

</details>

### kickOut

사용자가 룸에 참여해 방송을 개시한 이후에 다른 사용자를 강제퇴장 시키는 기능입니다. 인수로 전달하는 session은 룸에서 강제 퇴장되며 세션이 끊어지게 됩니다. 룸의 다른 참여자들에게는 KICKOUT\_EVENT가 발생합니다.

```dart
await sdk.kickOut(target);
```

<table><thead><tr><th>Parameter</th><th width="192">Mandatory/Optional</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>target</td><td>M</td><td>String</td><td>강제퇴장시킬 유저의 세션</td></tr></tbody></table>

***

{% hint style="info" %}
**sdk 2.1.x 이후 버전부터 사용 가능**
{% endhint %}

### recordingStart

음성 녹음을 시작하는 API입니다. 모든 call\_type에서 호출할 수 있습니다. 단, 녹음 시작 API 호출은 call/room에 참여한 사용자별로 한 번만 호출할 수 있습니다.  recordingStop()을 호출하지 않고 leave()를 호출 하거나 연결이 끊어져도 해당 시점까지 녹음은 마무리됩니다.

```javascript
await sdk.recordingStart();
```

### recordingStop

음성 녹음을 종료하는 API입니다. 녹음 완료 시 옴니톡 콘솔에 등록한 Webhook URL로 콜백을 받을 수 있습니다.

```javascript
await sdk.recordingStop();
```


# Developer's Guide


# Pre-requisite

## 1. **앱의 네이티브 권한 설정**

* `android>app>src>main>AndroidManifest.xml`

```jsx
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.audio.output" />
<uses-feature android:name="android.hardware.microphone" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
```

* `ios>Runner>info.plist`

```jsx
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) Camera Usage!</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) Microphone Usage!</string>
```

* ios>Podfile  (for permission handler [참고](https://github.com/Baseflow/flutter-permission-handler/tree/main/permission_handler))

```

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    # Start of the permission_handler configuration
    target.build_configurations.each do |config|
   
       #  Preprocessor definitions can be found in: https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler_apple/ios/Classes/PermissionHandlerEnums.h
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',
  
        
        # dart: PermissionGroup.camera
        'PERMISSION_CAMERA=1',
  
        # dart: PermissionGroup.microphone
        'PERMISSION_MICROPHONE=1',
         
        # dart: PermissionGroup.notification
        'PERMISSION_NOTIFICATIONS=1', 
           
        # dart: PermissionGroup.bluetooth
        'PERMISSION_BLUETOOTH=1',
      ]
  
    end 
    # End of the permission_handler configuration

```

## 2. 패키지 설치

* `pubspec.yaml`

```groovy
omnitalk_sdk: ^2.0.0
flutter_webrtc: ^0.9.34
```

## **3. 최소 지원 사양**

* Flutter >= 3.1.0
* Dart >= 2.19
* Android API >=21
* IOS>= 11

Android와 ios 설정은 다음을 참고하시면 됩니다.

* `android > add > build.gradle`

```
defaultConfig {
   minSdkVersion 21
}
```

* ios > Podfile

```
platform :ios, '11.0'
```

## 4. 앱 개발 공통 사항

### Step 0. SDK 객체 초기화

[콘솔](https://omnitalk.io/console/service/service-id)에서 발급받은 Service Id와 Service Key로 SDK를 초기화 합니다. 해당 정보는 노출되지 않도록 주의하여야 합니다. 초기화된 SDK 객체는 이후 모든 메서드 호출에 사용됩니다.&#x20;

Omnitalk SDK는 싱글톤 패턴으로 제공됩니다. 아래 방법으로 SDK를 초기화시키고 객체를 얻을 수 있습니다.

```dart
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();
```


# Audiocall Guide

Audio call 또는 Voice call은 일반 전화 기능을 앱으로 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 이용하여 offerCall(), answerCall()을 각각 호출하고 해당 이벤트 메시지에 대응하는 것으로 전화 기능을 간단히 구현할 수 있습니다.

[Call Flow](/commons/call-flow) 에서는 audiocall의 흐름을 sequence diagram으로 보여줍니다.

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의 [Pre-requisite](https://docs.omnitalk.io/flutter/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK 초기화를 제외한 모든 API 기능은 유효한 세션의 존재를 전제로 하고 있습니다. 세션의 생성을 위해 createSession API를 호출합니다. 사용하고 싶은 번호나 문자열을 userId로 전달해 등록할 수 있으며 생략시엔 Omnitalk 서버에서 부여한 임의의 id를 리턴받을 수 있습니다.

```dart
await sdk.createSession();
```

## Step 2. 발신

동일한 Service Id로  세션을 생성한 사용자 중  idle state의 사용자에게 전화 요청을 할 수 있습니다.

offerCall API를 이용하여 전화 발신 요청을 할 수 있습니다.&#x20;

* callType: 전화 타입을 의미합니다. CallType은 Omnitalk SDK에서 enum type으로 제공합니다. 음성 통화를 위해서는 `audiocall` 을 전달하시면 됩니다.&#x20;
* callee: callee의 userId를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. (defalut = false)

```dart
await sdk.offerCall(
    callType: CallType.audiocall, 
    callee : callee); //발신측
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 `RINGING_EVENT`를 수신합니다. ([Event Message](https://docs.omnitalk.io/commons/event-message) 참고)

## Step 3. 수신

### callee가 RINGING\_EVENT를 받은 경우

callee가 세션을 생성한 상태에서 caller가 offerCall(전화 요청)을 하여`RINGING_EVENT`를 받은 경우, callee는 별도의 인수를 전달하지 않고 answerCall()을 호출하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 `RINGING_EVENT`에서 받은 caller의 session을 인수로 전달하여 leave()를 호출하시면 됩니다.

```typescript
await sdk.answerCall();
```

### callee가 전화 요청(offerCall) 이후에 session을 생성한 경우

callee가 세션을 생성하기 전 caller가 offerCall(전화 요청)을 하여 `RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 callType, caller 파라미터에 인수를 전달하여 전화를 수신할 수 있습니다. 이 경우, 애플리케이션에서 callee 에게 callType과 caller를 전달해 주어야 합니다.

* callType: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 떄와 동일하게 `audiocall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 userId를 전달하시면 됩니다.

```typescript
await sdk.answerCall(callTYpe : CallType.audiocall, caller : caller);
```

## Step 4. 연결 성공

음성 통화 연결이 성공하면 caller, callee 양층 모두 `CONNECTED_EVENT` 를 수신합니다.

## #오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute)[ ](https://docs.omnitalk.io/flutter/api-reference#mute-unmute)부분을 참조 바랍니다. mute/unmute API의 파라미터인 track type은 Omnitalk SDK에서 제공합니다. 예시는 아래와 같습니다.

```typescript
await sdk.setMute(track : TrackType.audio);
await sdk.setUnmute(track : TrackType.audio);
```

### 입출력 장치 변경

전화 연결 전, 또는 전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 API를 제공합니다.&#x20;

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. setAudioInput() 또는 set AudioOutput()에  deviceId를 전달하여 입출력 장치를 변경할 수 있습니다.


# Videocall Guide

Video call 은 영상 통화 기능을 앱으로 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 이용하여 offerCall(), answerCall()을 각각 호출하고 해당 이벤트 메시지에 대응하는 것으로 전화 기능을 간단히 구현할 수 있습니다.

[Call Flow](/commons/call-flow) 에서는 audiocall의 흐름을 sequence diagram으로 보여줍니다.

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의 [Pre-requisite](https://docs.omnitalk.io/flutter/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK 초기화를 제외한 모든 API 기능은 유효한 세션의 존재를 전제로 하고 있습니다. 세션의 생성을 위해 createSession API를 호출합니다. 사용하고 싶은 번호나 문자열을 userId로 전달해 등록할 수 있으며 생략시엔 Omnitalk 서버에서 부여한 임의의 id를 리턴받을 수 있습니다.

```dart
await sdk.createSession();
```

## Step 2. 발신

동일한 Service Id로  세션을 생성한 사용자 중  idle state의 사용자에게 전화 요청을 할 수 있습니다.

offerCall API를 이용하여 전화 발신 요청을 할 수 있습니다. 비디오 객체의 타입 선언 및 초기화를 위해 flutter\_webrtc 패키지를 import 하여 사용합니다.

* callType: 전화 타입을 의미합니다. CallType은 Omnitalk SDK에서 enum type으로 제공합니다. 영상 통화를 위해서는 `videocall` 을 전달하시면 됩니다.&#x20;
* callee:  callee의 userId를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. (defalut = false)
* localRenderer : RTCVideoRenderer 타입의 객체로 초기화시켜 전달합니다.&#x20;
* remoteRenderer : RTCVideoRenderer 타입의 객체로 초기화시켜 전달합니다.

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

RTCVideoRenderer localvideo = RTCVideoRenderer();
RTCVIdeoRenderer remotevideo = RTCVideoRenderer();

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

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 `RINGING_EVENT`를 수신합니다. ([Event Message](https://docs.omnitalk.io/commons/event-message) 참고)

## Step 3. 수신

### callee가 RINGING\_EVENT를 받은 경우

callee가 세션을 생성한 상태에서 caller가 offerCall(전화 요청)을 하여`RINGING_EVENT`를 받은 경우, callee는 자신과 상대의 영상을 담을 객체로 answerCall()을 호출하여 전화를 수신할 수 있습니다. `RINGING_EVENT`에서 받은 call type과 caller정보와 녹음 여부, RTCVideoRenderer 타입으로 초기화된 객체를 전달하면 됩니다. 수신 거절을 하고싶은 경우 `RINGING_EVENT`에서 받은 caller의 session을 인수로 전달하여 leave()를 호출하시면 됩니다.

### callee가 전화 요청(offerCall) 이후에 session을 생성한 경우

callee가 세션을 생성하기 전 caller가 offerCall(전화 요청)을 하여 `RINGING_EVENT`를 받지 못한 경우, 애플리케이션에서 callee 에게 callType과 caller를 전달해 주어야 합니다. callee는 answerCall()을 호출하면서 callType, caller, RTCVideoRenderer 타입으로 초기화된 객체를 전달하여 전화를 수신할 수 있습니다.&#x20;

* callType: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 떄와 동일하게 `videocall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 userId를 전달하시면 됩니다.
* localRenderer : RTCVideoRenderer 타입의 객체로 초기화시켜 전달합니다.&#x20;
* remoteRenderer : RTCVideoRenderer 타입의 객체로 초기화시켜 전달합니다.

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

## Step 4. 연결 성공

영상 통화 연결이 성공하면 caller, callee 양층 모두 `CONNECTED_EVENT` 를 수신합니다.

## 비디오 장치 제어

### mute/unmute

전화 통화 중 로컬에서 송출되는 비디오 on/off 기능을 mute/unmue API를 이용하여 개발할 수 있습니다. 음소거는 TrackType.audio를 track 으로 전달해 별도의 mute API를 호출해야합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute)[ ](https://docs.omnitalk.io/flutter/api-reference#mute-unmute)부분을 참조 바랍니다. video mute는 자신의 영상 송출을 off 시키는 기능입니다.&#x20;

```typescript
await sdk.setMute(track : TrackType.video);  //비디오 송출만 off
await sdk.setUnmute(track : TrackType.video );
```

### 비디오 카메라 변경

전화 통화 중 비디오 장치를 전환할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의[setVideoDevice](https://docs.omnitalk.io/flutter/api-reference#setvideodevice) 부분을 참조 바랍니다.

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. setVideoDevice()에 선택하고자는 device id를 인수로 전달하면 됩니다.&#x20;


# SIPcall Guide

SIPcall은 애플리케이션과 일반 전화 간 전화를 연결 할 수 있도록 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 이용하여 offerCall(), answerCall()을 각각 호출하고 해당 이벤트 메시지에 대응하는 것으로 전화 기능을 간단히 구현할 수 있습니다.

[Call Flow](/commons/call-flow) 에서는 audiocall의 흐름을 sequence diagram으로 보여줍니다.

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의 [Pre-requisite](https://docs.omnitalk.io/flutter/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK 초기화를 제외한 모든 API 기능은 유효한 세션의 존재를 전제로 하고 있습니다. 세션의 생성을 위해 createSession API를 호출합니다. 사용하고 싶은 번호나 문자열을 userId로 전달해 등록할 수 있으며 생략시엔 Omnitalk 서버에서 부여한 임의의 id를 리턴받을 수 있습니다.

```dart
await sdk.createSession();
```

## Step 2. 발신

offerCall API를 이용하여 전화 발신 요청을 할 수 있습니다.&#x20;

* callType: 전화 타입을 의미합니다. CallType은 Omnitalk SDK에서 enum type으로 제공합니다. SIP 통화를 위해서는 `sipcall` 을 전달하시면 됩니다.&#x20;
* callee:  전화 수신자의 실제 전화번호(일반전화, 모바일) 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. (defalut = false)

```dart
await sdk.offerCall(
    callType: CallType.sipcall, 
    callee : '01011119999'
    );
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 `RINGING_EVENT`를 수신합니다. ([Event Message](https://docs.omnitalk.io/commons/event-message) 참고)

## Step 3. 수신

### callee가 callNumber를 생성한 상태에서 전화 요청이 왔을때&#x20;

애플리케이션이 makeSipNum API를 이용하여 callNumber를 생성한 상태에서 caller가 offerCall(전화 요청)을 하여`RINGING_EVENT`를 받은 경우, callee는 별도의 인수를 전달하지 않고 answerCall()을 호출하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 `RINGING_EVENT`에서 받은 caller의 session을 인수로 전달하여 leave()를 호출하시면 됩니다.

```typescript
await sdk.answerCall();
```

### callee가 callNumber를 생성하기 전 전화 요청이 왔을 때

애플리케이션이 callNumber를 생성하기 전 caller가 offerCall(전화 요청)을 하여 `RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터 callType과 caller에 직접 인수를 전달하여 전화를 수신할 수 있습니다. 이 경우, 옴니톡 서버에서 애플리케이션 백엔드로 별도의 이벤트로 call type과 caller의 정보를 제공드릴 예정입니다.

* callType: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 떄와 동일하게 `sipcall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 userId를 전달하시면 됩니다.

```typescript
await sdk.answerCall(callTYpe : CallType.sipcall, caller : caller);
```

## Step 4. 연결 성공

음성 통화 연결이 성공하면 caller, callee 양층 모두 `CONNECTED_EVENT` 를 수신합니다.

## #오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute)[ ](https://docs.omnitalk.io/flutter/api-reference#mute-unmute)부분을 참조 바랍니다. mute/unmute API의 파라미터인 track type은 Omnitalk SDK에서 제공합니다. 예시는 아래와 같습니다.

```typescript
await sdk.setMute(track : TrackType.audio);
await sdk.setUnmute(track : TrackType.audio);
```

### 입출력 장치 변경

전화 연결 전, 또는 전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 API를 제공합니다.&#x20;

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. setAudioInput() 또는 set AudioOutput()에  deviceId를 전달하여 입출력 장치를 변경할 수 있습니다.


# AudioRoom Guide

Audioroom은 음성 회의 기능을 인터넷을 이용한 앱으로 구현한 것입니다. Omnitalk SDK를 이용하여 회의실(룸) 생성 및 참여하는 것으로 1:1 또는 다자간 음성 회의실 기능을 간단히 구현할 수 있습니다.&#x20;

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의 [Pre-requisite](https://docs.omnitalk.io/flutter/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK 초기화를 제외한 모든 API 기능은 유효한 세션의 존재를 전제로 하고 있습니다. 세션의 생성을 위해 createSession API를 호출합니다. 사용하고 싶은 번호나 문자열을 userId로 전달해 등록할 수 있으며 생략시엔 Omnitalk 서버에서 부여한 임의의 id를 리턴받을 수 있습니다.

```dart
await sdk.createSession();
```

## Step 2. 회의실 생성 및 조회

기존 회의실을 조회해 참여하거나 새로운 회의실을 만들 수 있습니다. 기존 회의실(룸) 조회는 roomList API를, 회의실(룸) 생성은 createRoom API를 이용합니다. 룸 타입을 명시하지 않으면 모든 타입의 룸이 조회됩니다. 조회한 목록 결과의 room\_id 로 회의실에 참여할 수 있습니다.

```dart
var roomResult = await sdk.roomList(roomType: RoomType.audioroom);

await sdk.createRoom(roomType: RoomType.audioroom);
```

## Step 3. 회의실 참여

회의실에 참여하게 되면 별도의 작업 없이 참여자들과 음성 회의를 할 수 있게 되며, 회의실에 관련된 이벤트 메세지를 수신할 수 있습니다. 음성 회의실에서 수신 가능한 이벤트는 아래와 같습니다. 자세한 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

```dart
await sdk.joinRoom(roomId : roomId)
```

* CONNECTED\_EVENT - 새로운 참가자 입장했을 때
* LEAVE\_EVENT - 다른 참가자가 퇴장 했을 때
* MUTE\_EVENT - 다른 참가자가 mute 했을 때
* UNMUTE\_EVENT - 다른 참가자가 unmute 했을 때
* MESSAGE\_EVENT - 채팅 메세지 수신 이벤트, 회의실 입장시 채팅 기능을 사용할 수 있는 상태가 됩니다. 채팅기능 사용법은 [Chatting Guide](/typescript/developers-guide/chatting) 를 참조 바랍니다.

## 참여자 목록 조회

[partiList()](/typescript/api-reference#partilist) API 를 사용하여 입장한 회의실에 참여한 사용자 목록을 조회할 수 있습니다.

```dart
await sdk.pariList();
```


# VideoRoom Guide

Videoroom은 영상 회의 기능을 인터넷을 이용한 앱으로 구현한 것입니다. Omnitalk SDK를 이용하여 회의실(룸) 생성 및 참여하는 것으로 1:1 또는 다자간 영상 회의실 기능을 간단히 구현할 수 있습니다.&#x20;

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의 [Pre-requisite](https://docs.omnitalk.io/flutter/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK 초기화를 제외한 모든 API 기능은 유효한 세션의 존재를 전제로 하고 있습니다. 세션의 생성을 위해 createSession API를 호출합니다. 사용하고 싶은 번호나 문자열을 userId로 전달해 등록할 수 있으며 생략시엔 Omnitalk 서버에서 부여한 임의의 id를 리턴받을 수 있습니다.

```dart
await sdk.createSession();
```

## Step 2. 회의실 생성 및 조회

기존 회의실을 조회해 참여하거나 새로운 회의실을 만들 수 있습니다. 기존 회의실(룸) 조회는 roomList API를, 회의실(룸) 생성은 createRoom API를 이용합니다. 룸 타입을 명시하지 않으면 모든 타입의 룸이 조회됩니다. 조회한 목록 결과의 room\_id 로 회의실에 참여할 수 있습니다.

```dart
var roomResult = await sdk.roomList(roomType: RoomType.audioroom);

await sdk.createRoom(roomType: RoomType.videoroom);
```

## Step 3. 회의실 참여

회의실에 참여하게 되면 별도의 작업 없이 참여자들과 음성 회의를 할 수 있게 되며, 회의실에 관련된 이벤트 메세지를 수신할 수 있습니다. 음성 회의실에서 수신 가능한 이벤트는 아래와 같습니다. 자세한 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

```dart
await sdk.joinRoom(roomId : roomId)
```

* CONNECTED\_EVENT - 새로운 참가자 입장했을 때
* LEAVE\_EVENT - 다른 참가자가 퇴장 했을 때
* MUTE\_EVENT - 다른 참가자가 mute 했을 때
* UNMUTE\_EVENT - 다른 참가자가 unmute 했을 때
* MESSAGE\_EVENT - 채팅 메세지 수신 이벤트, 회의실 입장시 채팅 기능을 사용할 수 있는 상태가 됩니다. 채팅기능 사용법은 [Chatting Guide](/typescript/developers-guide/chatting)[ ](https://docs.omnitalk.io/flutter/developers-guide/chatting-guide)를 참조 바랍니다.

## Step 4. 방송 시작

비디오 방송의 시작은 자신의 영상을 담을 RTCVideoRenderer 타입의 객체를 인수로 전달해 publish API를 호출하면 됩니다. publish API호출이 성공하면 해당 방송의 세션 id가 담긴 객체를 리턴 받게 되고 룸의 다른 사용자들에게 `BROADCASTING_EVENT`가 발생합니다.

```dart
RTCVideoRenderer localVideo = RTCVideoRenderer();

await sdk.publish(localRenderer: localVideo);
```

## Step 5. 방송 구독

룸에서 방송중인 사용자의 영상을 구독하기 위해서는 subscribe API를 사용하면 됩니다. 방송 리스트를 조회하거나 `BROADCASTING_EVENT`를 수신해 구독할 방송의 세션을 구할 수 있습니다. 구독할 영상을 담을 RTCVideoRenderer 타입의 객체를 함께 인수로 전달합니다. 방송 구독에 성공하면 `CONNECTED_EVENT`를 받게 됩니다.&#x20;

```dart
RTCVideoRenderer remoteVideo = RTCVideoRenderer();
await sdk.subscribe(publisherSession : publisherSession, remoteRenderer : remoteVideo);
```

### 참여자 목록 조회

[publishList API](https://docs.omnitalk.io/flutter/api-reference#publishlist) 를 사용하여 입장한 회의실에 참여하여 방송을 개시한 사용자 목록을 조회할 수 있습니다.

```dart
await sdk.publishList();
```

### BROADCASTING\_EVENT 수신

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


# Chatting Guide

Omnitalk SDK에서는 어떤 타입의 룸이든 참여하게 되면 sendMessage API를 이용하여 채팅 메시지를 주고 받을 수 있습니다. message를 룸 전체 사용자에게 보내는 'send' action과 특정 사용자에게만 전달하는 'whisper' action이 있습니다. 귓속말 기능은 상대의 session을 target 인수로 전달해야합니다.&#x20;

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의 [Pre-requisite](https://docs.omnitalk.io/flutter/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK 초기화를 제외한 모든 API 기능은 유효한 세션의 존재를 전제로 하고 있습니다. 세션의 생성을 위해 createSession API를 호출합니다. 사용하고 싶은 번호나 문자열을 userId로 전달해 등록할 수 있으며 생략시엔 Omnitalk 서버에서 부여한 임의의 id를 리턴받을 수 있습니다.

```dart
await sdk.createSession();
```

## Step 2. 룸 참여

```dart
await sdk.createRoom();
await sdk.joinRoom();
```

## Step 3. 메시지 보내기

```dart
await sdk.sendMessage(action: MessageAction.send, message: msg); // 룸 전체 메시지 전송
await sdk.sendMessage(
   action : MessageAction.whisper,
   message : whispermsg,
   target : target,
   );  // 특정 상대에 귓속말 메시지 전송
```

## Step 4. 메시지 수신하기

룸의 다른 사용자가 보내는 메시지는 `MESSAGE_EVENT`를 수신하면 됩니다.&#x20;

```dart
sdk.on('event', (dynamic event) {
    switch(event['cmd']){
        case 'MESSAGE_EVENT':
            print(event['message']);
            print(event['user_id']);
            print(event['action'];
        }
    }
```


# Installation

공식 패키지 저장소(npmjs.com)에서 [React-Native용 옴니톡SDK](https://www.npmjs.com/package/omnitalk-rn-sdk)를 다운받아 설치할 수 있습니다.&#x20;

```dart
npm i omnitalk-rn-sdk
```


# Quick Start

Omnitalk SDK는 쉽고 간편하게 webrtc 기술을 이용할 수 있도록 만들어진 패키지입니다. Omnitalk SDK의 모든 API는 async \~ await 구조로 작성되었습니다. 요청이 실패하면 에러를 throw 합니다. 상세 API 사용법은 [REACT\_NATIVE API Reference](https://docs.omnitalk.io/react-native/api-reference)를 참조바랍니다.

### 1. 옴니톡 객체 생성

발급받은 Service Id와 Service Key로 omnitalk 객체를 생성합니다. (Service Id와 Service Key는 [console 페이지](https://omnitalk.io/console/service/service-id)에서 발급 가능하며 노출되지 않도록 주의하여야 합니다.)

```jsx
import Omnitalk from 'omnitalk-rn-sdk';
const SERVICE_ID = '발급받은 service id';
const SERVICE_KEY = '발급받은 service key';  

Omnitalk.sdkInit(SERVICE_ID, SERVICE_KEY);
const sdk = Omnitalk.getInstance();
```

### 2. 세션 생성

인수로 전달한 user\_id의 세션을 생성하게 됩니다. user\_id 생략시 Omnitalk 서버에서 임의의 id를 부여합니다.

```jsx
const [session, setSession] = useState('');
await sdk.createSession(user_id)
              .then((session: any) => setSession(session.session));
```

### 3. 룸 생성

인수로 전달한 룸 타입의 방을 생성합니다.

```jsx
import {DEFAULT_ROOM_TYPE} from 'omnitalk-rn-sdk';

const [roomId, setRoomId] = useState('');
await sdk.createRoom(DEFAULT_ROOM_TYPE.VIDEO_ROOM)
              .then((res: any) => setRoomId(res.room_id));

```

### 4. 룸 참여

룸에 참여하게 되면 자동으로 오디오 방송을 시작하고 채팅 메시지를 주고 받을 수 있는 상태가 됩니다.

```jsx
await sdk.joinRoom(roomId);
```

### 5. 방송 시작 (video)

오디오 방송은 룸에 참여하는 것만으로 시작 가능하며 영상 방송은 자신의 방송 영상 스트림을 담을 객체를 전달해 방송을 발행하는 것으로 시작합니다. publish API호출이 성공하면 해당 방송의 세션 id가 담긴 객체를 리턴 받게 됩니다.

```jsx
const [localStreamRef, setLocalStreamRef] = useState<typeof RTCView>({streamURL: ''});
await sdk.publish(localStreamRef)
```

### 6. 이벤트 메시지 수신

옴니톡 SDK에서 전달하는 이벤트 메시지 규격과 메시지 수신 방법은 [여기](/commons/event-message)를 참고하시기 바랍니다. 다음은 방송 이벤트 발생시 방송 세션을 저장하는 예시입니다.

```jsx
useEffect(() => {
    const eventListener = async (msg: any) => {
      console.log('Event Message : ', msg);
      switch (msg.cmd) {
        case 'RINGING_EVENT':
          setCaller(msg.caller);
          setCallee(msg.callee);
          break;
        case 'CONNECTED_EVENT':
          setLocalOn(true);
          break;
        case 'BROADCASTING_EVENT':
          setpublisherSession(msg.session);
          break;
      }
    };

    sdk?.on('event', eventListener);
    return () => {
      sdk?.off('event', eventListener);
    };
  }, []);
```

### 7. 방송 구독

구독하고자는 방송의 세션 id를 인수로 전달하면 해당 방송을 구독할 수 있습니다. 방송의 세션 id는 publish의 리턴 객체나 `BROADCASTING_EVENT`의 [이벤트 메시지](/commons/event-message#broadcasting_event)에서 확인할 수 있습니다.

```jsx
const [remoteStreamRef, setRemoteStreamRef] = useState<typeof RTCView>({streamURL: ''});

await sdk?.subscribe(publisherSession, remoteStreamRef);
```

### 8. 음성  통화

1:1 음성 통화를 구현하기 위한 발신 기능은 offerCall API를 이용하여 구현합니다. 상세 기능 구현 예시는 Dev guide의 [audio call](https://docs.omnitalk.io/react-native/developers-guide/audio-call-guide) 항목을 참조 바랍니다.  call flow는 [여기](https://docs.omnitalk.io/commons/call-flow)를 참조바랍니다.&#x20;

세션이 만들어진 상태에서 call type과 착신 상대방인 callee의 user\_id를 전달합니다. offerCall 호출이 성공하면 caller에게는 `RINGBACK_EVENT`가, callee에게는 `RINGING_EVENT`가 전달됩니다. callee측이 answerCall을 호출하면 caller, caller는 `CONNECTED_EVENT`를 수신하고 음성통화가 연결됩니다. callee는 [ leave API](/typescript/api-reference#leave)를 이용하여 수신거절할 수 있습니다. 상세 음성 통화 구현 예시는 여기를 참고바랍니다.

```jsx
import {CALL_TYPE} from 'omnitalk-rn-sdk';

await sdk.offerCall(CALL_TYPE.AUDIO_CALL, callee); //발신측

await sdk.answerCall();  // 착신측

await sdk.leave(caller); // 수신 거절
```

### 9. 영상 통화

1:1 영상 통화를 구현하기 위한 발신 기능은 offerCall API를 이용하여 구현합니다. 상세 기능 구현 예시는 Dev guide의 [video call](https://docs.omnitalk.io/react-native/developers-guide/video-call-guide) 항목을 참조 하시기 바랍니다. call flow는 [여기](https://docs.omnitalk.io/commons/call-flow)를 참조 하시기 바랍니다.&#x20;

세션이 만들어진 상태에서 call type과 착신 상대방인 callee의 user\_id, 그리고 각각의 영상 스트림 URL을 담을 객체를 전달합니다. offerCall 호출이 성공하면 caller에게는 `RINGBACK_EVENT`가, callee에게는 `RINGING_EVENT`가 전달됩니다. 착신측인 callee 또한 caller와 callee의 영상 스트림 URL을 담을 객체를 전달하여 answerCall을 호출하면 영상 통화가 연결됩니다.

```jsx
const [localStreamRef, setLocalStreamRef] = useState<typeof RTCView>({
    streamURL: '',
  });
  const [remoteStreamRef, setRemoteStreamRef] = useState<typeof RTCView>({
    streamURL: '',
  });

await sdk.offerCall(
          CALL_TYPE.VIDEO_CALL,
          callee,
	  false,
          localStreamRef,
          remoteStreamRef,
        );
```

착신측은 RINGING\_EVENT를 받고 answerCall API를 이용해 통화를 수락하거나 leave API를 이용해 거절할 수 있습니다.

```typescript
await sdk.answerCall(
              CALL_TYPE.VIDEO_CALL,
              caller,
              localStreamRef,
              remoteStreamRef,
            );
```

### 10. 채팅 메시지

어떤 타입이든 룸에 참여하게 되면 채팅 메시지를 주고 받을 수 있습니다. sendMessage API를 이용하여 action type을 명시하면 룸 전체에 채팅 메시지 발송 및 특정 상대로의 귓속말 기능을 구현할 수 있습니다. 귓속말은 상대의 session id를 target 인수로 전달하면 됩니다.

```jsx
await sdk.sendMessage(MESSAGE_ACTION.SEND, text); // 룸 전체 메시지 전송
await sdk.sendMessage(
                MESSAGE_ACTION.WHISPER,
                whispermsg,
                target,
              );  // 특정 상대에 귓속말 메시지 전송
```

### 11. 방송 종료

방송을 종료하는 API입니다. 종료시키고 싶은 session id를 전달하면 수신 거절이나 강제 퇴장 등의 기능으로 활용할 수 있습니다. session id를 전달하지 않으면 자신의 방송을 종료하게 됩니다.

```jsx
await sdk.leave();
```


# API Reference

⚠️ SDK 2.0.x 버전과 2.1.x 이후 버전간 호환 불가

## Synchronization

Omnitalk SDK는 통신 서비스를 제공하기 위해 Offer-Answer 구조로 설계되어 있으며, 이를 위해 반드시 async, await 비동기 처리를 지원해야 합니다.

## **Global Module**

Omnitalk 객체를 생성합니다. 생성된 객체는 이후 모든 메서드 호출에 사용됩니다. Service Id와 Service Key는 [console 페이지](https://omnitalk.io/console/service/service-id)에서 발급 가능하며 노출되지 않도록 주의하여야 합니다.

```javascript
import { Omnitalk } from "omnitalk-rn-sdk";

const SERVICE_ID = '발급받은 service id';
const SERVICE_KEY = '발급받은 service key';  // 앱

Omnitalk.sdkInit(SERVICE_ID, SERVICE_KEY);
const sdk = Omnitalk.getInstance();
```

### EVENT\_MESSAGE

### on

이벤트 메시지는 [여기](https://docs.omnitalk.io/commons/event-message)를 참고하시면 됩니다. 이벤트 메시지를 수신하기 위해서는 옴니톡의 이벤트 리스너 API를 이용하시면 됩니다. (React-native는 screen share/unshare 기능을 제공하지 않습니다.)

```
sdk.on('event', ()=>{})
```

leave 이벤트로 서버와의 연결이 끊기거나 사용자 인터넷 환경 불안정 등으로 인터넷 연결이 끊길 때 발생하는 close 메시지입니다.

```
sdk.on('close', ()=>{})
```

### createSession

사용자의 세션을 생성하기 위해 서버와 연결하고 그 결과로 세션 id, 유저 id가 담긴 객체를 리턴합니다. user\_id 생략시 Omnitalk 서버에서 임의의 id를 부여합니다.

```jsx
await sdk.createSession(user_id);
```

| Parameter | Mandatory/Optional | Type   | Description |
| --------- | ------------------ | ------ | ----------- |
| user\_id  | O                  | String | max 64      |

<details>

<summary><strong>리턴 객체 | createSession</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"user\_id":"omnitalk",

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* SDK가 초기화 되지 않은 경우(sdkInit 호출 전)
* SDK 초기화 할 때 인자로 전달한 service id와 service key가 유효하지 않은 경우
* 이미 세션을 생성한 경우
* user\_id가 64자를 초과하는 경우
* user\_id가 string type이 아닌 경우

### ~~sessionList(deprecated)~~

세션 생성 후 같은 Service Id 및 Key를 사용하는 모든 사용자를 조회합니다.

```jsx
await sdk.sessionList();
```

| Parameter | Mandatory/Optional | Type   | Description                |
| --------- | ------------------ | ------ | -------------------------- |
| page      | O                  | Number | default = 1, per page = 10 |

<details>

<summary><strong>리턴 객체 | sessionList</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

"page": 1,&#x20;

"count": 1,&#x20;

"list": \[&#x20;

&#x20;           { "user\_id": "omnitalk",&#x20;

&#x20;             "call\_type": "videocall",&#x20;

&#x20;             "state": "busy",&#x20;

&#x20;           }&#x20;

&#x20;         ]

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 세션을 생성하지 않은 경우
* page가 number type이 아닌 경우

### createRoom

모든 방송은 룸에서 이루어집니다. 방송을 시작할 룸 타입을 전달해 룸을 생성합니다. 방 주제나 방의 비밀 번호를 설정할 수 있습니다. start\_date 및 end\_date는 룸 생성 및 종료 예상 시간을 설정할 때 이용합니다.&#x20;

```jsx
await sdk.createRoom(room_type);
```

| Parameter   | Mandatory/Optional | Type                | Description |
| ----------- | ------------------ | ------------------- | ----------- |
| room\_type  | M                  | DEFAULT\_ROOM\_TYPE | sdk 제공      |
| subject     | O                  | String              | max 128     |
| secret      | O                  | Number              | 6 digits    |
| start\_date | O                  | Number              | Date 객체     |
| end\_date   | O                  | Number              | Date 객체     |

<details>

<summary><strong>리턴 객체 | createRoom</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"room\_id": "8a1086680e47261208eeff87000b"

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 세션을 생성하지 않은 경우
* subject가 128자를 초과하는 경우
* secret이 6자를 초과하는 경우

### roomList

인수로 전달한 룸타입에 해당하는 모든 룸을 조회해 리스트로 반환합니다. default인 "all"은 룸타입에 관계없이 전체 룸을 조회합니다.

```jsx
await sdk.roomList(room_type);
```

| Parameter  | Mandatory/Optional | Type       | Description                |
| ---------- | ------------------ | ---------- | -------------------------- |
| room\_type | O                  | ROOM\_TYPE | sdk 제공, default= "all"     |
| page       | O                  | Number     | default = 1, per page = 10 |

<details>

<summary><strong>리턴 객체 | roomList</strong></summary>

{

&#x20; "session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

&#x20;  "count": 1,&#x20;

&#x20;  "page": 1,&#x20;

&#x20;  "room\_type": "all",&#x20;

&#x20;  "list":&#x20;

&#x20;        \[&#x20;

&#x20;          {&#x20;

&#x20;             "room\_id": "8a1086680e47261208eeff87000b",&#x20;

&#x20;              "room\_type": "videoroom",&#x20;

&#x20;              "count": 0,&#x20;

&#x20;              "secret": true,&#x20;

&#x20;              "sip\_support": true,&#x20;

&#x20;              "sip\_number": "991000"  (optional)

&#x20;              "start\_date": 1686816051,&#x20;

&#x20;              "end\_date": 1686819651,&#x20;

&#x20;              "reg\_date": 1686816051,&#x20;

&#x20;              "subject": "fish"&#x20;

&#x20;         }    &#x20;

&#x20;      ]

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 세션을 생성하지 않은 경우

### joinRoom

방송을 시작하거나 다른 방송을 시청하기 위해서는 반드시 룸 참여 과정이 필요합니다.&#x20;

```jsx
await sdk.joinRoom(room_id);
```

| Parameter  | Mandatory/Optional | Type   | Description      |
| ---------- | ------------------ | ------ | ---------------- |
| room\_id   | M                  | String |                  |
| secret     | O                  | Number | 6 digits         |
| user\_name | O                  | String | max 64, nickname |

<details>

<summary><strong>리턴 객체 | joinRoom</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

"room\_id": "8a1086680e47261208eeff87000b",&#x20;

"room\_type": "videoroom"

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 세션을 생성하지 않은 경우
* room\_id가 32자를 초과하는 경우
* user\_name이 64자를 초과하는 경우
* secret이 6자를 초과하는 경우

### partiList

해당 룸에 참여한 모든 사용자(방송 개시 여부와 무관)를 조회합니다. room\_id를 전달하지 않으면 자신이 참여한 룸의 참여자 리스트를 조회합니다.&#x20;

```jsx
await sdk.partiList(room_id);
```

| Parameter | Mandatory/Optional | Type   | Description                |
| --------- | ------------------ | ------ | -------------------------- |
| room\_id  | O                  | String | max 32                     |
| page      | O                  | Number | default = 1, per page = 10 |

<details>

<summary><strong>리턴 객체 | partiList</strong></summary>

{

&#x20;   "session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

&#x20;   "page": 1,&#x20;

&#x20;   "count": 1,&#x20;

&#x20;   "list":&#x20;

&#x20;           \[&#x20;

&#x20;             {&#x20;

&#x20;                 "session": "YzMyYWE1YTA3MmJhMTY4",&#x20;

&#x20;                 "user\_id": "<jason@omnistory.net>",&#x20;

&#x20;                 "user\_name": "jason",&#x20;

&#x20;                 "call\_type": "videocall",&#x20;

&#x20;              }&#x20;

&#x20;           ]

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 룸에 참가중이 아닌 경우
* room\_id가 32자를 초과하는 경우

### publish

영상 방송을 개시하고 방송 세션 id가 담긴 객체를 리턴받습니다. 영상 stream url을 담을 객체를 전달해야 합니다. 같은 룸의 다른 사용자가 join하거나 publish를 하게 되면 `CONNECTED_EVENT`를 받게 됩니다. 이는 각 사용자(peer)의 오디오가 연결되어 방송을 구독할 수 있는 상태가 되었음을 의미합니다. publish한 방송의 영상을 보고 싶은 사용자는 구독 [subscribe API](https://app.gitbook.com/o/Kvp35YpCpS2xoh7EQYPA/s/aPg0bJkhusp9D4dvlOo2/~/changes/87/react-native/api-reference#subscribe)를 이용하면 됩니다.

```jsx
await sdk.publish(local_renderer);
```

| Parameter       | Mandatory/Optional | Type    | Description                         |
| --------------- | ------------------ | ------- | ----------------------------------- |
| local\_renderer | M                  | RTCView | react-native-webrtc의 RTCView 타입의 객체 |

<details>

<summary><strong>리턴 객체 | publish</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 이미 영상 방송을 개시중인 상태
* 룸에 참가중이 아닌 경우
* 참가중인 룸 타입이 영상 방송을 지원하지 않는 경우 (VIDEO\_ROOM 또는 WEBINAR가 아닌 경우)

### publishList

참여한 룸에서 방송 중인 사용자 리스트를 조회합니다. room\_id를 전달하지 않으면 자신이 참여한 룸의 참여자 리스트를 조회합니다.&#x20;

```jsx
await sdk.publishList();
```

| Parameter | Mandatory/Optional | Type   | Description                |
| --------- | ------------------ | ------ | -------------------------- |
| room\_id  | O                  | String |                            |
| page      | O                  | Number | default = 1, per page = 10 |

<details>

<summary><strong>리턴 객체 | publishList</strong></summary>

{

&#x20;  "session": "YjQ1ZGUzYzA3MmJhMTY4Njcx",&#x20;

&#x20;  "room\_id": "9389314d3cb1b92eeaa81b618e0f",

&#x20;  "page": 1,&#x20;

&#x20;  "count": 1,&#x20;

&#x20;  "list":&#x20;

&#x20;           \[&#x20;

&#x20;             {&#x20;

&#x20;              "session": "YzMyYWE1YTA3MmJhMTY4",&#x20;

&#x20;              "track": "video",&#x20;

&#x20;              "audio\_mute": false,&#x20;

&#x20;              "video\_mute": false,&#x20;

&#x20;              "user\_id": "sADKOqOGBA", &#x20;

&#x20;              "user\_name": "kAIaDnhpPH"&#x20;

&#x20;             }

&#x20;           ],

&#x20;}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 룸에 참가중이 아닌 경우
* 참가중인 룸 타입이 다자간 영상 회의 타입이 아닌 경우 (VIDEO\_ROOM 또는 WEBINAR가 아닌 경우)
* room\_id가 32자를 초과하는 경우
* room\_id가 string type이 아닌 경우
* page가 number type이 아닌 경우

### subscribe

구독할 방송의 세션 번호와 구독 영상의 stream url을 담을 객체를 전달하면 해당 방송을 구독할 수 있습니다. subscribe 호출이 성공하면 자신의 세션, 구독하는 세션, 화면 공유 여부에 대한 boolean 값을 리턴 객체로 받게 됩니다.

```jsx
await sdk.subscribe(publisher_session, remote_renderer);
```

| Parameter          | Mandatory/Optional | Type    | Description                         |
| ------------------ | ------------------ | ------- | ----------------------------------- |
| publisher\_session | M                  | String  |                                     |
| remote\_renderer   | M                  | RTCView | react-native-webrtc의 RTCView 타입의 객체 |

<details>

<summary><strong>리턴 객체 | subscribe</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Nj",  // 자신의 세션

"subscribe": "YzMyYWE1YTA3MmJhMTY4Njg"  // 구독하는 상대의 세션

"screen": false // 화면 공유 여부에 대한 boolean 값

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 룸에 참가중이 아닌 경우
* 참가중인 룸 타입이 다자간 영상 회의 타입이 아닌 경우 (VIDEO\_ROOM 또는 WEBINAR가 아닌 경우)
* publisher\_session를 전달하지 않은 경우
* publisher\_session이 40자를 초과하는 경우
* 너무 많은 방송을 구독한 경우
  * 장치 사양과 해상도에 따라 차이가 있으나, 많은 영상을 구독하여 한번에 시청하는 경우 영상 끊김 현상이 발생할 수 있습니다.

### unsubscribe

구독 중인 방송의 구독을 취소할 수 있습니다.

```jsx
await sdk.unSubscribe(publisher_session);
```

| Parameter          | Mandatory/Optional | Type   | Description |
| ------------------ | ------------------ | ------ | ----------- |
| publisher\_session | M                  | String |             |

<details>

<summary><strong>리턴 객체 | unsubscribe</strong></summary>

{

"session": "YjQ1ZGUzYzA3MmJhMTY4Nj", // 자신의 세션

"subscribe": "YzMyYWE1YTA3MmJhMTY4Njg"  // 구독취소한 세션

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 룸에 참가중이 아닌 경우
* publisher\_session를 전달하지 않은 경우
* publisher\_session이 40자를 초과하는 경우
* publisher\_session이 현재 구독중인 세션이 아닌 경우

### offerCall

음성 또는 영상 통화를 위한 발신 기능을 수행합니다. 음성 통화는 call\_type과, 상대방 번호인 callee를 전달하고 영상 통화의 경우 caller 와 callee의 영상 stream url을 담을 객체를 전달해야 합니다. offerCall 호출이 성공하면 callee에게는 `RINGING_EVENT`가 전달됩니다. offerCall을 호출한 측은 `RINGBACK_EVENT`를 받게 됩니다. (참고: [EVENT\_MESSAGE ](https://docs.omnitalk.io/commons/event-message))

```jsx
await sdk.offerCall(call_type, callee);
```

| Parameter        | Mandatory/Optional | Type       | Description                         |
| ---------------- | ------------------ | ---------- | ----------------------------------- |
| call\_type       | M                  | CALL\_TYPE | sdk제공 ("audiocall" \| "videocall")  |
| callee           | M                  | String     | 착신 상대방의 user\_id                    |
| record           | O                  | Boolean    | audio call만 지원                      |
| local\_renderer  | \*O                | RTCView    | react-native-webrtc의 RTCView 타입의 객체 |
| remote\_renderer | \*O                | RTCView    | react-native-webrtc의 RTCView 타입의 객체 |

<details>

<summary>이벤트 메시지 <strong>예시 | RINGBACK_EVENT</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"caller": "alice",&#x20;

"callee": "bob",&#x20;

"call\_type": "audiocall"

}

</details>

<details>

<summary>이벤트 메시지 <strong>예시 | RINGING_EVENT</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"room\_id": "9389314d3cb1b92eeaa81b618e0f",&#x20;

"room\_type": "audiocall",&#x20;

"call\_type": "audiocall",

"caller": "alice",&#x20;

"callee": "bob",&#x20;

"track": "audio",

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 세션을 생성하지 않은 경우
* call\_type 또는 callee를 전달하지 않은 경우
* call\_type이 전화 타입이 아닌 경우 (VIDEO\_CALL 또는 AUDIO\_CALL 또는 SIPCALL이 아닌 경우)
* callee가 32자를 초과하는 경우
* call\_type이 VIDEO\_CALL인데 local\_renderer와 remote\_renderer를 전달하지 않은 경우

### answerCall

음성 또는 영상 통화를 위한 착신 기능을 수행합니다. 음성 통화의 경우 인수 전달없이 API호출만으로 통화 연결 가능합니다. 영상 통화의 경우 자신과 상대의 영상 stream url을 담을 객체를 전달해야 합니다. answerCall 호출이 성공하면 caller, callee 양측 모두 CONNECTED\_EVENT를 받습니다.

```jsx
await sdk.answerCall(call_type, caller); 
```

| Parameter      | Mandatory/Optional | Type       | Description                                       |
| -------------- | ------------------ | ---------- | ------------------------------------------------- |
| call\_type     | O                  | CALL\_TYPE | sdk제공("audiocall" \| "videocall")                 |
| caller         | O                  | String     | 착신 상대방의 user\_id                                  |
| record         | O                  | Boolean    | audio call만 지원                                    |
| localRenderer  | \*O                | RTCView    | react-native-webrtc의 RTCView 타입의 객체. 영상 통화의 경우 필수 |
| remoteRenderer | \*O                | RTCView    | react-native-webrtc의 RTCView 타입의 객체. 영상 통화의 경우 필수 |

<details>

<summary>이벤트 메시지 예시 <strong>| CONNECTED_EVENT</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD"

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 세션을 생성하지 않은 경우

RINGING\_EVENT를 수신 했다면 인수 전달없이 API 호출만 하시면 통화 연결이 됩니다. 만약 RINGING\_EVENT를 수신 하지 않은 상태에서 아래와 같은 상황에서는 에러가 발생합니다.

* call\_type 또는 caller를 전달하지 않은 경우
* caller가 string type이 아닌 경우
* caller가 32자를 초과하는 경우
* call\_type이 전화 타입이 아닌 경우 (VIDEO\_CALL 또는 AUDIO\_CALL 또는 SIPCALL이 아닌 경우)
* call\_type이 VIDEO\_CALL인데 local\_renderer와 remote\_renderer를 전달하지 않은 경우

### makeSipNumber

개인 또는 방송 룸에 일반 전화를 수신할 수 있는 번호를 부여합니다. 만약 룸에 번호를 할당하면 룸의 참여자 모두에게 전화를 걸 수 있습니다.&#x20;

```jsx
await sdk.makeSipNumber();
```

| Parameter    | Mandatory/Optional | Type   | Description |
| ------------ | ------------------ | ------ | ----------- |
| call\_number | O                  | Number | 6 digits    |
| room\_id     | O                  | String |             |

아래와 같은 상황에서는 에러가 발생합니다.

* 세션을 생성하지 않은 경우
* call\_number가 string type이 아닌 경우
* room\_id가 string type이 아닌 경우

### mute/unmute

mute할 track을 인자로 넘겨주면 음소거 및 음소거 해제 기능을 수행할 수 있습니다. 비디오 mute는 로컬의 화면 송출을 off 시키는 기능입니다. mute/unmute API를 호출하면 룸의 다른 사용자들에게 `MUTE_EVENT` 또는 `UNMUTE_EVENT`가 전달됩니다.&#x20;

```jsx
await sdk.setMute(track);
await sdk.setUnmute(track);
```

| Parameter | Mandatory/Optional | Type  | Description             |
| --------- | ------------------ | ----- | ----------------------- |
| track     | M                  | TRACK | sdk제공("audio"\|"video") |

### sendMessage

채팅 기능 구현을 위한 메시지 전송 API입니다. 어떤 룸이든 입장하게 되면 기본적으로 채팅을 주고 받을 수 있는 상태가 됩니다. sendMessage API를 이용해 메시지는 발신하고, 옴니톡에서 전달하는 MESSAGE\_EVENT로 메시지를 수신할 수 있습니다. 채팅 메시지는 룸의 모든 참여자에게 전송되며 특정 사용자에게 전달할 귓속말 메시지는 whisper action타입으로 보내면 됩니다.

| Parameter | Mandatory/Optional | Type            | Description                               |
| --------- | ------------------ | --------------- | ----------------------------------------- |
| action    | M                  | MESSAGE\_ACTION | sdk제공(send \| whisper)                    |
| message   | M                  | String          | max 2048                                  |
| target    | \*O                | String          | 귓속말 상대방 session id. whisper action의 경우 필수 |

<details>

<summary>이벤트 메시지 예시 <strong>|</strong> MESSAGE_EVENT</summary>

{&#x20;

"action": "join",&#x20;

"cmd": "MESSAGE\_EVENT",&#x20;

"session": "U0lTUlpocVhOUTE2ODg3MDcxNjQtMzgy",&#x20;

"timestamp": 1688707215,&#x20;

"user\_id": "woo",&#x20;

"user\_name": "HJAhbndrmK"&#x20;

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 룸에 참가중이 아닌 경우
* action이 WHISPER인데 target이 없는 경우
* message가 string type이 아닌 경우
* message의 길이가 너무 긴 경우

### getAvailableMessageUsers

룸에서 채팅 가능한 사용자의 목록을 조회합니다.

```jsx
await sdk.getAvailableMessageUsers();
```

| Parameter | Mandatory/Optional | Type | Description |
| --------- | ------------------ | ---- | ----------- |
| -         | -                  | -    | -           |

<details>

<summary><strong>리턴 객체 |</strong> getAvailableMessageUsers</summary>

&#x20; {&#x20;

&#x20;  "session": "Smt1U29ncVRsSDE2ODg3MDcxMDctNTA0",&#x20;

&#x20;  "count": 3,&#x20;

&#x20;  "page": 1,&#x20;

&#x20; "list":&#x20;

&#x20;   \[&#x20;

&#x20;     {&#x20;

&#x20;        "call\_type": "audiocall",&#x20;

&#x20;        "session": "SHdyWlFMZEJ1VjE2ODg3MDc1MTYtNTA3",&#x20;

&#x20;        "user\_id": "222",

&#x20;        "user\_name": "TydFCkYSBL"&#x20;

&#x20;   },&#x20;

&#x20;   {

&#x20;       "call\_type": "audiocall",&#x20;

&#x20;       "session": "SWxJZ2tGcldNeDE2ODg3MDc4NTYtNTEw",&#x20;

&#x20;       "user\_id": "333",&#x20;

&#x20;       "user\_name": "ErKMqhVSzb"&#x20;

&#x20;   },&#x20;

&#x20;   {&#x20;

&#x20;     "call\_type": "audiocall",&#x20;

&#x20;     "session": "U0lTUlpocVhOUTE2ODg3MDcxNjQtMzgy",&#x20;

&#x20;     "user\_id": "woo",&#x20;

&#x20;     "user\_name": "HJAhbndrmK"

&#x20;   }&#x20;

&#x20; ]

&#x20;}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 세션을 생성하지 않은 경우

### getDeviceList

해당 장치의 모든 오디오, 비디오 장치를 조회할 수 있는 API 입니다.

```jsx
await sdk.getDeviceList();
```

<details>

<summary><strong>리턴 객체 예시 | getDeviceList</strong></summary>

{&#x20;

"videoinput":

&#x20;                   \[\
&#x20;                      {&#x20;

&#x20;                         "kind":"videoinput",&#x20;

&#x20;                          "label":"Logitech BRIO (046d:085e)",&#x20;

&#x20;                           "deviceId": "33fb0bfdda06b8815f94baa46d3965\
&#x20;                                                211b5476825021ac91578280a5d7c05b94",&#x20;

&#x20;                           "groupId":"cbc0be3ca9648a43fa29e144e1460bb6\
&#x20;                                             df916243eea817625a4700b2cf910654 ",&#x20;

&#x20;                      }, \
&#x20;                     {&#x20;

&#x20;                         "kind":"videoinput",&#x20;

&#x20;                          "label":"FaceTime HD 카메라 (3A71:F4B5)",&#x20;

&#x20;                           "deviceId": "9e82b7ecc5f2844f1109f31ac47b\
&#x20;                                                b1c5fc1d9d13d7f627e4f1db3fd0132bf9be",&#x20;

&#x20;                           "groupId":"5ccd5bf9211dfd080cfcc6f8187f486c9a1\
&#x20;                                             02e579a4d9e3f4e22cdfecb732cf7 ",&#x20;

&#x20;                      },&#x20;

&#x20;                     ], \
"audioinput":

&#x20;                   \[\
&#x20;                      {&#x20;

&#x20;                         "kind":"audioinput",&#x20;

&#x20;                          "label":"Logitech BRIO (046d:085e)",&#x20;

&#x20;                           "deviceId": "5f9715786e17b339dfdfabfd65fc0a5b5\
&#x20;                                                850ec11fc6509085c4a13b5fa760bef",&#x20;

&#x20;                           "groupId":"2479fd4c965cadd52de1d9dd54debbcdb0\
&#x20;                                             caf370a2c0b916f13554d9eaec782d ",&#x20;

&#x20;                      }, \
&#x20;                     {&#x20;

&#x20;                         "kind":"audioinput",&#x20;

&#x20;                          "label":"MacBook Pro 마이크 (Built-in)",&#x20;

&#x20;                           "deviceId": "1a825a6af6bb985db3dbcdedf67cfad\
&#x20;                                                0d2b850f892a4dbd049fa01f140c2a972",&#x20;

&#x20;                           "groupId":"dbec76dc0e283229718a34a2a07de4\
&#x20;                                             e98bb5987fb5db535affb6428c6b0f1339 ",&#x20;

&#x20;                      },&#x20;

&#x20;                     ],&#x20;

}

</details>

### setAudioDevice

제어하고 싶은 장치의 device id를 인수로 전달하면 됩니다.

```jsx
await setAudioDevice(device_id);

```

| Parameter  | Mandatory/Optional | Type   | Description |
| ---------- | ------------------ | ------ | ----------- |
| device\_id | M                  | String |             |

### switchVideoDevice

모바일 디바이스의 전/후면 카메라 switching 기능입니다.

```jsx
await sdk.switchVideoDevice();

```

| Parameter | Mandatory/Optional | Type | Description |
| --------- | ------------------ | ---- | ----------- |
| -         | -                  | -    | -           |

### destroyRoom

룸 삭제 기능을 수행하는 API 입니다. 룸에 어떤 참여자도 없으면 Omnitalk SDK에서 일정 시간 이후 자동으로 룸을 제거합니다. 만약 명시적으로 룸을 삭제하거나 추가 사용자의 룸 참여를 막고 싶다면 해당 room\_id를 전달하여 기능을 수행할 수 있습니다. 자신이 참여하고 있는 룸을 삭제할 수는 없습니다. 방송 중인 참여자가 있는 룸을 삭제하게 되면 방송 중인 참여자들은 계속 방송할 수 있지만 추가적인 룸 참여는 불가능하며 룸 리스트에 조회되지 않습니다.

```jsx
await sdk.destroyRoom(room_id);
```

| Parameter | Mandatory/Optional | Type   | Description |
| --------- | ------------------ | ------ | ----------- |
| room\_id  | M                  | String |             |

<details>

<summary><strong>리턴 객체 | destroyRoom</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

"room\_id":"8a1086680e47261208eeff87000b",

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 세션을 생성하지 않은 경우
* room\_id가 string type이 아닌 경우
* room\_id가 32자를 초과하는 경우

### leave

자신의 방송을 종료하는 API입니다.&#x20;

```jsx
await sdk.leave();
```

| Parameter | Mandatory/Optional | Type | Description |
| --------- | ------------------ | ---- | ----------- |
| -         | -                  | -    |             |

<details>

<summary><strong>리턴 객체 | leave</strong></summary>

{

"session":"YjQ1ZGUzYzA3MmJhMTY4NjcxMD",&#x20;

}

</details>

아래와 같은 상황에서는 에러가 발생합니다.

* 이미 연결이 끊어졌거나 leave를 호출한 경우

### kickOut

사용자가 룸에 참여해 방송을 개시한 이후에 다른 사용자를 강제퇴장 시키는 기능입니다. 인수로 전달하는 session은 룸에서 강제 퇴장되며 세션이 끊어지게 됩니다. 룸의 다른 참여자들에게는 KICKOUT\_EVENT가 발생합니다.

```jsx
await sdk.kickOut(target);
```

<table><thead><tr><th>Parameter</th><th width="192">Mandatory/Optional</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>target</td><td>M</td><td>String</td><td>강제종료 시킬 유저의 세션</td></tr></tbody></table>

아래와 같은 상황에서는 에러가 발생합니다.

* 세션을 생성하지 않은 경우
* 룸에 참가중이 아닌 경우

***

{% hint style="info" %}
**sdk 2.1.x 이후 버전부터 사용 가능**
{% endhint %}

### recordingStart

음성 녹음을 시작하는 API입니다. 모든 call\_type에서 호출할 수 있습니다. 단, 녹음 시작 API 호출은 call/room에 참여한 사용자별로 한 번만 호출할 수 있습니다.  recordingStop()을 호출하지 않고 leave()를 호출 하거나 연결이 끊어져도 해당 시점까지 녹음은 마무리됩니다.

```javascript
await sdk.recordingStart();
```

### recordingStop

음성 녹음을 종료하는 API입니다. 녹음 완료 시 옴니톡 콘솔에 등록한 Webhook URL로 콜백을 받을 수 있습니다.

```javascript
await sdk.recordingStop();
```


# Developer's Guide


# Pre-requisite

## 1. **앱의 네이티브 권한 설정**

* `android>app>src>main>AndroidManifest.xml`

```jsx
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.audio.output" />
<uses-feature android:name="android.hardware.microphone" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
```

* `ios>Runner>info.plist`

```jsx
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) Camera Usage!</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) Microphone Usage!</string>
```

## **2. 패키지 지원 설정**

옴니톡 React-native SDK는 react-native-webrtc 라이브러리에 의존하고 있습니다. 관련 지원 설정이 필요합니다.

* react-native-webrtc (`^111.0.1`)

  * `android> app> build.gradle` android section

  ```groovy
  compileOptions {
          sourceCompatibility JavaVersion.VERSION_1_8
          targetCompatibility JavaVersion.VERSION_11
      }
  ```

  * `ios > Podfile`

  ```jsx
    platform ≥ 12.0
  ```

## **3. 최소 지원 사양**

지원 아키텍처는 다음과 같습니다.

* Android: armeabi-v7a, arm64-v8a, x86, x86\_64
* iOS: arm64, x86\_64

안드로이드 지원 최소 compile sdk 버전은 다음과 같습니다.

* `android> app> build.gradle`

<pre class="language-xml"><code class="lang-xml"><strong>android {
</strong>	compileSdkVersion 33
}
</code></pre>

## 4. 앱 개발 공통 사항

### Step 0. SDK 객체 초기화

[콘솔](https://omnitalk.io/console/service/service-id)에서 발급받은 Service Id와 Service Key로 SDK를 초기화 합니다. 해당 정보는 노출되지 않도록 주의하여야 합니다. 초기화된 SDK 객체는 이후 모든 메서드 호출에 사용됩니다.&#x20;

Omnitalk SDK는 싱글톤 패턴으로 제공됩니다. 아래 방법으로 SDK를 초기화시키고 객체를 얻을 수 있습니다.

```tsx
import Omnitalk from 'omnitalk-rn-sdk';
const SERVICE_ID = '발급받은 service id';
const SERVICE_KEY = '발급받은 service key';  

Omnitalk.sdkInit(SERVICE_ID, SERVICE_KEY);
const sdk = Omnitalk.getInstance();
```


# Audiocall Guide

Audio call 또는 Voice call은 일반 전화 기능을 앱으로 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 이용하여 offerCall(), answerCall()을 각각 호출하고 해당 이벤트 메시지에 대응하는 것으로 전화 기능을 간단히 구현할 수 있습니다.

[Call Flow](/commons/call-flow) 에서는 audiocall의 흐름을 sequence diagram으로 보여줍니다.

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의 [Pre-requisite](https://docs.omnitalk.io/react-native/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK 초기화를 제외한 모든 API 기능은 유효한 세션의 존재를 전제로 하고 있습니다. 세션의 생성을 위해 createSession API를 호출합니다. 사용하고 싶은 번호나 문자열을 userId로 전달해 등록할 수 있으며 생략시엔 Omnitalk 서버에서 부여한 임의의 id를 리턴받을 수 있습니다.

```dart
await sdk.createSession();
```

## Step 2. 발신

동일한 Service Id로  세션을 생성한 사용자 중  idle state의 사용자에게 전화 요청을 할 수 있습니다.

offerCall API를 이용하여 전화 발신 요청을 할 수 있습니다.&#x20;

* call\_type: 전화 타입을 의미합니다. CALL\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 음성 통화를 위해서는 `audiocall` 을 전달하시면 됩니다.&#x20;
* callee: callee의 user\_id를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. (defalut = false)

```dart
await sdk.offerCall(
    CALL_TYPE.AUDIO_CALL, 
    callee); 
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 `RINGING_EVENT`를 수신합니다. ([Event Message](https://docs.omnitalk.io/commons/event-message) 참고)

## Step 3. 수신

### callee가 RINGING\_EVENT를 받은 경우

callee가 세션을 생성한 상태에서 caller가 offerCall(전화 요청)을 하여`RINGING_EVENT`를 받은 경우, callee는 별도의 인수를 전달하지 않고 answerCall()을 호출하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 `RINGING_EVENT`에서 받은 caller의 session을 인수로 전달하여 leave()를 호출하시면 됩니다.

```typescript
await sdk.answerCall();
```

### callee가 전화 요청(offerCall) 이후에 session을 생성한 경우

callee가 세션을 생성하기 전 caller가 offerCall(전화 요청)을 하여 `RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터 call\_type과 caller에 인수를 전달하여 전화를 수신할 수 있습니다. 이 경우, 애플리케이션에서 callee 에게 call\_type과 caller를 전달해 주어야 합니다.

* call\_type: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 떄와 동일하게 `audiocall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 user\_id를 전달하시면 됩니다.

```typescript
await sdk.answerCall(CALL_TYPE.AUDIO_CALL, caller);
```

## Step 4. 연결 성공

음성 통화 연결이 성공하면 caller, callee 양층 모두 `CONNECTED_EVENT` 를 수신합니다.

## #오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute)[ ](https://docs.omnitalk.io/flutter/api-reference#mute-unmute)부분을 참조 바랍니다. mute/unmute API의 파라미터인 track type은 Omnitalk SDK에서 제공합니다. 예시는 아래와 같습니다.

```typescript
await sdk.setMute(TRACK.AUDIO);
await sdk.setUnmute(TRACK.AUDIO);
```

### 입력 장치 변경

전화 연결 전, 또는 전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 API를 제공합니다.&#x20;

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. setAudioDevice()에  deviceId를 전달하여 입력 장치를 변경할 수 있습니다.


# Videocall Guide

Video call 은 영상 통화 기능을 앱으로 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 이용하여 offerCall(), answerCall()을 각각 호출하고 해당 이벤트 메시지에 대응하는 것으로 전화 기능을 간단히 구현할 수 있습니다.

[Call Flow](/commons/call-flow) 에서는 audiocall의 흐름을 sequence diagram으로 보여줍니다.

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의 [Pre-requisite](https://docs.omnitalk.io/react-native/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK 초기화를 제외한 모든 API 기능은 유효한 세션의 존재를 전제로 하고 있습니다. 세션의 생성을 위해 createSession API를 호출합니다. 사용하고 싶은 번호나 문자열을 userId로 전달해 등록할 수 있으며 생략시엔 Omnitalk 서버에서 부여한 임의의 id를 리턴받을 수 있습니다.

```dart
await sdk.createSession();
```

## Step 2. 발신

동일한 Service Id로  세션을 생성한 사용자 중  idle state의 사용자에게 전화 요청을 할 수 있습니다.

offerCall API를 이용하여 전화 발신 요청을 할 수 있습니다. 애플리케이션에서는 비디오 객체의 컴포넌트를 그리기 위해 react-native-webrtc 패키지를 import 하여 사용합니다.&#x20;

* call\_type: 전화 타입을 의미합니다. CallType은 Omnitalk SDK에서 enum type으로 제공합니다. 영상 통화를 위해서는 `videocall` 을 전달하시면 됩니다.&#x20;
* callee: callee의 user\_id를 전달하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. (defalut = false)
* localRenderer : streamURL을 담을 객체입니다.&#x20;
* remoteRenderer : streamURL을 담을 객체입니다.

```tsx

import {RTCView} from 'react-native-webrtc'; //비디오 영상을 담을 컴포넌트

let localvideo = {streamURL: ''};
let remoteVideo = {streamURL: ''};

await sdk.offerCall(
    call_type:  CALL_TYPE.VIDEO_CALL,
    callee: callee, 
    record:false, 
    local_renderer: localVideo, 
    remote_renderer: remoteVideo
    );

<RTCView
streamURL={localVideo.streamURL}
/>
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 `RINGING_EVENT`를 수신합니다. ([Event Message](https://docs.omnitalk.io/commons/event-message) 참고)

## Step 3. 수신

### callee가 RINGING\_EVENT를 받은 경우

callee가 세션을 생성한 상태에서 caller가 offerCall(전화 요청)을 하여`RINGING_EVENT`를 받은 경우, callee는 자신과 상대의 영상을 담을 객체로 answerCall()을 호출하여 전화를 수신할 수 있습니다. `RINGING_EVENT`에서 받은 call type과 caller정보와 녹음 여부, RTCVideoRenderer 타입으로 초기화된 객체를 전달하면 됩니다. 수신 거절을 하고싶은 경우 `RINGING_EVENT`에서 받은 caller의 session을 인수로 전달하여 leave()를 호출하시면 됩니다.

### callee가 전화 요청(offerCall) 이후에 session을 생성한 경우

callee가 세션을 생성하기 전 caller가 offerCall(전화 요청)을 하여 `RINGING_EVENT`를 받지 못한 경우, 애플리케이션에서 callee 에게 callType과 caller를 전달해 주어야 합니다. answerCall()의 파라미터 callType과 caller에 인수를 전달하고 RTCVideoRenderer 타입으로 초기화된 객체를 전달하여 전화를 수신할 수 있습니다.&#x20;

* call\_type: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 떄와 동일하게 `videocall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 user\_id를 전달하시면 됩니다.
* localRenderer : streamURL을 담을 객체입니다.&#x20;
* remoteRenderer : streamURL을 담을 객체입니다.

```typescript
await sdk.answerCall(
    call_type: CALL_TYPE.VIDEO_CALL, 
    caller: caller, 
    local_renderer: localVideo, 
    remote_renderer: remoteVideo
    );
```

## Step 4. 연결 성공

영상 통화 연결이 성공하면 caller, callee 양층 모두 `CONNECTED_EVENT` 를 수신합니다.

## 비디오 장치 제어

### mute/unmute

전화 통화 중 로컬에서 송출되는 비디오 on/off 기능을 mute/unmue API를 이용하여 개발할 수 있습니다. 음소거는 TRACK.AUDIO를 track 으로 전달해 별도의 mute API를 호출해야합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](https://docs.omnitalk.io/react-native/api-reference#mute-unmute)[ ](https://docs.omnitalk.io/flutter/api-reference#mute-unmute)부분을 참조 바랍니다. video mute는 자신의 영상 송출을 off 시키는 기능입니다.&#x20;

```typescript
await sdk.setMute(TRACK.VIDEO);  //비디오 송출만 off
await sdk.setUnmute(TRACK.VIDEO );
```

### 비디오 카메라 변경

전화 통화 중 비디오 장치를 전환할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의[switchVideoDevice](https://docs.omnitalk.io/react-native/api-reference#switchvideodevice) 부분을 참조 바랍니다.

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. switchVideoDevice API를 호출하면 전/후면 카메라 스위칭 됩니다.&#x20;


# SIPcall Guide

SIPcall은 애플리케이션과 일반 전화 간 전화를 연결 할 수 있도록 구현한 것입니다. 통화 발신자는 caller, 착신자를 callee라는 통신 용어로 구분합니다. Omnitalk SDK를 사용하여 offerCall(), answerCall()을 호출하고 해당 이벤트 메시지에 대응하는 것으로 애플리케이션과 일반 전화 간 전화 연결을 간단히 구현할 수 있습니다.

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의 [Pre-requisite](https://docs.omnitalk.io/react-native/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK의 초기화를 제외한 모든 API를 사용하기 위해서는 우선적으로 createSession()을 호출하여 세션을 생성해야 합니다. createSession()의 파라미터인 user\_id는 사용자를 구분하기 위한 고유한 id입니다. user\_id는 Optional 이며, 생략시 Omnitalk 서버에서 임의의 id를 부여합니다.

```typescript
await sdk.createSession(user_id);
```

## Step 2. 발신

offerCall() API로 애플리케이션에서 일반 전화로 전화 요청을 할 수 있습니다. 파라미터로 call\_type, callee의 전화번호, 녹음 여부를 전달하면 됩니다.

* call\_type: 전화 타입을 의미합니다. CALL\_TYPE은 Omnitalk SDK에서 enum type으로 제공합니다. 음성 통화를 위해서는 `sipcall` 을 전달하시면 됩니다.&#x20;
* callee: 전화를 걸고자 하는 수신자의 전화 번호를 입력하시면 됩니다.
* record: Optional 파라미터로, 녹음 여부를 의미합니다. defalut = false

```typescript
await sdk.offerCall(CALL_TYPE.SIP_CALL, '01012341234', true);
```

offerCall 호출 성공시 caller는 `RINGBACK_EVEVT`, callee는 전화 요청이 울리게 됩니다. 이 때, callee에게 보여지는 발신자 정보는 옴니톡에서 발급받은 번호 입니다.

## Step 3. 수신

### callee가 call\_number를 생성한 상태에서 전화 요청이 왔을때

callee(애플리케이션)가 call\_number를 생성한 상태에서 caller(일반 전화)가 전화를 걸어`RINGING_EVENT`를 받은 경우, callee는 별도의 파라미터를 전달하지 않고 answerCall()을 호출하여 전화를 수신할 수 있습니다. 수신 거절을 하고싶은 경우 leave()를 호출하시면 됩니다.

```typescript
await sdk.answerCall();
```

### callee가 call\_number를 생성하기 전 전화 요청이 왔을때

callee(애플리케이션)가 call\_number를 생성하기 전에 caller(일반 전화)가 전화를 걸어`RINGING_EVENT`를 받지 못한 경우, callee는 answerCall()의 파라미터에 call\_type과 caller의 전화번호를 전달하여 전화를 수신할 수 있습니다. 이 경우, 옴니톡 서버에서 애플리케이션 백엔드로 별도의 이벤트로 call\_type과 caller의 정보를 제공드릴 예정입니다.

* call\_type: 전화 타입을 의미합니다. caller가 offerCall()을 호출할 떄와 동일하게 `audiocall` 을 전달하시면 됩니다.&#x20;
* caller: caller(전화 발신자)의 user\_id를 전달하시면 됩니다.

```typescript
await sdk.answerCall(CALL_TYPE.AUDIO_CALL, caller);
```

## Step 4. 연결 성공

음성 통화 연결이 성공하면 caller, callee 양층 모두 `CONNECTED_EVENT` 를 수신합니다.

## 오디오 장치 제어

### mute/unmute

전화 통화중에 음소거를 할 수 있도록 API를 제공합니다. 사용법과 자세한 내용은 API Reference의 [mute/unmute](/typescript/api-reference#mute-unmute) 부분을 참조 바랍니다. mute/unmute API의 파라미터인 track type은 Omnitalk SDK에서 enum type으로 제공합니다. 예시는 아래와 같습니다.

```typescript
await sdk.setMute(TRACK_TYPE.AUDIO);
```

### 입력 장치 변경

전화 연결 전, 또는 전화 통화중에 입력(마이크) 장치를 변경할 수 있도록 API를 제공합니다.&#x20;

1. 우선, 사용 가능한 입력 장치 목록을 조회할 수 있는 [getDeviceList()](/typescript/api-reference#getdevicelist) 를 통해서 사용하고자 하는 장치의 deviceId를 획득합니다.
2. [setAudioDevice()](/typescript/api-reference#setaudiodevice) 파라미터로 deviceId를 전달하여 입력 장치를 변경할 수 있습니다.


# AudioRoom Guide

Audioroom은 음성 회의 기능을 인터넷을 이용한 앱으로 구현한 것입니다. Omnitalk SDK를 이용하여 회의실(룸) 생성 및 참여하는 것으로 1:1 또는 다자간 음성 회의실 기능을 간단히 구현할 수 있습니다.&#x20;

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의 [Pre-requisite](https://docs.omnitalk.io/react-native/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK 초기화를 제외한 모든 API 기능은 유효한 세션의 존재를 전제로 하고 있습니다. 세션의 생성을 위해 createSession API를 호출합니다. 사용하고 싶은 번호나 문자열을 userId로 전달해 등록할 수 있으며 생략시엔 Omnitalk 서버에서 부여한 임의의 id를 리턴받을 수 있습니다.

```dart
await sdk.createSession();
```

## Step 2. 회의실 생성 및 조회

기존 회의실을 조회해 참여하거나 새로운 회의실을 만들 수 있습니다. 기존 회의실(룸) 조회는 roomList API를, 회의실(룸) 생성은 createRoom API를 이용합니다. 룸 타입을 명시하지 않으면 모든 타입의 룸이 조회됩니다. 조회한 목록 결과의 room\_id 로 회의실에 참여할 수 있습니다.

```tsx
var roomResult = await sdk.roomList(ROOM_TYPE.AUDIO_ROOM);

await sdk.createRoom(ROOM_TYPE.AUDIO_ROOM);
```

## Step 3. 회의실 참여

회의실에 참여하게 되면 별도의 작업 없이 참여자들과 음성 회의를 할 수 있게 되며, 회의실에 관련된 이벤트 메세지를 수신할 수 있습니다. 음성 회의실에서 수신 가능한 이벤트는 아래와 같습니다. 자세한 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

```dart
await sdk.joinRoom(room_id);
```

* CONNECTED\_EVENT - 새로운 참가자 입장했을 때
* LEAVE\_EVENT - 다른 참가자가 퇴장 했을 때
* MUTE\_EVENT - 다른 참가자가 mute 했을 때
* UNMUTE\_EVENT - 다른 참가자가 unmute 했을 때
* MESSAGE\_EVENT - 채팅 메세지 수신 이벤트, 회의실 입장시 채팅 기능을 사용할 수 있는 상태가 됩니다. 채팅기능 사용법은 [Chatting Guide](https://docs.omnitalk.io/react-native/developers-guide/chatting-guide) 를 참조 바랍니다.

## 참여자 목록 조회

[partiList()](/typescript/api-reference#partilist) API 를 사용하여 입장한 회의실에 참여한 사용자 목록을 조회할 수 있습니다.

```dart
await sdk.pariList();
```


# VideoRoom Guide

Videoroom은 영상 회의 기능을 인터넷을 이용한 앱으로 구현한 것입니다. Omnitalk SDK를 이용하여 회의실(룸) 생성 및 참여하는 것으로 1:1 또는 다자간 영상 회의실 기능을 간단히 구현할 수 있습니다.&#x20;

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의 [Pre-requisite](https://docs.omnitalk.io/react-native/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK 초기화를 제외한 모든 API 기능은 유효한 세션의 존재를 전제로 하고 있습니다. 세션의 생성을 위해 createSession API를 호출합니다. 사용하고 싶은 번호나 문자열을 user\_id로 전달해 등록할 수 있으며 생략시엔 Omnitalk 서버에서 부여한 임의의 id를 리턴받을 수 있습니다.

```dart
await sdk.createSession();
```

## Step 2. 회의실 생성 및 조회

기존 회의실을 조회해 참여하거나 새로운 회의실을 만들 수 있습니다. 기존 회의실(룸) 조회는 roomList API를, 회의실(룸) 생성은 createRoom API를 이용합니다. 룸 타입을 명시하지 않으면 모든 타입의 룸이 조회됩니다. 조회한 목록 결과의 room\_id 로 회의실에 참여할 수 있습니다.

```dart
var roomResult = await sdk.roomList(ROOM_TYPE.VIDEO_ROOM);

await sdk.createRoom(DEFAUTL_ROOM_TYPE.VIDEO_ROOM);
```

## Step 3. 회의실 참여

회의실에 참여하게 되면 별도의 작업 없이 참여자들과 음성 회의를 할 수 있게 되며, 회의실에 관련된 이벤트 메세지를 수신할 수 있습니다. 음성 회의실에서 수신 가능한 이벤트는 아래와 같습니다. 자세한 내용은 [Event Message](/commons/event-message) 를 참조 바랍니다.

```dart
await sdk.joinRoom(roomId : roomId)
```

* CONNECTED\_EVENT - 새로운 참가자 입장했을 때
* LEAVE\_EVENT - 다른 참가자가 퇴장 했을 때
* MUTE\_EVENT - 다른 참가자가 mute 했을 때
* UNMUTE\_EVENT - 다른 참가자가 unmute 했을 때
* MESSAGE\_EVENT - 채팅 메세지 수신 이벤트, 회의실 입장시 채팅 기능을 사용할 수 있는 상태가 됩니다. 채팅기능 사용법은 [Chatting Guide](/typescript/developers-guide/chatting)[ ](https://docs.omnitalk.io/flutter/developers-guide/chatting-guide)를 참조 바랍니다.

## Step 4. 방송 시작

비디오 방송의 시작은 자신의 영상 streamURL을 담을 객체를 인수로 전달해 publish API를 호출하면 됩니다. publish API호출이 성공하면 해당 방송의 세션 id가 담긴 객체를 리턴 받게 되고 룸의 다른 사용자들에게 `BROADCASTING_EVENT`가 발생합니다. 애플리케이션에서 방송 영상을 담는 컴포넌트는  react-native-webrtc 패키지의 RTCView 를 이용하시면 됩니다.

```dart
import {RTCView} from 'react-native-webrtc'; 

let localVideo = {streamURL: ''};

await sdk.publish(localRenderer: localVideo);

<RTCView
streamURL={localVideo.streamURL}
/>
```

## Step 5. 방송 구독

룸에서 방송중인 사용자의 영상을 구독하기 위해서는 subscribe API를 사용하면 됩니다. 방송 리스트를 조회하거나 `BROADCASTING_EVENT`를 수신해 구독할 방송의 세션을 구할 수 있습니다. 구독할 영상을 담을 RTCVideoRenderer 타입의 객체를 함께 인수로 전달합니다. 방송 구독에 성공하면 `CONNECTED_EVENT`를 받게 됩니다.&#x20;

```dart
let remoteVideo = {streamURL: ''};
await sdk.subscribe(publisher_session, remoteVideo);

<RTCView
streamURL={remoteVideo.streamURL}
/>
```

### 참여자 목록 조회

[publishList API](https://docs.omnitalk.io/flutter/api-reference#publishlist) 를 사용하여 입장한 회의실에 참여하여 방송을 개시한 사용자 목록을 조회할 수 있습니다.

```dart
await sdk.publishList();
```

### BROADCASTING\_EVENT 수신

```dart
sdk.on('event', (event: any) async {
      switch (event["cmd"]) {
        case "BROADCASTING_EVENT":
          publisher_session = event['session'];
          break;
      }
    });
```


# Chatting Guide

옴니톡 SDK가 제공하는 채팅 기능은 룸 참여시(타입 무관) 기본으로 제공됩니다. 따라서 별도의 채팅룸을 구현하거나 오디오룸, 비디오룸에서 부가 기능으로 개발하실 수 있습니다.

[sendMessage API](https://docs.omnitalk.io/react-native/api-reference#sendmessage)를 이용하여 action type을 명시하면 룸 전체에 채팅 메시지 발송하거나 특정 상대로의 귓속말 기능을 구현할 수 있습니다. 귓속말은 상대의 session id를 target 인수로 전달하면 됩니다.

## Step 0. SDK 초기화 및 객체 생성

Developer's Guide의[ Pre-requisite](https://docs.omnitalk.io/react-native/developers-guide/pre-requisite#4.)에서 장치 설정 및 개발 공통 사항을 참고하시기 바랍니다.&#x20;

## Step 1. 세션 생성

Omnitalk SDK 초기화를 제외한 모든 API 기능은 유효한 세션의 존재를 전제로 하고 있습니다. 세션의 생성을 위해 createSession API를 호출합니다. 사용하고 싶은 번호나 문자열을 userId로 전달해 등록할 수 있으며 생략시엔 Omnitalk 서버에서 부여한 임의의 id를 리턴받을 수 있습니다.

```dart
await sdk.createSession();
```

## Step 2. 룸 참여

```dart
await sdk.createRoom();
await sdk.joinRoom();
```

## Step 3. 메시지 보내기

세션을 생성하고 기존 룸이나 신규 생성한 룸에 참여하면 채팅 메시지를 주고 받을 수 있는 상태가 됩니다.

```tsx
await sdk.sendMessage(MESSAGE_ACTION.SEND, message);
await sdk.senMessage(MESSAGE_ACTION.WHISPER, message, target);
```

## Step 4. 메시지 수신하기

룸의 다른 사용자가 보내는 채팅 메시지는 [`MESSAGE_EVENT`](https://docs.omnitalk.io/commons/event-message#message_event) 를 수신하면 얻을 수 있습니다. 이벤트 메시지 수신은 옴니톡의 [on API](https://docs.omnitalk.io/react-native/api-reference#on)를 이용하시면 됩니다.&#x20;

```tsx

sdk.on('event',  (event:any) {
    switch(event['cmd']){
        case 'MESSAGE_EVENT':
            print(event['message']);
            print(event['user_id']);
            print(event['action'];
        }
    }
```

###


