Play Callback

概要

Kollus Security Playerで再生する際に顧客側で指定したURLを呼出す(Callback)機能を説明します。Agentインストール型及びモバイルPlayerアプリ, Player SDKの使用が前提になります。

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を使用するにはチャンネル編集ページの運用ポリシー、Play Callback項目にCallbackを受け取るURLを事前に登録する必要があります。

チャンネルにPlay Callbackを指定するとこのチャンネルから再生される全てのコンテンツはCallbackに対したレスポンスが確認されてから再生されるため、Callback URLは常にレスポンスができる状態を維持する必要があります。

注意:

  1. 顧客側のユーザID(サービスに登録された会員が特定できる情報)を含むメディアトークン(Media token)を生成してリクエストするとPlay Callbackが呼出されます。(メディアトークンの生成は別途文書を参考にしてください。)

  2. Play Callback URLからレスポンスがないと再生されません。

  3. Play Callbackはダウンロードされたコンテンツ(DRM Callback)とは動作が異なります。ダウンロードされたコンテンツはPlay Callbackではなく、DRM Callbackが適用されます。必要に応じてPlay CallbackとDRM Callbackに同一なURLを指定する場合、ストリーミングとダウンロードに対してのレスポンスを同時に受け取ることができます。

Callback flow

  1. 配信チャンネルにPlay CallbackのURL設定します。

  2. Media tokenを生成して再生(ダウンロード)をリクエストします。

    • Kollus crypt SDKを使ってMedia tokenを生成します。

  3. Kollus Security playerがhttp://www.foo.com/auth.php に以下の情報をPOST転送します。

    • kind : 1, 3

    • client_user_id : ユーザID(サービス会員情報)

      • Media token 生成の際に含まれたID

    • player_id : ユーザのデバイスID

    • device_name : ユーザのデバイス名

    • media_content_key : 再生するコンテンツキー

      • チャンネルに登録されたコンテンツのメディアコンテンツキー(ユニーク)

      • 同じコンテンツを複数のチャンネルに登録する場合、それぞれのmedia_content_keyは全て異なります。

    • 顧客のPlay Callbackサーバーは転送された上記の情報に基づいて以下のjson フォーマットのdataを次の方式に合わせてHttp Bodyに転送します。(顧客が認証データをPlayerに転送する全てのデータは必ずinteger型で転送しなければなりません。)

      • 対応方式

        • Kollus crypt SDKで暗号化して転送

        • JWT Encodeして転送、アルゴリズムはHS256のみ対応しており、jsonフォーマットのdataをJWTのpayloadに追加してEncodingします。ヘッダーに指定された *ユーザーキー(X-KOLLUs-USERKEY)"を共に転送します。secret keyはCallbackリクエストの際に転送するcustom_keyパラメータ値を使用します。

Response JSON spec.

Callback Kind

Play Callbackが呼出される状況は以下の三つのケースになります。

コンテンツのExpire情報をリクエストする場合 (kind:1)

Request

  • uservalues sample

    • uservalues={"uservalue0":"商品種類コード01","uservalue1":"商品名コード02","uservalue9":"生成コード03"}

    • VideoGateway(v.jp.kollus.com)の呼出に使用されたuservalue0~9 情報が一緒にリターンされます。

Response

Example

{
    “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 Callbackに対したレスポンスが確認されてから再生が始まります。レスポンスがなければ再生できません。

Request

Response

Example

{
    “data” : {
        "content_expired": 1,
        "result": 1
    },
    "exp" : 1477558242
}

Sample

  • Play callback url

    • http://www.foo.com/auth.php

  • コンテンツ有効期限 : 2014年 6月 10日 24:00まで

    • DATE (M/D/Y @ h : m : s): 6 / 10 / 2014 @ 24:0:0 UTC

    • Unix time stamp : 1402444800

    • http://www.epochconverter.com から1402444800値を変更することができます。※UTC基準(GMTではない)

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

{
    “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

{
    “data” : {
        "content_expired": 1,
        "result": 1
    },
    "exp" : 1477558242
}

Code sample

以下のように顧客のDBが構成されていると想定したサンプルコードになります。

PHP sample

<?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

<%@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"; // ユーザアカウントID
        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)%>

サービスサポート

サンプルコードについてのお問い合わせは担当までご連絡ください。

E-mail お問い合わせ > jp_team@catenoid.net

電話番号 > 03-4405-8462

Last updated