Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


Player

LIST

JWT

Expand
titleVersion History

작성일

문서버전

비고

2016.05.03

v1.0

문서 초안 작성

2017.02.09

v1.1

seekable_end, disable_playrate 추가

2017.03.09

v1.2

live.url, live.poster_url 추가

2017.03.23

v1.3

title 추가

2017.06.26

v1.4

cdn, auth_type, use_ip_validation, use_kollus_token 추가

2017.09.06

v1.5

pc_skin 추가

2017.12.19

v1.6

Live spec에 kollus 인증 추가

2018.02.08

v1.7

thumbnail 추가

2018.08.20

v1.8

subtitle_policy, drm_policy 추가

live jwt payload 항목 추가

2018.10.29

v1.9

video_watermarking_code_policy 추가

2018.11.06

v1.10

play_section 추가

2019.01.07

v.1.11

video_watermarking_code_policy.enable_html5_player 추가

2019.03.06

v.1.12

live chatting 옵션 추가, live payload key 추가 및 레가시 처리

2019.07.11

v.1.13

Live spec 에 video_watermarking_code_policy 추가

2019.07.18

v.1.14

disable_nscreen 추가

2019.09.20

v.1.15

live jwt 에 play_expt 추가

2019.12.05

v.1.16

scroll_event 추가

개요

기존 Kollus 시스템에서 Media Token은 고객사가 Videogateway로 컨텐츠 재생 요청을 전달할 때 요청 내용을 은닉(암호화)하고, 직접 url에 대한 유효 기간을 설정하기 위해 사용했습니다. 하지만 Media Token을 사용하기 위해서는 Kollus에서 제공하는 모듈을 서버에 직접 설치해야 하고, 모듈이 서버를 지원하지 않는 경우엔 Kollus API를 호출하여 Media Token을 원격으로 생성해 사용해야 하거나, Media Token의 스펙이 변경될 때마다 서버에 모듈을 재 설치해야 하는 등 문제가 많았습니다. 이에 암호학적으로 안전하고 구현이 간단한 JSON Webtoken을 이용하여 Kollus 모듈에 대한 의존성을 줄이고 좀 더 유연하게 스펙 변경에 대응할 수 있도록 합니다.

유의사항

  1. JSON Webtoken(이하 JWT)에 대해선 http://jwt.io 사이트를 참조해주세요.
  2. JWT의 Payload 부분에 다음에 기술된, 먼저 등록된 Claim들을 사용해선 안됩니다. (https://tools.ietf.org/html/rfc7519#section-4) 이 경우 기대했던 대로 동작하지 않을 수 있습니다.
  3. 암호화 알고리즘은 HMAC SHA256 (HS256) 만을 지원합니다

JWT Request

용어

  • 보안 키 (Security Key)
    • 보안 키는 JWT를 signing 하기 위해 Kollus와 고객사만이 공유하는 비밀 키 입니다. 보안 키는 “설정 > 서비스 계정” 페이지에서 확인할 수 있습니다. 이 값은 고객이 희망하면 언제든 변경 가능하며, 변경 즉시 기존에 사용하던 보안 키는 폐기됩니다. 따라서 보안 키는 고객사의 정기점검 시간을 이용하여 변경하는 것을 권장합니다
  • 사용자 키 (Custom Key)
    • 사용자 키는 평문 보안 키를 암호화한 키입니다. JWT를 이용하여 Videogateway에 요청시 JWT와 함께 전달되어야 합니다.

JWT 생성 방법

암호화 알고리즘은 HMAC SHA256 (HS256) 으로 하고, Secret key는 보안 키, Payload에는 아래 Payload Spec에 맞춘 JSON String을 추가하여 JWT를 생성합니다.

생성한 JWT를 이용하여 Videogateway에 요청하기

생성한 JWT와 사용자 키를 다음과 같은 형식의 url로 생성하여 호출합니다.

Code Block
languagejs
themeMidnight
http://v.kr.kollus.com/s?jwt=생성한 JWT&custom_key=사용자 키

JWT Payload Spec

jwt PayLoad의 형식은 다음과 같은 JSON 문자열입니다.

Code Block
languagejs
themeMidnight
{
	"cuid": "CLIENT_USER_ID",
	"awtc": “AUDIO_WATERMARKING_CODE”,
	"expt": EXPIRE_TIME,
	"pc_skin": {
		"skin_path": "http://file.kr.dev.kollus.com/public/custom/skin2.zip",
		"skin_sha1sum": "B2B688123F68BFA7DB4B1F89EC292C0835086D9B"
	},
	"mc": [{
		"mckey": “MEDIA_CONTENT_KEY”,
		"mcpf": “MEDIA_CONTENT_PROFILE_KEY”,
		"title": “TITLE”,
		"intr": IS_INTRO,
		"seek": IS_SEEKABLE,
		"seekable_end": SEEKABLE_END,
		"disable_playrate": DISABLE_PLAYRATE,
                         "thumbnail": {
                             "enable": IS_ENABLE,
                             "thread": IS_THREAD,
                             "type": "TYPE"
                         }
                   "live": {
                       "url" : "LIVE_URL",
                       "poster_url" : "LIVE_POSTER",
                       "cdn": {
                           "type": "akamai",
                           "password": {
                               "short": "901490a9",
                               "long": "B2E2B80BCC848FB302EC55215C95E826"
                           }
                       },
                       "auth_type": "user",
                       "use_ip_validation": true,
                       "use_kollus_token": false
                   }
	}]
}
Payload 항목이름Datatype필수여부내용Mediatypecuid
(CLIENT_USER_ID)String필수컨텐츠에 억세스하려는 고객사의 사용자 아이디. 북마크나 NScreen 데이터의 Key로 사용됩니다.VOD/LIVEawtc
(AUDIO_WATERMARKING_CODE)String선택
(기본값: null)Kollus 오디오 워터마킹 기능을 이용하려고 할 때에 사용하는 워터마킹 코드. 워터마킹 코드는 API를 호출하여 획득하며, 자세한 내용은 기술 담당자에게 문의 바랍니다.사용하지 않으면 해당 Entry를 삭제하거나, null로 입력하면 됩니다.VODexpt
(EXPIRE_TIME)Integer필수JWT가 유효한 시간. Unix timestamp 형식으로 입력합니다. 고객사 서버와의 시간이 정확하게 일치하지 않을 수도 있으므로, 최대 1분 정도는 유효기간이 지났더라도 접근할 수 있습니다.VOD/LIVEpc_skin
(PC_EX_PLAYER_SKIN)Array선택V2 PC Player 스킨을 고객이 지정하기 위한 용도로 사용합니다. 설정할 스킨이 없는 경우는 필드 자체를 생략할 수 있으나, 이 필드를 추가했을때는 반드시 하위 필드인 skin_path, skin_sha1sum 값이 정확히 입력되어야 합니다.V2 Playerskin_pathString필수V2 PC Player 스킨 정보를 담고 있는 압축 파일의 URLV2 Playerskin_sha1sumString필수V2 PC Player 스킨 정보를 담고 있는 압축 파일에 대한 sha1 checksum 값V2 Playermc필수재생할 컨텐츠의 재생정보를 담고 있는 Object 타입의 Entry를 배열로 담고 있는 배열입니다.VOD/LIVEmckey
(MEDIA_CONTENT_KEY)String필수재생할 컨텐츠의 식별 키. 확장 미디어 컨텐츠 키 형식도 동일하게 사용할 수 있습니다.VOD/LIVEmcpf
(MEDIA_CONTENT_PROFILE_KEY)String선택
(기본값: null)컨텐츠의 프로파일 가운데 하나를 강제로 지정해 재생할 경우에 사용합니다. 강제로 지정할 프로파일의 키를 입력합니다.
자동 선택하게 두려면 해당 Entry를 삭제하거나, null로 입력하면 됩니다.VODtitleString선택
(기본값: null)컨텐츠의 기존 타이틀을 대체하는 문자열입니다.VOD/LIVEintr
(IS_INTRO)Boolean선택
(기본값: false)컨텐츠가 인트로인지 아닌지의 여부를 입력합니다. 인트로에 관한 내용은 하단의 예제를 참조하세요.인트로가 아닌 정상 컨텐츠인 경우엔 해당 Entry를 삭제하거나, false를 입력하면 됩니다.VODseek
(IS_SEEKABLE)Boolean선택
(기본값: true)컨텐츠의 seek를 허용할 것인지 아닌지의 여부를 입력합니다. 보통 인트로인 경우는 seek를 허용하지 않습니다. seek를 허용하는 경우엔 해당 Entry를 삭제하거나, true를 입력하면 됩니다.VODseekable_end
(SEEKABLE_END)Integer선택
(기본값: -1)seek 허용이 안된 컨텐츠도 시작 부터 입력 값까지의 구간은 seek가 가능하게 됩니다.VODdisable_playrate
(DISABLE_PLAYRATE)Boolean선택
(기본값: true)배속컨트롤 사용 여부를 설정합니다.VODthumbnail.enableBoolean선택
(기본값: false)썸네일 활성화 여부를 설정합니다.해당옵션은 안드로이드만 지원합니다.안드로이드 공용앱/SDKthumbnail.threadBoolean선택
(기본값: false)쓰레드 방식 여부를 설정합니다.해당옵션은 안드로이드만 지원합니다.안드로이드 공용앱/SDKthumbnail.typeString선택
(기본값: null)썸네일 사이즈를 설정합니다. (big / small)해당옵션은 안드로이드만 지원합니다안드로이드 공용앱/SDKlive.url
(LIVE_URL)String선택
(기본값: null)라이브 스트리밍 재생 주소를 입력합니다.LIVElive.poster_url
(LIVE_POSTER)String선택
(기본값: null)라이브 스트리밍 재생 전 포스터 이미지 주소를 입력합니다.LIVElive.cdnObject선택CDN을 사용하지 않을때는 JSON 블럭을 생략합니다.LIVElive.cdn.typeString필수Kollus에 미리 정의된 타입 CDN Type(사용 가능 타입: akamai)LIVElive.cdn.passwordObject선택
(기본값: 빈 문자열)CDN 접근 비밀번호short, long 두가지가 필요합니다.LIVElive.auth_typeString선택
(기본값: user)Edge 인증 타입LIVElive.use_ip_validationBoolean선택
(기본값: FALSE)Edge의 Media URL 생성시  IP 인증 사용 여부LIVElive.use_kollus_tokenBoolean선택
(기본값: FALSE)Edge의 Media URL 생성시 Kollus Token (ktn 파라미터) 사용 여부LIVE

예제

일반 컨텐츠 재생을 위한 JWT Payload

catenoid 라는 아이디를 가진 사용자가 미디어 컨텐츠 키 vnCVPVyV 를 재생하는 경우

Code Block
languagejs
themeMidnight
{
	"cuid": “catenoid”,
	"expt": 1462931880,
	"mc": [{
		"mckey": “vnCVPVyV“
	}]
}
인트로가 포함된 컨텐츠 재생을 위한 JWT Payload

catenoid 라는 아이디를 가진 사용자가 인트로로 미디어 컨텐츠 키 gDV2B1ZG를 seek 불가능한 상태로, 본 컨텐츠로는 vnCVPVyV 를  재생하는 경우

Code Block
languagejs
themeMidnight
{
	"cuid": “catenoid”,
	"expt": 1462931880,
	"mc": [{
		"mckey": “gDV2B1ZG“,
		"intr": true,
		"seek": false,
	},{
		"mckey": “vnCVPVyV“
	}]
}
        
스킵 안되는 컨텐츠 재생시 시작부분 일부만 스킵 허용하기 위한 JWT Payload

catenoid 라는 아이디를 가진 사용자가 인트로로 미디어 컨텐츠 키 gDV2B1ZG를 seek 불가능한 상태로 재생하지만, 시작 부터 30초 구간은 스킵을 허용하는 경우

Code Block
languagejs
themeMidnight
{
	"cuid": “catenoid”,
	"expt": 1462931880,
	"mc": [{
		"mckey": “gDV2B1ZG“,
		"intr": true,
		"seek": false,
		"seekable_end": 30,
	}]
}

Live JWT Payload Spec

Payload 항목

이름Datatype필수여부내용cdn tpyecuid
(CLIENT_USER_ID)String필수컨텐츠에 억세스하려는 고객사의 사용자 아이디. 북마크나 NScreen 데이터의 Key로 사용됩니다.akamai
kollusexpt
(EXPIRE_TIME)Integer필수JWT가 유효한 시간. Unix timestamp 형식으로 입력합니다. 고객사 서버와의 시간이 정확하게 일치하지 않을 수도 있으므로, 최대 1분 정도는 유효기간이 지났더라도 접근할 수 있습니다.akamai
kollusmckey
(MEDIA_CONTENT_KEY)String필수재생할 컨텐츠의 식별 키.
라이브 컨텐츠에서는 VG 매핑을 위한 키로 사용되며 mckey에 업로드 된 컨텐츠가 아닌 JWT의 live.url로 넘겨받은 컨텐츠를 재생함.akamai
kollustitle
(TITLE)String선택
(기본값: null)컨텐츠의 기존 타이틀을 대체하는 문자열입니다.akamaikolluslive.url
(LIVE_URL)String선택
(기본값: null)라이브 스트리밍 재생 주소를 입력합니다.akamai
kolluslive.cdnObject선택CDN을 사용하지 않을때는 JSON 블럭을 생략합니다.akamai
kolluslive.cdn.typeString필수Kollus에 미리 정의된 타입 CDN Type(사용 가능 타입: akamai, kollus)akamai
kolluslive.cdn.passwordObject선택
(기본값: 빈 문자열)CDN 접근 비밀번호short, long 두가지가 필요합니다.akamailive.auth_typeString선택
(기본값: user)Edge 인증 타입akamailive.use_ip_validationBoolean선택
(기본값: FALSE)Edge의 Media URL 생성시  IP 인증 사용 여부akamai
kolluslive.use_kollus_tokenBoolean선택
(기본값: FALSE)Edge의 Media URL 생성시 Kollus Token (ktn 파라미터) 사용 여부akamailive.use_duplication_blockBoolean선택
(기본값: TRUE)중복 재생 차단 여부akamai

예제

Live Streaming JWT Payload

Live Streaming으로 재생시에는 intro / seek / playbackRate 관련 기능이 모두 비활성화 되기 때문에, 해당 JWT 옵션은 의미가 없음.

Code Block
languagejs
themeMidnight
{
	"cuid": “catenoid”,
	"expt": 1462931880,
	"mc": [{
		"mckey": “gDV2B1ZG“,
		"title": “Live Sample“,
                         "live" : {
                                  "url": "http://XXXXX/XXX.m3u8",
                                  "poster_url": "http://XXXXX/XXX.jpg"
                         },
	}]
}
Live Streaming JWT Payload + Akamai CDN 인증

Live Streaming으로 재생시에는 intro / seek / playbackRate 관련 기능이 모두 비활성화 되기 때문에, 해당 JWT 옵션은 의미가 없음.

Code Block
languagejs
themeMidnight
{
  "mc": [
    {
      "mckey": "gDV2B1ZG",
      "live": {
        "url": "http://XXXXX/XXX.m3u8",
        "poster_url": "http://XXXXX/XXX.jpg",
        "cdn": {
           "type": "akamai",
           "password": {
              "short": "000000a0",
              "long": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
           },
           "auth_type": "user",
           "use_ip_validation": true,
           "use_kollus_token": false
        }
      },
      "title": "Live Sample"
    }
  ],
  "cuid": "test",
  "expt": 1462931880
}

Live Streaming JWT Payload + Kollus 인증

Live Streaming으로 재생시에는 intro / seek / playbackRate 관련 기능이 모두 비활성화 되기 때문에, 해당 JWT 옵션은 의미가 없음

Code Block
languagejs
themeMidnight
{
  "mc": [
    {
      "mckey": "gDV2B1ZG",
      "live": {
        "url": "http://XXXXX/XXX.m3u8",
        "poster_url": "http://XXXXX/XXX.jpg",
        "cdn": {
           "type": "kollus",
           "use_ip_validation": true,
           "use_duplication_block": false
        }
      },
      "title": "Kollus Live"
    }
  ],
  "cuid": "test",
  "expt": 1462931880
}

※ expt 필드의 값은 onetime URL의 expire time이며 동시에 라이브 스트림의 expire time으로 사용됩니다. 예를 들어 1시간 짜리 라이브를 하기 위해서는 expt의 값을 1시간 이상후의 값으로 설정해야 합니다.

샘플 코드

 Json Web Tokens – Java

 Json Web Tokens – ruby

 Json Web Tokens – php

Download

샘플 코드

 Download – jsp

 Download – php

 Download – dotnet

V/G Query String

사용방법

Code Block
languagejs
themeMidnight
http://v.kr.kollus.com/[MEDIA_CONTENT_KEY]?key=value&...

query string은 url 뒤에 ?를 붙이고 key와 value를 =로 엮는다. data type이 null인 경우는 key만 붙인다. key, value 쌍을 하나 이상 엮을 경우엔 &로 구분한다.

플레이어구분

플레이어는 다음과 같은 명칭으로 통일한다.

  • 모바일 : Mobile
    • iOS 전용 플레이어 : iOS
    • Android 전용 플레이어 : Android
  • 데스크탑 : Desktop
    • Flash 플레이어 : Flash
    • V2 플레이어 (ActiveX, NPAPI 플레이어) : V2
    • V3 전용 플레이어 (설치형, Agent 방식의 플레이어) : V3e
    • V3 플레이어 (HTML5 Agent 방식의 플레이어) : V3h
    • V4 플레이어 (HTML5 플레이어, 비암호화) : V4

파라미터

keyDataType지원플레이어설명pfstringAll프로파일 자동 설정을 무시하고 지정된 프로파일 키에 해당하는 트랜스코딩 파일을 서빙. 존재하지 않으면 자동 설정.
예> ?pf=mixnut-pc-high1 (mixnut-pc-high1에 해당하는 트랜스코딩 파일을 서빙)autoplay (a)nullAll로딩 후 동영상 자동 시작. 단, 모바일 전용 플레이어는 기본이 자동시작이다. (옵션에 영향을 받지 않음)mutenullAll로딩 후 음소거된 상태에서 동영상 재생. 모바일 HTML5 플레이어는 시작시 음소거가 가능하지 않음.downloadnullMobile,
V3e, V3h컨텐츠 다운로드 기능. download 옵션을 추가하면 비디오 게이트웨이가 다운로드 모드로 동작한다. 만약 채널에서 모바일이나 PC 다운로드 옵션을 사용하지 않음으로 설정하면, 실제 다운로드를 시도하더라도 플레이어가 다운로드하지 않음.titlestringAll지정된 제목 외에 강제로 제목 지정. 모바일 HTML5 플레이어의 경우 원래 제목이 지원되지 않음.tintegerAll지정한 위치부터 재생함. nscreen 정보가 있더라도 이를 무시하고 주어진 시간부터 재생함. (이 경우 이어보기 팝업이 뜬다.)
예> ?t=10 (10초부터 재생)sintegerAll지정한 위치부터 재생하는 것은 t 옵션과 동일하지만, s 옵션은 이어보기 팝업이 뜨지 않는다.force_exclusive_playernullV2,
V3e, V3h비암호화 컨텐츠의 경우에도 데스크탑 전용 플레이어를 강제 사용하도록 설정. (모바일은 지원하지 않음.)uservalue0~9mixedAll고객사가 원하는대로 uservalue0부터 9까지 값을 설정하여 사용함.brightnessintegerV2기본 밝기 값을 설정. 값의 범위는 -50 <= brightness <= 50임. default는 0contrastintegerV2기본 대비 값을 설정. 값의 범위는 -50 <= contrast <= 50임. default는 0saturationintegerV2기본 색조 값을 설정. 값의 범위는 -50 <= saturation <= 50임. default는 0mobile_return_urlstringiOS재생 중 뒤로가기 버튼을 누르거나 재생 종료시에 지정한 url을 safari web browser로 오픈.mobile_folder_downloadstringMobile모바일 다운로드시 지정할 폴더명을 입력한다.
예> 폴더1/폴더2/폴더3wmodestringFlash데스크탑의 경우 Flash player의 wmode를 강제로 지정한다. 지정하지 않은 경우는 ‘direct’ 사용.
wmode는 다음의 값 가운데서 하나를 지정할 수 있다.
예> direct, transparent, window, opaque, gpupc_player_versionstringDesktop데스크탑에서 Player2.0 ~ 3.0 버전을 사용하도록 선택한다. 지정하지 않을 경우는 환경에 맞는 플레이어가 자동으로 실행된다.다음의 값 가운데서 하나만 지정할 수 있다.
가능한 옵션> v2, v3, v3e \
* v3e를 지정할 경우엔 v3 전용 플레이어가 호출된다.
* 호환성 이슈로 유지. 신규 사용자는 player_version 옵션을 사용하는 것을 권장한다.player_versionstringDesktop데스크탑에서 Player2.0 ~ 4.0 버전을 사용하도록 선택한다. 지정하지 않을 경우는 환경에 맞는 플레이어가 자동으로 실행된다.다음의 값 가운데서 하나만 지정할 수 있다.가능한 옵션> v2, v3, v3e, html5* v3e를 지정할 경우엔 v3 전용 플레이어가 호출된다.pc_folder_downloadstringV2, V3e, V3hPC 다운로드시 지정할 폴더명을 입력한다. (모바일과 형식은 동일)play_downloaded_filenullV3e, V3h다운로드된 파일을 재생한다.bufferintegerV2, V3e, V3h기본 버퍼링 값을 무시하고 지정한 값만큼 버퍼링을 수행한다. 2 <= buffer <= 10 사이의 정수만 유효하며, 해당 값은 기본 버퍼링 값의 배수로 작용한다.예> 2 -> 기본 버퍼링값의 2배show_controls_pausedbooleanFlash, V4값이 true이면 일시정지 상태일 경우 inactive 상태가 되었을 때 controlbar와 overlay button을 계속 보여줌. (Default : false)show_poster_endedbooleanFlash, V4값이 true이면 컨텐츠 재생이 끝난 후 포스터를 보여준다. (Default : false)overlay_button_positionstringFlash, V4Overlay button의 위치값을 설정한다.
- TR : Top & Right
- TL : Top & Left
- BR : Bottom & Right
- BL : Bottom & Left
해당 옵션이 설정되지 않거나 위 4개의 값 외의 다른 문자열이 오면 가운데 정렬되어 보여진다.

샘플코드

V/G Query String – java

Upload

FTP

  • Kollus FTP 접속 정보 확인

    1. 웹 브라우저에서 Kollus 관리 페이지에 접속합니다.
    2. 로그인 계정 정보를 입력하여 로그인합니다.
    3. '파일 업로드 하기' 선택하여 '파일 업로드' 페이지를 엽니다
    4. FTP 접속 정보를 확인합니다

    Image Removed

  • FTP 프로그램 실행

    FTP 프로그램이 있다면 '3) FTP 접속' 세션으로 이동하세요. 만약 기존에 이용중인 FTP 프로그램이 있으시다면 기존 프로그램을 통하여 업로드 할 수 있습니다. 다만, FTP 업로드 가이드 문서는 'Filezilla' 프로그램을 기준으로 작성하여 문서에 명시한 명칭은 FTP 프로그램 마다 다를 수 있음을 감안해주시길 바랍니다

    1. Filezilla 다운로드 웹 사이트에 접속합니다
    2. Filezilla 다운로드 후 설치합니다
    3. Filezilla 프로그램을 실행합니다
  • FTP 접속

    Kollus FTP 접속 정보를 입력하여 접속합니다

    1. 호스트: FTP
    2. 사용자명: 아이디
    3. 패스워드: 패스워드

    Image Removed

  • 비디오 업로드

    FTP 프로그램을 통한 파일 업로드 시에는 '파일 암호화', '카테고리 등록', '패스쓰루'에 따라 사전에 약속된 업로드 폴더 규칙이 있습니다

    4-1. 일반/암호화 파일 업로드

    파일 방식에 따라 '일반 업로드'와 '암호화 업로드'2가지를 지원하며, 파일 방식에 맞게 사전에 정해진 규칙에 맞게 폴더를 생성하여 파일을 업로드 하셔야 합니다. '일반 업로드는 파일을 암호화하지 않은 표준 형태로 업로드하며, '암호화 업로드'는 파일을 암호화하여 업로드 합니다

    파일 보안FTP 폴더 경로일반/_카테고리암호화/_encrypt/_카테고리

    서비스 계정에 SecurityPack이 적용되어 있지 않은 경우에는 '암호화 업로드' 지원하지 않습니다

    4-2. 카테고리 등록

    Kollus 관리 페이지에서 생성한 카테고리에 파일을 등록하기 위해서는 사전에 정해진 규칙으로 폴더를 만들어 생성한 폴더에 파일을 업로드 함으로써 원하는 카테고리에 파일을 등록할 수 있습니다

    카테고리 구조FTP 폴더 경로(1depth) 카테고리1/_카테고리1(2depth) 카테고리1
    └ 카테고리2/_카테고리1/_카테고리2(3depth) 카테고리1
    └ 카테고리2
    └ 카테고리3/_카테고리1/_카테고리2/_카테고리3

    Kollus 관리 페이지에 2016- 뮤직비디오 - 빅뱅 3depth 구조로 생성한 카테고리 중 '빅뱅' 카테고리에 FTP로 '일반 업로드'하는 경우 /-2016/-뮤직비디오/-빅뱅 폴더를 생성하여 파일을 업로드 하면 됩니다

    • Kollus 관리 페이지 생성한 카테고리(명)와 일치하지 않는 폴더(명)를 생성하여 파일을 업로드 하는 경우, 일치하지 않는 폴더 명을 카테고리로 신규 생성하여 파일을 등록합니다

    • 카테고리는 최대 3depth까지 생성할 수 있습니다

    4-3. 패쓰쓰루

    파일을 트랜스코딩 하지 않고 원본 그대로 업로드 업로드 하기 위한 방법입니다. 트랜스코딩 작업 없이 동영상의 '포스터 이미재와 '썸네일 이미지'만 추출하여 등록 합니다. '일반 업로드와 '암호화 업로드'에 따란 사전에 정해진 폴더 규칙에 맞게 폴더를 생성하여 파일을 업로드 하셔야 합니다

    파일보안FTP 폴더 경로패스쓰루 일반 업로드/_passthrough/_카테고리패스쓰루 암호화 업로드/_passthrough_encrypt/_카테고리
    • 서비스 계정에 SecurityPack이 적용되어 있지 않은 경우에는 '암호화 업로드' 지원하지 않습니다
    • 패스쓰루 업로드를 이용하기 위해서는 아래의 조건을 충족해야 합니다.
      • 'MP4' 확장자에 'H.264' 포멧인 원본 파일
      • 원본 파일명에 '인코딩 프로파일 키' 반영
      • 서비스 계정에 '원본 백업' 비 활성화

    원본 파일명 '인코딩 프로파일 키' 반영

    반영 다양한 화질의 원본 파일을 트랜스코딩 없이 그대로 서비스하는 경우 복수 원본 파일을 하나의 콘텐츠로 인식하고 원본 파일 화질에 맞게 프로파일을 지정하기 위해 Kollus 관리 페이지에 '인코딩 프로파일 키' 확인하여 원본 파일명에 반영해야 합니다

    원본 파일명인코딩 프로파일 키 반영A.mp4A_인코딩프로파일키.mp4

    '인코딩 프로파일 키'는 Kollus 관리 페이지 설정 - 인코딩 프로파일 페이지에서 확인할 수 있습니다.

    Image Removed

    Upload API

    개요

    Kollus HTTP 업로드 Endpoint는 고객사가 업로드를 원하는 시점에 Kollus Open API의 일회성 업로드 URL 발급 API를 호출하여 획득한 업로드 URL로 HTTP multipart/form-data 형식으로 파일을 업로드하여, 이후 과정 (트랜스코딩) 을 진행토록 합니다.

    Use case scenario

          Image Removed

    1. 사용자가 고객사의 Web 사이트에서 동영상 파일을 업로드 하기 위해 특정 페이지를 요청합니다.
    2. 고객사 업로드 페이지에서 사용자에게 업로드 경로를 반환하기 위해 Kollus Api를 이용해 업로드 URL 생성을 요청합니다.
    3. 업로드 URL 생성 요청에 대한 반환으로 업로드 URL과 업로드 파일키(Upload file key), 키 만료시간 정보등을 획득합니다.
    4. 3에서 반환 받은 업로드 URL 정보를 기반으로 고객에게 보여지는 업로드 페이지를 생성합니다.
    5. 고객사의 업로드 페이지에서 업로드를 하면 실제 업로드는 고객사의 웹사이트가 아닌 Kollus 업로드 서버로 직접 전송하게 됩니다.

    유의사항

    HTTP 프로토콜을 이용한 업로드를 지원하기 위해 사용자에게 업로드에 필요한 정보를 생성하는 API를 제공합니다. HTTP Upload API는 아래와 같은 특성을 갖습니다.

    • 생성된 업로드 URL, 업로드 파일키는 일회용입니다.
    • 생성된 업로드 파일키는 지정된 시간 이후 자동 폐기됩니다.

    요청규격

    업로드 URL 발급 요청시에는 다음과 같은 파라미터를 설정할 수 있습니다. Request는 Kollus API 정책에 따라 HTTP(80), POST만 지원합니다.

    POST keyData type기본값비고expire_timeinteger600 (초)값의 범위는 0 < expire_time <= 21600 입니다. 빈값을 보내거나 항목 자체를 제거하면 기본 600초로 설정됩니다.category_keystring(없음)업로드한 파일이 속할 카테고리의 키입니다. 빈값을 보내거나 항목 자체를 제거하면 ‘없음’에 속합니다.titlestring(없음)입력한 제목을 컨텐츠의 제목으로 강제지정합니다. 이 값을 보내지 않거나 빈 값으로 보내면 기본적으로 파일명이 제목으로 사용됩니다.is_encryption_uploadinteger0 (일반)0은 일반 업로드, 1은 암호화 업로드입니다. 암호화 업로드시 파일이 암호화 되어 Kollus의 전용 플레이어로만 재생됩니다. Security-pack이 적용되지 않은 서비스 계정에서 이 값을 1로 지정하여 요청한 경우는 업로드 URL 생성이 실패합니다.is_audio_uploadinteger0 (비디오)0은 비디오 업로드, 1은 음원 파일 업로드 입니다.is_multipart_uploadinteger0 (일반)파일의 분할 업로드를 지원하기 위한 값입니다. 추후 제공될 기능이며, 현재는 동작하지 않습니다.

    응답규격

    JSON / UTF-8 으로 결과를 반환 합니다.

    (# upload_url에 사용되는 도메인 정보를 포함한 모든 정보는 Kollus 시스템 정책에 의해 변경될 수 있습니다.)

    Code Block
    languagejs
    themeMidnight
    Sample
    {
        "error": 0,
        "message": "",
        "result": {
            "upload_url": "http: //upload.kr.kollus.com/api/v1/UploadMultiParts/KUS_BOHG2eTQhPSIaG2511G1jfkpWOYAOjDc/20151204-dh6o2goz",
            “progress_url”: “http: //upload.kr.kollus.com/api/v1/GetUploadingProgress/KUS_BOHG2eTQhPSIaG2511G1jfkpWOYAOjDc”,
            "upload_file_key": "20141017-y4sae7td",
            "will_be_expired_at": 1413883670
        }
    }
            

    JSON Structure Description

    • error : 에러코드, 0이면 정상
    • message : 에러의 경우 상세 설명이 포함됩니다.
    • result : 정상인 경우 업로드 API 호출 결과를 포함 합니다.
      • upload_url : 업로드할 URL (HTTP)
      • progress_url : 업로드 진행률을 획득할 수 있는 URL (HTTP)
      • upload_file_key : 업로드 파일키
      • will_be_expired_at : upload_file_key 만료 시간 (unix timestamp)

    파일업로드

    업로드 URL 발급요청 API를 통해 획득한 업로드 URL(upload_url)이 실제 파일을 전송할 업로드 서버의 주소입니다. 이 주소에 대해 HTML multipart/form-data 형식으로 파일을 전송해야 합니다.

    유의사항

    • 전송할 파일의 input name은 upload-file입니다.
    • 하나의 업로드 URL은 하나의 파일에 대응합니다. (하나의 업로드 URL로 하나 이상의 파일을 전송하려 시도할 경우 뒤에 업로드하는 파일의 업로드는 실패합니다.)
    • 업로드는 업로드 URL의 만료시간 전까지 완료되어야 합니다. 만료시간 판단은 업로드 시작 시점이 아니라 종료 시점에 판단합니다.

    업로드 옵션

    POST keyData type기본값비고return_urlstring(없음)return_url이 주어지면 업로드 종료 후 해당 url로 redirect 합니다. 이때, result와 message값을 추가합니다.예> http://foo.com/result.html?result=S&message=...disable_alertinteger0기본적으로는 업로드 종료시 결과 메세지를 alert로 뿌려주도록 되어 있으나, 이 기능을 사용하지 않으려면 disable_alert값을 1로 하여 전송해주십시요.redirection_scopestring‘outer’업로드 완료 후 redirect할 domain scope를 지정합니다. 이 옵션은 다음의 값 가운데 하나를 가질 수 있습니다.acceptstringRequest Header 가운데 Accept의 값업로드 완료 후 전달받을 결과의 컨텐츠 타입을 지정합니다. 빈값으로 두면 text/html 방식으로 전달합니다. 이 경우는 return_url, disable_alert, redirection_scope 옵션들을 적용하여 생성된 html 페이지가 결과로 리턴됩니다. 이 값을 ‘application/json’ 형식으로 지정하면 위 세가지 옵션은 무시되며, 결과가 JSON 형식으로 리턴됩니다.

    RETURN URL

    • result는 S와 F 두 값을 갖습니다. S는 업로드 성공을, F는 실패를 의미합니다.
    • message는 업로드 결과를 안내하는 메세지입니다. (alert창으로 보여지는 메세지와 같습니다.)

    Sample

    Code Block
    languagejs
    themeMidnight
    <form action="http: //upload.kr.kollus.com/20141017-y4sae7td" method="post" enctype="multipart/form-data">
         <!-- redirect scope 설정 -->
         <input type=”hidden” name=”redirection_scope” value=”outer” />
    
         <!-- 업로드 종료시 redirect할 url 설정 -->
         <input type=”hidden” name=”return_url” value=”http://www.lotte.com/upload_result.html” />
    
         <!-- 업로드 종료시 alert창을 띄우지 않도록 설정 (1) -->
         <input type=”hidden” name=”disable_alert” value=”1” />
    
         <input type=”file” name=”upload-file” />
         <input type=”submit” />
    </form>

    업로드 진행률

    업로드 URL 생성 API 호출을 통해 획득한 결과 가운데 progress_url 엔트리를 참조하여 업로드 진행률을 획득합니다. (JSON 형식)

    응답규격

    JSON / UTF-8 으로 결과를 반환 합니다.

    Sample

    Code Block
    languagejs
    themeMidnight
    {
        "error": 0,
        "message": null,
        "result": {
            "progress": 100
        }
    }
    
    

    샘플코드

    Upload API – ruby

    Upload API – jquery

    Upload API – php

    Upload API – java

    기본 Callback

    개요

    Kollus 서비스를 이용 중 진행 상황은 직접 CMS를 통해서 확인할 수 있습니다. 다만, 편의를 위해 각 진행 상황마다 사전에 설정된 고객사의 Web URL로 진행 상황을 전송하고 있습니다. 이것을 Kollus Callback 서비스라고 부릅니다. 또한, 고객사의 Web URL로 Callback 전송이 실패했을 때 재시도합니다. 각 재시도 마다 내부적으로 로그를 기록하여 모든 재시도가 실패할 때에는 문제가 된 Callback 전송의 원인을 파악하고 정상적으로 Callback을 전송할 수 있도록 하고 있습니다. 본 문서는 Callback 전송과 재시도에 관한 Kollus Callback 전송서버의 처리 과정에 대해서 설명합니다.

    Callback 설정

    Callback 설정은 채널과 관련된 부분의 설정은 관리자 권한을 가진 사용자가 해당 채널의 운영정책 설정 화면에서 지정할 수 있으며, 기타 Callback은 Kollus 서비스 담당자에게 설정을 요청하여야 합니다.

    채널 Callback 설정 (채널 컨텐츠 추가, 삭제)

  • 상위 메뉴에서 채널을 선택합니다.

    Image Removed

  • 생선된 채널의 속성 수정을 선택합니다.

  • 채널 속성 편집화면에서 채널 운영 정책을 선택합니다.

    Image Removed

  • 콜백 사용을 “활성화” 합니다.

    Image Removed

  • 필요한 채널 콜백을 등록합니다.

    Image Removed

  • 기타 Callback 설정 (업로드 완료, 트랜스코딩 완료, 컨텐츠 업데이트)

    Kollus 서비스 담당자에게 별도 요청해 주십시오.

    Callback 전송 처리

    전송방법

    1. 모든 Callback은 고객사가 설정한 Web URL의 80번 포트로 POST 방식을 사용하여 전달합니다.
    2. 모든 Callback은 전송 시점이 되면 즉시 전달하는 것을 원칙으로 합니다. (다만, Callback을 처리하는 서버의 상황이 몹시 분주한 경우 지연될 수 있습니다.)
    3. 고객사 웹서버는 Callback을 성공적으로 전달 받았을 경우 200 HTTP Status Code로 응답해야 합니다. 이때 HTTP body 부분은 확인하지 않습니다. (200이 아닌 코드로 응답할 경우 전송 실패로 간주하고 지정된 시간 후에 재시도 합니다.)

    유의사항

    고객사 서버는 Kollus의 Callback 전송 요청에 대해 2초 이내 연결이 수립되어야 하며, 연결이 수립된 이후 3초 내에 응답해야 합니다. 이 시간 내에 연결이 수립되지 않거나 응답하지 않는다면, Kollus Callback 전송서버는 전송 실패로 간주하고 지정된 시간 후에 재시도 합니다. (Connect Time­out 2초, Response Time­out 3초)

    시나리오

    Callback 전송 재시도 처리

    전송방법

    1. 기본적인 전송 방법은 “Callback 전송 처리” 항목과 동일합니다.
    2. 재시도는 5분 간격으로 최대 3번까지 시도합니다.

    유의사항

    고객사 서버는 Kollus의 Callback을 정상 처리했다고 간주하여 200 HTTP Status Code로 응답했다고 하여도, Connect/Response Time­out을 넘겨서 이미 Kollus Callback 전송 서버가 요청을 실패로 처리하였다면, Callback 요청이 재시도될 수 있습니다. 즉, Time­out으로 인한 동일한 Callback이 요청될 수 있으니 Callback URL 개발시 대비해야 합니다.

    시나리오

    Callback 전송 파라미터

    업로드 완료 Callback

    POSTData type비고content_provider_keystring고객사의 서비스 계정 키 입니다.filenamestring폴더를 포함한 업로드된 파일명입니다.upload_file_keystring업로드 파일 키

    트랜스코딩 완료 Callback

    POSTData type비고
    content_provider_keystring고객사의 서비스 계정 키 입니다.
    filenamestring폴더를 포함한 업로드된 파일명입니다.
    upload_file_keystring업로드 파일 키
    transcoding_resultstring트랜스코딩 결과 (success, fail)

    채널 컨텐츠 추가 완료 Callback

    POSTData type비고content_provider_keystring고객사의 서비스 계정 키 입니다.filenamestring폴더를 포함한 업로드 된 파일명입니다.upload_file_keystring업로드 파일 키media_content_keystring미디어 컨텐츠 키. 동영상 재생을 위해 채널에 할당된 컨텐츠를 식별하기 위한 키.channel_keystring콘텐츠가 할당된 채널의 식별 키channel_namestring콘텐츠가 할당된 채널의 이름profile_keystring콘텐츠가 트랜스코딩된 프로파일 명. 하나 이상일 경우는 ‘|’를 구분자로 하여 표현합니다.update_typestring업데이트 종류

    채널 컨텐츠 삭제 완료 Callback

    POSTData type비고content_provider_keystring고객사의 서비스 계정 키 입니다.filenamestring폴더를 포함한 업로드 된 파일명입니다.upload_file_keystring업로드 파일 키media_content_keystring미디어 컨텐츠 키. 동영상 재생을 위해 채널에 할당된 컨텐츠를 식별하기 위한 키.channel_keystring콘텐츠가 할당된 채널의 식별 키channel_namestring콘텐츠가 할당된 채널의 이름update_typestring업데이트 종류

    컨텐츠 업데이트 Callback

    POSTData type비고content_provider_keystring고객사의 서비스 계정 키 입니다.filenamestring폴더를 포함한 업로드 된 파일명입니다.upload_file_keystring업로드 파일 키update_typestring업데이트 정류

    Player Callback

    Play

    개요

    Kollus 전용플레이어에서 재생을 할때 고객사에서 정의한 URL을 호출(Callback)하는 기능을 정의한 문서입니다.

    Expire option

    설정 항목의 data-type이나 값이 범위를 벗어나는 경우 컨텐츠 이용에 문제가 발생할 수 있으며, 잘못된 설정 값에 대한 사용 제한을 회수하는 방법은 존재하지 않습니다.

    • Expire date : 컨텐츠 만료 시간

      • data-type : integer, unixtime stamp

      • 컨텐츠 재생이 만료될 시간

        • 컨텐츠 재생이 만료될 시간

          ex) 2014. 3. 3. 5시 45분 30초 GMT → 1393825531

        • 0 : unlimited (무제한)

        • 최대값 : 2029년 12월 31일 23시 59분 59초 (1893455999)

    Play callback

    Play callback(이하 콜백)을 사용하기 위해서는 CMS의 관리 화면에서 관리자 이상의 권한을 소유한 로그인 계정으로 채널 속성에 Play 콜백 항목에 고객사에서 콜백을 응답받기 위해 정의된 URL을 등록하셔야 합니다.

    Play 콜백이 정의되지 않은 채널은 콜백의 응답과 관계없이 재생을 진행합니다. 콜백이 정의된 채널을 통해 서비스되는 콘텐츠는 콜백에 대한 응답을 확인 후 재생하기 때문에 고객사에서 정의한 콜백 URL은 항상 응답상태를 유지하셔야 원활한 서비스를 받으실 수 있습니다.

    주의:

    1. 고객사의 회원 아이디를 포함한 미디어 토큰(Media token)을 생성하여 요청된 경우에 Play 콜백이 호출됩니다. (미디어 토큰 생성은 별도 문서를 참고해 주십시오.)
    2. Play 콜백 URL이 응답하지 않으면 재생 되지 않습니다.
    3. Play 콜백은 다운로드된 콘텐츠에 대한 DRM 콜백과 다르게 동작합니다. 다운로드된 콘텐츠는 Play 콜백이 아닌 DRM 콜백으로 동작하게 됩니다. 필요에 따라 Play 콜백과 DRM 콜백 URL을 동일하게 등록하면 다운로드와 스트리밍시에 재생에 대한 응답을 동일하게 받으실 수 있습니다.

    Callback flow

    Image Removed

    1. 채널에 Play 콜백 URL을 설정합니다.

      • ex> http://www.foo.com/auth.php 가 고객사 Play 콜백 서버인 경우
    2. Media token을 생성하여 다운로드를 요청합니다.

      • Kollus crypt SDK를 이용해 Media token을 생성합니다.
    3. Kollus mobile player가 http://www.foo.com/auth.php 에 다음의 정보를 POST 전송 합니다.

      • kind : 1, 3
      • client_user_id : 고객사 회원 아이디
        • Media token 생성시 포함된 아이디입니다.
      • player_id : 고객사 회원이 가지고 있는 단말 아이디
      • device_name : 고객사 회원이 가지고 있는 단말명
      • media_content_key : 현재 재생하려는 콘텐츠 key 입니다.
        • 채널에 등록된 컨텐츠에 부여된 고유 키입니다.
        • 업로드된 컨텐츠를 여러채널에 등록하면 media_content_key는 모두 다르게 생성됩니다.
    4. 고객사 Play 콜백 서버는 전달 받은 위 정보를 바탕으로 다음의 json 포멧의 data를 아래의 방식 중에서 하나로 Http Body에 전송합니다.

      (고객사가 인증 정보를 플레이어로 전달할 때 모든 데이터의 자료형은 반드시 기술된대로 integer 형이여야만 합니다.)

      • 지원하는 방식
        • Kollus crypt SDK를 이용해 암호화하여 전송합니다.
        • JWT Encode하여 전송합니다. 알고리즘은 HS256만 지원하며 secret키는 콜백 요청 시 넘겨주는 custom_key파라미터 값을 사용합니다.

    Response JSON spec.

    Json TagDescriptionexpiration_dateunixtime stamp (만료될 시간의 unixtime stamp)
    최대값 : 2029년 12월 31일 23시 59분 59초 (1893455999)result반환 결과가 정상인 경우 1, 비정상인 경우 0을 반환하도록 합니다.content_expiredDRM 컨텐츠를 강제로 expire 시킵니다.

    Callback Kind

    Play 콜백이 호출되는 상황은 아래 3가지 경우입니다.

    콘텐츠의 Expire 정보를 요청하는 경우 (kind:1)

    Request
    구분DescriptionPOSTHttp POST로 요청합니다. (parameter가 아닙니다.)kind1client_user_id고객사 사용자 ID, media_token 생성시 사용된 client_user_id와 동일합니다.player_id고객사 사용자가 가지고 있는 단말의 아이디hardware_id단말의 hardware 아이디(PC, 입력값이 있으면)device_name고객사 사용자가 가지고 있는 단말의 모델명media_content_keyKollus 컨텐츠 unique keyuservaluesJSON format (VideoGateway 호출시 사용된 uservalue0~9)
    • uservalues sample
      • uservalues={"uservalue0":"강의코드01","uservalue1":"상품코드02","uservalue9":" 생성코드03"}
      • VideoGateway(v.kr.kollus.com)호출시 사용된 uservalue0~9 정보를 함께 전달 받습니다.
    Response
    카테고리구분DescriptionData(int) expiration_date만료될 시간의 unixtime stamp
    최대값 : 2029년 12월 31일 23시 59분 59초 (1893455999)(int) result0 (비정상), 1 (정상)(string) message0 (비정상)의 경우 message를 추가하면 상황에 따른 메시지가 표시됩니다.(int) vmcheck0 (사용안함), 1 (사용함, default) virtural machine 체크 여부, PC(v3)용에서만 사용 가능(array)
    play_section{
    start_time,
    end_time
    }미리 보기 구간 초로 구분(end_time이 start_time 보다 커야 한다)(int) disable_tvout0 (tvout 차단 안함), 1 (tvout 차단) 이 항목이 없으면 채널에 있는 disable_tvout정책이 적용됩니다.(int)
    expiration_playtime이 항목이 없거나 0이면 재생 시간을 사용하지 않고 0보다 크면 해당 값의 초만큼만 재생 후 종료합니다.exp(int)사용 가능 시간 unixtime stamp(옵션)
    Example
    Code Block
    languagejs
    themeMidnight
    {
        “data” : {
            "expiration_date": 1402444800,
            "vmcheck": 1,
            "play_section": [
                “start_time”: 0,
                “end_time” : 60
            ],
            "disable_tvout": 1,
            "expiration_playtime": 1800,
            "result": 1
        },
        “exp” : 1477558242
    }
    
    

    콘텐츠를 재생하는 경우 (kind:3)

    주의) 콘텐츠 재생을 위해 반드시 응답해야 합니다. Play 콜백에 대한 응답을 확인 후에 재생을 시작합니다.

    Request
    구분Description
    POSTHttp POST로 요청합니다. (parameter가 아닙니다.)
    kind3
    client_user_id고객사 사용자 ID, media_token 생성시 사용된 client_user_id와 동일합니다.
    player_id고객사 사용자가 가지고 있는 단말의 아이디
    device_name고객사 사용자가 가지고 있는 단말의 모델명
    media_content_keyKollus 컨텐츠 unique key
    uservaluesJSON format (VideoGateway 호출시 사용된 uservalue0~9)
    Response
    카테고리구분Descriptiondata(int) content_expired0 (재생가능), 1 (재생 제한)
    재생을 차단합니다. DRM 콜백과 동일한 스펙 유지를 위해 동일한 항목으로 유지됩니다.(int) result0 (비정상), 1 (정상)
    0 인 경우 재생되지 않습니다. 이때 conent_expired가 1이어도 expire가 수행되지 않습니다.(string) message0 (비정상)의 경우나 content_expired이 1(재생 제한)의 경우 message를 추가하면 상황에 따른 메시지가 표시됩니다.exp(int) expiration_date사용 가능 시간 unixtime stamp(옵션)
    최대값 : 2029년 12월 31일 23시 59분 59초 (1893455999)
    Example
    Code Block
    languagejs
    themeMidnight
    {
        “data” : {
            "content_expired": 1,
            "result": 1
        },
        "exp" : 1477558242
    }
    Sample
    • Play callback url
      • http://www.foo.com/auth.php
    • 컨텐츠 만료 시간 : 2014년 6월 10일 자정 종료
      • DATE (M/D/Y @ h : m : s): 6 / 10 / 2014 @ 24:0:0 UTC
      • Unix time stamp : 1402444800
      • http://www.epochconverter.com 를 이용해 1402444800 값을 변경해 볼 수 있습니다. GMT가 아닌 UTC입니다.
    kind1 : request expire option
    request
    • URL : http://www.foo.com/auth.php

    • post data

      • kind=1

      • client_user_id=guest1

      • media_content_key=VXBW1VdY

      • uservalues={"uservalue0":"강의코드01","uservalue1":"상품코드02","uservalue9":" 생성코드03"}

    response
    Code Block
    languagejs
    themeMidnight
    {
        “data” : {
            "expiration_date": 1402444800,
            "result": 1
        },
        "exp" : 1477558242
    }
    
    
    kind3 : play content (expire content)
    request
    • URL : http://www.foo.com/auth.php
    • post data
      • kind=3
      • client_user_id=guest1
      • media_content_key=VXBW1VdY
      • uservalues={"uservalue0":"강의코드01","uservalue1":"상품코드02","uservalue9":" 생성코드03"}
    response
    Code Block
    languagejs
    themeMidnight
    {
        “data” : {
            "content_expired": 1,
            "result": 1
        },
        "exp" : 1477558242
    }
    
    

    Code sample

    다음과 같은 고객사의 DB가 구성된 것으로 고려되어 샘플이 구성되어있습니다.

    PHP sample
    Code Block
    languagejs
    themeMidnight
    <?php
        /**
        * PHP Version : 5.4 above
        * by yupmin
        */
        include "./config.php";
        
        // 주의 : kind가 1일때 자동으로 expiration_date가 생성되는 샘플 페이지입니다.
        // 재생 제한 횟수
        $_default_expiration_count = 3;
        $_expired_duration = 60 * 60 * 24; // 1 day
        // DB Connection
        $_db_conn = mysql_connect($_hostname, $_username, $_password);
        if (!$_db_conn) {
       		die('Could not connect: ' . mysql_error());
        }
        $_db_selected = mysql_select_db($_database, $_db_conn);
        if (!$_db_selected) {
        	die ('Can\'t use database : ' . mysql_error());
        }
        $_kind = isset($_POST['kind']) ? ((int) $_POST['kind']) : NULL;
        $_media_content_key = isset($_POST['media_content_key']) ? $_POST['media_content_key'] : 		NULL;
        $_client_user_id = isset($_POST['client_user_id']) ? $_POST['client_user_id'] : NULL;
        
        $channel = NULL;
        $_query = sprintf("SELECT * FROM `channels` WHERE `media_content_key` = '%s'",
       		mysql_real_escape_string($_media_content_key, $_db_conn));
        $_result = mysql_query($_query, $_db_conn);
        if ($_result) {
       		$channel = mysql_fetch_array($_result, MYSQL_ASSOC);
        	if ($channel === FALSE) $channel = NULL;
        } else {
        	die('Invalid query: ' . mysql_error());
        }
        
        $user = NULL;
        $_query = sprintf("SELECT * FROM `users` WHERE `client_user_id` = '%s'",
        	mysql_real_escape_string($_client_user_id, $_db_conn));
        $_result = mysql_query($_query, $_db_conn);
        if ($_result) {
        	$channel = mysql_fetch_array($_result, MYSQL_ASSOC);
        	if ($channel === FALSE) $channel = NULL;
        } else {
        	die('Invalid query: ' . mysql_error());
        }
        
        $channel_user = NULL;
        if (!is_null($_media_content_key) && !is_null($_client_user_id)) {
        	$_query = sprintf("SELECT * FROM `channel_users` WHERE `user_id` = '%s', `channel_id` = 			'%s'",
        	$user['id'], $channel['id']);
        	$_result = mysql_query($_query, $_db_conn);
            if ($_result) {
            	$channel_user = mysql_fetch_array($_result, MYSQL_ASSOC);
                if ($channel_user === FALSE) $channel_user = NULL;
            } else {
            	die('Invalid query: ' . mysql_error());
            }
       	}
        $_json_result = array('result' => 0);
        switch($_kind) {
        case 1:
            if (is_null($channel_user)){
                $_expiration_date = time() + $_expired_duration;
                $_expiration_count = $_default_expiration_count;
                $_query = sprintf("INSERT INTO `channel_users`(`user_id`, `channel_id`, 						`expiration_date`
                    ,`expiration_count` , `created_at`, `updated_at`) VALUES('%s', '%s', '%s', '%s', 			 UNIX_TIMESTAMP(),
                    UNIX_TIMESTAMP())", $user['id'], $channel['id'], $_expiration_date, 						$_expiration_count);
    
                $_result = mysql_query($_query, $_db_conn);
                 if (!$_result) {
                    die('Invalid query: ' . mysql_error());
                }
            } else {
                $_expiration_date = $channel_user['expiration_date'];
                $_expiration_count = $channel_user['$expiration_count'];
            }
            $_json_result['expiration_date'] = (int) $_expiration_date;
            $_json_result['expiration_count'] = (int) $_expiration_count;
            break;
        case 3:
        	if (!is_null($channel_user) && $channel_user['is_expired']) {
        		$_json_result['content_expired'] = 1;
        	}
        	break;
        }
        
        // DB Close
        mysql_close($_db_conn);
        
        // json_encode된 결과를 kollus_encrypt를 통해 암호화시킴
        echo kollus_encrypt(json_encode($_json_encode));
    }
    
    
    JSP ​sample
    Code Block
    languagejs
    themeMidnight
    <%@page import="org.codehaus.jettison.json.JSONObject"%>
    <%@page import="java.util.Locale"%>
    <%@page import="java.util.Date"%>
    <%@page import="java.text.SimpleDateFormat"%>
    <%@page import="java.util.ArrayList"%>
    <%@page import="org.codehaus.jackson.map.ObjectMapper"%>
    <%@page import="java.util.HashMap"%>
    <%@page import="java.sql.*"%>
    <%@ page import="test.*"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%
        String kind_str = request.getParameter("kind");
        String media_content_key = request.getParameter("media_content_key");
        String client_user_id = request.getParameter("client_user_id");
        int kind = Integer.parseInt(kind_str);
        int _default_expiration_count = 3;
        int _expired_duration = 60 * 60 * 24; //one day
        int channel_id = 0;
        int user_id = 0;
        int channel_user_id = 0;
        int expiration_count = 0;
        int is_expired = 0;
        int download_times = 0;
    
        Long expiration_date = 0l;
        Connection conn = null; // null로 초기화 한다.
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        JSONObject jsonobj = new JSONObject();
    	try {
            String url = "jdbc:mysql://localcost:3306/kollus_base";
            String id = "test"; // 사용자 계정
            String pw = "test"; // 사용자 계정의 패스워드
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            conn = DriverManager.getConnection(url, id, pw);
            String sql = "SELECT * FROM `channels` WHERE `media_content_key` = ? ";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1,media_content_key);
            rs = pstmt.executeQuery();
    		while(rs.next()){
    			channel_id = rs.getInt("id");
    		}
            rs.close();
            pstmt.close();
            sql = "SELECT * FROM `users` WHERE `client_user_id` = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1,client_user_id);
            rs = pstmt.executeQuery();
            while(rs.next()){
            	user_id = rs.getInt("id");
            }
    		rs.close();
    		pstmt.close();
    		if (channel_id > 0 && user_id > 0) {
                sql = "SELECT * FROM `channel_users` WHERE `user_id` = ?, `channel_id` = ? ";
                pstmt = conn.prepareStatement(sql);
                pstmt.setInt(1, channel_id);
                pstmt.setInt(2, user_id);
                rs = pstmt.executeQuery();
    		   while(rs.next()){
                    channel_user_id = rs.getInt("id");
                    expiration_date = rs.getLong("expiration_date");
                    expiration_count = rs.getInt("expiration_date");
                    is_expired = rs.getInt("is_expired");
                    download_times = rs.getInt("download_times");
    	       }	
               rs.close();
               pstmt.close();
    	    }
    		jsonobj.put("result", "0");
            switch(kind) {
                case 1:
                    if (channel_user_id == 0) {
                        Long starttime = System.currentTimeMillis()/1000;
                        expiration_date = starttime + _expired_duration;
                        expiration_count = _default_expiration_count;
                        sql = "INSERT INTO `channel_users`(`user_id`, `channel_id`,
                        `expiration_date` ,`expiration_count` , `created_at`, `updated_at`) VALUES 						(?,?,?,?,?,?)"; // sql 쿼리
                        pstmt = conn.prepareStatement(sql); // prepareStatement에서 해당 sql을 미리 컴파일한다.
    
                        pstmt.setInt(1, user_id);
                        pstmt.setInt(2, channel_id);
                        pstmt.setLong(3, expiration_date);
                        pstmt.setInt(4, expiration_count);
                        pstmt.setLong(5, starttime); // 현재 날짜와 시간
                        pstmt.setLong(6, starttime); // 현재 날짜와 시간
                        pstmt.executeUpdate();
                        pstmt.close();
                     }
                     jsonobj.put("expiration_date", expiration_date);
                     jsonobj.put("expiration_count", expiration_count);
                     break;
                case 3:
                     if (channel_user_id > 0 && is_expired > 0) {
                        jsonobj.put("expiration_date", expiration_date);
                    }
            }
    		break;
    		conn.close();
    	} catch (Exception e) { // 예외가 발생하면 예외 상황을 처리한다.
    		e.printStackTrace();
    	}
    	String sendMsg = jsonobj.toString();
    	// System.out.println(sendMsg);
    %>
    <%= kollus_encrypt(sendMsg)%>
    
    

    샘플코드

    https://github.com/kollus-service/kollus-playcallback-dotnet

    https://github.com/kollus-service/kollus-samples-jsp

    https://github.com/kollus-service/kollus-drm-callback-php

    https://github.com/kollus-service/kollus-samples-php

    DRM

    개요

    Kollus 모바일 다운로드 DRM을 이용해 다운로드한 컨텐츠의 ‘재생 재한 횟수’, ‘컨텐츠 만료 기간’, ‘컨텐츠 재생시간'을 설정하여 컨텐츠의 재생을 제어하는 기능을 설명하는 문서입니다. 서비스 모델에 따라 중복 제한으로 설정되어 사용될 수 있습니다.

    Expire option

    설정 항목의 data-type이나 값이 범위를 벗어나는 경우 컨텐츠 이용에 문제가 발생할 수 있으며, 잘못된 설정 값에 대한 사용 제한을 회수하는 방법은 존재하지 않습니다.

    • Expire count : 재생 제한 횟수

      • data-type : integer
      • range : 0 ~ 1000
      • 0 : unlimited (무제한)
    • Expire date : 컨텐츠 만료 시간

      • data-type : integer, unixtime stamp

      • 컨텐츠 재생이 만료될 시간

        • 컨텐츠 재생이 만료될 시간

          ex) 2014. 3. 3. 5시 45분 30초 GMT → 1393825531

        • 0 : unlimited (무제한)

        • 최대값 : 2029년 12월 31일 23시 59분 59초 (1893455999)

    • Expire playtime : 재생시간 제한 (배속의 경우 배속이 적용된 시간 적용)

      • data-type : integer
      • range : 0, 60 ~ 604800 (단위:초, 최소: 60초, 최대:1주일)
      • 0 : unlimited (무제한)

    DRM callback

    DRM 정책을 적용하기 위해서는 채널에 DRM 콜백 URL(DRM callback url)을 설정해야 합니다.

    채널에 DRM 콜백 URL을 설정하면 컨텐츠를 다운로드하는 시점에 채널에 설정된 DRM 콜백 URL을 호출하여 반환된 값을 DRM 정책으로 사용하게 됩니다. ​ 이때 다운로드되는 DRM 정책 정보는 JWT Encode 되어 Http Body에 반환 되어야 합니다.

    주의:

    1. DRM 콜백 URL이 응답하지 않으면 다운로드가 되지 않습니다.
    2. 알고리즘은 HS256만 지원을 하며 Http 헤더에 지정된 헤더(X-KOLLUS-USERKEY)의 값으로 “사용자키"를 함께 전송해야 합니다.

    Callback ​flow

    Image Removed

    1. 채널에 DRM 콜백 URL을 설정합니다.

      • ex> http://www.foo.com/auth.php 가 고객사 인증 DRM 서버인 경우
    2. JSON 데이터를 생성 후 JWT로 인코딩 한다.

    3. Kollus mobile player가 http://www.foo.com/auth.php 에 다음의 정보를 POST 전송 합니다.

      • session_key : 플레이어에서 생성한 요청 확인용 세션키
        • kind3의 content_expire_reset 경우 요청한 session_key를 확인합니다.
        • Callback v2가 적용되는 v1.6에서 적용됩니다.
      • kind : 1 - 3
      • client_user_id : 고객사 회원 아이디
        • Media token 생성시 포함된 아이디입니다.
      • player_id : 고객사 회원이 가지고 있는 단말 아이디
      • device_name : 고객사 회원이 가지고 있는 단말명
        • 안드로이드, 아이폰에 따라 단말명이 다르게 전달됩니다.
        • 아이폰의 경우 사전에 Apple에서 정의한 문자열로 전달되며 안드로이드의 경우 ​디바이스명, ​모델명이 ​함께 ​전달됩니다. 안드로이드의 경우 해당 정보가 없을 경우 NULL을 전달 합니다.
      • media_content_key : 현재 다운로드하려는 컨텐츠 key 입니다.
        • 채널에 등록된 컨텐츠에 부여된 고유 키입니다.
        • 업로드된 컨텐츠를 여러채널에 등록하면 media_content_key는 모두 다르게 ​생성됩니다.
    4. 고객사 DRM 인증서버는 전달받은 위 정보를 바탕으로 다음의 json 포멧의 data를 JWT의 payload ​에 ​추가하여 Encoding ​하고 ​헤더에 ​지정된 “시용자키(X-KOLLUS-USERKEY)"를 함께 ​전송합니다.

      (고객사가 인증 정보를 플레이어로 전달할 때 모든 데이터의 자료형은 반드시 기술된대로 integer 형이여야만 합니다.)

    Response JSON spec.

    Json TagDescriptionexpiration_dateunixtime stamp (만료될 시간의 unixtime stamp)
    최대값 : 2029년 12월 31일 23시 59분 59초 (1893455999)expiration_count재생 제한 횟수expiration_playtime재생시간 제한result반환 결과가 정상인 경우 1, 비정상인 경우 0을 반환하도록 합니다.content_expiredDRM 콘텐츠를 강제로 expire 시킵니다.content_deleteDRM 콘텐츠를 강제 삭제 합니다.content_expire_resetexpire 콘텐츠를 복구합니다.session_key* v1.6 이후 Callback v2에서 적용됩니다.
    kind3의 요청으로 content_expire_reset
    작업시 Request에 포함된 session_key를 Response에 포함시켜야 합니다.media_content_keyKollus 컨텐츠 Unique Keykind요청에 대한 구분

    device_name 추가 설명

    • Andoid

      안드로이드 어플 개발시 사용되는 Build.DEVICE, Build.MODEL을 /(슬래쉬)로 구분한 문자열로 ​만들어 ​사용합니다.

      • Build.DEVICE+”/”+Build.MODEL
      • 단말기의 특성에 따라 해당 정보는 NULL로 표시될 수 있습니다.
    • iOS

      iOS의 경우 iOS에서 제공하는 device-name을 사용합니다.

    
              
    Device TypeProduct NameiPhone1,1iPhoneiPhone1,2iPhone 3GiPhone2,1iPhone 3GSiPhone3,1iPhone 4 (GSM)iPhone3,3iPhone 4 (CDMA)iPhone4,1iPhone 4SiPhone5,1iPhone 5 (A1428)iPhone5,2iPhone 5 (A1429)iPhone5,3iPhone 5c (A1456/A1532)iPhone5,4iPhone 5c (A1507/A1516/A1529)iPhone6,1iPhone 5s (A1433/A1453)iPhone6,2iPhone 5s (A1457/A1518/A1530)iPhone7,1iPhone 6 PlusiPhone7,2iPhone 6iPhone8,1iPhone 6siPhone8,2iPhone 6s PlusiPhone8,4iPhone SEiPhone9,1iPhone 7 (A1660/A1779/A1780)iPhone9,2iPhone 7 Plus (A1661/A1785/A1786)iPhone9,3iPhone 7 (A1778)iPhone9,4iPhone 7 Plus (A1784)iPhone10,1iPhone 8 (A1863/A1906)iPhone10,2iPhone 8 Plus (A1864/A1898)iPhone10,3iPhone X (A1865/A1902)iPhone10,4iPhone 8 (A1905)iPhone10,5iPhone 8 Plus (A1897)iPhone10,6iPhone X (A1901)iPad1,1iPadiPad2,1iPad 2 (Wi-Fi)iPad2,2iPad 2 (GSM)iPad2,3iPad 2 (CDMA)iPad2,4iPad 2 (Wi-Fi, revised)iPad2,5iPad mini (Wi-Fi)iPad2,6iPad mini (A1454)iPad2,7iPad mini (A1455)iPad3,1iPad (3rd gen, Wi-Fi)iPad3,2iPad (3rd gen, Wi-Fi+LTE Verizon)iPad3,3iPad (3rd gen, Wi-Fi+LTE AT&T)iPad3,4iPad (4th gen, Wi-Fi)iPad3,5iPad (4th gen, A1459)iPad3,6iPad (4th gen, A1460)iPad4,1iPad Air (Wi-Fi)iPad4,2iPad Air (Wi-Fi+LTE)iPad4,3iPad Air (Rev)iPad4,4iPad mini 2 (Wi-Fi)iPad4,5iPad mini 2 (Wi-Fi+LTE)iPad4,6iPad mini 2 (Rev)iPad4,7iPad mini 3 (Wi-Fi)iPad4,8iPad mini 3 (A1600)iPad4,9iPad mini 3 (A1601)iPad5,1iPad mini 4 (Wi-Fi)iPad5,2iPad mini 4 (Wi-Fi+LTE)iPad5,3iPad Air 2 (Wi-Fi)iPad5,4iPad Air 2 (Wi-Fi+LTE)iPad6,3iPad Pro (9.7 inch) (Wi-Fi)iPad6,4iPad Pro (9.7 inch) (Wi-Fi+LTE)iPad6,7iPad Pro (12.9 inch, Wi-Fi)iPad6,8iPad Pro (12.9 inch, Wi-Fi+LTE)iPad6,11iPad 9.7-Inch 5th Gen (Wi-Fi Only)iPad6,12iPad 9.7-Inch 5th Gen (Wi-Fi/Cellular)iPad7,1iPad Pro (12.9 inch, A1670)iPad7,2iPad Pro (12.9 inch, A18219)iPad7,3iPad Pro (10.5 inch, A1701)iPad7,4iPad Pro (10.5 inch, A1709)iPad7,5iPad (6th gen, A1893)iPad7,6iPad (6th gen, A1954)iPod1,1iPod touchiPod2,1iPod touch (2nd gen)iPod3,1iPod touch (3rd gen)iPod4,1iPod touch (4th gen)iPod5,1iPod touch (5th gen)iPod7,1iPod touch (6th gen)
    
    

    Callback ​kind

    DRM callback이 호출되는 상황은 아래 3가지 경우입니다.

    DRM 컨텐츠의 Expire 정보를 요청하는 경우 (kind:1)
    Request
    구분DescriptionPOSTHttp POST로 요청합니다. (parameter가 아닙니다.)kind1client_user_id고객사 사용자 ID, media_token 생성시 사용된 client_user_id와 동일합니다.player_id고객사 사용자가 ​가지고 ​있는 ​단말의 ​아이디device_name고객사 사용자가 가지고 있는 단말의 모델명media_content_keyKollus 컨텐츠 unique keyuservaluesJSON format (VideoGateway 호출시 사용된 uservalue0~9)
    • uservalues sample
      • uservalues={"uservalue0":"강의코드01","uservalue1":"상품코드02","uservalue9":" 생성코드03"}
      • VideoGateway(v.kr.kollus.com)호출시 사용된 uservalue0~9 정보를 함께 전달 받습니다.
    Response
    카테고리구분Descriptiondata(int) expiration_date만료될 시간의 unixtime stamp
    최대값 : 2029년 12월 31일 23시 59분 59초
    (1893455999)(int) expiration_count재생 제한 횟수, 예) 10 ← 10번 재생 가능(int) result0 (비정상), 1 (정상)
    0 인 경우 다운로드 되지 않습니다.
    0 인 경우 재요청되지 않습니다.(string) message0 (비정상)의 경우 message를 추가하면 상황에 따른 메시지가 표시됩니다.(int) expiration_refresh_popup만료후 갱신 여부 팝업 표시
    0 인 경우 표시하지 않음 (기본값)
    1 인 경우 DRM 만료후 갱신이 필요할때 사용자
    확인을 받는 팝업을 표시합니다.(int) disable_tvout0 (tvout 차단 안함), 1 (tvout 차단)
    이 항목이 없으면 채널에 있는 disable_tvout정책이 적용됩니다.
    Example
    Code Block
    languagejs
    themeMidnight
    {
        “data” : {
            "expiration_date": 1402444800,
            "expiration_count": 10,
       		"result": 1
        }
    }
    
    
    DRM 컨텐츠의 Download가 100% 완료된 경우 (kind:2)

    주의) 반드시 응답해야 하며, Block 상태로 통신합니다.

    Request
    구분DescriptionPOSTHttp POST로 요청합니다. (parameter가 아닙니다.)kind2client_user_id고객사 사용자 ID, media_token 생성시 사용된 client_user_id와 동일합니다.player_id고객사 사용자가 ​가지고 ​있는 ​단말의 ​아이디device_name고객사 사용자가 가지고 있는 단말의 모델명media_content_keyKollus 컨텐츠 unique keyuservaluesJSON format (VideoGateway 호출시 사용된 uservalue0~9)
    Response
    카테고리구분Descriptsiondata(int) expiration_date만료될 시간의 unixtime stamp
    해당 항목이 있으면 kind1의 값을 대체합니다.
    최대값 : 2029년 12월 31일 23시 59분 59초
    (1893455999)(int) content_delete0 (삭제하지 않음), 1 (다운로드 받은 파일 삭제)
    다운로드된 컨텐츠를 요청에 의해 삭제하는 옵션입니다.(int) result0 (비정상), 1 (정상)
    0 인 경우 추가 작업은 없습니다.
    0 인경우 추가 옵션은 무시됩니다.
    0 인 경우 재요청되지 않습니다.(string) message0 (비정상)의 경우나 content_delete이 1(다운로드 받은 파일 삭제) 시 message를 추가하면 상황에 따른 메시지가 표시됩니다.
    Example
    Code Block
    languagejs
    themeMidnight
    {
        “data” : {
            "content_delete": 1,
            "result": 1
    	}
    }
    
    
    DRM 컨텐츠를 재생하는 경우 (kind:3)

    주의) v1.6 이후 재생시 네트워크 통신이 가능한 경우 전송되며 요청 실패시 네트워크 통신이 가능할 때 재 전송 됩니다.

    Image Removed

    Request
    구분DescriptionPOSTHttp POST로 요청합니다. (parameter가 아닙니다.)kind3client_user_id고객사 사용자 ID, media_token 생성시 사용된 client_user_id와 동일합니다.player_id고객사 사용자가 가지고 있는 단말의 아이디device_name고객사 사용자가 가지고 있는 단말의 모델명media_content_keyKollus 컨텐츠 unique keystart_atunixtimestamp (localtime)
    - 전송 요청 시간uservaluesJSON format (VideoGateway 호출시 사용된 uservalue0~9)
    Response
    카테고리구분Descriptiondata(int) content_expired0 (재생가능), 1 (재생 제한)
    다운로드 컨텐츠를 강제로 expire 시킵니다.
    필요시 content_expire_reset 옵션으로 다시 복구 할 수 있습니다.
    * expired 컨텐츠는 0(재생가능)으로 응답해도 재생되지 않습니다.(int) result0 (비정상), 1 (정상)
    0 인 경우 재생되지 않습니다.
    0 인 경우 추가 옵션은 무시됩니다.
    0 인 경우 재요청되지 않습니다.(string) message0 (비정상)의 경우나 content_expired이 1(재생 제한) 시 message를 추가하면 상황에 따른 메시지가 표시됩니다.
    Example
    Code Block
    languagejs
    themeMidnight
    {
        “data: {
            "content_expired" : 1,
            "result": 1
    	}
    }
    
    

    Sample

    • DRM callback url
      • http://www.foo.com/auth.php
    • 컨텐츠 만료 시간 : 2014년 6월 10일 자정 종료
      • DATE (M/D/Y @ h : m : s): 6 / 10 / 2014 @ 24:0:0 UTC
      • Unix time stamp : 1402444800
      • http://www.epochconverter.com 를 이용해 1402444800 값을 변경해 볼 수 있습니다. GMT가 아닌 UTC입니다.
    • 컨텐츠 재생 횟수 제한 : 10회
    kind1 : request expire option
    request
    • URL : http://www.foo.com/auth.php
    • post data
      • kind=1
      • client_user_id=guest1
      • media_content_key=VXBW1VdY
      • uservalues={"uservalue0":"강의코드01","uservalue1":"상품코드02","uservalue9":" 생성코드03"}
    response
    Code Block
    languagejs
    themeMidnight
    {
        “data” : {
            "expiration_date": 1402444800,
            "expiration_count": 10,
            "result": 1
    	}
    }
    kind2 : ​download​ ​complete
    request
    • URL : http://www.foo.com/auth.php
    • post data
      • kind=2
      • client_user_id=guest1
      • media_content_key=VXBW1VdY
      • uservalues={"uservalue0":"강의코드01","uservalue1":"상품코드02","uservalue9":" 생성코드03"}
    response
    Code Block
    languagejs
    themeMidnight
    {
        “data” : {
        	"result": 1
        }
    }
    
    

    DRM Callback 신규 버전 v2

    이전 1.4까지 제공되던 kind1, kind2, kind3의 호출이 한번의 호출로 통합되어 호출되는 버전으로 변경됩니다. ​이전 ​버전은 ​사용자의 ​사용자의 ​빈번한 ​호출에 ​대응하기 ​용이하지 ​않다는 ​다수 고객사의 요청에 따라 추가 되었습니다. 편의상 새로운 버전을 v2로 이전버전을 v1으로 합니다.

    Reuest

    구분DescriptionPOSTHttp POST로 요청합니다. (parameter가 아닙니다.)itemsJsonArray로 구성된 string 입니다.

    items 항목은 kind1, kind2, kind3의 데이터를 모두 포함한 호출이 될 수 있습니다.

    items (JsonArray)
    kind1, kind2
    구분Descriptionkind1,2client_user_id고객사 사용자 ID, media_token 생성시 사용된 client_user_id와 동일합니다.player_id고객사 사용자가 가지고 있는 단말의 아이디hardware_id단말의 hardware 아이디(PC, 입력값이 있으면)device_name고객사 사용자가 가지고 있는 단말의 모델명media_content_keyKollus 컨텐츠 unique keyuservaluesJSON format (VideoGateway 호출시 사용된 uservalue0~9)
    kind3
    구분Descriptionkind3session_keycontent_expire_reset 요청시 동일한 session_key를 확인합니다.client_user_id고객사 사용자 ID, media_token 생성시 사용된 client_user_id와 동일합니다.player_id고객사 사용자가 가지고 있는 단말의 아이디hardware_id단말의 hardware 아이디(PC, 입력값이 있으면)device_name고객사 사용자가 가지고 있는 단말의 모델명media_content_keyKollus 컨텐츠 unique keystart_atunixtimestamp (localtime)
    - 전송 요청 시간uservaluesJSON format (VideoGateway 호출시 사용된 uservalue0~9)content_expired만료된 컨텐츠 확인 flag( 1 : 만료, 0 : 재생가능)reset_req일괄갱신 요청인지 판단( 0 (default), 1 : 일괄갱신)
    Items Sample
    Code Block
    languagejs
    themeMidnight
    [
        {
            "kind": 1,
            "media_content_key" : "XXX-MEDIA_CONTENTKEY-XXX",
            "client_user_id": "XXXXXXX",
            "player_id": "xxxxxxxxxxxxxxxx",
            "device_name": "XXXXX",
            "uservalues": {
                "uservalue0": "value0"
            }
        },
        {
            "kind": 2,
            "media_content_key" : "XXX-MEDIA_CONTENTKEY-XXX",
            "client_user_id": "XXXXXXX",
            "player_id": "xxxxxxxxxxxxxxxx",
            "device_name": "XXXXX",
            "uservalues": {
                "uservalue0": "value0"
            }
        },
        {
            "kind": 3,
            "session_key" : "XXX-SESSION_KEY-XXX", ← content_expire_reset 요청시 확인합니다.
            "media_content_key" : "XXX-MEDIA_CONTENTKEY-XXX",
            "client_user_id": "XXXXXXX",
            "player_id": "xxxxxxxxxxxxxxxx",
            "device_name": "XXXXX",
            "uservalues": {
           		"uservalue1": "value1"
            }
        }
    ]
    
    

    Response

    Array은 “data” 필드로 응답 받는다.

    kind1
    구분필수Description(int) kindO1(string) media_content_keyOKollus 컨텐츠 Unique Key(int) expiration_date만료될 시간의 unixtime stamp
    최대값 : 2029년 12월 31일 23시 59분 59초 (1893455999)(int) expiration_count재생 제한 횟수, 예) 10 ← 10번 재생 가능(int) expiration_playtime재생 시간 제한, 예) 60 ← 60초 재생 가능(int) resultO0 (비정상), 1 (정상)
    0 인 경우 다운로드 되지 않습니다.
    0 인 경우 재 요청되지 않습니다.(string) message0 (비정상)의 경우 message를 추가하면 상황에 따른 메시지가 표시됩니다.(int)
    expiration_refresh_popup만료후 갱신 여부 팝업 표시
    0 인 경우 표시하지 않음 (기본값)
    1 인 경우 DRM 만료후 갱신이 필요할때 사용자 확인을 받는
    팝업을 표시합니다.(int) vmcheckvirtual machine 체크 여부 판단, PC용
    0 : check 안 함, 1 : check 함(기본값)(int) check_abuseDRM kind3 항상 물어보기(0 : 안함(기본값), 1: 체크)
    kind2
    구분필수Description(int) kindO2(string) media_content_keyOKollus 컨텐츠 Unique Key(int) content_delete0 (삭제하지 않음), 1 (다운로드 받은 파일 삭제)
    다운로드된 컨텐츠를 요청에 의해 삭제하는 옵션입니다.(string) message0 (비정상)의 경우나 content_delete이 1(다운로드 받은 파일 삭제)시 message를 추가하면 상황에 따른 메시지가 표시됩니다.(int) resultO0 (비정상), 1 (정상)
    0 인 경우 추가 작업은 없습니다.
    0 인 경우 추가 옵션은 무시됩니다.
    0 인 경우 재 요청되지 않습니다.
    kind3
    구분필수Description(int) kindO3(string) session_keycontent_expire_reset 요청시 session_key 확인합니다.(string) media_content_keyOKollus 컨텐츠 Unique Key(int) start_atORequest에 포함된 start_at(int) content_expired0 (재생가능), 1 (재생 제한)
    다운로드 컨텐츠를 강제로 expire 시킵니다.
    필요시 content_expire_reset 옵션으로 다시 복구 할 수 있습니다.
    * expired 컨텐츠는 0(재생가능)으로 응답해도 재생되지 않습니다.
    * 1인 경우 content_expire_reset 무시됩니다.(int) content_delete0 (삭제하지 않음), 1 (다운로드 받은 파일 삭제)
    다운로드된 컨텐츠를 요청에 의해 삭제하는 옵션입니다.
    content_expired 옵션과 상관 관계없이 해당 옵션이 존재하는 경우 삭제합니다.(int) content_expire_reset0 (추가 액션 없음), 1 (expired된 콘텐츠 권한 Reset)
    expired된 콘텐츠 권한을 Reset 하는 옵션입니다.(int) expiration_date만료될 시간의 unixtime stamp
    최대값 : 2029년 12월 31일 23시 59분 59초 (1893455999)
    * content_expire_reset 옵션이 1일때 재설정 됩니다.(int) expiration_count재생 제한 횟수, 예) 10 ← 10번 재생 가능
    * content_expire_reset 옵션이 1일때 재설정 됩니다.(int) expiration_playtime재생 시간 제한, 예) 3600 ← 1시간(3600초) 재생 가능
    * content_expire_reset 옵션이 1일때 재설정 됩니다.(int) resultO0 (비정상), 1 (정상)
    0 인 경우 재생되지 않습니다.
    0 인 경우 추가 옵션은 무시됩니다.
    0 인 경우 재 요청되지 않습니다.(string) message0 (비정상), content_expired이 1(재생 제한) 또는 content_delete이 1(다운로드 받은 파일 삭제) 시 message를 추가하면 상황에 따른 메시지가 표시됩니다.(int) check_abuseDRM kind3 항상 물어보기(0 : 안함(기본값), 1: 체크)
    Response ​Example
    Code Block
    languagejs
    themeMidnight
    {
        “data” : [
            {
                "kind": 1,
                "media_content_key": "XXX-MEDIA_CONTENT_KEY-XXX",
                "expiration_date": 1402444800,
                "expiration_count": 10,
                "expiration_playtime": 60,
                "result": 1
            },
            {
                "kind": 2,
                "media_content_key": "XXX-MEDIA_CONTENT_KEY-XXX",
                "content_delete": 1,
                "result": 1
            },
            {
                "kind": 3,
                "session_key" : "XXX-SESSION_KEY-XXX",
                "media_content_key": "XXX-MEDIA_CONTENT_KEY-XXX",
                "start_at": 140000000,
                "content_expired": 1,
                "content_delete": 1,
                "content_expire_reset": 1,
                "expiration_date": 1402444800,
                "expiration_count": 10,
                "expiration_playtime": 3600,
                "result": 1
            }
        ]
    }
    
    

    JWT 지원

    DRM 정책을 JWT로 반환하는 것을 지원합니다. JWT 웹사이트(https://jwt.io) 에서 공인한 라이브러리를 이용하여 생성된 Token으로 변경하여 반환하도록 추가 되었습니다.

    플레이어에 JWT Token으로 반환하는 경우에 지정된 헤더에 사용자키를 포함 시켜 전송해야 합니다.

    Code Block
    languagejs
    themeMidnight
    HTTP/1.1 200 OK
    Date: Fri, 14 Oct 2016 04:12:46 GMT
    Content-Type: text/html; charset=utf-8
    Transfer-Encoding: chunked
    Connection: keep-alive
    X-Kollus-UserKey: 0993d76eb424a72f2005b874ac49405d44a6c
    Content-Encoding: gzip
    지정된(X-Kollus-UserKey) 해더로 전송된 사용자키가 일치 하는 경우 플레이어에서 정상적으로 동작하게 됩니다.

    JWT ​Secret,​ ​JWT​ ​사용자​ ​키

    기존 사용자 키(2)키를 header에 추가하는 것 외에 추가적으로 기존의 JWT scpec에 명시되어 있는 secret key는 보안키(1)​를 ​입력해야 ​해야 ​합니다. ​고객사는 ​관련 ​정보를 ​아래와 ​같이 Kollus CMS 에서 확인 할 수 있습니다.

    설정 > 서비스 계정 설정

    Image Removed

    JWT payload

    각 callback의 response를 JWT playload에 담아 전송합니다.

    Sample

    http://jwt.io 에서 제공하는 다양한 언어로 구현된 라이브러리와 예제를 이용해 구현하도록 합니다. JWT ​스펙과 ​동일하나 ​반환되는 http ​헤더에 X-Kollus-UserKey​를 ​이용하여 ​사용자키를 함께 전송해주셔야 합니다.

    (예시) php

    Code Block
    languagejs
    themeMidnight
    define('KOLLUS_KEY', '**사용자키**'); // X-Kollus-UserKey
    define('JWT_KEY', '**보안키**'); // JWT 보안 키
    
    function encode_jwt($payload, $key, $alg = 'HS256') {
        $header = array('alg' => $alg, 'typ' => 'JWT' );
        $unsignedToken = base64_encode(json_encode($header)).'.'.
        base64_encode(json_encode($payload));
        $signature = hash_hmac('sha256', $unsignedToken, $key, TRUE);
        return $unsignedToken.'.'.base64_encode($signature);
    }
    $payload = array(
        'data' => array(
            array(
                'kind' => 1,
                'result' =>1,
                'expiration_date' => time()+3600,
                'expiration_playtime' => 30,
                'vmcheck' => 1,
            ),
            array(
                'kind' => 2,
                'result' =>1,
                'expiration_date' => time()+3600,
                'expiration_playtime' => 30,
                'vmcheck' => 1,
            ),
            array(
                'kind' => 3,
                'result' =>1,
                'expiration_date' => time()+3600,
                'expiration_playtime' => 30,
                'vmcheck' => 1,
            ),
        ),
    );
    
    $result = encode_jwt($payload, JWT_KEY);
    
    //header('Content-Type: application/jwt');
    header('X-Kollus-UserKey: '.KOLLUS_KEY);
    echo $result;
    
    

    Code sample (v1.4 기준)

    다음과 같은 고객사의 DB가 구성된 것으로 고려되어 샘플이 구성되어있습니다.

    Image Removed

    PHP ​sample

    Code Block
    languagejs
    themeMidnight
    <?php
    /**
    * PHP Version : 5.4 above
    */
    function get_jwt($payload, $key, $alg = 'HS256')
    {
    	$header = array('alg' => $alg, 'typ' => 'JWT' );
    	$unsignedToken = base64_encode(json_encode($header)).'.'.base64_encode(json_encode($payload));
    	$signature = hash_hmac('sha256', $unsignedToken, $key, TRUE);
    	return $unsignedToken.'.'.base64_encode($signature);
    }
    
    function print_kollus_jwt($data)
    {
        define('KOLLUS_KEY', '**사용자키**'); // X-Kollus-UserKey
        define('JWT_KEY', '**보안키**'); // JWT 보안 키
        $payload = array( ‘data’ => $data );
        $result = encode_jwt($payload, JWT_KEY);
        //header('Content-Type: application/jwt');
        header('X-Kollus-UserKey: '.KOLLUS_KEY);
        echo $result;
    }
    
    /////////////////////////////////////////////////
    
    include "./config.php";
    // 주의 : kind가 1일때 자동으로 expiration_date가 생성되는 샘플 페이지입니다.
    // 재생 제한 횟수
    $_default_expiration_count = 3;
    $_expired_duration = 60 * 60 * 24; // 1 day
    
    // DB Connection
    $_db_conn = mysqli_connect($_hostname, $_username, $_password);
    if (!$_db_conn) {
    	die('Could not connect: ' . mysql_error());
    }
    
    $_db_selected = mysqli_select_db($_database, $_db_conn);
    if (!$_db_selected) {
    	die ('Can\'t use database : ' . mysqli_error());
    }
    
    $_kind = isset($_POST['kind']) ? ((int) $_POST['kind']) : NULL;
    $_media_content_key = isset($_POST['media_content_key']) ? $_POST['media_content_key'] : NULL;
    $_client_user_id = isset($_POST['client_user_id']) ? $_POST['client_user_id'] : NULL;
    
    $channel = NULL;
    $_query = sprintf("SELECT * FROM `channels` WHERE `media_content_key` = '%s'",
    mysqli_real_escape_string($_media_content_key, $_db_conn));
    $_result = mysqli_query($_query, $_db_conn);
    
    if ($_result) {
    	$channel = mysqli_fetch_array($_result, MYSQL_ASSOC);
    	if ($channel === FALSE) $channel = NULL;
    } else {
    	die('Invalid query: ' . mysqli_error());
    }
    
    $user = NULL;
    $_query = sprintf("SELECT * FROM `users` WHERE `client_user_id` = '%s'",
    mysqli_real_escape_string($_client_user_id, $_db_conn));
    $_result = mysqli_query($_query, $_db_conn);
    if ($_result) {
    	$user = mysqli_fetch_array($_result, MYSQL_ASSOC);
    	if ($user === FALSE) $user = NULL;
    } else {
    	die('Invalid query: ' . mysqli_error());
    }
    
    $channel_user = NULL;
    if (!is_null($_media_content_key) && !is_null($_client_user_id)) {
    	$_query = sprintf("SELECT * FROM `channel_users` WHERE `user_id` = '%s', `channel_id` = '%s'", $user['id'], $channel['id']);
    	$_result = mysqli_query($_query, $_db_conn);
    	if ($_result) {
    		$channel_user = mysqli_fetch_array($_result, MYSQL_ASSOC);
    		if ($channel_user === FALSE) $channel_user = NULL;
    	} else {
    		die('Invalid query: ' . mysqli_error());
    	}
    }
    
    $_jwt_result = array('result' => 0);
    switch($_kind) {
    case 1:
    	if (is_null($channel_user)){
    		$_expiration_date = time() + $_expired_duration;
            $_expiration_count = $_default_expiration_count;
            $_query = sprintf("INSERT INTO `channel_users`(`user_id`, `channel_id`, `expiration_date`
            ,`expiration_count` , `created_at`, `updated_at`) VALUES('%s', '%s', '%s', '%s', UNIX_TIMESTAMP(),
            UNIX_TIMESTAMP())", $user['id'], $channel['id'], $_expiration_date, $_expiration_count);
            $_result = mysqli_query($_query, $_db_conn);
    		if (!$_result) {
    			die('Invalid query: ' . mysqli_error());
    		}
    	} else {
            $_expiration_date = $channel_user['expiration_date'];
            $_expiration_count = $channel_user['$expiration_count'];
    	}
        $_jwt_result['expiration_date'] = (int) $_expiration_date;
        $_jwt_result['expiration_count'] = (int) $_expiration_count;
    	break;
    case 2:
        if (!is_null($channel_user)){
            $_download_times = ++((int) $channel_user['download_times']);
            $_query = sprintf("UPDATE `channel_users` SET `download_times` = '%s', `updated_at` =
            UNIX_TIMESTAMP() WHERE id = %s", $_download_times, $channel_user['id']);
            $_result = mysqli_query($_query, $_db_conn);
      	    if (!$_result) {
        		die('Invalid query: ' . mysql_error());
       		}
            $_jwt_result['result'] = 1;
        }
    	break;
    case 3:
        if (!is_null($channel_user) && $channel_user['is_expired']) {
        	$_jwt_result['content_expired'] = 1;
        }
        break;
    }
    
    // DB Close
    mysqli_close($_db_conn);
    // 결과인 data array를 JWT로 변환하여 출력함
    print_kollus_jwt($_jwt_result);
    
    

    샘플코드

     DRM – dotnet

     DRM – jsp

     DRM – php

    LMS

    Kollus에서 제공하는 Callback 정보는 플랫폼에서 전달하는 내용과 플레이어에서 전달하는 내용으로 구분될 수 있습니다. 플레이어에서 전달하는 정보는 사용자가 컨텐츠를 이용한 정보를 활용할 수 있도록 관련 정보를 지정된 Url에 전달하는 기능입니다. 진도율을 전송할때 응답을 확인하지 않습니다. 단, 네트워크 오류인 경우 해당 데이터를 보관후 재 전송 가능할때 재 전송됩니다. 해당 기능을 사용하기 위해서는 Kollus에 접속하여 관련 정보를 설정하시면 Video-gateway를 통해 관련 내용이 전달되어 재생과 관련된 정보를 전달합니다.

    Callback process

    재생 정보를 전달 받는 흐름을 설명합니다.

    1. Kollus 설정에서 관련 정보 요청을 설정합니다.
      • Kollus는 컨텐츠 배포 단위인 채널 마다 다양한 옵션을 지정할 수 있습니다.
      • 배포하는 채널마다 지정된 데이터 수집이 가능합니다.
    2. 동영상 재생을 위해 Video-gateway를 호출하면 컨텐츠 재생을 위한 다양한 정보를 플레이어 전달하게 되며, 이때 재생과 관련된 정보를 전달할 설정을 함께 전달합니다.
    3. 재생 정보를 활용하기 위해 설정한 Url에 관련 정보를 전달합니다.
    4. Kollus는 컨텐츠 재생과 관련된 기본 정보를 수집하기 위해 관련 정보를 수집합니다.
      • 사용자 정보를 일체 포함되지 않습니다.
      • Mac Address, IP Address 개인의 위치 정보와 관련된 정보를 수집 되지 않습니다.

    Customer Requirement

    Kollus에서 전달하는 재생 관련 정보는 고객의 다양한 요청을 수렴하여 개발되었습니다.

    • 마지막 종료 시간
    • 컨텐츠 구간별 재생 정보
    • 사용자 정보
    • 컨텐츠 정보
    • PC 정보
    • 동영상 구간을 시스템에서 지정된 블럭으로 나누어 정보를 수집

    Plugin option

    • {MAC}
      • Mac Address
      • 사용자 개인정보에 해당하여 수집을 권장하지 않습니다.
      • 고급 사용자의 경우 Mac Address를 임의로 변경할 수 있으며, 모바일 플레이어의 경우 App의 등록 제한으로 인해 지원하지 않습니다.
    • {IP} - RemoteAddress의 이슈로 지원하지 않습니다. (서버쪽에서 확인하도록합니다.)
      • 컨텐츠를 재생하는 사용자 PC의 IP Address
      • 사용자 개인정보에 해당하여 수집을 권장하지 않습니다.
      • 공유기를 사용하는 환경에서 수집 되는 IP Address는 Private 영역 IP Address 입니다. 정확한 사용자의 IP를 수집하기 위해서는 Callback을 받는 Web 서버에서 Remote_Address를 확인하는 것이 정확합니다.
    • {CLIENT_USER_ID}
      • 사용자의 User ID 입니다.
      • MediaToken 생성시 파라미터로 입력한 사용자의 ID 정보입니다. 이때 입력된 사용자 ID는 Kollus 시스템에서 관리되지 않고 사용자를 구분하는 Unique 정보로만 사용됩니다.
    • {START_AT}
      • Video-gateway를 호출한 시점의 Unixtimestamp 입니다.
      • 사용자의 컨텐츠 이용중 다수의 재생정보 전달이 발생할 수 있습니다. 동일한 요청에 같은 {START_AT} 값을 갖게 되며, 같은 시간에 다수의 이용자가 발생할 경우 Unixtimestamp 이기 때문에 중복될 수 있습니다.
      • 다운로드 컨텐츠의 경우 start_at은 컨텐츠 재생시 단말의 unixtimestamp 입니다.
    • {BLOCK_CNT}
      • Kollus에서 설정한 블럭의 개수입니다.
      • 재생 정보를 지정된 블럭 개수로 나누어 관리하며 정보 전달시 함께 포함시킬수 있습니다.
    • {PLAY_TIME}
      • 전체 재생 시간 (단위:초)
      • 배속 기능을 사용하는 경우 배속을 포함한 시간입니다. 시간 값은 누적입니다.
      • 10초간 2배속으로 재생한 경우 20초로 계산됩니다.
      • 모든 재생 시간을 포함한 시간입니다. (구간반복을 한 경우도 모두 포함됩니다.)
    • {PLAYTIME_PERCENT}
      • DURATION에 대한 전체 재생 비율 (단위:%, 정수, 절사)
      • 컨텐츠를 두번 반복해서 본 경우 200%로 계산됩니다.
    • {DURATION}
      • 컨텐츠 길이 (단위:초)
    • {MEDIA_CONTENT_KEY}
      • Kollus media_content_key
    • {ENCODING_PROFILE_KEY}
      • Kollus encoding profile key
    • {PLAY_BLOCK_JSON}
      • 데이터 포멧: JSON
      • 블럭 재생 정보
    • {BLOCK_PLAY_1}~{BLOCK_PLAY_##{BLOCK_CNT}}
      • 블럭 재생 여부
      • 재생하지 않고 Skip
      • 해당 블럭 재생 (0초 이상 재생하면 1로 설정됩니다.)
    • {BLOCK_TIME_1} ~{BLOCK_TIME_##{BLOCK_CNT}}
      • 해당 블럭을 재생한 시간입니다. (단위:초)
      • 플레이어의 배속기능을 이용해 재생한 경우 재생시간은 배속을 적용하여 계산됩니다.
      • 반복해서 3초의 범위를 갖는 블럭을 2회 재생한 경우 블럭의 재생시간은 6초입니다.
      • {DURATION}이 {BLOCK_CNT} 보다 작은 경우 {BLOCK_TIME#}의 합은 {DURATION}을 초과합니다. (각 블럭의 재생시간이 밀리초로 나오는 경우 올림하여 1초로 계산합니다.)
    • {LAST_PLAY_AT}
      • 마지막 재생 위치 (단위:초)
    • {HOST_NAME}
      • 비디오 링크 요청 도메인명
      • ex) catenoid.video.kr.kollus.com
    • {PLAYER_ID}
      • Kollus 플레이어의 고유 ID 입니다.
      • 플레이어 설치시 생성된 고유 ID 입니다.
      • 플래쉬 플레이어의 경우 kfp 라는 고유 문자열을 전송합니다.
    • {PLAYLIST_SKIP}
      • 플레이어 리스트로 재생되는 경우 컨텐츠 Skip을 한 경우에 사용됩니다.
      • 0 : 모두 재생
      • 1 : Skip
    • {USERVALUE0}~{USERVALUE9}
      • Video-gateway호출에 추가된 추가 정보 입니다.
      • ex) LCD={USERVALUE0}&UCD={USERVALUE4}
      • 영문,숫자 이외의 한글등의 문자열을 전달할 경우 웹 브라우저들의 차이점이 있기 때문에 해당 변수 전달시 UTF-8로 전달해야 합니다. (전달되는 문자열은 웹의 특성상 UrlEncode해서 전달해야 합니다.)
    • {JSON_DATA}
      • 데이터 포멧: JSON
      • 모든 재생 정보를 포함한 데이터

    {PLAY_BLOCK_JSON}

    • {JSON_DATA}의 block_info 항목과 동일합니다.
    • block_info Object의 하위 노드를 포함합니다.

    {JSON_DATA}

    • user_info

      • content_provider_key : 고객사 key
      • client_user_id : 사용자(고객) ID
      • player_id : 플레이어(player) ID
      • hardware_id : 플레이어(player) hardware ID, 고객 확인용
      • host_name : 비디오 링크 요청 도메인명
      • device : 디바이스명
    • content_info

      • duration : 컨텐츠 길이
      • encoding_profile : 인코딩 프로파일
      • media_content_key : 미디어 컨텐츠 키
      • channel_key : 채널키
      • real_playtime : 실제 전체 재생 시간 (단위:초)
        • 배속 기능을 사용하는 경우 배속을 포함한 시간입니다.
        • 10초간 2배속으로 재생한 경우 20초로 계산됩니다.
        • 모든 재생 시간을 포함한 시간입니다. (구간반복을 한 경우는 제외됩니다.)
      • playtime : 컨텐츠 재생 시간
      • playtime_percent : duration에 대한 전체 재생 비율
      • start_at : Video-gateway를 호출한 시점의 Unixtimestamp 입니다. 다운로드 컨텐츠의 경우 start_at은 컨텐츠 재생시 단말의 unixtimestamp 입니다.
      • last_play_at : 마지막 재생 위치 (단위:초)
    • block_info

      • block_count : 구간 횟수

      • blocks: 마일스톤 (재생시간 단위:초)

        • b0 : 블럭 재생여부 (0:재생하지 않음, 1:해당블럭 재생)

        • b1 : 0 ~ (int)

        • b2 : block_period 만큼 반복됩니다.

          ...

        • t0 : 블럭 재생시간 (단위:초)

        • t1 : 0 ~ (int)

        • t2 : block_period 만큼 반복됩니다.

          ...

        • p0 : 블럭 재생 비율 (단위:퍼센트%)

        • p1 : 0~ (int) , 블럭 재생을 반복하는 경우 100이상으로 표시됩니다.

        • p2 : block_period 만큼 반복됩니다.

      • sessions : 사용자 블럭 재생을 시간별로 관리하는 항목 (배열) 세션 데이터는 이전 데이터를 모두 누적으로 전송합니다.

        • block : 블럭 인덱스 (0부터 시작)
        • start_time : 해당 블럭을 시작한 시간 (unixtimestamp-localtime)
        • play_time : 해당 블럭 재생 시간
    • uservalues : 사용자 정의 변수, 각 변수의 전체 합은 1KB를 넘지 않도록 해야 합니다.

      • uservalue0
      • uservalue1
      • ....
      • uservalue9

    Support options

    플레이어별 지원 옵션을 확인할 수 있습니다. {MAC}, {IP}의 경우 개인정보에 해당하는 요소로 필요한 경우 별도 협의해 주십시오.

    OptionFlashPlayerKollusPlayer(PC)KollusPlayer(Monlie){MAC}XXX{IP}XXX{CLIENT_USER_ID}OOO{START_AT}OOO{BLOCK_CNT}OOO{PLAY_TIME}OOO{PLAYTIME_PERCENT}OOO{DURATION}OOO{MEDIA_CONTENT_KEY}OOO{ENCODING_PROFILE_KEY}OOO{PLAY_BLOCK_JSON}OOO{BLOCK_PLAY_1} ~OOO{BLOCK_TIME_1} ~OOO{LAST_PLAY_AT}OOO{HOST_NAME}OOO{PLAYER_ID}X(kfp)OO{PLAYLIST_SKIP}XOO{USERVALUE0} ~OOO{JSON_DATA}OOO

    Settings

    Callback에 대한 설정은 채널에서 할 수 있습니다. Callback이 필요한 채널 마다 설정해야 합니다.

    • Callback URLs: 캐리지 리턴으로 각각 치환자를 포함한 URL을 등록합니다.
      • 재생정보를 다수의 시스템에서 전달 받을 수 있도록 캐리지리턴(\n)으로 구분된 다수의 callback_url 을 등록할 수 있습니다.
      • Kollus 플랫폼의 필요에 따라 URL 설정 수를 제한할 수 있습니다.
    • Format: [block_count]:[peroid]:[enable_sessions]:[callback_url]
      • 구분자 : (콜론)
      • block_count
        • 컨텐츠 재생 구간을 나누는 블럭의 수 입니다. 10으로 설정하면 컨텐츠의 길이가 300초의 경우 각 블럭은 30초로 구성됩니다.
      • peroid
        • 데이터 전송 주기
        • Callback이 전송되는 주기로 지정된 period(단위:초) 마다 호출되고 프로그램(플레이어)이 종료될 때 추가로 호출 됩니다. 단, 플래시 플레이어의 경우는 플레이어 종료시 호출되지 않습니다.
        • 플레이를 일시정시 또는 정지했을 때 추가로 호출 됩니다.
        • 단위 :초
      • enable_blocks
        • 1 이면 block_info 항목에 blocks 정보를 포함 시킵니다.
        • 0 이면 block_info 항목에 blocks 정보는 없습니다.
      • enable_sessions
        • 1 이면 block_info 항목에 sessions 정보를 포함 시킵니다.
        • 0 이면 block_info 항목에 sessions 정보는 없습니다.
      • callback_url
        • Callback Url 입니다. 컨텐츠를 재생하는 사용자 환경에서 전송하기 때문에 방화벽 환경을 고려하여 http, 80포트 사용을 권장합니다.

    Callback URLs

    Code Block
    languagejs
    themeMidnight
    10:30:1:0:http://domain.com/check.asp?ip={IP}&id={CLIENT_USER_ID}&start={START_AT}&lms={
    PLAY_BLOCK_JSON}&uservalue0={USERVALUE0}
    20:180:0:1:http://another_domain.com/anohter_check.php?ip={IP}&id={CLIENT_USER_ID}&start={
    START_AT}&lms={JSON_DATA}&uservalue0={USERVALUE0}
    
    

    Plugin options

    재생 정보를 전달하기 위한 옵션은 JSON 형태의 Array로 전달됩니다.

    • progress_plugin (array)
      • http://domain.com/check.asp?block_period=10&ip={IP}&id={CLIENT_USER_ID}&start={START_AT}&json_data={JSON_DATA}&uservalue0={USERVALUE0}
      • http://another_domain.com/anohter_check.php?block_period=20&ip={IP}&id={CLIENT_USER_ID}&start={START_AT}&lms={PLAY_BLOCK_JSON}&uservalue0={USERVALUE0}

    Callback data sample

    Code Block
    languagejs
    themeMidnight
    ● URL: http://lms.servicedomain.com/lms/register
    ● Method: POST
    ● Params:
        ● ID={CLIENT_USER_ID}
        ● MAC={MAC}
        ● LRN={USERVALUE0}
        ● LHF={USERVALUE1}
        ● IP={IP}
        ● LCD={USERVALUE2}
        ● TM={START_AT}
        ● PT={PLAY_TIME}
        ● ET={LAST_PLAT_AT}
        ● B1={BLOCK_PLAY_1}
        ● T1={BLOCK_TIME_1}
        ● ...
        ● SKIP={PLAYLIST_SKIP}
    ● http://lms.servicedomain.com/lms/register?ID=pobi&MAC=123456789ABCDEF&LRN=
    123456789ABCDEF&LHF=1&IP=192.168.0.118&LCD=L123&UCD=U123&TM=12345678
    9&PT=123456789&E T=123456789&SKIP=0&B1=1&B2=1&B3=1&B4=1&B5=1&B6=1&B7
    =1&B8=1&B9=1&B10=1&T 1=123456789&T2=123456789&T3=123456789&T4=12345678
    9&T5=123456789&T6=123456789&T7=123456789&T8=123456789&T9=123456789&T10
    =123456789
            

    Etc.

    블럭개수 제한 (Limit the number of blocks)

    • 최대 100을 넘을 수 없습니다. (range: 1~100)
      • 100을 넘는 데이터가 입력되면 최대값 100으로 처리 됩니다.
      • 0으로 입력되는 경우 1로 처리 됩니다.
    • 모든 컨텐츠의 {DURATION}보다 작거나 같도록 {BLOCK_CNT}를 설정하는 것을 권장합니다. {DURATION}이 {BLOCK_CNT}보다 작은 경우 아래와 같이 처리됩니다.
      • {BLOCK_CNT}가 100일때 {DURATION}이 30이면 전송되는 블럭 정보는 30개로 조정됩니다.

    Callback 호출 주기 (Callback period)

    • Callback은 시스템에 설정된 Callback Url 정보의 period 설정에 따라 호출됩니다.
    • 플레이어가 일시정지, 정지를 하는 경우도 Callback이 호출됩니다.
    • 주기적으로 호출되는 동일한 사용자의 정보는 {START_AT}, {CLIENT_USER_ID}값으로 구분하여 마지막 정보를 확인할 수 있습니다.
    • 플래시 플레이어의 경우는 플레이어 종료시 호출되지 않습니다.

    USERVALUE0 ~ USERVALUE9 사용시 주의 할 점

    • 특수문자(영문,숫자이외의 모든문자:한글,한자,일어등)는 반드시 UTF-8문자열을 UrlEncode된 상태로 전달되어야 합니다.

    crossdomain.xml

    Flash Player 사용시 callback을 받을 서버(고객사)에는 crossdomain.xml 파일이 있어야 합니다.

    Code Block
    languagejs
    themeMidnight
    <?xml version="1.0"?>
    <!DOCTYPE cross-domain-policy SYSTEM
    "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
    <cross-domain-policy>
        <site-control permitted-cross-domain-policies="master-only" />
        <allow-access-from domain="*" to-ports="*" />
        <allow-http-request-headers-from domain="*" headers="*" to-ports="*" />
    </cross-domain-policy>

    데이터 보안

  • LMS callback 데이터를 변조 방지를 위해 POST로 전달되는 모든 정보에 대해 Hash 를 생성하여 전달되는 Hash값과 일치하는 지 확인합니다.

    ※ Hash 생성방식에 대해 노출 우려가 있는 Flash Player, HTML5 Single Player는 제외합니다.

  • Hash 생성 규칙은 아래와 같습니다.

    Code Block
    languagejs
    themeMidnight
    hash_1 = md5 ( post-data ) 
    hash_2 = md5 ( hash_1 + service_account ) ← + 문자 포함 
    hash_2값을 post data의 hash 파라메터의 값으로 전송합니다.

    전송되는 Post 데이터 예시

    Code Block
    languagejs
    themeMidnight
    ID=pobi&MAC=123456789ABCDEF&LRN=123456789ABCDEF&LHF=1&IP=192.16 8.0.118&LCD=L123&UCD=U123&TM=123456789&PT=123456789&ET=123456789 &SKIP=0&B1=1&B2=1&B3=1&B4=1&B5=1&B6=1&B7=1&B8=1&B9=1&B10=1&T1= 123456789&T2=123456789&T3=123456789&T4=123456789&T5=123456789&T6=1 23456789&T7=123456789&T8=123456789&T9=123456789&T10=123456789&hash =7dec341ff384574f24c6c441b46bc9b1

    Children Display


    Page Tree Search