Callback 요청 처리

재생 허용 요청, 재생 시간 보고 등 플레이어 관련 이벤트를 직접 처리하는 예시 코드를 설명합니다.

자세한 사항은 아래 링크를 참고해주세요.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;
        }
    }
}

위로 스크롤