PallyCon NCG iOS SDK 개발 가이드

PallyCon NCG iOS SDK는 iOS용 미디어 서비스 앱을 개발할 때 잉카엔트웍스의 NCG(Netsync Content Guard) DRM을 쉽게 적용할 수 있게 해주는 제품입니다. 본 문서는 SDK에 포함된 라이브러리와 샘플 프로젝트의 사용법에 대해 설명합니다.

NCG DRM 클라이언트와 연동되는 PallyCon 멀티 DRM 서비스에 대한 설명은 라이선스 콜백 API 또는 라이선스 토큰 API를 참고하시기 바랍니다. SDK 사용과 관련한 기술 문의는 헬프데스크 사이트를 이용해 주시기 바랍니다.

NOTE : SDK 제품은 PallyCon 클라우드 상용 서비스 가입 시 신청할 수 있으며, 신청한 SDK는 PallyCon 어드민 사이트의 다운로드 페이지에서 다운로드 받을 수 있습니다.


지원 환경

  • iOS 9.0 이상
  • ARC(Automatic Reference Counting) 적용 필요
  • 본 SDK는 Xcode 8에서 테스트 되었으며, 시뮬레이터에서 동작하지 않습니다.

재생 시나리오

NCG iOS SDK에서 지원하는 재생 시나리오와 콘텐츠 유형은 다음과 같습니다.

  • 로컬 다운로드 재생 : mp4 동영상을 암호화한 NCG 콘텐츠 (*.mp4.ncg 파일)
  • 프로그래시브 다운로드 : mp4 동영상을 암호화한 NCG 콘텐츠 (*.mp4.ncg 파일)
  • HLS 스트리밍 : NCG DRM으로 보호된 HLS(HTTP Live Streaming) 콘텐츠

로컬 다운로드 재생

NCG로 암호화된 MP4 콘텐츠를 로컬 스토리지에 다운로드 받은 후 재생하는 시나리오입니다.

프로그래시브 다운로드

NCG로 암호화된 MP4 콘텐츠를 원격 서버에서 스트리밍 방식으로 직접 재생하는 시나리오입니다.

HLS 스트리밍

NCG DRM으로 보호된 HLS 콘텐츠를 스트리밍으로 재생하는 시나리오입니다.

SDK 워크플로우

  1. SDK를 초기화합니다.
  2. 재생할 DRM 콘텐츠의 라이선스를 확인합니다.
  3. 만약 라이선스가 있다면 유효한지 확인합니다.
  4. 라이선스가 없다면 라이선스 서버에 라이선스를 요청해 발급 받습니다.
  5. 콘텐츠를 재생합니다.
  6. 유효한 라이선스를 이용해 DRM 콘텐츠를 재생합니다.

SDK 초기화

SDK는 초기화를 통해 라이선스 DB, 기기 ID, 온/오프라인 정책, 시큐어 타임, 로컬 웹 서버 시작 등의 정보를 설정합니다.

sharedInstance

SDK는 싱글턴 패턴이 적용되어 있으며, Ncg2Agent 객체를 이용하기 위해서는 sharedInstance: 를 통해 접근해야 합니다. 만약 alloc, init 형태로 객체의 생성을 시도한다면 Exception이 발생되므로 직접 객체 생성은 피해야 합니다.

Ncg2Agent.h
+ (id) sharedInstance Ncg2Agent 객체 생성

- initialize:

Ncg2Agent 객체가 생성되면 initialize:를 호출하여 SDK 내 정보를 설정합니다. SDK를 사용하기 위해 최소 한번은 호출해야하며 앱 초기화 때 호출을 권장합니다.

OfflineSupportPolicy는 디바이스의 온라인/오프라인 상태에 따른 DRM 라이선스 정책을 설정하는 옵션입니다.

typedef enum _OfflineSupportPolicy
{
    OfflineSupportNo = 1,
    OfflineSupportYes = 2,
} OfflineSupportPolicy;
  • OfflineSupportNo: 디바이스가 온라인일 경우에만 콘텐츠 재생을 허용하는 정책입니다. 디바이스에 유효한 라이선스가 존재하더라도 재생 시마다 라이선스 서버를 통해 라이선스를 획득합니다. 오프라인 재생을 허용하는 경우보다 높은 보안성이 필요한 경우에 사용합니다.

  • OfflineSupportYes: 디바이스가 오프라인일 경우에도 이전에 획득한 유효 라이선스가 존재하면 해당 라이선스로 콘텐츠를 재생합니다.

executionLimit 는 오프라인 상태에서 앱의 실행 횟수를 제한하는 옵션입니다. OfflineSupportYes 옵션이 설정된 경우라도 해당 횟수 이상 앱이 실행된 후에는 온라인 상태에서 initialize를 호출해야 합니다. 횟수 제한 없이 무제한으로 실행을 허용하는 경우에는 0을 설정합니다.

NOTE:

  • executionLimit는 오프라인 상태에서 initialize:의 호출 횟수로, Background에서 Foreground로 전환되는 경우는 횟수가 증가되지 않습니다.
  • executionLimit 파라미터가 없는 initialize:OfflineSupportPolicyOfflineSupportYes일 경우 오프라인 상태에서 앱 실행 횟수가 10회로 설정됩니다.

rodbPath는 라이선스 DB의 저장 경로를 지정합니다. 지정하지 않을 경우 SDK에서 설정된 기본 경로로 지정됩니다. deviceId 는 사용자 ID당 이용할 수 있는 디바이스 갯수 제한과 라이선스 서버와 암호화 통신 등에서 중요하게 사용되는 값입니다. ID는 유일해야(Unique)하며, 변경되지 않아야 합니다. nil을 입력할 경우 SDK 내부에서 자동 생성됩니다.

NOTE:

  • SDK 내부에서 생성된 Device ID는 KeyChain에 저장되며, 앱이 삭제되어도 Device ID는 삭제되지 않습니다.
  • 앱을 재설치하면 KeyChain에 있는 Device ID를 사용합니다.
  • 디바이스를 DFU(Device Firmware Upgrade) 시행하면 KeyChain이 초기화되므로 Device ID는 삭제됩니다.
  • Device ID가 삭제되면 SDK는 새로운 Device ID를 생성합니다.

로컬 웹 서버

로컬 웹 서버는 외부출력감지, 다중접속감지, 복호화 등의 역활을 수행합니다. 로컬 웹 서버에서 발생하는 이벤트를 받기 위해서는 받고자 하는 곳에서 Delegate를 등록해야 합니다. 만약 라이선스를 확인하는 코드와 재생하는 코드가 서로 다른 클래스에 존재하면, 각각 이벤트를 받을 수 있도록 Delegate를 등록해야 합니다.

- getLocalWebServerInstance

initialize:에서 내에서 생성된 Ncg2Webserver 객체를 얻습니다.

Ncg2Agent.h
- (Ncg2Webserver*) getLocalWebServerInstance Ncg2Webserver 객체 반환

Local Web Server Protocol

로컬 웹 서버에서 발생하는 이벤트를 받는 콜백 함수입니다.

- onNotification

로컬 웹 서버에서 알림이 있을 경우 알림을 반환합니다.

WebServerDelegate(Required)
- (void) onNotification (int)notificationCode Noti 코드 반환
notifyMessage (NSString*)notifyMessage Noti 메시지 반환
- onError:

로컬웹서버에서 에러가 발생 했을 경우 에러를 반환합니다.

WebServerDelegate(Required)
- (void) onError : (int)errorCode 에러 코드 반환
errorMessage : (NSString*)errorMessage 에러 메시지 반환
- onCheckPlayerStatus:

로컬웹서버가 데이터를 전달할 때 실제 플레이어에게 전달하는지 확인하기 위해 사용합니다. 로컬웹서버는 일정 시간마다 이 함수를 호출합니다.

WebServerDelegate(Required)
- (PlayerState) onCheckPlayerStatus : (NSString*)uri 재생 URL 반환
- (PlayerState) onCheckPlayerStatus:(NSString *)uri
{
    int nReturnVal = 0;//NCGPlayerStatusFailed;
    switch ([self.mPlayer.currentItem status])
    {
        case AVPlayerItemStatusUnknown:
            nReturnVal = PlayerStateUnknown;
            break;
        case AVPlayerItemStatusReadyToPlay:
            nReturnVal = PlayerStateReadyToPlay;
            break;
        default:
            nReturnVal = PlayerStateFail;
            break;
    }
    return nReturnVal;
}

PlayerState

플레이어의 상태를 나타내기 위한 값

PlayerState
      PlayerStateUnknown 알 수 없는 플레이어의 상태
      PlayerStateReadyToPlay 재생준비가 완료된 상태
      PlayerStateFail 에러 혹은 릴리즈된 상태

- setWebServerDelegate:

로컬웹서버 이벤트를 받을 클래스의 객체를 등록하는 함수입니다. 해당 클래스에 WebServerDelegate를 선언합니다.

Ncg2Webserver.h
- (void) setWebServerDelegate : (id< WebServerDelegate >)webServerDelegate 이벤트를 받을 객체 등록

NOTE:

  • 로컬웹서버에서 발생하는 이벤트를 받아 적절하게 이벤트를 처리해야 합니다. 예를 들어 외부출력이 제한된 콘텐츠 이용 중 외부출력이 발생했을 경우, 로컬웹서버는 복호화를 중단하고 이벤트를 발생시키므로 이를 받아 적절히 처리해야 합니다.

HTTP Callback (Optional)

SDK는 내부 HTTP 이용하여 필요한 정보를 서버와 주고 받습니다. 하지만 내부 HTTP 통신이 아닌 외부에서 통신이 필요할 경우가 있습니다. 예를 들어 일회성 URL 또는 HTTPS 통신 같은 서비스를 사용한다면 반드시 외부에서 HTTP 통신을 제어해야 합니다.

HTTP Callback Protocol

HTTP 콜백 함수입니다. setHttpRequestDelegate:로 객체가 등록되면 내부 HTTP 통신은 아래 함수를 통해 진행됩니다.

NcgHttpRequestDelegate(Required)
- (NSData*) handleHttpRequest : (NSString*)requestURL Request URL
urlParameter : (NSString *)parameter URL 추가 정보
- (int) getResponseStatus HTTP 상태 코드 콜백
- (NSString*) getResponseMessage HTTP 응답 메시지 콜백
- (NSString*) getLastErrorMessage HTTP 오류 메시지 콜백

- setHttpRequestDelegate:

HTTP 콜백 이벤트를 받는 클래스의 객체를 등록하는 함수입니다. 해당 클래스에 NcgHttpRequestDelegate를 선언합니다.

Ncg2Agent.h
- (void) setHttpRequestDelegate : (id< NcgHttpRequestDelegate >)delegate 이벤트를 받을 객체 등록

Exception Handle (Optional)

SDK 내부에서 발생한 오류나 로그를 받고 싶을 때 사용합니다. 또한 상용 Crash Report 제품을 사용할 때 내부에서 발생하는 오류를 확인하면 신속한 원인 파악이 가능합니다.

Exceptional Event Protocol

예외 이벤트를 받을 함수입니다.

NcgExceptionalEventDelegate(Optional)
- (void) log : (NSString*)logMessage 로그 메시지 반환
- (void) logHandle : (NSError*)error 에러 코드 반환

- setExceptionalEventDelegate:

Exception Event를 받을 클래스의 객체를 등록하는 함수입니다.

Ncg2Agent.h
- (void) setExceptionalEventDelegate : (id< NcgExceptionalEventDelegate >)delegate 이벤트를 받을 객체 등록

라이선스 관리

이 장에서는 패키지된 콘텐츠의 라이선스 유효성 검사 및 획득/제거하는 방법을 알아봅니다.

Contents Check

콘텐츠가 DRM 패키지된 콘텐츠인지 확인합니다.

- isNcgContent:

파일 경로 또는 URL을 넣으면 패키지된 콘텐츠 여부를 반환합니다.

Ncg2Agent.h
-(BOOL) isNcgContent : (NSString*)path 콘텐츠 경로 또는 URL
error : (NSError**)error 에러 반환

NOTE:

  • isNcgContent: 함수는 SDK가 제공하는 함수들 내에서도 많이 사용됩니다. 예를 들어 라이선스 체크, 획득, 검증 같은 함수들 내에서 패키지된 콘텐츠인지를 확인을 먼저 진행됩니다.

License Check

패키지된 콘텐츠의 라이선스 존재 및 유효성을 확인합니다.

- checkLicenseValidByPath:

패키지된 콘텐츠의 경로 또는 URL를 입력하여 라이선스 유효성을 확인할수 있습니다.

Ncg2Agent.h
-(BOOL) checkLicenseValidByPath : (NSString*)path 콘텐츠 경로 또는 URL
result : (LicenseValidation*)lv 라이선스 검증 결과 반환
error : (NSError**)error 에러 반환

- checkLicenseValidByCID:

패키지된 콘텐츠의 CID와 Site ID를 입력하여 라이선스 유효성을 확인할 수 있습니다.

cidsiteIDgetNcg2HeaderInfo: 로 얻을 수 있습니다.

Ncg2Agent.h
-(BOOL) checkLicenseValidByCID : (NSString*)cid 콘텐츠 ID
siteID : (NSString*)siteID 콘텐츠 Site ID
result : (LicenseValidation*)lv 라이선스 검증 결과 반환
error : (NSError**)error 에러 반환

License Acquisition

패키지된 콘텐츠의 라이선스가 없을 때 라이선스를 획득 할수 있는 함수입니다.

- acquireLicenseByPath:

패키지된 콘텐츠의 경로 또는 URL를 입력하여 라이선스 획득을 할수 있습니다. orderID는 콘텐츠 공급자(Contents Provider:CP)가 제공하는 정보입니다.

Ncg2Agent.h
-(BOOL) acquireLicenseByPath : (NSString*)path 콘텐츠 경로 또는 URL
userID : (NSString*)userID 사용자 ID
orderID : (NSString*)orderID 구매 ID
isTemporary : (BOOL)isTemporary 라이선스 저장 여부
error : (NSError**)error 에러 반환

- acquireLicenseByCID:

패키지된 콘텐츠의 CID와 Site ID를 입력하여 라이선스를 획득할 수 있습니다.

cidsiteIDgetNcg2HeaderInfo: 로 얻을 수 있습니다. orderID는 콘텐츠 공급자가 필요 시 사용할 수 있는 부가 정보입니다.

Ncg2Agent.h
-(BOOL) acquireLicenseByCID : (NSString*)cid 콘텐츠 ID
siteID : (NSString*)siteID 콘텐츠 Site ID
userID : (NSString*)userID 사용자 ID
orderID : (NSString*)orderID 구매 ID 또는 부가 정보
acquisitionUrl : (NSString*)acquisitionUrl 라이선스 서버 URL
isTemporary : (BOOL)isTemporary 라이선스 저장 여부
error : (NSError**)error 에러 반환

NOTE:

  • 라이선스를 획득할 때 isTemporary 파라미터는 라이선스 운용 방식을 결정합니다. YES: 라이선스를 저장하지 않습니다. 라이선스를 저장하지 않고 매번 라이선스 서버에서 획득하는 시나리오에 적합합니다. 라이선스를 사용 후에는 반드시 removeAllTemporaryLicense:를 호출하여 메모리상의 라이선스를 제거해줘야 합니다. NO: 라이선스를 저장하여 사용합니다. 라이선스를 받아 저장하면 다음에도 저장된 라이선스를 사용하는 오프라인 시나리오에 적합합니다. 필요한 경우 removeLicenseByPath:, removeLicenseByCID: 를 호출하여 라이선스를 제거할 수 있습니다.
  • License Acquisition 리턴값이 NCGERR_LICENSE_SERVER_RESPONSE_ERROR(0xF0002003)일 경우 이는 서버의 명시적인 오류이므로 해당 에러(NSError)를 확인해야 합니다. 특히 서버 에러 코드가 8002 에러일 경우 커스텀 에러이므로 해당 에러를 확인하여 대응해야 합니다.

- acquireLicenseByToken:

토큰(token)을 이용하여 라이선스를 획득할 수 있습니다. cidsiteIDgetNcg2HeaderInfo: 로 얻을 수 있습니다.

Ncg2Agent.h
-(BOOL) acquireLicenseByToken : (NSString*)token token
cid : (NSString*)cid 콘텐츠 ID
siteID : (NSString*)siteID 콘텐츠 Site ID
userID : (NSString*)userID 사용자 ID(optional)
acquisitionUrl : (NSString*)acquisitionUrl 라이선스 서버 URL
isTemporary : (BOOL)isTemporary 라이선스 저장 여부
error : (NSError**)error 에러 반환

NOTE:

  • 토큰을 이용하여 라이선스를 획득하기 위해서는 토큰이 이미 생성되어 있어야 합니다.
  • 토큰으로 라이선스를 받으려면 콘텐츠 패키징 정보인 Site ID, ContentID(cid), Access Key가 필요합니다.
  • 토큰 발급 과정은 PallyCon 멀티 DRM 라이선스 토큰 API에서 확인할 수 있습니다.
  • 토큰 생성에 대한 자세한 정보는 INKA HelpDesk로 문의 주시기 바랍니다.

License Remove

패키지된 콘텐츠의 라이선스를 삭제할수 있는 함수입니다.

- removeLicenseByPath:

저장된 라이선스를 삭제합니다. 패키지된 콘텐츠의 경로를 입력하여 라이선스를 삭제 할수 있습니다.

Ncg2Agent.h
-(BOOL) removeLicenseByPath : (NSString*)path 콘텐츠 경로 또는 URL
error : (NSError**)error 에러 반환

- removeLicenseByCID:

저장된 라이선스를 삭제합니다. 패키지된 콘텐츠의 CID를 입력하여 라이선스를 삭제 할 수 있습니다. cidsiteIDgetNcg2HeaderInfo: 로 얻을 수 있습니다.

Ncg2Agent.h
-(BOOL) removeLicenseByCID : (NSString*)cid 콘텐츠 ID
error : (NSError**)error 에러 반환
-(BOOL) removeLicenseByCID : (NSString*)cid 콘텐츠 ID
siteID : (NSString*)siteID 콘텐츠 Site ID
error : (NSError**)error 에러 반환

- removeAllTemporaryLicense:

메모리상에 저장된 라이선스를 삭제합니다. 패키지된 콘텐츠의 라이선스 획득(acquireLicenseByPath, acquireLicenseByCID) 시 임시로 획득했을 경우(isTemporary=YES) 해당 콘텐츠 사용이 끝나면 반드시 호출하여 라이선스를 삭제해 줘야합니다.

Ncg2Agent.h
-(BOOL) removeAllTemporaryLicense : (NSError**)error 에러 반환

NOTE:

  • 임시로 획득한 라이선스를 제거하지 않으면 어플리케이션이 종료될 때까지 License Acquisition을 시도하지 않습니다.

License Information

패키지된 콘텐츠의 라이선스 정보를 확인할 수 있습니다. 라이선스 정보를 확인하기 위해서는 반드시 라이선스를 획득된 상태여야 합니다.

- getLicenseInfoByPath:

획득한 라이선스가 있는 경우, 패키지된 콘텐츠의 경로를 입력하여 라이선스 정보를 확인할 수 있습니다.

Ncg2Agent.h
-(BOOL) getLicenseInfoByPath : (NSString*)path 콘텐츠 경로 또는 URL
licenseValidation : (LicenseValidation*)lv 라이선스 검증 결과 반환
licenseInformation : (Ncg2LicenseInformation**)li 라이선스 정보 반환
error : (NSError**)error 에러 반환

- getLicenseInfoByCID:

획득한 라이선스가 있는 경우 패키지된 콘텐츠의 Contents ID(CID)와 Site ID를 입력하여 라이선스 정보를 확인할 수 있습니다. cidsiteIDgetNcg2HeaderInfo: 로 얻을 수 있습니다.

Ncg2Agent.h
-(BOOL) getLicenseInfoByCID : (NSString*)cid 콘텐츠 ID
siteID : (NSString*)siteID 콘텐츠 Site ID
licenseValidation : (LicenseValidation*)lv 라이선스 검증 결과 반환
licenseInformation : (Ncg2LicenseInformation**)li 라이선스 정보 반환
error : (NSError**)error 에러 반환

Ncg2LicenseInformation

라이선스 정보 클래스입니다.

Ncg2LicenseInformation
      - (NSString*) getPlayStartDate 라이선스 유효 시작일시
      - (NSString*) getPlayEndDate 라이선스 만료일시
      - (long) getPlayFirstDate 최초 사용 일시
      - (NSString*) getPlayVerificationMethod 기간체크 시 검증 방법
      - (long) getPlayDurationHour 총 가용 시간
      - (long) getPlayTotalCount 남은 가용 횟수
      - (long) getPlayRemainCount 사용하지 않음
      - (Ncg2LicenseOutputProtectionPermission*) getOutputProtectionPermission 외부출력 허용 여부

Ncg2LicenseOutputProtectionPermission

외부출력 권한 정보 클래스입니다.

Ncg2LicenseOutputProtectionPermission
      - (bool) getIsExternalDisplayAllow 외부출력 허용여부
      - (int) getAps 사용하지 않음
      - (int) getCgms_a 사용하지 않음
      - (int) getCavendish 사용하지 않음
      - (int) getHdcp 사용하지 않음
      - (bool) getIsJailBreakAllow 탈옥단말 허용여부
      - (int) getSendReport 사용하지 않음
      - (int) getIsJailBreakExternalDisplayAllow 탈옥단말 외부출력 허용여부

LicenseValidation

라이선스 권한 정보입니다.

LicenseValidation 처리
      LicenseValidationValid 유효한 라이선스 Playback
      LicenseValidationNotExist 라이선스가 없을 때 License Acquisition
      LicenseValidationExpired 라이선스 만료 콘텐츠 사용못함
      LicenseValidationBeforeStartDate 아직시작 일시가 아닐 때 시작일시까지 기다림
      LicenseValidationExceededPlayCount 횟수 만료 콘텐츠 사용못함
      LicenseValidationExternalDeviceDisallowed 외부출력 허용안함 External Display
      LicenseValidationNotSupportOffline Off-line 지원하지 않음 On-line 환경 필요
      LicenseValidationAbnormalDevice 탈옥 단말 허용안함 콘텐츠 사용못함
      LicenseValidationOfflineTooLong Secure Time 업데이트 필요 updateSecureTimeFromServer호출
      LicenseValidationScreenRecorderDetected 화면녹화 앱이 발견되었을 때 Screen Recorder

Header Information

패키지된 콘텐츠의 헤더는 콘텐츠에 대한 정보를 저장하고 있습니다.

- getNcg2HeaderInfo:

패키지된 콘텐츠 파일 헤더 정보를 가져온다.

Ncg2Agent.h
-(Ncg2HeaderInformation*) getNcg2HeaderInfo : (NSString*)path 콘텐츠 경로 또는 URL
error : (NSError**)error 에러 반환

Ncg2HeaderInformation

패키지된 콘텐츠 헤더 정보를 나타내는 클래스입니다.

Ncg2HeaderInformation
      - (NSString*) contentID 콘텐츠 ID
      - (NSString*) siteID 사이트 ID
      - (NSString*) acquisitionUrl 라이선스 서버 URL
      - (NSString*) source 서비스 제공자
      - (NSString*) packDate 패키징된 날짜
      - (int) encryptionLevel 암호화 레벨
      - (int) encryptionRange 암호화 범위

3. Playback

패키지된 콘텐츠의 라이선스가 유효하다면 콘텐츠를 재생할 수 있습니다. 패키지된 콘텐츠는 암호화되어 있으므로 이를 복호화해줘야 하는데 이러한 역활은 로컬웹서버가 담당합니다. 따라서 패키지된 콘텐츠를 재생할 때 실제 콘텐츠의 경로 또는 URL이 아니라, 로컬웹서버로 요청해야 합니다. 이러한 과정은 아래와 같은 순서로 진행됩니다.

  1. 로컬웹서버로부터 재생 URL을 획득합니다.
  2. 플레이어는 로컬웹서버가 준 재생 URL로 콘텐츠 데이터를 요청합니다.
  3. 로컬웹서버는 다운로드된 콘텐츠 또는 원격지에 있는 콘텐츠 데이터를 요청합니다.
  4. 콘텐츠는 암호화된 상태로 로컬웹서버로 전달된다.
  5. 로컬웹서버는 암호화된 데이터를 복화화합니다.
  6. 복호화된 데이터를 플레이어에게 전달합니다.
  7. 플레이어는 복호화된 데이터를 재생하게 된다.
  8. 재생이 종료되면 임시 라이선스/재생 URL을 삭제합니다.

Download Contents

다운로드된 콘텐츠나 다운로드 중인 콘텐츠인 경우 아래 함수를 이용하여 재생 URL을 요청합니다.

- addLocalFilePathForPlayback:

Ncg2Webserver.h
- (NSString*) addLocalFilePathForPlayback : (NSString*)path 저장된 콘텐츠 또는 다운로드 중인 경로
remoteUrlForDnp : (NSString*)remoteUrlForDnp 콘텐츠 다운로드 URL
fileSize : (int64_t)fileSize 콘텐츠 파일 사이즈
error : (NSError**)error 에러 반환

Progressive Download

패키지된 콘텐츠가 웹서버에 올려진 콘텐츠일 경우 아래 함수를 이용하여 재생 URL을 요청합니다.

- addProgressiveDownloadUrlForPlayback:

Ncg2Webserver.h
- (NSString*) addProgressiveDownloadUrlForPlayback : (NSString*)url 콘텐츠 URL
error : (NSError**)error 에러 반환

HTTP Live Streaming(HLS)

패키지된 콘텐츠가 HLS 콘텐츠일 경우 재생 URL을 요청할 수 있습니다.

- addHttpLiveStreamUrlForPlayback:

Ncg2Webserver.h
- (NSString*) addHttpLiveStreamUrlForPlayback : (NSString*)url 콘텐츠 URL
error : (NSError**)error 에러 반환
- (NSString*) addHttpLiveStreamUrlForPlayback : (NSString*)url 콘텐츠 URL
cid : (NSString*)cid 콘텐츠 ID
error : (NSError**)error 에러 반환

Playback Finish

재생이 종료되면 사용한 재생URL을 삭제합니다.

- clearVirtualPlaybackUrls

Ncg2Webserver.h
- (void) clearVirtualPlaybackUrls 플레이어 종료 시 호출합니다.

4. Security

SDK 동작 중 발생할 수 있는 보안 이슈의 운용 요소와 보안 요소에 대해 설명합니다.

Secure Time

디바이스 시간은 사용자가 변경 가능하므로 패키지된 콘텐츠 사용 시간 검증에 적합하지 않습니다. 이러한 문제를 해결하기 위해 SDK이 내부에 Secure Time을 관리하고 있습니다. 하지만 베터리 방전, OS/디바이스/어플리케이션 오류로 인해 시간이 정확한 시간이 아닐 수 있습니다. 이러한 경우 SDK가 On-line상태에서 시간 업데이트가 필요함을 리턴하고, 어플리케이션에서 시간을 업데이트 할 수 있도록 안내해야합니다. Secure Time은 GMT 시간으로 관리하며 기간제 콘텐츠의 라이선스 검증에 사용됩니다.

- getNcgSecureTime:

SDK 내부에서 사용되는 시간을 확인할 수 있습니다.

Ncg2Agent.h
- (NSString*) getNcgSecureTime GMT 시간을 리턴

- updateSecureTimeFromServer:

LicenseValidation 값 중 LicenseValidationOfflineTooLong이 리턴되면 Secure Time 오차가 발생했다는 의미이므로 Secure Time 을 유효한 시간으로 업데이트 해줘야합니다. 시간은 외부서버로부터 얻어오므로 디바이스는 반드시 On-line 상태여야 합니다.

Ncg2Agent.h
- (BOOL) updateSecureTimeFromServer : (NSError**)error

External Display

라이선스에는 외부출력을 제한할 수 있는 정보가 포함되어 있습니다. 이 정보에 따라 외부출력이 결정되며, 외부출력을 허용하는 경우 HDMI, Mirror, AirPlay를 통해 다른 화면에 영상을 출력할 수 있습니다. 외부출력이 제한된 콘텐츠는 사용자에게 외부출력이 제한된 콘텐츠 임을 안내해야 하며 외부출력 안내는 2가지 시나리오가 있습니다.

  • 콘텐츠 재생 전: 외부출력이 연결된 상태에서 콘텐츠 라이선스 확인(License Check) 시 외부출력이 제한된 경우 재생하지 않습니다.

  • 콘텐츠 재생 중: 콘텐츠 재생 중 외부출력 장치가 연결되는 경우 로컬웹서버는 복호화를 멈추고 onNotification:로 외부출력이 연결되었다는 이벤트가 발생합니다. 이에 맞는 안내 메시지와 함께 재생을 멈추어야 합니다.

NOTE:

  • 재생 중 외부출력이 연결되면 로컬웹서버는 복호화를 멈추고 데이터를 플레이어에게 주지 않습니다. 이때 onNotification:로 알려주는 알림코드는 LWS_NOTIFY_HDMI_DETECTED입니다.
  • 로컬웹서버가 데이터를 주지 않더라도 캐시에 남아있는 데이터를 다 재생한 후 플레이어가 멈추므로 이벤트 발생 시 재생을 바로 멈추는 것을 권장합니다.
  • iOS8.0 이상 + 라이트닝케이블 + MAC OS 요세미티 QuickTime Player 를 통해 iOS 디바이스 화면을 녹화할 수 있습니다. 이러한 녹화를 방지하기 위해서는 HLS 콘텐츠를 사용해야 합니다.

Screen Recorder

스크린 녹화 앱을 통해 재생되는 콘텐츠를 녹화할 수 있습니다. 이러한 녹화앱이 설치된 경우 콘텐츠 재생을 멈추어야 합니다.

- setScreenRecorderAppDetecting:

녹화앱이 설치되어 있는 경우 콘텐츠 재생이 안되도록 되어 있습니다(디폴트). 하지만 오디오 콘텐츠의 경우 녹화앱 사용이 불편할 수 있습니다. 이러한 경우 기능을 사용하지 않도록 설정할 수 있습니다.

Ncg2Agent.h
- (BOOL) setScreenRecorderAppDetecting : (BOOL)enabled 녹화앱 검출여부

- getDetectedScreenRecorderName:

발견된 녹화앱 이름을 리턴합니다. 사용자에게 어떤 앱인지 알려주어 삭제하도록 안내합니다.

Ncg2Agent.h
- (NSString*) getDetectedScreenRecorderName 발견된 녹화앱이름 리턴

NOTE:

  • 녹화앱 검출 방식은 녹화앱 리스트를 통해 검출합니다. 만약 리스트에 없는 녹화앱이라면 검출되지 않습니다.
  • 이러한 경우 해당 앱 정보를 잉카에게 제공하여 리스트에 반영하고 업데이트된 SDK를 사용해야 합니다.

5. NCG File I/O

패키지된 콘텐츠는 일반적인 파일 I/O(fopen, fread, fseek..)로 제어 할 수 없습니다. 패키지된 콘텐츠를 복호화된 형태로 읽기 위해서는 Ncg2File 인터페이스를 이용해야 합니다. 이 장에서는 패키지된 NCG 콘텐츠를 제어할 수 있는 파일 I/O 인터페이스와 언팩(Decryption)하는 방법을 설명합니다.

- createNcgFile:

NCG 콘텐츠를 다룰려면 Ncg2File 객체를 직접 생성하지 말고 createNcgFile:메소드로 생성해야 합니다.

Ncg2Agent.h
- (Ncg2File*) createNcgFile : (NSError**)error NCG file 객체 반환

- open:

패키지된 NCG 콘텐츠를 오픈합니다.

Ncg2File.h
- (BOOL) open : (NSString*)path 파일 경로
isPrepare : (BOOL)isPrepare 복호화 가능상태로 파일 오픈할것인지 여부
error : (NSError**)error 에러 반환

isPrepare YES일 경우 패키지된 콘텐츠 정보와 라이선스 정보를 획득하여 언팩이 가능해집니다. NO 일 경우 패키지된 콘텐츠 정보만 확보됩니다.

NOTE:

  • 언팩하려는 콘텐츠의 유효한 라이선스가 존재해야 open 됩니다.
  • 언팩하려는 콘텐츠의 라이선스가 없다면 라이선스를 획득(License Acquisition)해야 합니다.

- read:

암호화된 파일을 읽어 복호화된 데이터와 실제 읽은 데이터 사이즈를 반환합니다.

Ncg2File.h
- (int) read : (unsigned char*)buffer 복호화된 데이터가 저장되는 버퍼
sizeToRead : (int)sizeToRead 버퍼 사이즈
error : (NSError**)error 에러 반환

- seek:

파일의 원하는 위치로 이동할 때 사용합니다.

Ncg2File.h
- (BOOL) seek : (int64_t)offset 이동시킬 위치지정(offset)
method : (SeekMethod)method 어느 위치에서 offset을 할것인지 결정
error : (NSError**)error 에러 반환

Seek Method

seek method를 설명합니다.

Seek Method
      SM_Begin 파일 처음 위치
      SM_Current 파일 포인터의 현재 위치
      SM_End 파일 끝 위치

- getCurrentPointer:

현재의 파일 포인터 위치를 반환합니다.

Ncg2File.h
- (int64_t) getCurrentPointer : (NSError**)error 현재 파일 포인터 위치 반환

- getContentSize:

원본 파일의 크기를 반환합니다.

Ncg2File.h
- (int64_t) getContentSize : (NSError**)error 원본파일 크기 반환

- getNcgHeaderSize:

패키지된 콘텐츠 헤더 크기를 반환합니다.

Ncg2File.h
- (int64_t) getNcgHeaderSize : (NSError**)error 헤더크기 반환

- close:

오픈한 파일 및 할당된 자원을 해제합니다.

Ncg2File.h
- (void) close open 된 파일을 닫는다.

Unpack Sample Code

패키지된 콘텐츠를 언팩하는 샘플 코드입니다.

NSError* error = nil;
Ncg2File* ncgFile = [Ncg2Agent createNcgFile:&error];
if( error != nil )
{
    NSLog(@"createNcgFile() Failed!");
    return;
}

if( [ncgFile open:ncgFilePath isPrepare:YES error:&error] == NO )
{
    NSLog(@"open() Failed!");
    return;
}

FILE* fp = fopen( [unpackFilePath UTF8String], "wb" );
fseeko(fp, 0, SEEK_SET);
unsigned char buffer[8192] = {0};
while( TRUE )
{
    int32_t read = [ncgFile read:buffer sizeToRead:sizeof(buffer) error:&error];
    if(error != nil)
    {
        NSLog(@"read() Failed!");
        [ncgFile close];
        fclose( fp );
        return;
    }
    if ( read <= 0 )
        break;
    fwrite( buffer, 1, read, fp );
}

fclose( fp );
[ncgFile close];

results matching ""

    No results matching ""