video.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: ellisran
  5. * Date: 2016/9/21
  6. * Time: 14:41
  7. */
  8. class video {
  9. private $AppKey = 'f277356253794d16bbef1f2107c3e84e'; //开发者平台分配的AppKey
  10. private $AppSecret = 'dbb0e89f0e9943b5b7e837731a8deacd'; //开发者平台分配的AppSecret,可刷新
  11. private $Nonce; //随机数(最大长度128个字符)
  12. private $CurTime; //当前UTC时间戳,从1970年1月1日0点0 分0 秒开始到现在的秒数(String)
  13. private $CheckSum; //SHA1(AppSecret + Nonce + CurTime),三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写)
  14. const HEX_DIGITS = "0123456789abcdef";
  15. private $baseUrl = 'https://vcloud.163.com'; //网易上传地址
  16. /**
  17. * 析构函数
  18. * @param $AppKey 网易视频云提供的key
  19. * @param $AppSecret 网易视频云提供的AppSecret
  20. */
  21. function __construct() {
  22. }
  23. // function __construct($AppKey,$AppSecret) {
  24. // $this->AppKey = $AppKey;
  25. // $this->AppSecret = $AppSecret;
  26. // }
  27. /**
  28. * 生成验证码
  29. */
  30. public function checkSumBuilder(){
  31. //此部分生成随机字符串
  32. $hex_digits = self::HEX_DIGITS;
  33. $this->Nonce;
  34. for($i=0;$i<128;$i++){ //随机字符串最大128个字符,也可以小于该数
  35. $this->Nonce.= $hex_digits[rand(0,15)];
  36. }
  37. $this->CurTime = (string)(time()); //当前时间戳,以秒为单位
  38. $join_string = $this->AppSecret.$this->Nonce.$this->CurTime;
  39. $this->CheckSum = sha1($join_string);
  40. }
  41. /**
  42. * post 获取网易视频云接口信息
  43. * 获取上传加速节点、文件数据上传、断点续传查询断点三个接口,不使用本方法。
  44. */
  45. public function postDataCurl($url,$data=array()){
  46. $this->checkSumBuilder(); //发送请求前需先生成checkSum
  47. if(!empty($data)){
  48. $json=json_encode($data);
  49. }else{
  50. $json="";
  51. }
  52. $timeout = 5000;
  53. $http_header = array(
  54. 'AppKey:'.$this->AppKey,
  55. 'Nonce:'.$this->Nonce,
  56. 'CurTime:'.$this->CurTime,
  57. 'CheckSum:'.$this->CheckSum,
  58. 'Content-Type: application/json;charset=utf-8;',
  59. 'Content-Length: ' . strlen($json)
  60. );
  61. $ch = curl_init();
  62. curl_setopt ($ch, CURLOPT_URL, $url);
  63. curl_setopt ($ch, CURLOPT_POST, 1);
  64. curl_setopt ($ch, CURLOPT_POSTFIELDS, $json);
  65. curl_setopt ($ch, CURLOPT_HEADER, false);
  66. curl_setopt ($ch, CURLOPT_HTTPHEADER,$http_header);
  67. curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER,false);
  68. curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  69. curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
  70. $result = curl_exec($ch);
  71. if (false === $result) {
  72. $result = curl_errno($ch);
  73. }
  74. curl_close($ch);
  75. return json_decode($result,true) ;
  76. }
  77. //start 视频分类管理
  78. /**
  79. * 获取视频分类列表信息
  80. * @currentPage 获取视频分类列表分页后的索引
  81. * @pageSize 获取视频分类列表一页的记录数(若为-1,表示不用分页)
  82. */
  83. public function videoTypeList($currentPage, $pageSize){
  84. $url = $this->baseUrl.'/app/vod/type/list';
  85. return $this->postDataCurl($url,array('currentPage' => $currentPage, 'pageSize' => $pageSize));
  86. }
  87. /**
  88. * 创建视频分类
  89. * @typeName 视频分类的名称
  90. * @description 视频分类的描述信息
  91. */
  92. public function videoTypeCreate($typeName, $description = ''){
  93. $url = $this->baseUrl.'/app/vod/type/create';
  94. if($description != ''){
  95. return $this->postDataCurl($url,array('typeName' => $typeName, 'description' => $description));
  96. }else{
  97. return $this->postDataCurl($url,array('typeName' => $typeName));
  98. }
  99. }
  100. /**
  101. * 获取视频分类信息
  102. * @typeId 视频分类的Id
  103. */
  104. public function videoTypeGet($typeId){
  105. $url = $this->baseUrl.'/app/vod/type/get';
  106. return $this->postDataCurl($url,array('typeId' => $typeId));
  107. }
  108. /**
  109. * 修改视频分类信息
  110. * @typeId 视频分类的Id
  111. * @typeName 视频分类的名称
  112. * @description 视频分类的描述信息
  113. */
  114. public function videoTypeUpdate($typeId, $typeName, $description = ''){
  115. $url = $this->baseUrl.'/app/vod/type/update';
  116. if($description != ''){
  117. return $this->postDataCurl($url,array('typeId' => $typeId, 'typeName' => $typeName, 'description' => $description));
  118. }else{
  119. return $this->postDataCurl($url,array('typeId' => $typeId, 'typeName' => $typeName));
  120. }
  121. }
  122. /**
  123. * 删除视频分类
  124. * @typeId 视频分类的Id
  125. */
  126. public function videoTypeDelete($typeId){
  127. $url = $this->baseUrl.'/app/vod/type/typeDelete';
  128. return $this->postDataCurl($url,array('typeId' => $typeId));
  129. }
  130. //end 视频分类管理
  131. //start 视频管理
  132. /**
  133. * 获取视频文件信息
  134. * @vid 视频Id
  135. */
  136. public function videoGet($vid){
  137. $url = $this->baseUrl.'/app/vod/video/get';
  138. return $this->postDataCurl($url,array('vid' => $vid));
  139. }
  140. /**
  141. * 获取视频文件信息列表
  142. * @currentPage 获取视频列表分页后的索引
  143. * @pageSize 获取视频列表一页的记录数(若为-1,表示不用分页)
  144. * @statys 根据视频状态过滤选择(0表示获取所有状态视频,10表示初始,20表示失败,30表示处理中,40表示成功,50表示屏蔽)
  145. * @typeId 根据视频分类过滤选择(0表示获取所有分类视频)
  146. */
  147. public function videoList($currentPage, $pageSize, $status, $type){
  148. $url = $this->baseUrl.'/app/vod/video/list';
  149. return $this->postDataCurl($url,array('currentPage' => $currentPage, 'pageSize' => $pageSize, 'status' => $status, 'type' => $type));
  150. }
  151. /**
  152. * 修改视频文件信息
  153. * @vid 视频Id
  154. * @videoName 视频的名称
  155. * @typeId 视频分类Id
  156. * @description 视频的描述信息
  157. */
  158. public function videoEdit($vid, $videoName, $typeId, $description = ''){
  159. $url = $this->baseUrl.'/app/vod/video/edit';
  160. if($description != ''){
  161. return $this->postDataCurl($url,array('vid' => $vid, 'videoName' => $videoName, 'typeId' => $typeId, 'description' => $description));
  162. }else{
  163. return $this->postDataCurl($url,array('vid' => $vid, 'videoName' => $videoName, 'typeId' => $typeId));
  164. }
  165. }
  166. /**
  167. * 删除视频文件
  168. * @vid 视频Id
  169. */
  170. public function videoDetele($vid){
  171. $url = $this->baseUrl.'/app/vod/video/videoDelete';
  172. return $this->postDataCurl($url,array('vid' => $vid));
  173. }
  174. //end 视频管理
  175. //start 视频上传管理
  176. /**
  177. * 检测文件编码
  178. * @param string $file 文件路径
  179. * @return string|null 返回 编码名 或 null
  180. */
  181. function detect_encoding($file) {
  182. $list = array('GBK', 'UTF-8', 'UTF-16LE', 'UTF-16BE', 'ISO-8859-1');
  183. $str = file_get_contents($file);
  184. foreach ($list as $item) {
  185. $tmp = mb_convert_encoding($str, $item, $item);
  186. if (md5($tmp) == md5($str)) {
  187. return $item;
  188. }
  189. }
  190. return null;
  191. }
  192. /**
  193. * get curl 方法
  194. * 断点续传查询断点,获取上传加速节点地址 使用本方法
  195. */
  196. public function GetUrlMsg($url, $xNosToken = ''){
  197. $ch = curl_init();
  198. curl_setopt ($ch, CURLOPT_URL, $url);
  199. if($xNosToken != ''){
  200. $header = array(
  201. 'x-nos-token:'. $xNosToken
  202. );
  203. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  204. }
  205. curl_setopt ($ch, CURLOPT_HEADER, false);
  206. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  207. $result = curl_exec($ch);
  208. if (false === $result) {
  209. $result = curl_errno($ch);
  210. }
  211. curl_close($ch);
  212. return json_decode($result,true);
  213. }
  214. /**
  215. * 上传视频初始化
  216. * @originFileName 上传文件的原始名称(包含后缀名)(必填)
  217. * @userFileName 用户命名的上传文件名称
  218. * @typeId 视频所属的类别Id(不填写为默认分类)
  219. */
  220. public function videoInit($oname, $uname = '', $type = ''){
  221. $url = $this->baseUrl.'/app/vod/upload/init';
  222. return $this->postDataCurl($url,array('originFileName' => $oname, 'userFileName' => $uname, 'typeId' => $type));
  223. }
  224. /**
  225. * 获取上传加速节点地址
  226. * @version API版本号,填写固定值1.0
  227. * @bucketname 存储上传文件的桶名,可在视频上传初始化接口的返回参数bucket获取
  228. */
  229. public function videoLbsGet($bucketname){
  230. $url = 'http://wanproxy.127.net/lbs?version=1.0&bucketname='.$bucketname;
  231. return $this->GetUrlMsg($url);
  232. }
  233. /**
  234. * 上传视频
  235. * @url 上传地址格式:POST {UploadHost}/{bucket}/{object}?offset=0&complete=false&version=1.0
  236. {UploadHost}值为获取的上传加速节点地址,{bucket}值为存储对象的桶名,{object}值为生成的唯一对象名。
  237. * @file 服务器缓存文件
  238. *
  239. * 请求参数
  240. * @x-nos-token 请求头参数,上传token
  241. * @bucket 存储对象的桶名
  242. * @object 生成的唯一对象名
  243. * @offset 当前分片在整个对象中的起始偏移量,单位:字节(Byte)
  244. * @complete 是否为最后一块数据。合法值:true/false
  245. * @version http api版本号。这里是固定值1.0
  246. * @context 上传上下文。本字段是只能被上传服务器解读使用的不透明字段,
  247. 上传端不应修改其内容。
  248. 注意:用户第一次上传应不带此参数或置为空字符串,
  249. 之后上传剩余部分数据都需要带上这个参数。
  250. context对应的桶名或者对象名不匹配返回400 code
  251. *
  252. * 响应参数(返回结果)
  253. * @requestId uuid字符串,服务器端生成的唯一UUID
  254. * @offset 下一个上传片在上传块中的偏移。
  255. 注意:偏移从0开始,比如:用户上传0-128字节后,
  256. 服务器返回的offset为128,下一次上传offset值应置为128
  257. * @context 上传上下文
  258. * @callbackRetMsg 上传回调信息
  259. */
  260. public function videoUpload($url,$token,$file){
  261. // return $this->sendStreamFile($url,$token,$file);
  262. // if(file_exists($file)){
  263. // $filesize=filesize($file);
  264. // $handle = fopen ($file , "rb" );
  265. // $contents = fread ( $handle , $filesize);
  266. //// var_dump($this->detect_encoding($file));
  267. //// $contents = mb_convert_encoding($contents ,'utf-8', 'ISO-8859-1');
  268. // fclose ( $handle );
  269. // x-www-form-urlencoded
  270. // $header = array(
  271. // 'Content-Type:application/json;charset=utf-8',
  272. // 'Content-Length:'.strlen($file),
  273. // 'x-nos-token:'.$token,
  274. // 'Content-MD5:'.md5($file)
  275. //// 'Access-Control-Allow-Origin: *'
  276. // );
  277. $headers = array('x-nos-token' => $token,'Content-type'=>'application/json;charset=UTF-8');
  278. $t1 = microtime(true);
  279. $ch = curl_init();
  280. $options = array(
  281. CURLOPT_RETURNTRANSFER => true,
  282. CURLOPT_SSL_VERIFYPEER => false,
  283. CURLOPT_SSL_VERIFYHOST => false,
  284. CURLOPT_HEADER => true,
  285. CURLOPT_NOBODY => false,
  286. CURLOPT_CUSTOMREQUEST => 'POST',
  287. CURLOPT_URL => $url
  288. );
  289. // curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  290. // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  291. // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  292. // curl_setopt($ch, CURLOPT_HEADER, true);
  293. // curl_setopt($ch, CURLOPT_NOBODY, false);
  294. // curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  295. // curl_setopt($ch, CURLOPT_URL, $url);
  296. // Handle open_basedir & safe mode
  297. if (!ini_get('safe_mode') && !ini_get('open_basedir')) {
  298. $options[CURLOPT_FOLLOWLOCATION] = true;
  299. }
  300. $header = array();
  301. foreach ($headers as $key => $val) {
  302. array_push($header, "$key: $val");
  303. }
  304. $options[CURLOPT_HTTPHEADER] = $header;
  305. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
  306. $options[CURLOPT_POSTFIELDS] = $file;
  307. curl_setopt_array($ch, $options);
  308. // curl_setopt($ch, CURLOPT_POSTFIELDS, $file);
  309. // curl_getinfo($ch);
  310. $return_data = curl_exec($ch);
  311. // curl_close($ch);
  312. $t2 = microtime(true);
  313. $duration = round($t2-$t1, 3);
  314. $ret = curl_errno($ch);
  315. if ($ret !== 0) {
  316. $r = new Response(-1, $duration, array(), null, curl_error($ch));
  317. curl_close($ch);
  318. return $r;
  319. }
  320. $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  321. $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  322. $headers = self::parseHeaders(substr($return_data, 0, $header_size));
  323. $body = substr($return_data, $header_size);
  324. curl_close($ch);
  325. // var_dump($return_data);
  326. // var_dump($code);
  327. // var_dump($duration);
  328. // var_dump($headers);
  329. var_dump($body);
  330. // exit;
  331. return json_decode($return_data,true);
  332. // $opts = array(
  333. // 'http' => array(
  334. // 'method' => 'POST',
  335. // 'header' => array("Content-Type: application/x-www-form-urlencoded;charset=utf-8","x-nos-token:".$token,"Content-Length:".strlen($contents)),
  336. // 'content' => $contents
  337. // )
  338. // );
  339. // $context = stream_context_create($opts);
  340. // $response = file_get_contents($url, false, $context);
  341. // $ret = json_decode($response, true);
  342. //// return $ret['success'];
  343. //// var_dump($ret);
  344. //// exit;
  345. // return $ret;
  346. // }else{
  347. // return false;
  348. // }
  349. }
  350. private static function parseHeaders($raw)
  351. {
  352. $headers = array();
  353. $headerLines = explode("\r\n", $raw);
  354. foreach ($headerLines as $line) {
  355. $headerLine = trim($line);
  356. $kv = explode(':', $headerLine);
  357. if (count($kv) >1) {
  358. $headers[$kv[0]] = trim($kv[1]);
  359. }
  360. }
  361. return $headers;
  362. }
  363. /**
  364. * 断点续传查询断点
  365. * @url 上传地址格式:GET {UploadHost}/{bucket}/{object}?uploadContext
  366. *
  367. * 请求参数
  368. * @x-nos-token 请求头参数,上传token
  369. * @bucket 存储对象的桶名
  370. * @object 生成的唯一对象名
  371. * @context 上传上下文。本字段是只能被上传服务器解读使用的不透明字段,
  372. 上传端不应修改其内容。对应context在服务端不存在则返回404。
  373. context对应的桶名或者对象名不匹配返回400 code。
  374. * @version http api版本号。这里是固定值1.0
  375. */
  376. public function videoUploadContext($url,$token,$context){
  377. $url = $url.'?uploadContext&context='.$context.'&version=1.0';
  378. return $this->GetUrlMsg($url,$token);
  379. }
  380. /**
  381. * 视频上传完成查询视频主id,存在id则表示上传完成
  382. * @objectNames 上传文件的对象名列表
  383. *
  384. */
  385. public function videoQuery($objectName){
  386. $url = $this->baseUrl.'/app/vod/video/query';
  387. return $this->postDataCurl($url,array('objectNames' => array($objectName)));
  388. }
  389. /**
  390. * 设置上传回调地址接口 用于视频上传,设置上传成功后的回调地址。
  391. * @callbackUrl 上传成功后回调客户端的URL地址
  392. *
  393. */
  394. public function videoCallback($cburl){
  395. $url = $this->baseUrl.'/app/vod/upload/setcallback';
  396. return $this->postDataCurl($url,array('callbackUrl' => $cburl));
  397. }
  398. /**
  399. * 获取视频封面
  400. * @id 视频Id
  401. * @size 截图尺寸,包含以下几种值:1表示640X360,2表示400X300,3表示320X180,4表示200X150
  402. * @offset 截图偏移,包含以下几种值:
  403. 0表示视频第一帧,1表示时间轴10%位置,2表示时间轴20%位置,3表示时间轴30%位置,
  404. 4表示时间轴40%位置,5表示时间轴50%位置,6表示时间轴60%位置,
  405. 7表示时间轴70%位置,8表示时间轴80%位置,9表示时间轴90%位置
  406. */
  407. public function videoSnapshotCreate($id, $size, $offset){
  408. $url = $this->baseUrl.'/app/vod/snapshot/create';
  409. return $this->postDataCurl($url,array('vid' => $id, 'size' => $size, 'offset' => $offset));
  410. }
  411. /**
  412. * 设置视频封面
  413. * @id 视频Id
  414. * @typeId 封面设置方法:1表示使用截图URL,2表示使用本地上传图片
  415. * @path type值为1,则代表截图URL;type值为2,则代表本地图片路径
  416. * @data type值为2时,需填写,代表本地图片数据的base64编码字符串数据
  417. */
  418. public function videoSnapshotSet($id, $typeId, $path, $data = ''){
  419. $url = $this->baseUrl.'/app/vod/snapshot/set';
  420. if($data != ''){
  421. return $this->postDataCurl($url,array('vid' => $id, 'type' => $typeId, 'path' => $path, 'data' => $data));
  422. }else{
  423. return $this->postDataCurl($url,array('vid' => $id, 'type' => $typeId, 'path' => $path));
  424. }
  425. }
  426. //end 视频上传管理
  427. }
  428. ?>