재생 허용 요청, 재생 시간 보고 등 플레이어 관련 이벤트를 직접 처리하는 예시 코드를 설명합니다.
자세한 사항은 아래 링크를 참고해주세요.Callback URL
php 예시
php 예시입니다.이 코드는 PHP 5.2 이상에서 지원하는 json 라이브러리를 사용합니다.
<?php
// POST로 넘겨받은 JSON 데이터 변수화
$json = file_get_contents('php://input');
$data = json_decode($json);
function callback($e) { // 분류에 맞춰 올바른 Call 처리 함수 호출
if ($e == null) { // 아무 값이 없으면 Block
header('HTTP/1.1 403 Forbidden');
die();
}
$type = $e->type; // Callback 요청 분류
// 모든 응답은 JSON 형식으로 해야 합니다.
if ($type == "CheckAccessRights") {
$result = checkAccessRights($e);
echo json_encode($result);
} elseif ($type == "NotifyPlaybackProgress") {
$result = notifyPlaybackProgress($e);
echo json_encode($result);
} elseif ($type == "NotifyPlaybackStatus") {
$result = notifyPlaybackStatus($e);
echo json_encode($result);
} elseif ($type == "NotifyPlaybackFinish") {
$result = notifyPlaybackFinish($e);
echo json_encode($result);
} elseif ($type == "NotifyDownloadStatus") {
$result = notifyDownloadStatus($e);
echo json_encode($result);
} elseif ($type == "GetBookmarks") {
$result = getBookmarks($e);
echo json_encode($result);
} elseif ($type == "UpdateBookmarks") {
$result = updateBookmarks($e);
echo json_encode($result);
} else {
header('HTTP/1.1 403 Forbidden'); // 올바른 값이 아니면 Block
die();
}
}
function checkAccessRights($e) { // 접근 권한 검사
// 아래 정보를 이용, 고객사 DB 등과 비교하여 return 값을 할당해야 합니다.
$mediaUrl = $e->mediaUrl; // 미디어 URL check
$userId = $e->userId; // 사용자 id check
$device_id = $e->deviceId; // 기기 등록 정보 check
$offline = $e->offline; // 다운로드 요청은 true, 스트리밍 요청은 false
// $userData = $e->userData; // Agent를 실행할 때 인증데이터(mediaItem)에 "userData" 값을 추가한 경우
// $userData 사용 예제
// $userData = $e->userData->CustomKey;
// DB 연동 로직을 구현해 주시기 바랍니다.
$DB_conncet = true;
if ($DB_conncet == true) {
$result = array("result" => "Ok"); // 로직에 따라 값을 부여합니다. "Ok" = 성공, "Expired" = 접근 권한 만료, "NoRights" = 접근 권한 없음, "DeviceLimitExceeded" = 디바이스 제한 초과
// $result = array("result" => "Ok", "expiresOn" => "3600"); // expiresOn 옵션은 다운로드 컨텐츠의 만료일(UTC, 초)을 지정할 수 있습니다. 이 옵션은 "result"가 "Ok"여야 합니다.
}
return $result;
}
function notifyPlaybackProgress($e) { // 재생 진행 상태 보고
// 아래 정보를 이용, 고객사 DB 등과 비교하여 return 값을 할당해야 합니다.
$userId = $e->userId; // 사용자 id check
$position = $e->position; // 현재 재생 위치
$duration = $e->duration; // 전체 재생 길이
$playTime = $e->progress->playTime; // 재생 시간 (배속 X)
$watchTime = $e->progress->watchTime; // 시청 시간 (배속 O)
// $userData = // Agent를 실행할 때 인증데이터(mediaItem)에 "userData" 값을 추가한 경우
// $userData 사용 예제
// $userData = $e->userData->CustomKey;
// DB 연동 로직을 구현해 주시기 바랍니다.
$DB_conncet = true;
$result = array("result" => "Ok");
if ($DB_conncet == true) {
$result = array("result" => "Ok"); // 로직에 따라 값을 부여합니다. "Ok" = 성공, "PlaybackLimitExceeded" = 재생 제한 초과 (배수 제한, 재생 횟수 등)
}
return $result;
}
function notifyPlaybackStatus($e) { // 재생 상태 보고
// 아래 정보를 이용, 고객사 DB 등과 비교하여 return 값을 할당해야 합니다.
$userId = $e->userId; // 사용자 id check
// $userData = // Agent를 실행할 때 인증데이터(mediaItem)에 "userData" 값을 추가한 경우
// $userData 사용 예제
// $userData = $e->userData->CustomKey;
$mediaUrl = $e->mediaUrl; // 미디어 URL check
$status = $e->status; // 재생 상태 “Started” = 미디어 재생 시작, “Stopped” = 미디어 종료
$createdAt = $e->createdAt; // Callback JSON 데이터가 생성된 시간
// DB 연동 로직을 구현해 주시기 바랍니다.
$DB_conncet = true;
$result = array("result" => "Ok");
if ($DB_conncet == true) {
$result = array("result" => "Ok"); // 로직에 따라 값을 부여합니다. "Ok" = 성공
}
return $result;
}
function notifyPlaybackFinish($e) { // 재생 종료 보고
// 아래 정보를 이용, 고객사 DB 등과 비교하여 return 값을 할당해야 합니다.
$userId = $e->userId; // 사용자 id check
// $userData = // Agent를 실행할 때 인증데이터(mediaItem)에 "userData" 값을 추가한 경우
// $userData 사용 예제
// $userData = $e->userData->CustomKey;
$mediaUrl = $e->mediaUrl; // 미디어 URL check
$position = $e->position; // 현재 재생 위치 (단위: ms)
$duration = $e->duration; // 전체 재생 길이 (단위: ms)
// 현재 세션의 진행 상태
$playTime = $e->progress->playTime; // 재생한 시간 (배속 X)
$watchTime = $e->progress->watchTime; // 재생한 시간 (배속 O)
// 미디어 종료 원인
$reason = $e->reason; // "Ended" = 미디어가 끝까지 재생된 후 종료, "Error" = 오류로 인하여 재생 종료, "UserExited" = 사용자가 미디어를 제어하여 종료
// DB 연동 로직을 구현해 주시기 바랍니다.
$DB_conncet = true;
$result = array("result" => "Ok");
if ($DB_conncet == true) {
$result = array("result" => "Ok"); // 로직에 따라 값을 부여합니다. "Ok" = 성공
}
return $result;
}
function notifyDownloadStatus($e) { // 다운로드 상태 보고
// 아래 정보를 이용, 고객사 DB 등과 비교하여 return 값을 할당해야 합니다.
$userId = $e->userId; // 사용자 id check
// $userData = // Agent를 실행할 때 인증데이터(mediaItem)에 "userData" 값을 추가한 경우
// $userData 사용 예제
// $userData = $e->userData->CustomKey;
$mediaUrl = $e->mediaUrl; // 미디어 URL check
$status = $e->status; // 다운로드 상태 "Started" = 다운로드 시작, "Completed" = 다운로드 완료, "Canceled" = 다운로드 취소, "Failed" = 다운로드 실패
$createdAt = $e->createdAt; // Callback JSON 데이터가 생성된 시간
// DB 연동 로직을 구현해 주시기 바랍니다.
$DB_conncet = true;
$result = array("result" => "Ok");
if ($DB_conncet == true) {
$result = array("result" => "Ok"); // 로직에 따라 값을 부여합니다. "Ok" = 성공
}
return $result;
}
function getBookmarks($e) { //북마크 데이터 변경 시 호출됩니다.
// 참고: useBookmarkCallback 가 true일 경우 동작합니다.
// 서버에 저장된 북마크 데이터를 플레이어에 전달합니다.
$userId = $e->userId; // 사용자 id check,
$userData = $e->userData; // Agent를 실행할 때 인증데이터(mediaItem)에 "userData" 값을 추가한 경우
$mediaUrl = $e->mediaUrl; // 미디어 URL check
$appId = $e->appId; // App ID
$DB_conncet = true; // DB와 연결 로직을 구현해 주셔야 합니다. DB에서 user의 북마크 데이터를 가져와야 합니다.
$bookmarks = [{"title": "제목", "pos": 60}]; // 저장된 북마크 목록(배열), 이 값을 DB에 등록하는 등 활용하실 수 있습니다.
$result= array("result" => "Ok", "bookmarks" => $bookmarks);
return $result;
}
function updateBookmarks($e) { //북마크 데이터 변경 시 호출됩니다.
// 참고: useBookmarkCallback 가 true일 경우 동작합니다.
// 플레이어에서 업데이트된 북마크 정보를 받아 DB에 업로드합니다.
$userId = $e->userId; // 사용자 id check,
$userData = $e->userData; // Agent를 실행할 때 인증데이터(mediaItem)에 "userData" 값을 추가한 경우
$mediaUrl = $e->mediaUrl; // 미디어 URL check
$appId = $e->appId; // App ID
$bookmarks = $e->bookmarks; // 저장된 북마크 목록(배열), 이 값을 DB에 등록하여 업데이트
$result= array("result" => "Ok");
return $result;
}
callback($data);
?>
jsp 예시
jsp 예시입니다.이 코드는 Java SE 7 이상에서 지원하는 org.json 라이브러리를 사용합니다.Front 부분
<%@ page import="java.io.BufferedReader, java.io.IOException" %>
<%@ page import="org.json.JSONObject" %>
<%@ page import="com.example.CallbackHandler" %>
<%
response.setContentType("application/json");
StringBuilder jsonBuilder = new StringBuilder();
// JSON 데이터 수신
try (BufferedReader reader = request.getReader()) {
String line;
while ((line = reader.readLine()) != null) {
jsonBuilder.append(line);
}
} catch (IOException e) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
out.print(new JSONObject().put("error", "Invalid request").toString());
return;
}
JSONObject data;
try {
data = new JSONObject(jsonBuilder.toString());
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
out.print(new JSONObject().put("error", "Invalid JSON format").toString());
return;
}
String type = data.optString("type", null);
JSONObject result = new JSONObject();
if (type == null) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
out.print(new JSONObject().put("error", "Type not specified").toString());
return;
}
// 요청 유형에 따른 처리
try {
switch (type) {
case "CheckAccessRights":
result = CallbackHandler.checkAccessRights(data);
break;
case "NotifyPlaybackProgress":
result = CallbackHandler.notifyPlaybackProgress(data);
break;
case "NotifyPlaybackStatus":
result = CallbackHandler.notifyPlaybackStatus(data);
break;
case "NotifyPlaybackFinish":
result = CallbackHandler.notifyPlaybackFinish(data);
break;
case "NotifyDownloadStatus":
result = CallbackHandler.notifyDownloadStatus(data);
break;
case "GetBookmarks":
result = CallbackHandler.getBookmarks(data);
break;
case "UpdateBookmarks":
result = CallbackHandler.updateBookmarks(data);
break;
default:
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
out.print(new JSONObject().put("error", "Invalid type").toString());
return;
}
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
out.print(new JSONObject().put("error", "Internal server error").toString());
return;
}
out.print(result.toString());
%>
Handler 부분
package com.example;
import org.json.JSONObject;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.util.Base64;
public class CallbackHandler {
// Base64로 인코딩된 AES 암호화된 문자열을 복호화하는 메서드 (option)
private static long decryptAuthtime(String authtime, String secretKey) throws Exception {
byte[] key = secretKey.getBytes("UTF-8");
byte[] iv = new byte[16];
// Base64 디코딩
byte[] encryptedData = Base64.getDecoder().decode(authtime);
// AES 복호화
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
byte[] decryptedTimeBytes = cipher.doFinal(encryptedData);
return Long.parseLong(new String(decryptedTimeBytes, "UTF-8"));
}
public static JSONObject checkAccessRights(JSONObject e) {
boolean dbConnect = true;
if (dbConnect) {
return new JSONObject().put("result", "Ok");
}
return new JSONObject().put("result", "NoRights");
}
// 나머지 메서드 유지
public static JSONObject notifyPlaybackProgress(JSONObject e) {
boolean dbConnect = true;
if (dbConnect) {
return new JSONObject().put("result", "Ok");
}
return new JSONObject().put("result", "PlaybackLimitExceeded");
}
public static JSONObject notifyPlaybackStatus(JSONObject e) {
boolean dbConnect = true;
if (dbConnect) {
return new JSONObject().put("result", "Ok");
}
}
public static JSONObject notifyPlaybackFinish(JSONObject e) {
boolean dbConnect = true;
if (dbConnect) {
return new JSONObject().put("result", "Ok");
}
}
public static JSONObject notifyDownloadStatus(JSONObject e) {
boolean dbConnect = true;
if (dbConnect) {
return new JSONObject().put("result", "Ok");
}
}
public static JSONObject getBookmarks(JSONObject e) {
// 직접 북마크를 관리하는 경우에만 사용됩니다.
boolean dbConnect = true; // DB에서 user의 저장된 북마크 데이터를 가져오는 로직 구현
JSONArray putBookmarks = new JSONArray(); // DB 와 연결하여 받아온 데이터를 이 배열변수에 저장해 주세요
// 예시: putBookmarks의 값 = [{"title": "제목1", "pos": 60}, {"title": "제목2", "pos": 120}] 의 형태가 되어야 합니다.
if (dbConnect) {
JSONObject response = new JSONObject();
response.put("result", "Ok");
response.put("bookmarks", putBookmarks);
return response;
}
}
public static JSONObject updateBookmarks(JSONObject e) {
JSONArray updateBookmark = new JSONArray(); // 업데이트된 북마크를 저장할 변수 생성
updateBookmark = e.getJSONArray("bookmarks"); // 콜백 데이터 중 업데이트 된 북마크 데이터를 가져옴
boolean dbConnect = true; // updateBookmark 값을 DB에 업로드해주세요.
if (dbConnect) {
response.put("result", "Ok");
return response;
}
}
}
asp 예시
asp 예시입니다.이 코드는 .NET Framework 3.5 이상, C# 3.0 이상에서 지원하는 Newtonsoft.Json 라이브러리를 사용합니다.Front 부분
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Callback.aspx.cs" Inherits="WebApplication.Callback" %>
Handler 부분
using System;
using System.IO;
using Newtonsoft.Json;
using System.Security.Cryptography;
using System.Text;
public class EncryptionHelper
{
public static string Decrypt(string encryptedText, string secretKey) // 시간값 암호 복호화 (option)
{
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(secretKey.PadRight(16).Substring(0, 16)); // 16바이트 키
aes.IV = new byte[16]; // 16바이트 초기화된 IV 생성
aes.Mode = CipherMode.CBC; // CBC 모드 설정
aes.Padding = PaddingMode.PKCS7; // 패딩 모드 설정 (Key가 16바이트 이하일 경우 위함)
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
byte[] encryptedBytes = Convert.FromBase64String(encryptedText);
byte[] decryptedBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
return BitConverter.ToInt64(decryptedBytes, 0).ToString(); //디코딩된 값 Return
}
}
}
namespace WebApplication
{
public partial class Callback : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Request.HttpMethod == "POST") // 요청이 POST 메서드일 때만 처리합니다.
{
// JSON 데이터를 요청 본문에서 읽음
using (var reader = new StreamReader(Request.InputStream))
{
var json = reader.ReadToEnd();
var data = JsonConvert.DeserializeObject<dynamic>(json);
var result = HandleCallback(data);
// JSON 형식으로 응답
Response.ContentType = "application/json";
Response.Write(JsonConvert.SerializeObject(result));
Response.End();
}
}
else
{
Response.StatusCode = 405; // 허용되지 않는 메서드의 경우
Response.End();
}
}
private dynamic HandleCallback(dynamic e)
{
if (e == null || e.type == null)
{
Response.StatusCode = 400; // 잘못된 요청일 경우
Response.End();
return null;
}
string type = e.type;
dynamic result = null;
switch (type)
{
case "CheckAccessRights":
result = CheckAccessRights(e);
break;
case "NotifyPlaybackProgress":
result = NotifyPlaybackProgress(e);
break;
case "NotifyPlaybackStatus":
result = NotifyPlaybackStatus(e);
break;
case "NotifyPlaybackFinish":
result = NotifyPlaybackFinish(e);
break;
case "NotifyDownloadStatus":
result = NotifyDownloadStatus(e);
break;
case "GetBookmarks":
result = GetBookmarks(e);
break;
case "UpdateBookmarks":
result = UpdateBookmarks(e);
break;
default:
Response.StatusCode = 400; // 잘못된 요청일 경우
Response.End();
return null;
}
return result;
}
private dynamic CheckAccessRights(JObject e)
{
// 데이터베이스 연결 및 기타 로직 구현바랍니다.
JObject response = new JObject(); // response 객체 생성
response["result"] = "Ok";
// 이외 경우: response["result"] = "Expired" 권한만료| "NoRights" 권한없음 | "DeviceLimitExceeded" 기기대수초과
// 다운로드의 경우, 컨텐츠 유효시간 기입: response["result"] = "Ok", response["expireOn"] = 만료일(숫자형, UTC)
return response;
}
private dynamic NotifyPlaybackProgress(JObject e)
{
// 데이터베이스 연결 및 기타 로직 구현바랍니다.
JObject response = new JObject(); // response 객체 생성
response["result"] = "Ok";
return response;
}
private dynamic NotifyPlaybackStatus(JObject e)
{
// 데이터베이스 연결 및 기타 로직 구현바랍니다.
JObject response = new JObject(); // response 객체 생성
response["result"] = "Ok";
return response;
}
private dynamic NotifyPlaybackFinish(JObject e)
{
// 데이터베이스 연결 및 기타 로직 구현바랍니다.
JObject response = new JObject(); // response 객체 생성
response["result"] = "Ok";
return response;
}
private dynamic NotifyDownloadStatus(JObject e)
{
// 데이터베이스 연결 및 기타 로직 구현바랍니다.
JObject response = new JObject(); // response 객체 생성
response["result"] = "Ok";
return response;
}
private dynamic GetBookmarks(JObject e)
{
// 북마크를 직접 관리하시는 경우 DB에서 값을 받아 입력합니다.
// 데이터베이스 연결 및 기타 로직 구현바랍니다.
bool dbConnect = true; // DB에서 user의 저장된 북마크 데이터를 가져오는 로직 구현
JArray putBookmarks = new JArray(); // DB 와 연결하여 받아온 데이터를 이 배열변수에 저장해 주세요
// 예시: putBookmarks의 값 = [{"title": "제목1", "pos": 60}, {"title": "제목2", "pos": 120}] 의 형태가 되어야 합니다.
JObject response = new JObject();
response["result"] = "Ok";
response["bookmarks"] = putBookmarks;
return response;
}
public static JObject UpdateBookmarks(JObject e)
{
JArray updateBookmark = new JArray(); // 업데이트된 북마크를 저장할 변수 생성
updateBookmark = (JArray)e["bookmarks"]; // 콜백 데이터 중 업데이트 된 북마크 데이터를 가져옴
bool dbConnect = true; // updateBookmark 값을 DB에 업로드해주세요.
JObject response = new JObject(); // response 객체 생성
response["result"] = "Ok";
return response;
}
}
}