Spark API 开发指南 版本 : 2.0.4 日期 : 2013-02-25 北京梦之窗数码科技有限公司
目录 1. 概述!... 1 2. 通信约定!... 1 2.1 Http 方法!... 1 2.2 返回格式!... 1 2.3 编码格式!... 1 2.4 加密!... 1 2.5 接 口访问次数限制!... 2 3. Http 接 口!... 2 3.1 获取 用户信息!... 2 3.2 获取视频信息!... 2 3.3 批量获取视频信息!... 3 3.4 获取视频播放代码!... 5 3.5 编辑视频信息!... 6 3.6 删除视频!... 7 3.7 获取视频分类!... 7 4. Flash 接 口!... 8 4.1 视频上传!... 8 4.2 视频播放!... 10 附录 1. Http 通信加密算法!... 12 附录 2. Flash 和 Javascript 交互!... 12
1. 概述 利 用 Spark API 可以与 CC 视频 Spark 云进 行对接, 使 用 Spark 云的主要视频功能 当前 Spark API 的版本号为 2.0, 具有上传 播放 获取视频信息 获取 用户信息 删除视频 获取视频分类等接 口 目前 Spark API 仅对合作 方开启, 如果您有使 用的需求, 请通过 CC 视频后台申请 API Key, 通过审核后才能使 用 Spark API 2. 通信约定 Spark API 的远程通信接 口基于 Http 协议, 并有以下约定 : 2.1 Http 方法! 所有接 口采 用 GET 请求 2.2 返回格式 接 口的返回格式包括 XML 格式和 JSON 格式, 编码均为 UTF-8 对于不同的接 口, 正确的返回结果的格式会在每个接 口中单独定义, 错误的返回结果具有统 一的形式, 如下所 示 : <error>error_code</error> error : ERROR_CODE 实际中, 下表中的某 一个具体的错误码会替换掉上 面的 ERROR_CODE: 错误码 INVALID_REQUEST SPACE_NOT_ENOUGH SERVICE_EXPIRED PROCESS_FAIL TOO_MANY_REQUEST PERMISSION_DENY 说明 用户输 入错误 用户剩余空间不 足 用户服务已经过期服务器处理失败访问过于频繁 用户服务 无权限 2.3 编码格式 Spark API 只接受 UTF-8 格式编码的信息, 返回的数据也都是 UTF-8 编码的 当需要通过 GET 请求传递时,QueryString 里 面的 value 值都需要进 行 URL Encode 之后, 再进 行传递 2.4 加密 所有的 HTTP 通信都是加密的, 加密的核 心思想是将原始的 QueryString 转换为和请求时间相关的 HashedQueryString, 我们称这个加密算法为 THQS 算法 关于 THQS 算法的细节请参 见附录 1 第 1 页共 13 页
2.5 接 口访问次数限制 当某 一个接 口的访问频率在 一分钟之内超过 100 次的时候, 该 用户的 API 功能将被禁 用, 之后所有请求都将失效 如果上述阈值 无法满 足您的正常需求的时候, 可以联系 CC 客服申请提升 API 的请求频率 3. Http 接 口 3.1 获取 用户信息 通过该接 口可以获取指定 用户的账户信息, 地址为 : http://spark.bokecc.com/api/user 需要传递以下 : userid format 说明 用户 id, 不可为空 返回格式,xml 或 json Xml 格式的返回信息如下 : <user> <account>test@test.com</account> <version><![cdata[ 试 用版 ]]></version> <expired>2011-06-06</expired> <space> <total>2</total> <used>0.1</used> </space> <traffic> <total>5</total> <used>0.2</used> </traffic> </user> Json 格式的返回信息如下 : "user": "account":"test@test.com", "version":" 试 用版 ", "expired":"2011-06-06", "space": "total":2, "used":0.1,, "traffic": "total":5, "used":0.2, 3.2 获取视频信息 通过该接 口可以获取指定 用户的有效视频的信息, 地址为 : 第 2 页共 13 页
http://spark.bokecc.com/api/video 需要传递以下 : userid videoid format 说明 用户 id, 不可为空视频 id, 不可为空返回格式,xml 或 json Xml 格式的返回信息如下 : <video> <id>01234567</id> <title><![cdata[ 视频标题 ]]></title> <desp><![cdata[ 视频描述 ]]></desp> <tags><![cdata[ 标签 1 标签 2 标签 3]]></tags> <duration>314</duration> <category>12345</category> <image>http://image.bokecc.com/abc.jpg</image> <imageindex>1</imageindex> <image-alternate> <index>1</index> <url>http://image.bokecc.com/abc1.jpg</url> </image-alternate> <image-alternate> <index>2</index> <url>http://image.bokecc.com/abc2.jpg</url> </image-alternate>... </video> Json 格式的返回信息如下 : "video": "id":"01234567", "title":" 视频标题 ", "desp":" 视频描述 ", "tags":" 标签 1 标签 2 标签 3", "duration":"12345", "category":"12345", "image":"http://image.bokecc.com/abc.jpg", "imageindex":1, "image- alternate":[ "index":1, "url":"http://image.bokecc.com/abc1.jpg",... ] 3.3 批量获取视频信息 通过该接 口可以获取指定 用户的 一批有效视频 ( 不包括删除 正在处理的视频 ) 的信息, 地址为 : 第 3 页共 13 页
http://spark.bokecc.com/api/videos 需要传递以下 : userid videoid_from videoid_to 说明 用户 id, 不可为空起始 videoid, 若为空, 则从上传的第 一个视频开始终 止 videoid, 若为空, 则到最后 一个上传的视频 num_per_page 返回信息时, 每 页包含的视频个数注 : 阈值为 1~100 page format 当前 页码 返回格式,xml 或 json Xml 格式的返回信息如下 : <videos> <total>100</total> <video> <id>01234567</id> <title><![cdata[video Title]]></title> <desp><![cdata[video Description]]></desp> <tags><![cdata[tag1 tag2 tag3]]></tags> <duration>314</duration> <category>12345</category> <image>http://image.bokecc.com/abc.jpg</image> <imageindex>1</imageindex> <image-alternate> <index>1</index> <url>http://image.bokecc.com/abc1.jpg</url> </image-alternate> <image-alternate> <index>2</index> <url>http://image.bokecc.com/abc2.jpg</url> </image-alternate>... </video>... </videos> Json 格式的返回信息如下 : 第 4 页共 13 页
! Spark API 开发指南 "videos": "total":100, "video":[ "id":"01234567", "title":"video Title", "desp":"video Description", "tags":"tag1 tag2 tag3", "duration":"12345", "category":"12345", "image":"http://image.bokecc.com/abc.jpg", "imageindex":1, "image-alternate":[ "index":1, "url":"http://image.bokecc.com/abc1.jpg", ], ] 3.4 获取视频播放代码通过该接 口可以获取指定视频的视频播放 html 代码段, 地址为 : http://spark.bokecc.com/api/video/playcode 需要传递以下 : videoid playerid player_width player_height auto_play format 说明视频 id, 不可为空播放器 id, 若为空则返回默认播放器播放器宽度, 单位 px 播放器 高度, 单位 px 是否 自动播放,true 或 false 返回格式,xml 或 json Xml 格式的返回信息如下 : <video> <playcode> <![CDATA[<script src='http://union.bokecc.com/player? vid=96479767c315e6a9&siteid=1936d297411c3a27&autostart=false&width=600&height=490&playerid =6ED7421AB96B522E&playertype=1'type='text/javascript'></script>]]> </playcode> </video> 第 5 页共 13 页
Json 格式的返回信息如下 : "video": "playcode":"<script src='http://union.bokecc.com/player? vid=96479767c315e6a9&siteid=1936d297411c3a27&autostart=false&width=600&height=490&playerid =6ED7421AB96B522E&playertype=1'type='text/javascript'></script>" 3.5 编辑视频信息通过该接 口可以编辑指定视频的信息, 地址为 : http://spark.bokecc.com/api/video/update 需要传递以下 : videoid title tag description categoryid playurl imageindex format 说明 视频 id, 不可为空 视频标题 视频标签 视频描述 视频 子分类 id 视频播放 页 面地址, 如果不编辑播放地址, 请勿加 入此 视频封 面截图序号, 如果不编辑封 面截图, 请勿加 入此注 : 只可编辑正常可播放状态的视频截图 返回格式,xml 或 json Xml 格式的返回信息如下 : <video> <id>01234567</id> <title><![cdata[video Title]]></title> <desp><![cdata[video Description]]></desp> <tags><![cdata[tag1 tag2 tag3]]></tags> <category>12345</category> <playurl>http://xxxx/1.html</playurl> <imageindex>1</imageindex> </video> Json 格式的返回信息如下 : 第 6 页共 13 页
! Spark API 开发指南 "video": "id":"01234567", "title":"video Title", "desp":"video Description", "tags":"tag1 tag2 tag3", "category":"12345", "playurl":"http://xxxx/1.html", "imageindex":1 3.6 删除视频通过该接 口可以删除指定视频的信息, 地址为 : http://spark.bokecc.com/api/video/delete 需要传递以下 : videoid format 说明 视频 id, 不可为空 返回格式,xml 或 json Xml 格式的返回信息如下 : <video>ok</video> Json 格式的返回信息如下 : "result":"ok" 3.7 获取视频分类通过该接 口可以获取指定 用户创建的全部视频分类, 地址为 : http://spark.bokecc.com/api/video/category 需要传递以下 : userid format 说明 用户 id, 不可为空 返回格式,xml 或 json 注 : 返回结果中的 level 包括 BASIC 和 PREMIUM,BASIC 中只包含 一个默认 父分类, 无法创建 自定义 父分类, PREMIUM 版本中包含 用户创建的 父分类 Xml 格式的返回信息如下 : 第 7 页共 13 页
<video> <level>basic</level> <category> <id>123</id> <name><![cdata[category1]]></name> <sub-category> <id>456</id> <name><![cdata[category1]]></name> <sub-category>... </category>... </video> Json 格式的返回信息如下 : "video": "level":"premium", "category":[ "id":123, "name":"category1", "sub-category":[ "id":456, "name":"sub category1",... ],... ] 4. Flash 接 口 Spark API 中所有的 Flash 接 口需要 Flash 插件的版本在 10.1 以上才有效, 使 用前请确保 Flash 插件版本符合要求 4.1 视频上传 在上传视频的过程中, 不 用与 Spark 平台进 行 Http 通信, 使 用 javascript 和 Spark 提供的 Flash 进 行交互即可完成 关于如何在 网 页中嵌 入 Flash 以及如何和 Flash 进 行交互, 请参阅附录 2 上传接 口 用到的所有 javascript 函数定义 见下表 : 函数定义 on_spark_selected_file(file_name, file_size) on_spark_upload_validated(status, videoid) on_spark_upload_progress(progress) 说明 file_name: 上传 文件名 file_size: 上传的 文件 大 小, 单位字节 status: 验证结果 videoid: 视频 id progress: 上传进度 正确时,0~100 之间的整数, 包括 0 和 100; 错误时, 返回 -1. 网 页嵌 入 Spark 提供的上传 Flash 时, 需要传递下列 : 第 8 页共 13 页
Flash (flashvars) progress_interval notify_url 说明 回调进度函数的时间间隔, 默认 1 秒 视频处理完毕后的通知地址 上传 文件的过程 一共分为四步 : 第 一步, 选择 文件 Spark 提供 一个透明的 Flash 进 行 文件上传, 地址如下 : http://union.bokecc.com/flash/api/uploader.swf 由于它是透明的, 所以可以置于任何 一个 html 元素的上 方 而不影响的 页 面视觉效果 上传 文件时, 必须通过点击到该 flash 从 而打开浏览对话框进 行 文件选择 文件选择成功后,Flash 会调 用 页 面中的 on_spark_selected_file 函数, 页 面可以选择合适的 方式处理该事件 第 二步, 验证 当 用户选择 文件后, 需将下 面的按照 THQS 算法处理后传递给 Flash 的 start_upload 函数后, 才能开始上传流程 首先要进 行和权限的验证, 通过后才开始 文件上传 userid title description tag 说明 用户 id, 不可为空视频标题, 若为空, 则采 用去后缀 文件名作为 title 视频简介, 可以为空视频标签, 可以为空 验证完成后,Flash 会调 用 on_spark_upload_validated 函数传递验证结果以及视频 id 验证状态码的含义如下 : 验证状态码 OK NETWORK_ERROR 其它 说明成功 网络错误 Spark API 错误码 第三步, 文件上传 文件开始上传后,Flash 会周期性调 用 on_spark_upload_progress 函数来报告上传进度, 间隔秒数由 progress_interval 指定 如果上传的进度为负数, 则说明发 生 网络错误, 上传中断 返回 100 则表 示上传成功 当返回 100 或者 -1 后,Flash 就不再调 用该函数了 第四步, 回调 当 Spark 处理完毕视频后 ( 上传 转码 审核都完成后 ), 会通过 Http 的 GET 方式通知你的 网站 该地址由 notify_url 指定 通知时会以 THQS 方式携带以下 : 第 9 页共 13 页
videoid status 说明 视频 id,16 位 hex 字符串 视频状态 OK 表 示视频处理成功, FAIL 表 示视频处理失败 duration 片 长 ( 单位 : 秒 ) image 视频截图地址 视频处理失败有多种情况, 例如视频 文件异常 视频内容违规等等 <result>ok</result> 当 notify_url 指定的接 口返回上述 xml 时,Spark 会认为 网站已经成功接收到了回调信息, 不再进 行重试 返回其它任何内容,Spark 视频平台会进 行重试, 重试的间隔会随着重试次数的增 大 而增 大 若重试 7 次后, 依然没有成功, 则不再进 行通知 因此,Spark 视频平台最多通知 8 次 这 8 次的通知时间距第 一次的通知时间的差分别为 : [0,15s, 1m, 4m, 16m, 1h4m, 4h16m, 17h4m] 4.2 视频播放 视频播放是通过在 网 页中嵌 入 Spark 平台提供的 flash 播放器来实现的, 地址如下 : http://union.bokecc.com/flash/player.swf 需要给播放器传递的如下 : userid videoid mode autostart jscontrol 说明 用户 id, 不可为空视频 id, 不可为空播放 方式, 在 目前版本中必须传递该, 取值只能为 api 是否 自动播放, 默认 true 是否启 用 js 控制, 默认为 false 同时, 播放器还会在以下事件发 生时调 用相应的 js 函数 : Javascript 函数 on_spark_player_ready on_spark_player_start on_spark_player_pause on_spark_player_resume on_spark_player_stop 事件播放器加载完毕开始播放暂停播放暂停后继续播放播放停 止 页 面也可以调 用 Flash 提供的接 口, 来控制播放的过程 : 第 10 页共 13 页
Flash 函数 spark_player_start spark_player_pause spark_player_resume 播放器动作开始播放暂停播放恢复播放 spark_player_seek 拖动播放 ( 单位 : 秒 ) spark_player_duration 获取视频 片 长 ( 单位 : 秒 ) spark_player_position 获取当前播放时间 ( 单位 : 秒 ) 第 11 页共 13 页
附录 1. Http 通信加密算法 当需要和 Spark 系统进 行 Http 通信时, 需要将原始的 Query String 转换为和请求时刻相关的 Hashed Query String 后再通过 GET 方法请求 Spark 接 口 为了描述的 方便, 我们将 QueryString 转换为 HashQueryString 的算法称为 THQS 算法 在描述详细的算法流程之前, 我们先介绍 一下 Unix 时间戳的概念 Unix 时间戳, 即该时间到 1970 年 1 月 1 日 (UTC/GMT 的午夜 ) 之间的秒数 例如, 北京时间 2010 年 12 月 9 日 15 点 23 分 12 秒的 Unix 时间戳为 1291879392 THQS 算法 假设原来的 QueryString 为 q, 通过以下 4 个步骤, 即可得到最终 用于通信的 HashedQueryString: 1. 对于 q 中的每个键值对按照键的字 母顺序升序排序, 得到排序后的请求字符串 qs; 2. 加 入当前时间的 Unix 时间戳和 Spark 帐号对应的 API Key 值, 得到散列前的字符串 qf: qf qs&time=12345&salt=asdf1234 3. 计算得到 qf 的 md5 值, 假设为 abcdefg hash md5(qf) 4. 最终的 HashedQueryString 为 : hqs qs&time=12345&hash=abcdefg 用 hqs 代替 q 进 行 Http 通信 下 面举 一个例 子说明计算过程 假设 用户从 Spark 获取到的 API Key 值是 asdf1234, 当前时间为 2010 年 12 月 9 日 15 点 23 分 12 秒, 原始的 QueryString 是 name=harry&level=top&salary=1000 第 一步, 将上述 QueryString 按照字 母顺序进 行升序排序, 结果是 level=top&name=harry&salary=1000 第 二步, 附加 time 值和 salt 值, 得到取 hash 前的字符串 level=top&name=harry&salary=1000&time=1291879392&salt=asdf1234 第三步, 对上述字符串取 md5 值 hash=bf04a55b30cff562f7add9f054ab7ffb 因此, 最终进 行 Http 通信的字符串为 level=top&name=harry&salary=1000&time=1291879392&hash=bf04a55b30cff562f7add9f054ab7ffb 附录 2. Flash 和 Javascript 交互 Spark 的通信模式中, 有若干种 方式需要通过与 页 面中嵌 入的 Flash 交互完成 Flash 和 页 面有多种 方式可以交互, 为了保证 Spark 提供的 flash 能够在各种环境下都能正常 工作, 推荐采 用以下 方式进 行处理 首先, 需要 用将 swf 文件嵌 入到 网 页中, 推荐采 用 swfobject 1.5 版本 将 swfobject.js 添加到 网 页中后, 用以下 js 语句将 swf 嵌 入到 网 页中, 第 12 页共 13 页
<script type="text/javascript"> var swfobj=new SWFObject('http://xxx/xx.swf', 'swfname', '80', '80', '8'); swfobj.addvariable('title','test');! swfobj.addvariable('number', 123); swfobj.addparam('allowfullscreen','true'); swfobj.addparam('allowscriptaccess','always'); swfobj.addparam('wmode','transparent'); swfobj.write('divid'); </script> 其次, 调 用 Flash 中的函数的时候, 如果 Flash 提供的函数名叫 func, 而需要传递的是 param 的话, 那么下 面这句就可以调 用该函数 swfname["func"](param); 其中,swfname 是嵌 入 Flash 的 id 值 第 13 页共 13 页