AliyunVodUtils.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. /**
  3. * Created by Aliyun ApsaraVideo VoD.
  4. * User: https://www.aliyun.com/product/vod
  5. */
  6. use OSS\Core\OssUtil;
  7. class AliyunVodUtils
  8. {
  9. const VOD_MAX_TITLE_LENGTH = 128;
  10. const VOD_MAX_DESCRIPTION_LENGTH = 1024;
  11. public static function convertOssInternal($ossUrl, $ecsRegion=null, $isEnableSSL=false)
  12. {
  13. if (!$isEnableSSL) {
  14. $ossUrl = str_replace("https:", "http:", $ossUrl);
  15. }
  16. if (!is_string($ossUrl) || !is_string($ecsRegion)) {
  17. return $ossUrl;
  18. }
  19. $availableRegions = array('cn-qingdao', 'cn-beijing', 'cn-zhangjiakou', 'cn-huhehaote', 'cn-hangzhou', 'cn-shanghai', 'cn-shenzhen',
  20. 'cn-hongkong', 'ap-southeast-1', 'ap-southeast-2', 'ap-southeast-3',
  21. 'ap-northeast-1', 'us-west-1', 'us-east-1', 'eu-central-1', 'me-east-1');
  22. if (!in_array($ecsRegion, $availableRegions)) {
  23. return $ossUrl;
  24. }
  25. $ossUrl = str_replace("https:", "http:", $ossUrl);
  26. return str_replace(sprintf("oss-%s.aliyuncs.com", $ecsRegion),
  27. sprintf("oss-%s-internal.aliyuncs.com", $ecsRegion), $ossUrl);
  28. }
  29. public static function getFileName($fileUrl)
  30. {
  31. $fileUrl = urldecode($fileUrl);
  32. $pos = strrpos($fileUrl, '?');
  33. $briefPath = $fileUrl;
  34. if ($pos !== false) {
  35. $briefPath = substr($fileUrl, 0, $pos);
  36. }
  37. return array($briefPath, basename($briefPath));
  38. }
  39. public static function getFileExtension($fileName)
  40. {
  41. $pos = strrpos($fileName, '.');
  42. if ($pos !== false) {
  43. return substr($fileName, $pos + 1);
  44. }
  45. return null;
  46. }
  47. // 考虑分隔符为"/" 或 "\"(windows)
  48. public static function replaceFileName($filePath, $replace) {
  49. if (strlen($filePath) <= 0 || strlen($replace) <= 0) {
  50. return $filePath;
  51. }
  52. $filePath = urldecode($filePath);
  53. $separator = '/';
  54. $start = strrpos($filePath, $separator);
  55. if ($start === false) {
  56. $separator = '\\';
  57. $start = strrpos($filePath, '\\');
  58. if ($start === false) {
  59. return false;
  60. }
  61. }
  62. return substr($filePath, 0, $start) . $separator. $replace;
  63. }
  64. public static function mkDir($filePath) {
  65. if (strlen($filePath) <= 0) {
  66. return true;
  67. }
  68. $filePath = urldecode($filePath);
  69. $start = strrpos($filePath, '/');
  70. if ($start === false) {
  71. return false;
  72. }
  73. $fileDir = substr($filePath, 0, $start);
  74. if (!is_dir($fileDir)) {
  75. return mkdir($fileDir, 0777, true);
  76. }
  77. return true;
  78. }
  79. // 截取字符串,在不超过最大字节数前提下确保中文字符不被截断出现乱码
  80. public static function subString($strVal, $maxBytes)
  81. {
  82. $i = mb_strlen($strVal);
  83. while (strlen($strVal) > $maxBytes) {
  84. $i--;
  85. if ($i <= 0) {
  86. return '';
  87. }
  88. $strVal = mb_substr($strVal, 0, $i);
  89. }
  90. return $strVal;
  91. }
  92. public static function getCurrentTimeStr() {
  93. return date("Y-m-d H:i:s");
  94. }
  95. public static function startsWith($haystack, $needle){
  96. return strncmp($haystack, $needle, strlen($needle)) === 0;
  97. }
  98. public static function endsWith($haystack, $needle){
  99. return $needle === '' || substr_compare($haystack, $needle, -strlen($needle)) === 0;
  100. }
  101. }
  102. class AliyunVodLog
  103. {
  104. public static $logSwitch = false;
  105. public static function printLog($format, $args = null, $_ = null) {
  106. if (!AliyunVodLog::$logSwitch) {
  107. return;
  108. }
  109. $vargs = func_get_args();
  110. unset($vargs[0]);
  111. $msg = vsprintf($format, $vargs);
  112. self::printStr($msg);
  113. }
  114. private static function printStr($msg) {
  115. printf("[%s]%s\n", AliyunVodUtils::getCurrentTimeStr(), $msg);
  116. }
  117. }
  118. class AliyunVodReportUpload
  119. {
  120. public static $isEnableSSL = false;
  121. const VOD_REPORT_URL = 'vod.cn-shanghai.aliyuncs.com';
  122. const VOD_REPORT_VERSION = '1.0.2';
  123. const VOD_REPORT_KEY ='wXr&aLIJdfI7so';
  124. const REPORT_FILE_HASH_READ_LEN = 1048576;
  125. public static function reportUploadProgress($clientId, $videoId, $progressInfo)
  126. {
  127. try {
  128. HttpHelper::$connectTimeout = 1;
  129. HttpHelper::$readTimeout = 2;
  130. $authTimestamp = time();
  131. $authInfo = md5(sprintf("%s|%s|%s", $clientId, self::VOD_REPORT_KEY, $authTimestamp));
  132. $fields = array('Action'=>'ReportUploadProgress', 'Format'=>'JSON', 'Version'=>'2017-03-21',
  133. 'Timestamp'=>gmdate('Y-m-d\TH:i:s\Z'), 'SignatureNonce'=>md5(uniqid(mt_rand(), true)),
  134. 'VideoId'=>$videoId, 'Source'=>'PHPSDK', 'ClientId'=>$clientId,
  135. 'BusinessType'=>'UploadVideo', 'TerminalType'=>'PC', 'DeviceModel'=>'Server',
  136. 'AppVersion'=>self::VOD_REPORT_VERSION, 'AuthTimestamp'=>$authTimestamp, 'AuthInfo'=>$authInfo,
  137. 'FileName'=>$progressInfo['FileName'], 'FileHash'=>$progressInfo['FileHash'],
  138. 'FileSize'=>empty($progressInfo['FileSize']) ? 0 : $progressInfo['FileSize'],
  139. 'FileCreateTime'=>empty($progressInfo['CreateTime']) ? $authTimestamp : $progressInfo['CreateTime'],
  140. 'UploadRatio'=>empty($progressInfo['UploadRatio']) ? 0 : $progressInfo['UploadRatio'],
  141. 'UploadId'=>empty($progressInfo['UploadId']) ? 0 : $progressInfo['UploadId'],
  142. 'DonePartsCount'=>empty($progressInfo['DonePartsCount']) ? 0 : $progressInfo['DonePartsCount'],
  143. 'PartSize'=>empty($progressInfo['PartSize']) ? 0 : $progressInfo['PartSize'],
  144. 'UploadPoint'=>$progressInfo['UploadPoint'], 'UploadAddress'=>$progressInfo['UploadAddress']
  145. );
  146. $url = (self::$isEnableSSL ? 'https://' : 'http://') . self::VOD_REPORT_URL;
  147. HttpHelper::curl($url,'POST', $fields);
  148. } catch (Exception $e) {
  149. AliyunVodLog::printLog("reportUploadProgress failed, ErrorMessage: %s\n", $e->getMessage());
  150. }
  151. }
  152. public static function generateFilePartHash($clientId, $filePath, $fileSize)
  153. {
  154. try {
  155. $fp = @fopen(OssUtil::encodePath($filePath),"r");
  156. $len = $fileSize <= self::REPORT_FILE_HASH_READ_LEN ? $fileSize : self::REPORT_FILE_HASH_READ_LEN;
  157. $str = fread($fp, $len);
  158. fclose($fp);
  159. } catch (Exception $e) {
  160. $str = sprintf("%s|%s|%s", $clientId, $filePath, @filemtime($filePath));
  161. }
  162. return md5($str);
  163. }
  164. }
  165. class AliyunVodDownloader
  166. {
  167. public function __construct($saveLocalDir=null)
  168. {
  169. if (isset($saveLocalDir)) {
  170. $this->saveLocalDir = $saveLocalDir;
  171. }
  172. else {
  173. $this->saveLocalDir = dirname(__DIR__) . '/tmp_dlfiles/';
  174. }
  175. }
  176. public function downloadFile($downloadUrl, $localFileName, $fileSize=null)
  177. {
  178. $localPath = $this->saveLocalDir . $localFileName;
  179. AliyunVodLog::printLog("Download %s To %s", $downloadUrl, $localPath);
  180. if (isset($fileSize)) {
  181. $lsize = @filesize($localPath);
  182. if ($lsize > 0 and $lsize == $fileSize) {
  183. return $localPath;
  184. }
  185. }
  186. if (!is_dir($this->saveLocalDir)) {
  187. @mkdir($this->saveLocalDir, 0777, true);
  188. }
  189. $sfp = @fopen($downloadUrl, "rb");
  190. if ($sfp === false) {
  191. throw new Exception("download file fail while reading ".$downloadUrl,
  192. AliyunVodError::VOD_ERR_FILE_DOWNLOAD);
  193. }
  194. $dfp = @fopen(OssUtil::encodePath($localPath), "ab+");
  195. if ($sfp === false) {
  196. throw new Exception("download file fail while writing ".$localPath,
  197. AliyunVodError::VOD_ERR_FILE_DOWNLOAD);
  198. }
  199. while (!feof($sfp)) {
  200. $contents = fread($sfp,8 * 1024);
  201. fwrite($dfp, $contents);
  202. }
  203. fclose($sfp);
  204. fclose($dfp);
  205. return $localPath;
  206. }
  207. public function getSaveLocalDir() {
  208. return $this->saveLocalDir;
  209. }
  210. public function setSaveLocalDir($localDir) {
  211. return $this->saveLocalDir = $localDir;
  212. }
  213. private $saveLocalDir = null;
  214. }
  215. class AliyunVodError
  216. {
  217. const VOD_ERR_FILE_READ = 10000;
  218. const VOD_ERR_FILE_DOWNLOAD = 10001;
  219. const VOD_ERR_M3U8_FILE_REWRITE = 10002;
  220. const VOD_INVALID_M3U8_SLICE_FILE = 10003;
  221. }