概要
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
最大値 : 2029年 12月 31日 23時 59分 59秒 (1893455999)
Play callback
Play callbackを使用するにはチャンネル編集ページの運用ポリシー、Play Callback項目にCallbackを受け取るURLを事前に登録する必要があります。
チャンネルにPlay Callbackを指定するとこのチャンネルから再生される全てのコンテンツはCallbackに対したレスポンスが確認されてから再生されるため、Callback URLは常にレスポンスができる状態を維持する必要があります。
注意:
顧客側のユーザID(サービスに登録された会員が特定できる情報)を含むメディアトークン(Media token)を生成してリクエストするとPlay Callbackが呼出されます。(メディアトークンの生成は別途文書を参考にしてください。)
Play Callback URLからレスポンスがないと再生されません。
Play Callbackはダウンロードされたコンテンツ(DRM Callback)とは動作が異なります。ダウンロードされたコンテンツはPlay Callbackではなく、DRM Callbackが適用されます。必要に応じてPlay CallbackとDRM Callbackに同一なURLを指定する場合、ストリーミングとダウンロードに対してのレスポンスを同時に受け取ることができます。
Callback flow
配信チャンネルにPlay CallbackのURL設定します。
Media tokenを生成して再生(ダウンロード)をリクエストします。
Kollus crypt SDKを使ってMedia tokenを生成します。
Kollus Security playerがhttp://www.foo.com/auth.php に以下の情報をPOST転送します。
client_user_id : ユーザID(サービス会員情報)
media_content_key : 再生するコンテンツキー
チャンネルに登録されたコンテンツのメディアコンテンツキー(ユニーク)
同じコンテンツを複数のチャンネルに登録する場合、それぞれのmedia_content_keyは全て異なります。
顧客のPlay Callbackサーバーは転送された上記の情報に基づいて以下のjson フォーマットのdataを次の方式に合わせてHttp Bodyに転送します。(顧客が認証データをPlayerに転送する全てのデータは必ずinteger型で転送しなければなりません。)
対応方式
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"}
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
kind1 : request expire option
request
URL : http://www.foo.com/auth.php
post data
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
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