---
title: "멀티DRM 크로스플랫폼 클라이언트 연동 가이드"
description: "본 문서는 React Native, Flutter와 같은 크로스플랫폼 개발 환경에 도브러너 멀티 DRM 라이선스를 연동하는 방법을 안내합니다."
---
> For the complete documentation index, see [llms.txt](/llms.txt).

`크로스플랫폼 프레임워크`는 단일 개발 언어와 프레임워크로 웹, 안드로이드, iOS 등의 다양한 클라이언트 환경을 지원할 수 있는 앱 개발 방식입니다.

크로스플랫폼 앱의 최종 결과물은 각각의 환경에 대한 네이티브 코드로 변환되어 적용되므로, 네이티브 앱과 웹 앱을 결합한 하이브리드 앱보다 성능적으로 유리하다는 장점이 있습니다. 여러 크로스플랫폼 프레임워크 중에서도 최근에는 구글에서 개발한 [Flutter](https://flutter.dev/)와 페이스북의 [React Native](https://reactnative.dev/)가 개발자들에 의해 가장 많이 사용되고 있습니다.

본 문서는 도브러너 멀티 DRM 서비스의 고객사에서 `Flutter` 또는 `React Native`를 이용해 클라이언트 앱을 개발하는 경우에 DRM 콘텐츠 재생을 쉽고 빠르게 지원할 수 있는 방법들을 안내합니다.

## 크로스플랫폼 연동 예제

Flutter와 React Native 환경에 대한 쉽고 빠른 도브러너 멀티 DRM 연동을 위해 각각의 연동 예제와 가이드를 제공합니다.

:::note 

아래 링크된 크로스플랫폼 연동 예제들은 DRM 콘텐츠의 스트리밍 재생만을 지원합니다. 다운로드/오프라인 시나리오 지원이 필요한 경우, 해당 기능을 직접 구현하거나 본 문서 아래 쪽에 명시된 `크로스플랫폼 클라이언트 SDK` 제품을 사용하시기 바랍니다. 또는 다운로드 기능을 지원하는 상용 플레이어 솔루션의 크로스플랫폼 SDK를 이용할 수도 있습니다. 

:::

### Flutter 예제

`도브러너 멀티 DRM Flutter 연동 예제`는 오픈 소스 프로젝트인 [Better Player Plus](https://github.com/SunnatilloShavkatov/better_player_plus)를 기반으로 작성되었습니다. 예제 코드와 연동 가이드 문서는 아래 링크를 참고하시기 바랍니다.

  [**도브러너 Multi-DRM Flutter Sample**](https://github.com/doverunner/better_player_plus_doverunner_streaming_integration)

### React Native 예제

`도브러너 멀티 DRM React Native 연동 예제`는 오픈 소스 프로젝트인 [react-native-video](https://github.com/react-native-video/react-native-video)를 기반으로 작성되었습니다. 예제 코드와 연동 가이드 문서는 아래 링크를 참고하시기 바랍니다.

  [**도브러너 Multi-DRM React Native Sample**](https://github.com/doverunner/multi-drm-react-native-sample)

## 크로스플랫폼 클라이언트 SDK

크로스플랫폼 프레임워크로 개발된 클라이언트 앱에서 DRM 콘텐츠의 다운로드 및 오프라인 재생 지원이 필요한 경우, 사용하는 프레임워크에 따라 `도브러너 멀티 DRM Flutter SDK` 또는 `도브러너 멀티 DRM React Native SDK` 제품을 사용할 수 있습니다. 

### 도브러너 멀티 DRM Flutter SDK

`도브러너 멀티DRM Flutter SDK`(이하 `Flutter SDK`)는 Flutter 기반의 크로스플랫폼 애플리케이션 개발 환경에서 미디어 서비스 앱을 개발할 때 Widevine과 FairPlay DRM을 쉽게 적용할 수 있게 해주는 제품입니다. Flutter로 개발된 안드로이드와 iOS 앱에서 각각 Widevine과 FairPlay DRM으로 암호화된 콘텐츠의 스트리밍과 다운로드 시나리오를 지원합니다.

:::note 

해당 SDK 제품은 [도브러너 깃허브 저장소](https://github.com/doverunner/multi-drm-flutter-sdk)와 [Flutter Pub 패키지 매니저](hhttps://pub.dev/packages/dr_multi_drm_sdk/install)를 통해 다운로드 받을 수 있습니다. 트라이얼 계정에서는 라이선스 발급 수 제한 내에서 자유롭게 SDK 제품을 테스트할 수 있으나, 상용 서비스에 SDK를 적용하기 위해서는 도브러너 상용 서비스 가입 시 SDK 사용 권한이 포함된 요금제로 신청해야 합니다.

:::

  [**도브러너 Multi-DRM Flutter SDK**](https://github.com/doverunner/multi-drm-flutter-sdk/)

#### SDK 구성

Github 저장소에 등록된 Flutter SDK는 다음과 같이 구성되어 있습니다.

- `dr_multi_drm_sdk`: 
  - `dr_multi_drm_sdk`: Flutter 기반의 안드로이드/iOS 앱에서 DRM 콘텐츠 재생을 지원하는 플러그인 패키지
  - `dr_multi_drm_sdk_android`: `dr_multi_drm_sdk` 플러그인의 안드로이드 버전 구현
  - `dr_multi_drm_sdk_ios`: `dr_multi_drm_sdk` 플러그인의 iOS 버전 구현
  - `dr_multi_drm_sdk_interface`: `dr_multi_drm_sdk` 플러그인을 위한 공통 플랫폼 인터페이스
- `player-samples`: DRM 콘텐츠 재생을 지원하는 Flutter 샘플 앱
  - `basic`: 스트리밍 재생만 지원하는 기본 기능 샘플 
  - `advanced`: 스트리밍과 다운로드/오프라인 재생을 지원하는 샘플

#### 지원 환경

- Android 6.0 (API 23) & Android targetSdkVersion 34 or higher
- iOS 14.0 이상

#### SDK 적용 

[설치 가이드](https://pub.dev/packages/dr_multi_drm_sdk)를 참고해 Flutter 앱 프로젝트에 `dr_multi_drm_sdk`를 추가합니다. 그 후 안드로이드와 iOS 프로젝트 별로 다음과 같은 속성을 설정합니다.

##### 안드로이드 버전

`android/app/build.gradle` 파일에 다음과 같이 `compileSdkVersion` 값을 설정합니다.
```js
android {
  compileSdkVersion 34
  ...
}
```

Flutter SDK를 사용하려면 대상 애플리케이션에 다음과 같은 퍼미션이 추가되어야 합니다.

```xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
```

##### iOS 버전

`cocoapods`를 이용해 `DoveRunnerFairPlay`를 프로젝트에 추가합니다.

#### SDK 초기화

앱 실행 후 초기화 단계에 아래 코드를 추가해 Flutter SDK를 초기화 합니다.

```java
PallyConDrmSdk.initialize(siteId); // siteId: 도브러너 서비스 가입 시 생성되는 네 자리 사이트 ID
```

#### 이벤트 설정

Flutter SDK와 관련한 이벤트를 다음과 같이 설정합니다.

```java
DrMultiDrmSdk.onDrEvent.listen((event) {
    var downloadState = DownloadStatus.pending;
    switch (event.eventType) {
        case DrEventType.prepare:
          // 
          break;
        case DrEventType.complete:
          // Called when download is complete
          break;
        case DrEventType.pause:
          // Called when downloading is stopped during download
          break;
        case DrEventType.download:
          // Called when download starts
          break;
        case DrEventType.contentDataError:
          // Called when an error occurs in the parameters passed to the sdk
          break;
        case DrEventType.drmError:
          // Called when a license error occurs
          break;
        case DrEventType.licenseServerError:
          // Called when an error comes down from the license server
          break;
        case DrEventType.downloadError:
          // Called when an error occurs during download
          break;
        case DrEventType.networkConnectedError:
          // Called in case of network error
          break;
        case DrEventType.detectedDeviceTimeModifiedError:
          // Called when device time is forcibly manipulated
          break;
        case DrEventType.migrationError:
          // Called when sdk migration fails
          break;
        case DrEventType.unknown:
          // Internally called when an unknown error occurs
          break;
    }
    // content state
  }).onError((error) {
});
```

#### 콘텐츠 다운로드 관련 기능

오프라인 재생을 위한 콘텐츠 다운로드는 다음과 같은 API를 사용해 구현합니다.

```java
// start download
DrMultiDrmSdk.addStartDownload(PallyConContentConfiguration);

// cancel downloads
DrMultiDrmSdk.cancelDownloads();

// pause downloads
DrMultiDrmSdk.pauseDownloads();

// resume downloads
DrMultiDrmSdk.resumeDownloads();
```

콘텐츠 다운로드 시 진행 상황을 UI 상에 표시하려면 아래와 같은 이벤트 리스너를 등록합니다.

```java
DrMultiDrmSdk.onDownloadProgress.listen((event) {
    // event.url is url
    // event.percent is downloaded percent
});
```

다운로드 진행 중 또는 완료 등의 상황은 다음의 코드로 확인할 수 있습니다.

```java
PallyConDownloadState downloadState =
        await DrMultiDrmSdk.getDownloadState(DrContentConfiguration);
    switch (downloadState) {
      case PallyConDownloadState.DOWNLOADING:
        break;
      case PallyConDownloadState.PAUSED:
        break;
      case PallyConDownloadState.COMPLETED:
        break;
      default:
        break;
    }
```

다운로드된 콘텐츠와 DRM 라이선스는 다음과 같은 API로 삭제할 수 있습니다.

```java
// remove downloaded content
DrMultiDrmSdk.removeDownload(DrContentConfiguration);

// remove license for content
DrMultiDrmSdk.removeLicense(DrContentConfiguration);
```

#### SDK 릴리즈

애플리케이션 종료 시점에 다음과 같은 코드로 SDK를 릴리즈합니다.

```java
DrMultiDrmSdk.release();
```

### 도브러너 멀티 DRM React Native SDK

`도브러너 멀티 DRM React Native SDK`(이하 `React Native SDK`)는 React Native 기반의 크로스플랫폼 애플리케이션 개발 환경에서 미디어 서비스 앱을 개발할 때 Widevine과 FairPlay DRM을 쉽게 적용할 수 있게 해주는 제품입니다. React Native로 개발된 안드로이드와 iOS 앱에서 각각 Widevine과 FairPlay DRM으로 암호화된 콘텐츠의 스트리밍과 다운로드 시나리오를 지원합니다.

:::note 

해당 SDK 제품은 [도브러너 깃허브 저장소](https://github.com/doverunner/multi-drm-react-native-sdk)를 통해 다운로드 받을 수 있습니다. 트라이얼 계정에서는 라이선스 발급 수 제한 내에서 자유롭게 SDK 제품을 테스트할 수 있으나, 상용 서비스에 SDK를 적용하기 위해서는 도브러너 상용 서비스 가입 시 SDK 사용 권한이 포함된 요금제로 신청해야 합니다.

:::

  [**도브러너 Multi-DRM React Native SDK**](https://github.com/doverunner/multi-drm-react-native-sdk)

#### 지원 환경

- Android 6.0 (API 23) & Android targetSdkVersion 34 or higher
- iOS 14.0 이상

#### SDK 적용 

[설치 가이드](https://yarnpkg.com/)를 참고해 React Native 앱 프로젝트에 `MultiDRMReactNativeSDK`를 추가합니다. 그 후 안드로이드와 iOS 프로젝트 별로 다음과 같은 속성을 설정합니다.

##### 안드로이드 버전


`android/app/build.gradle` 파일에 다음과 같이 `compileSdkVersion` 값을 설정합니다.
```js
android {
  compileSdkVersion 34
  ...
}
```

##### iOS 버전

`cocoapods`를 이용해 `DoveRunnerFairPlay`를 프로젝트에 추가합니다.

##### Import

```sh
import MultiDRMReactNativeSDK , {
	MultiDrmEventType,
	DrmContentConfiguration,
	ContentDownloadState
} from 'doverunner-react-native-sdk';
```

#### SDK 초기화

앱 실행 후 초기화 단계에 아래 코드를 추가해 React Native SDK를 초기화 합니다.

```java
MultiDRMReactNativeSDK.initialize(siteId); // siteId: 도브러너 서비스 가입 시 생성되는 네 자리 사이트 ID
```

#### 이벤트 설정

React Native SDK와 관련한 이벤트를 다음과 같이 설정합니다.

- SDK 내부에서 발생하는 이벤트를 등록합니다.
  ```java
  // ex) advanced/src/presentation/controllers/DrmMovieController.ts
  MultiDRMReactNativeSDK.setMultiDrmEvents()
  ```
- Multi Drm 이벤트 타입

```java
  // ex) advanced/src/presentation/controllers/DrmMovieController.ts
  export enum MultiDrmEventType {
      complete = 'complete',    /// The download completed
      pause = 'pause',          /// The download paused
      remove = 'remove',        /// The download is removed
      stop = 'stop',            /// The download is stop
      download = 'download',    /// The download is start
      /// Error when the content information to be downloaded is incorrect
      contentDataError = 'contentDataError',
      drmError = 'drmError',                            /// License error     
      licenseServerError = 'licenseServerError',        /// Server error when issuing license
      downloadError = 'downloadError',                  /// Error during download
      networkConnectedError = 'networkConnectedError',  /// Error when there is no network connection
      /// Error that occurs when the time is forcibly manipulated on an Android device
      detectedDeviceTimeModifiedError = 'detectedDeviceTimeModifiedError',
      migrationError = 'migrationError',            /// Error that occurs when migrating from SDK
      licenseCipherError = 'licenseCipherError',    /// Error that occurs when licenseCipher from SDK
      unknownError = 'unknownError',                /// Unknown error type
      progress = 'progress'                         /// Download progress data
  }
```

#### 콘텐츠 다운로드 관련 기능

오프라인 재생을 위한 콘텐츠 다운로드는 다음과 같은 API를 사용해 구현합니다.

```java
// start download
MultiDRMReactNativeSDK.addStartDownload(DrmContentConfiguration);

// cancel downloads
MultiDRMReactNativeSDK.cancelDownloads();

// pause downloads
MultiDRMReactNativeSDK.pauseDownloads();

// resume downloads
MultiDRMReactNativeSDK.resumeDownloads();
```

콘텐츠 다운로드 시 진행 상황을 UI 상에 표시하려면 아래와 같은 코드를 이용합니다.

```java
MultiDRMReactNativeSDK.addMultiDrmEvent(MultiDrmEventType.progress, (event) => {
	// event.url is url
	// event.percent is downloaded percent
})
```

다운로드 진행 중 또는 완료 등의 상황은 다음의 코드로 확인할 수 있습니다.

```java
try {
	const state =
			await MultiDRMReactNativeSDK.getDownloadState(config);
	switch (state) {
		case ContentDownloadState.DOWNLOADING:
			break;
		case ContentDownloadState.PAUSED:
			break;
		case ContentDownloadState.COMPLETED:
			break;
		default:
			break;
	}
} catch (e) {
	setError(e.message);
}
```

다운로드된 콘텐츠와 DRM 라이선스는 다음과 같은 API로 삭제할 수 있습니다.

```java
// remove downloaded content
MultiDRMReactNativeSDK.removeDownload(DrmContentConfiguration);

// remove license for content
MultiDRMReactNativeSDK.removeLicense(DrmContentConfiguration);
```

#### SDK 릴리즈

애플리케이션 종료 시점에 다음과 같은 코드로 SDK를 릴리즈합니다.

```java
MultiDRMReactNativeSDK.release();
```

## 서드파티 상용 플레이어 SDK

`Bitmovin`과 `THEOplayer` 등의 상용 플레이어 솔루션들도 최근 React Native 용 SDK를 출시하며 크로스플랫폼 지원에 나서고 있습니다. 해당 솔루션을 이용해 React Native 앱을 개발하려는 고객사는 아래 링크를 참고하시기 바랍니다.

 - [Bitmovin Player SDK for React Native](https://github.com/bitmovin/bitmovin-player-react-native)
 - [THEOplayer SDK for React Native](https://www.theoplayer.com/sdk/react-native)