初始化项目:添加后端代码、ThinkPHP框架、前端资源
This commit is contained in:
@@ -0,0 +1,694 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by Aliyun ApsaraVideo VoD.
|
||||
* User: https://www.aliyun.com/product/vod
|
||||
*/
|
||||
|
||||
use vod\Request\V20170321 as vod;
|
||||
use OSS\OssClient;
|
||||
use OSS\Core\OssUtil;
|
||||
|
||||
class AliyunVodUploader
|
||||
{
|
||||
|
||||
public function __construct($accessKeyId, $accessKeySecret, $apiRegionId=null)
|
||||
{
|
||||
$this->accessKeyId = $accessKeyId;
|
||||
$this->accessKeySecret = $accessKeySecret;
|
||||
if (empty($apiRegionId)) {
|
||||
// VoD的接入地址,国内为cn-shanghai,参考:https://help.aliyun.com/document_detail/98194.html
|
||||
$this->apiRegionId = 'cn-shanghai';
|
||||
}
|
||||
else {
|
||||
$this->apiRegionId = $apiRegionId;
|
||||
}
|
||||
|
||||
// VOD和OSS的连接超时时间,单位秒
|
||||
$this->connTimeout = 1;
|
||||
|
||||
// 设置VOD请求超时时间,单位秒
|
||||
$this->vodTimeout = 3;
|
||||
|
||||
// 设置OSS请求超时时间,单位秒,默认是7天, 建议不要设置太小,如果上传文件很大,消耗的时间会比较长
|
||||
$this->ossTimeout = 86400*7;
|
||||
|
||||
// 失败后的最大重试次数
|
||||
$this->maxRetryTimes = 3;
|
||||
|
||||
$this->multipartThreshold = 10 * 1024 * 1024;
|
||||
$this->multipartPartSize = 10 * 1024 * 1024;
|
||||
$this->multipartThreadsNum = 3;
|
||||
|
||||
$this->vodClient = $this->initVodClient();
|
||||
$this->ossClient = null;
|
||||
$this->ecsRegionId = null;
|
||||
$this->enableSSL = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置上传脚本部署的ECS区域(如有),当检测上传区域和点播存储区域位于同一区域时,会自动开启内网上传,能节省流量费用且上传速度更快
|
||||
* @param string, $regionId 可选值参考:https://help.aliyun.com/document_detail/40654.html,如cn-shanghai
|
||||
*/
|
||||
public function setEcsRegionId($regionId)
|
||||
{
|
||||
$this->ecsRegionId = $regionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否启用SSL(网络请求使用HTTPS),默认不启用,以避免相关扩展未安装或配置异常时无法使用
|
||||
* @param bool, $isEnable 可选值参考:https://help.aliyun.com/document_detail/40654.html,如cn-shanghai
|
||||
*/
|
||||
public function setEnableSSL($isEnable)
|
||||
{
|
||||
$this->enableSSL = $isEnable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传本地视频或音频文件到点播,最大支持48.8TB的单个文件,暂不支持断点续传
|
||||
* @param UploadVideoRequest $uploadVideoRequest: UploadVideoRequest类的实例,注意filePath为本地文件的绝对路径
|
||||
* @return string, $videoId
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadLocalVideo($uploadVideoRequest)
|
||||
{
|
||||
$uploadInfo = $this->createUploadVideo($uploadVideoRequest);
|
||||
$headers = $this->getUploadHeaders($uploadVideoRequest);
|
||||
$this->uploadOssObject($uploadVideoRequest->getFilePath(), $uploadInfo->UploadAddress->FileName, $uploadInfo, $headers);
|
||||
return $uploadInfo->VideoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传网络视频或音频文件到点播,最大支持48.8TB的单个文件(需本地磁盘空间足够);会先下载到本地临时目录,再上传到点播存储
|
||||
* @param UploadVideoRequest $uploadVideoRequest: UploadVideoRequest类的实例,注意filePath为网络文件的URL地址
|
||||
* @return string, $videoId
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadWebVideo($uploadVideoRequest)
|
||||
{
|
||||
// 下载文件
|
||||
$uploadVideoRequest = $this->downloadWebMedia($uploadVideoRequest);
|
||||
|
||||
// 上传到点播
|
||||
$uploadInfo = $this->createUploadVideo($uploadVideoRequest);
|
||||
$headers = $this->getUploadHeaders($uploadVideoRequest);
|
||||
$this->uploadOssObject($uploadVideoRequest->getFilePath(), $uploadInfo->UploadAddress->FileName, $uploadInfo, $headers);
|
||||
|
||||
// 删除下载的本地视频
|
||||
unlink($uploadVideoRequest->getFilePath());
|
||||
|
||||
return $uploadInfo->VideoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传本地图片文件到点播,最大支持48.8TB的单个文件
|
||||
* @param UploadImageRequest $uploadImageRequest: UploadImageRequest类的实例,注意filePath为本地文件的绝对路径
|
||||
* @return array, array('ImageId'=>'xxxxx', 'ImageURL'=>'http://xxx.jpg')
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadLocalImage($uploadImageRequest)
|
||||
{
|
||||
$uploadInfo = $this->createUploadImage($uploadImageRequest);
|
||||
$this->uploadOssObject($uploadImageRequest->getFilePath(), $uploadInfo->UploadAddress->FileName, $uploadInfo);
|
||||
return array('ImageId'=>$uploadInfo->ImageId, 'ImageURL'=>$uploadInfo->ImageURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传网络图片文件到点播,最大支持48.8TB的单个文件(需本地磁盘空间足够);会先下载到本地临时目录,再上传到点播存储
|
||||
* @param UploadImageRequest $uploadVideoRequest: UploadImageRequest类的实例,注意filePath为网络文件的URL地址
|
||||
* @return array, array('ImageId'=>'xxxxx', 'ImageURL'=>'http://xxx.jpg')
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadWebImage($uploadImageRequest)
|
||||
{
|
||||
// 下载文件
|
||||
$uploadImageRequest = $this->downloadWebMedia($uploadImageRequest);
|
||||
|
||||
// 上传到点播
|
||||
$uploadInfo = $this->createUploadImage($uploadImageRequest);
|
||||
$this->uploadOssObject($uploadImageRequest->getFilePath(), $uploadInfo->UploadAddress->FileName, $uploadInfo);
|
||||
|
||||
// 删除下载的本地图片
|
||||
unlink($uploadImageRequest->getFilePath());
|
||||
|
||||
return array('ImageId'=>$uploadInfo->ImageId, 'ImageURL'=>$uploadInfo->ImageURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传本地辅助媒资文件(如水印、字幕等)到点播,最大支持48.8TB的单个文件
|
||||
* @param UploadAttachedMediaRequest $uploadAttachedRequest: UploadAttachedMediaRequest类的实例,注意filePath为本地文件的绝对路径
|
||||
* @return array, array('MediaId'=>'xxxxx', 'MediaURL'=>'http://xxx.jpg', 'FileURL'=>'http://xxx.jpg')
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadLocalAttachedMedia($uploadAttachedRequest)
|
||||
{
|
||||
$uploadInfo = $this->createUploadAttachedMedia($uploadAttachedRequest);
|
||||
$this->uploadOssObject($uploadAttachedRequest->getFilePath(), $uploadInfo->UploadAddress->FileName, $uploadInfo);
|
||||
return array('MediaId'=>$uploadInfo->MediaId, 'MediaURL'=>$uploadInfo->MediaURL, 'FileURL'=>$uploadInfo->FileURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传网络辅助媒资文件(如水印、字幕等)到点播,最大支持48.8TB的单个文件(需本地磁盘空间足够);会先下载到本地临时目录,再上传到点播存储
|
||||
* @param UploadAttachedMediaRequest $uploadAttachedRequest: UploadAttachedMediaRequest类的实例,注意filePath为网络文件的URL地址
|
||||
* @return array, array('MediaId'=>'xxxxx', 'MediaURL'=>'http://xxx.jpg', 'FileURL'=>'http://xxx.jpg')
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadWebAttachedMedia($uploadAttachedRequest)
|
||||
{
|
||||
// 下载文件
|
||||
$uploadAttachedRequest = $this->downloadWebMedia($uploadAttachedRequest);
|
||||
|
||||
// 上传到点播
|
||||
$uploadInfo = $this->createUploadAttachedMedia($uploadAttachedRequest);
|
||||
$this->uploadOssObject($uploadAttachedRequest->getFilePath(), $uploadInfo->UploadAddress->FileName, $uploadInfo);
|
||||
|
||||
// 删除下载的本地文件
|
||||
unlink($uploadAttachedRequest->getFilePath());
|
||||
|
||||
return array('MediaId'=>$uploadInfo->MediaId, 'MediaURL'=>$uploadInfo->MediaURL, 'FileURL'=>$uploadInfo->FileURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传本地m3u8视频或音频文件到点播,m3u8文件和分片文件默认在同一目录($sliceFiles为null时,会按照同一目录去解析分片地址)
|
||||
* @param UploadVideoRequest $uploadVideoRequest: 注意filePath为本地m3u8索引文件的绝对路径,
|
||||
* 且m3u8文件的分片信息必须是相对地址,不能含有URL或本地绝对路径
|
||||
* @param array $sliceFiles: ts分片文件的绝对路径列表,如指定则以此为准,若不指定,则自动解析$uploadVideoRequest里的m3u8文件
|
||||
* @return string, $videoId
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadLocalM3u8($uploadVideoRequest, $sliceFiles)
|
||||
{
|
||||
if (!is_array($sliceFiles) || empty($sliceFiles)) {
|
||||
throw new Exception("m3u8 slice files invalid", AliyunVodError::VOD_INVALID_M3U8_SLICE_FILE);
|
||||
}
|
||||
|
||||
// 上传到点播的m3u8索引文件会重写,以此确保分片地址都为相对地址
|
||||
$downloader = new AliyunVodDownloader();
|
||||
$m3u8LocalDir = $downloader->getSaveLocalDir() . md5($uploadVideoRequest->getFileName()) . '/';
|
||||
$downloader->setSaveLocalDir($m3u8LocalDir);
|
||||
$m3u8LocalPath = $m3u8LocalDir . basename($uploadVideoRequest->getFileName());
|
||||
$this->rewriteM3u8File($uploadVideoRequest->getFilePath(), $m3u8LocalPath);
|
||||
|
||||
// 解析分片文件地址和文件名
|
||||
$sliceList = array();
|
||||
if (isset($sliceFiles)) {
|
||||
foreach ($sliceFiles as $sliceFilePath) {
|
||||
$arr = AliyunVodUtils::getFileName($sliceFilePath);
|
||||
$sliceList[] = array($sliceFilePath, $arr[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取上传地址和凭证
|
||||
$uploadVideoRequest->setFilePath($m3u8LocalPath);
|
||||
$uploadInfo = $this->createUploadVideo($uploadVideoRequest);
|
||||
$headers = $this->getUploadHeaders($uploadVideoRequest);
|
||||
|
||||
// 依次上传分片文件
|
||||
foreach ($sliceList as $slice) {
|
||||
$this->uploadOssObject($slice[0], $uploadInfo->UploadAddress->ObjectPrefix . $slice[1], $uploadInfo, $headers);
|
||||
}
|
||||
|
||||
// 上传m3u8索引文件
|
||||
$this->uploadOssObject($uploadVideoRequest->getFilePath(), $uploadInfo->UploadAddress->FileName, $uploadInfo, $headers);
|
||||
|
||||
// 删除重写到本地的m3u8文件
|
||||
unlink($m3u8LocalPath);
|
||||
|
||||
return $uploadInfo->VideoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传网络m3u8视频或音频文件到点播,需本地磁盘空间足够,会先下载到本地临时目录,再上传到点播存储
|
||||
* @param UploadVideoRequest $uploadVideoRequest: 注意filePath为网络m3u8索引文件的URL地址,
|
||||
且m3u8文件的分片信息必须是相对地址,不能含有URL或本地绝对路径
|
||||
* @param array $sliceFileUrls: ts分片文件的URL地址列表;可自行拼接ts分片的URL地址列表,或者使用parseWebM3u8解析
|
||||
* @return string, $videoId
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadWebM3u8($uploadVideoRequest, $sliceFileUrls)
|
||||
{
|
||||
if (!is_array($sliceFileUrls) || empty($sliceFileUrls)) {
|
||||
throw new Exception("m3u8 slice files invalid", AliyunVodError::VOD_INVALID_M3U8_SLICE_FILE);
|
||||
}
|
||||
|
||||
// 下载m3u8文件和所有ts分片文件到本地;上传到点播的m3u8索引文件会重写,确保分片地址都为相对地址
|
||||
$downloader = new AliyunVodDownloader();
|
||||
$m3u8LocalDir = $downloader->getSaveLocalDir() . md5($uploadVideoRequest->getFileName()) . '/';
|
||||
$downloader->setSaveLocalDir($m3u8LocalDir);
|
||||
$m3u8LocalPath = $m3u8LocalDir . basename($uploadVideoRequest->getFileName());
|
||||
$this->rewriteM3u8File($uploadVideoRequest->getFilePath(), $m3u8LocalPath);
|
||||
|
||||
$sliceList = array();
|
||||
foreach ($sliceFileUrls as $sliceFileUrl) {
|
||||
$arr = AliyunVodUtils::getFileName($sliceFileUrl);
|
||||
$sliceLocalPath = $downloader->downloadFile($sliceFileUrl, $arr[1]);
|
||||
if ($sliceLocalPath === false) {
|
||||
throw new Exception("ts file download fail: ".$sliceFileUrl, AliyunVodError::VOD_ERR_FILE_DOWNLOAD);
|
||||
}
|
||||
$sliceList[] = array($sliceLocalPath, $arr[1]);
|
||||
}
|
||||
|
||||
// 获取上传地址和凭证
|
||||
$uploadVideoRequest->setFilePath($m3u8LocalPath);
|
||||
$uploadInfo = $this->createUploadVideo($uploadVideoRequest);
|
||||
$headers = $this->getUploadHeaders($uploadVideoRequest);
|
||||
|
||||
// 依次上传分片文件
|
||||
foreach ($sliceList as $slice) {
|
||||
$this->uploadOssObject($slice[0], $uploadInfo->UploadAddress->ObjectPrefix . $slice[1], $uploadInfo, $headers);
|
||||
}
|
||||
|
||||
// 上传m3u8索引文件
|
||||
$this->uploadOssObject($uploadVideoRequest->getFilePath(), $uploadInfo->UploadAddress->FileName, $uploadInfo, $headers);
|
||||
|
||||
// 删除下载到本地的文件
|
||||
unlink($m3u8LocalPath);
|
||||
foreach ($sliceList as $slice) {
|
||||
unlink($slice[0]);
|
||||
}
|
||||
rmdir($m3u8LocalDir);
|
||||
|
||||
return $uploadInfo->VideoId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析m3u8文件得到所有分片文件地址列表,原理是将m3u8地址前缀拼接ts分片名称作为后者的地址;同时支持本地、网络m3u8文件的解析
|
||||
本函数解析时会默认分片文件和m3u8文件位于同一目录,如不是则请自行拼接分片文件的地址列表
|
||||
* @param m3u8FileUrl: string, m3u8网络文件url,例如:/opt/sample.m3u8 或 http://host/sample.m3u8
|
||||
* @return array, $sliceFileUrls
|
||||
* @throws Exception
|
||||
*/
|
||||
public function parseM3u8File($m3u8FilePath) {
|
||||
$sliceFileUrls = array();
|
||||
$str = @file_get_contents(OssUtil::encodePath($m3u8FilePath));
|
||||
if ($str === false) {
|
||||
throw new Exception("m3u8 file access fail: ".$m3u8FilePath, AliyunVodError::VOD_ERR_FILE_READ);
|
||||
}
|
||||
$lines = explode("\n", $str);
|
||||
foreach ($lines as $line) {
|
||||
$sliceFileName = trim($line);
|
||||
if (strlen($sliceFileName) <= 0) {
|
||||
continue;
|
||||
}
|
||||
if (AliyunVodUtils::startsWith($sliceFileName,'#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sliceFile = AliyunVodUtils::replaceFileName($m3u8FilePath, $sliceFileName);
|
||||
if ($sliceFile === false) {
|
||||
throw new Exception("m3u8 file invalid", AliyunVodError::VOD_INVALID_M3U8_SLICE_FILE);
|
||||
}
|
||||
$sliceFileUrls[] = $sliceFile;
|
||||
}
|
||||
|
||||
return $sliceFileUrls;
|
||||
}
|
||||
|
||||
private function rewriteM3u8File($srcM3u8FilePath, $dstM3u8FilePath) {
|
||||
$str = @file_get_contents(OssUtil::encodePath($srcM3u8FilePath));
|
||||
if ($str === false) {
|
||||
throw new Exception("m3u8 file access fail: ".$srcM3u8FilePath, AliyunVodError::VOD_ERR_M3U8_FILE_REWRITE);
|
||||
}
|
||||
$lines = explode("\n", $str);
|
||||
$newM3u8Text = '';
|
||||
foreach ($lines as $line) {
|
||||
$sliceFileName = trim($line);
|
||||
if (strlen($sliceFileName) <= 0) {
|
||||
continue;
|
||||
}
|
||||
if (AliyunVodUtils::startsWith($sliceFileName,'#')) {
|
||||
$newM3u8Text .= $sliceFileName . "\n";
|
||||
continue;
|
||||
}
|
||||
$arr = AliyunVodUtils::getFileName($sliceFileName);
|
||||
$newM3u8Text .= $arr[1] . "\n";
|
||||
}
|
||||
|
||||
$res = AliyunVodUtils::mkDir($dstM3u8FilePath);
|
||||
if ($res === false) {
|
||||
throw new Exception("m3u8 file mkdir fail: ".$dstM3u8FilePath, AliyunVodError::VOD_ERR_M3U8_FILE_REWRITE);
|
||||
}
|
||||
|
||||
$res = @file_put_contents(OssUtil::encodePath($dstM3u8FilePath), $newM3u8Text);
|
||||
if ($res === false) {
|
||||
throw new Exception("m3u8 file rewrite fail: ".$dstM3u8FilePath, AliyunVodError::VOD_ERR_M3U8_FILE_REWRITE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function downloadWebMedia($request)
|
||||
{
|
||||
// 下载视频文件到本地临时目录
|
||||
$downloader = new AliyunVodDownloader();
|
||||
$localFileName = sprintf("%s.%s", md5($request->getFileName()), $request->getMediaExt());
|
||||
$webFilePath = $request->getFilePath();
|
||||
$localFilePath = $downloader->downloadFile($webFilePath, $localFileName);
|
||||
if ($localFilePath === false) {
|
||||
throw new Exception("file download fail: ".$webFilePath, AliyunVodError::VOD_ERR_FILE_DOWNLOAD);
|
||||
}
|
||||
|
||||
// 重新设置上传请求对象
|
||||
$request->setFilePath($localFilePath);
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
private function initOssClient($uploadAuth, $uploadAddress)
|
||||
{
|
||||
$endpoint = AliyunVodUtils::convertOssInternal($uploadAddress->Endpoint, $this->ecsRegionId, $this->enableSSL);
|
||||
//printf("oss endpoint: %s\n", $endpoint);
|
||||
$this->ossClient = new OssClient($uploadAuth->AccessKeyId, $uploadAuth->AccessKeySecret, $endpoint,
|
||||
false, $uploadAuth->SecurityToken);
|
||||
$this->ossClient->setTimeout($this->ossTimeout);
|
||||
$this->ossClient->setConnectTimeout($this->connTimeout);
|
||||
return $this->ossClient;
|
||||
}
|
||||
|
||||
private function initVodClient()
|
||||
{
|
||||
HttpHelper::$connectTimeout = $this->connTimeout;
|
||||
HttpHelper::$readTimeout = $this->vodTimeout;
|
||||
$profile = DefaultProfile::getProfile($this->apiRegionId, $this->accessKeyId, $this->accessKeySecret, $this->securityToken);
|
||||
//DefaultProfile::addEndpoint($this->apiRegionId, $this->apiRegionId, "vod", "vod.".$this->apiRegionId.".aliyuncs.com");
|
||||
return new DefaultAcsClient($profile);
|
||||
}
|
||||
|
||||
private function getUploadHeaders($uploadVideoRequest) {
|
||||
$switch = $uploadVideoRequest->getWatermarkSwitch();
|
||||
if (is_null($switch)) {
|
||||
return null;
|
||||
}
|
||||
$userData = sprintf("{\"Vod\":{\"UserData\":{\"IsShowWaterMark\": \"%s\"}}}", $switch);
|
||||
return array('x-oss-notification' => base64_encode($userData));
|
||||
}
|
||||
|
||||
private function createUploadVideo($uploadVideoRequest)
|
||||
{
|
||||
$request = new vod\CreateUploadVideoRequest();
|
||||
$title = AliyunVodUtils::subString($uploadVideoRequest->getTitle(), AliyunVodUtils::VOD_MAX_TITLE_LENGTH);
|
||||
$request->setTitle($title);
|
||||
$request->setFileName($uploadVideoRequest->getFileName());
|
||||
|
||||
if (!is_null($uploadVideoRequest->getDescription())) {
|
||||
$request->setDescription($uploadVideoRequest->getDescription());
|
||||
}
|
||||
if (!is_null($uploadVideoRequest->getCateId())) {
|
||||
$request->setCateId($uploadVideoRequest->getCateId());
|
||||
}
|
||||
if (!is_null($uploadVideoRequest->getTags())) {
|
||||
$request->setTags($uploadVideoRequest->getTags());
|
||||
}
|
||||
if (!is_null($uploadVideoRequest->getCoverURL())) {
|
||||
$request->setCoverURL($uploadVideoRequest->getCoverURL());
|
||||
}
|
||||
if (!is_null($uploadVideoRequest->getTemplateGroupId())) {
|
||||
$request->setTemplateGroupId($uploadVideoRequest->getTemplateGroupId());
|
||||
}
|
||||
if (!is_null($uploadVideoRequest->getStorageLocation())) {
|
||||
$request->setStorageLocation($uploadVideoRequest->getStorageLocation());
|
||||
}
|
||||
if (!is_null($uploadVideoRequest->getUserData())) {
|
||||
$request->setUserData($uploadVideoRequest->getUserData());
|
||||
}
|
||||
if (!is_null($uploadVideoRequest->getAppId())) {
|
||||
$request->setAppId($uploadVideoRequest->getAppId());
|
||||
}
|
||||
if (!is_null($uploadVideoRequest->getWorkflowId())) {
|
||||
$request->setWorkflowId($uploadVideoRequest->getWorkflowId());
|
||||
}
|
||||
|
||||
$data = $this->requestUploadInfo($request, 'video');
|
||||
AliyunVodLog::printLog("CreateUploadVideo, FilePath: %s, VideoId: %s", $uploadVideoRequest->getFilePath(), $data->VideoId);
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function requestUploadInfo($request, $mediaType)
|
||||
{
|
||||
$request->setAcceptFormat('JSON');
|
||||
$data = $this->vodClient->getAcsResponse($request, null, null, true, $this->maxRetryTimes);
|
||||
$data->OriUploadAddress = $data->UploadAddress;
|
||||
$data->OriUploadAuth = $data->UploadAuth;
|
||||
|
||||
$data->UploadAddress = json_decode(base64_decode($data->OriUploadAddress));
|
||||
$data->UploadAuth = json_decode(base64_decode($data->OriUploadAuth));
|
||||
$data->MediaType = $mediaType;
|
||||
if ($mediaType == 'video') {
|
||||
$data->MediaId = $data->VideoId;
|
||||
}
|
||||
elseif ($mediaType == 'image') {
|
||||
$data->MediaId = $data->ImageId;
|
||||
$data->MediaURL = $data->ImageURL;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function refreshUploadVideo($videoId)
|
||||
{
|
||||
$request = new vod\RefreshUploadVideoRequest();
|
||||
$request->setVideoId($videoId);
|
||||
|
||||
$data = $this->requestUploadInfo($request, 'video');
|
||||
AliyunVodLog::printLog("RefreshUploadVideo, VideoId: %s", $data->VideoId);
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function createUploadImage($uploadImageRequest)
|
||||
{
|
||||
$request = new vod\CreateUploadImageRequest();
|
||||
$request->setImageType($uploadImageRequest->getImageType());
|
||||
$request->setImageExt($uploadImageRequest->getImageExt());
|
||||
|
||||
if (!is_null($uploadImageRequest->getTitle())) {
|
||||
$title = AliyunVodUtils::subString($uploadImageRequest->getTitle(), AliyunVodUtils::VOD_MAX_TITLE_LENGTH);
|
||||
$request->setTitle($title);
|
||||
}
|
||||
if (!is_null($uploadImageRequest->getDescription())) {
|
||||
$request->setDescription($uploadImageRequest->getDescription());
|
||||
}
|
||||
if (!is_null($uploadImageRequest->getCateId())) {
|
||||
$request->setCateId($uploadImageRequest->getCateId());
|
||||
}
|
||||
if (!is_null($uploadImageRequest->getTags())) {
|
||||
$request->setTags($uploadImageRequest->getTags());
|
||||
}
|
||||
if (!is_null($uploadImageRequest->getStorageLocation())) {
|
||||
$request->setStorageLocation($uploadImageRequest->getStorageLocation());
|
||||
}
|
||||
if (!is_null($uploadImageRequest->getUserData())) {
|
||||
$request->setUserData($uploadImageRequest->getUserData());
|
||||
}
|
||||
if (!is_null($uploadImageRequest->getAppId())) {
|
||||
$request->setAppId($uploadImageRequest->getAppId());
|
||||
}
|
||||
if (!is_null($uploadImageRequest->getWorkflowId())) {
|
||||
$request->setWorkflowId($uploadImageRequest->getWorkflowId());
|
||||
}
|
||||
|
||||
$data = $this->requestUploadInfo($request, 'image');
|
||||
AliyunVodLog::printLog("CreateUploadImage, FilePath: %s, ImageId: %s, ImageURL: %s",
|
||||
$uploadImageRequest->getFilePath(), $data->ImageId, $data->ImageURL);
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function createUploadAttachedMedia($uploadAttachedRequest)
|
||||
{
|
||||
$request = new vod\CreateUploadAttachedMediaRequest();
|
||||
$request->setBusinessType($uploadAttachedRequest->getBusinessType());
|
||||
$request->setMediaExt($uploadAttachedRequest->getMediaExt());
|
||||
|
||||
if (!is_null($uploadAttachedRequest->getTitle())) {
|
||||
$title = AliyunVodUtils::subString($uploadAttachedRequest->getTitle(), AliyunVodUtils::VOD_MAX_TITLE_LENGTH);
|
||||
$request->setTitle($title);
|
||||
}
|
||||
if (!is_null($uploadAttachedRequest->getDescription())) {
|
||||
$request->setDescription($uploadAttachedRequest->getDescription());
|
||||
}
|
||||
if (!is_null($uploadAttachedRequest->getCateId())) {
|
||||
$request->setCateId($uploadAttachedRequest->getCateId());
|
||||
}
|
||||
if (!is_null($uploadAttachedRequest->getTags())) {
|
||||
$request->setTags($uploadAttachedRequest->getTags());
|
||||
}
|
||||
if (!is_null($uploadAttachedRequest->getStorageLocation())) {
|
||||
$request->setStorageLocation($uploadAttachedRequest->getStorageLocation());
|
||||
}
|
||||
if (!is_null($uploadAttachedRequest->getFileSize())) {
|
||||
$request->setFileSize($uploadAttachedRequest->getFileSize());
|
||||
}
|
||||
if (!is_null($uploadAttachedRequest->getUserData())) {
|
||||
$request->setUserData($uploadAttachedRequest->getUserData());
|
||||
}
|
||||
if (!is_null($uploadAttachedRequest->getAppId())) {
|
||||
$request->setAppId($uploadAttachedRequest->getAppId());
|
||||
}
|
||||
if (!is_null($uploadAttachedRequest->getWorkflowId())) {
|
||||
$request->setWorkflowId($uploadAttachedRequest->getWorkflowId());
|
||||
}
|
||||
|
||||
$data = $this->requestUploadInfo($request, 'attached');
|
||||
AliyunVodLog::printLog("CreateUploadAttachedMedia, FilePath: %s, MediaId: %s, MediaURL: %s",
|
||||
$uploadAttachedRequest->getFilePath(), $data->MediaId, $data->MediaURL);
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function uploadOssObject($filePath, $object, $uploadInfo, $headers=null)
|
||||
{
|
||||
$this->initOssClient($uploadInfo->UploadAuth, $uploadInfo->UploadAddress);
|
||||
$this->multipartUploadMediaFile($filePath, $object, $uploadInfo, $headers);
|
||||
|
||||
$bucketHost = str_replace('://', '://'.$uploadInfo->UploadAddress->Bucket.".",
|
||||
$uploadInfo->UploadAddress->Endpoint);
|
||||
AliyunVodLog::printLog("UploadFile %s Finish, MediaId: %s, FilePath: %s, Destination: %s/%s",
|
||||
$uploadInfo->MediaType, $uploadInfo->MediaId, $filePath, $bucketHost, $object);
|
||||
}
|
||||
|
||||
// 定义进度条回调函数;$consumedBytes: 已上传的数据量,$totalBytes:总数据量
|
||||
public function uploadProgressCallback($mediaId, $consumedBytes, $totalBytes)
|
||||
{
|
||||
if ($totalBytes > 0) {
|
||||
$rate = 100 * (floatval(($consumedBytes) / floatval($totalBytes)));
|
||||
}
|
||||
else {
|
||||
$rate = 0;
|
||||
}
|
||||
printf("[%s]UploadProgress of Media %s, uploaded %s bytes, percent %s%s\n",
|
||||
AliyunVodUtils::getCurrentTimeStr(), $mediaId, $consumedBytes, round($rate, 1), '%');
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
// 分片上传函数
|
||||
private function multipartUploadMediaFile($filePath, $object, $uploadInfo, $headers=null)
|
||||
{
|
||||
|
||||
$uploadFile = OssUtil::encodePath($filePath);
|
||||
if (!file_exists($uploadFile)) {
|
||||
throw new Exception("file not exists: ".$uploadFile, AliyunVodError::VOD_ERR_FILE_READ);
|
||||
}
|
||||
$fileSize = @filesize($uploadFile);
|
||||
if ($fileSize === false || $fileSize < 0) {
|
||||
throw new Exception('The size of file cannot be determined: '.$filePath,AliyunVodError::VOD_ERR_FILE_READ);
|
||||
}
|
||||
$this->filePartHash = null;
|
||||
$bucket = $uploadInfo->UploadAddress->Bucket;
|
||||
|
||||
// 文件大小未超过分片上传阈值,或不到一个分片的大小,则直接简单上传
|
||||
if ($fileSize <= $this->multipartThreshold || $fileSize < $this->multipartPartSize) {
|
||||
$res = $this->ossClient->uploadFile($bucket, $object, $uploadFile);
|
||||
if ($uploadInfo->MediaType == 'video') {
|
||||
$this->reportVideoUploadProgress('put', $uploadInfo, $filePath, $fileSize, 0, $fileSize,
|
||||
1, 1, $fileSize);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
// 初始化分片
|
||||
$uploadId = $this->ossClient->initiateMultipartUpload($bucket, $object);
|
||||
$pieces = $this->ossClient->generateMultiuploadParts($fileSize, $this->multipartPartSize);
|
||||
$resUploadPart = array();
|
||||
$uploadPosition = 0;
|
||||
$isCheckMd5 = false;
|
||||
$totalPart = count($pieces);
|
||||
|
||||
// 上传凭证有效期3000秒,如果是音视频,则需要提前刷新
|
||||
$startTime = time();
|
||||
$expireSeconds = 2500;
|
||||
|
||||
// 逐个上传分片
|
||||
foreach ($pieces as $i => $piece) {
|
||||
$fromPos = $uploadPosition + (integer)$piece[OssClient::OSS_SEEK_TO];
|
||||
$toPos = (integer)$piece[OssClient::OSS_LENGTH] + $fromPos - 1;
|
||||
$upOptions = array(
|
||||
OssClient::OSS_FILE_UPLOAD => $uploadFile,
|
||||
OssClient::OSS_PART_NUM => ($i + 1),
|
||||
OssClient::OSS_SEEK_TO => $fromPos,
|
||||
OssClient::OSS_LENGTH => $toPos - $fromPos + 1,
|
||||
OssClient::OSS_CHECK_MD5 => $isCheckMd5,
|
||||
);
|
||||
|
||||
if ($isCheckMd5) {
|
||||
$contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos);
|
||||
$upOptions[OssClient::OSS_CONTENT_MD5] = $contentMd5;
|
||||
}
|
||||
|
||||
// 上传分片
|
||||
$resUploadPart[] = $this->ossClient->uploadPart($bucket, $object, $uploadId, $upOptions);
|
||||
/*AliyunVodLog::printLog("UploadPart, FilePath: %s, MediaId: %s, MediaType: %s, UploadId: %s, PartNumber: %s, PartSize: %s",
|
||||
$uploadFile, $uploadInfo->MediaId, $uploadInfo->MediaType, $uploadId, $upOptions[OssClient::OSS_PART_NUM], $upOptions[OssClient::OSS_LENGTH]);*/
|
||||
|
||||
// 上传进度回调
|
||||
$this->uploadProgressCallback($uploadInfo->MediaId, $toPos, $fileSize);
|
||||
|
||||
if ($uploadInfo->MediaType == 'video') {
|
||||
// 上报上传进度
|
||||
$this->reportVideoUploadProgress('multipart', $uploadInfo, $uploadFile, $fileSize,
|
||||
$uploadId, $this->multipartPartSize, $totalPart, $upOptions[OssClient::OSS_PART_NUM], $toPos);
|
||||
|
||||
|
||||
// 检测视频上传凭证是否过期
|
||||
$nowTime = time();
|
||||
if ($nowTime - $startTime >= $expireSeconds) {
|
||||
$uploadInfo = $this->refreshUploadVideo($uploadInfo->MediaId);
|
||||
$this->initOssClient($uploadInfo->UploadAuth, $uploadInfo->UploadAddress);
|
||||
$startTime = $nowTime;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$uploadParts = array();
|
||||
foreach ($resUploadPart as $i => $eTag) {
|
||||
$uploadParts[] = array(
|
||||
'PartNumber' => ($i + 1),
|
||||
'ETag' => $eTag,
|
||||
);
|
||||
}
|
||||
|
||||
// 完成上传
|
||||
$options = is_null($headers) ? null : array(OssClient::OSS_HEADERS => $headers);
|
||||
$res = $this->ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts, $options);
|
||||
if ($uploadInfo->MediaType == 'video') {
|
||||
$this->reportVideoUploadProgress('multipart', $uploadInfo, $filePath, $fileSize, $uploadId,
|
||||
$this->multipartPartSize, $totalPart, $totalPart, $fileSize);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
private function reportVideoUploadProgress($uploadMethod, $uploadInfo, $filePath, $fileSize, $uploadId, $partSize,
|
||||
$totalPart, $donePartsCount, $doneBytes)
|
||||
{
|
||||
if (is_null($this->filePartHash)) {
|
||||
$this->filePartHash = AliyunVodReportUpload::generateFilePartHash($this->accessKeyId, $filePath, $fileSize);
|
||||
}
|
||||
$uploadPoint = array('upMethod'=>$uploadMethod, 'threshold'=>$this->multipartThreshold,
|
||||
'partSize'=>$this->multipartPartSize, 'doneBytes'=>$doneBytes);
|
||||
$progressInfo = array('FileName'=>$filePath, 'FileHash'=>$this->filePartHash, 'FileSize'=>$fileSize, 'UploadId'=>$uploadId,
|
||||
'PartSize'=>$partSize, 'TotalPart'=>$totalPart, 'DonePartsCount'=>$donePartsCount,
|
||||
'UploadPoint'=>json_encode($uploadPoint), 'UploadAddress'=>$uploadInfo->OriUploadAddress);
|
||||
|
||||
AliyunVodReportUpload::reportUploadProgress($this->accessKeyId, $uploadInfo->MediaId, $progressInfo);
|
||||
}
|
||||
|
||||
|
||||
private $accessKeyId;
|
||||
private $accessKeySecret;
|
||||
private $apiRegionId;
|
||||
private $ecsRegionId;
|
||||
private $connTimeout;
|
||||
private $ossTimeout;
|
||||
private $vodTimeout;
|
||||
private $vodClient;
|
||||
private $ossClient;
|
||||
private $maxRetryTimes;
|
||||
private $filePartHash;
|
||||
private $enableSSL;
|
||||
private $securityToken = null;
|
||||
|
||||
// 分片上传的阈值,超过此值开启分片上传
|
||||
private $multipartThreshold;
|
||||
// 分片大小,单位byte
|
||||
private $multipartPartSize;
|
||||
// 分片上传时并行上传的线程数,暂时为串行上传,不支持并行,后续会支持。
|
||||
private $multipartThreadsNum;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by Aliyun ApsaraVideo VoD.
|
||||
* User: https://www.aliyun.com/product/vod
|
||||
*/
|
||||
use OSS\Core\OssUtil;
|
||||
|
||||
class AliyunVodUtils
|
||||
{
|
||||
const VOD_MAX_TITLE_LENGTH = 128;
|
||||
const VOD_MAX_DESCRIPTION_LENGTH = 1024;
|
||||
|
||||
public static function convertOssInternal($ossUrl, $ecsRegion=null, $isEnableSSL=false)
|
||||
{
|
||||
if (!$isEnableSSL) {
|
||||
$ossUrl = str_replace("https:", "http:", $ossUrl);
|
||||
}
|
||||
|
||||
if (!is_string($ossUrl) || !is_string($ecsRegion)) {
|
||||
return $ossUrl;
|
||||
}
|
||||
$availableRegions = array('cn-qingdao', 'cn-beijing', 'cn-zhangjiakou', 'cn-huhehaote', 'cn-hangzhou', 'cn-shanghai', 'cn-shenzhen',
|
||||
'cn-hongkong', 'ap-southeast-1', 'ap-southeast-2', 'ap-southeast-3',
|
||||
'ap-northeast-1', 'us-west-1', 'us-east-1', 'eu-central-1', 'me-east-1');
|
||||
|
||||
if (!in_array($ecsRegion, $availableRegions)) {
|
||||
return $ossUrl;
|
||||
}
|
||||
|
||||
$ossUrl = str_replace("https:", "http:", $ossUrl);
|
||||
return str_replace(sprintf("oss-%s.aliyuncs.com", $ecsRegion),
|
||||
sprintf("oss-%s-internal.aliyuncs.com", $ecsRegion), $ossUrl);
|
||||
}
|
||||
|
||||
public static function getFileName($fileUrl)
|
||||
{
|
||||
$fileUrl = urldecode($fileUrl);
|
||||
$pos = strrpos($fileUrl, '?');
|
||||
$briefPath = $fileUrl;
|
||||
if ($pos !== false) {
|
||||
$briefPath = substr($fileUrl, 0, $pos);
|
||||
}
|
||||
return array($briefPath, basename($briefPath));
|
||||
}
|
||||
|
||||
public static function getFileExtension($fileName)
|
||||
{
|
||||
$pos = strrpos($fileName, '.');
|
||||
if ($pos !== false) {
|
||||
return substr($fileName, $pos + 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 考虑分隔符为"/" 或 "\"(windows)
|
||||
public static function replaceFileName($filePath, $replace) {
|
||||
if (strlen($filePath) <= 0 || strlen($replace) <= 0) {
|
||||
return $filePath;
|
||||
}
|
||||
$filePath = urldecode($filePath);
|
||||
$separator = '/';
|
||||
$start = strrpos($filePath, $separator);
|
||||
if ($start === false) {
|
||||
$separator = '\\';
|
||||
$start = strrpos($filePath, '\\');
|
||||
if ($start === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return substr($filePath, 0, $start) . $separator. $replace;
|
||||
}
|
||||
|
||||
public static function mkDir($filePath) {
|
||||
if (strlen($filePath) <= 0) {
|
||||
return true;
|
||||
}
|
||||
$filePath = urldecode($filePath);
|
||||
$start = strrpos($filePath, '/');
|
||||
if ($start === false) {
|
||||
return false;
|
||||
}
|
||||
$fileDir = substr($filePath, 0, $start);
|
||||
if (!is_dir($fileDir)) {
|
||||
return mkdir($fileDir, 0777, true);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// 截取字符串,在不超过最大字节数前提下确保中文字符不被截断出现乱码
|
||||
public static function subString($strVal, $maxBytes)
|
||||
{
|
||||
$i = mb_strlen($strVal);
|
||||
while (strlen($strVal) > $maxBytes) {
|
||||
$i--;
|
||||
if ($i <= 0) {
|
||||
return '';
|
||||
}
|
||||
$strVal = mb_substr($strVal, 0, $i);
|
||||
}
|
||||
return $strVal;
|
||||
}
|
||||
|
||||
public static function getCurrentTimeStr() {
|
||||
return date("Y-m-d H:i:s");
|
||||
|
||||
}
|
||||
|
||||
public static function startsWith($haystack, $needle){
|
||||
return strncmp($haystack, $needle, strlen($needle)) === 0;
|
||||
}
|
||||
|
||||
public static function endsWith($haystack, $needle){
|
||||
return $needle === '' || substr_compare($haystack, $needle, -strlen($needle)) === 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
class AliyunVodLog
|
||||
{
|
||||
public static $logSwitch = true;
|
||||
public static function printLog($format, $args = null, $_ = null) {
|
||||
if (!AliyunVodLog::$logSwitch) {
|
||||
return;
|
||||
}
|
||||
$vargs = func_get_args();
|
||||
unset($vargs[0]);
|
||||
$msg = vsprintf($format, $vargs);
|
||||
self::printStr($msg);
|
||||
}
|
||||
|
||||
private static function printStr($msg) {
|
||||
printf("[%s]%s\n", AliyunVodUtils::getCurrentTimeStr(), $msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class AliyunVodReportUpload
|
||||
{
|
||||
public static $isEnableSSL = false;
|
||||
|
||||
const VOD_REPORT_URL = 'vod.cn-shanghai.aliyuncs.com';
|
||||
const VOD_REPORT_VERSION = '1.0.2';
|
||||
const VOD_REPORT_KEY ='wXr&aLIJdfI7so';
|
||||
const REPORT_FILE_HASH_READ_LEN = 1048576;
|
||||
|
||||
public static function reportUploadProgress($clientId, $videoId, $progressInfo)
|
||||
{
|
||||
try {
|
||||
HttpHelper::$connectTimeout = 1;
|
||||
HttpHelper::$readTimeout = 2;
|
||||
$authTimestamp = time();
|
||||
$authInfo = md5(sprintf("%s|%s|%s", $clientId, self::VOD_REPORT_KEY, $authTimestamp));
|
||||
$fields = array('Action'=>'ReportUploadProgress', 'Format'=>'JSON', 'Version'=>'2017-03-21',
|
||||
'Timestamp'=>gmdate('Y-m-d\TH:i:s\Z'), 'SignatureNonce'=>md5(uniqid(mt_rand(), true)),
|
||||
'VideoId'=>$videoId, 'Source'=>'PHPSDK', 'ClientId'=>$clientId,
|
||||
'BusinessType'=>'UploadVideo', 'TerminalType'=>'PC', 'DeviceModel'=>'Server',
|
||||
'AppVersion'=>self::VOD_REPORT_VERSION, 'AuthTimestamp'=>$authTimestamp, 'AuthInfo'=>$authInfo,
|
||||
'FileName'=>$progressInfo['FileName'], 'FileHash'=>$progressInfo['FileHash'],
|
||||
'FileSize'=>empty($progressInfo['FileSize']) ? 0 : $progressInfo['FileSize'],
|
||||
'FileCreateTime'=>empty($progressInfo['CreateTime']) ? $authTimestamp : $progressInfo['CreateTime'],
|
||||
'UploadRatio'=>empty($progressInfo['UploadRatio']) ? 0 : $progressInfo['UploadRatio'],
|
||||
'UploadId'=>empty($progressInfo['UploadId']) ? 0 : $progressInfo['UploadId'],
|
||||
'DonePartsCount'=>empty($progressInfo['DonePartsCount']) ? 0 : $progressInfo['DonePartsCount'],
|
||||
'PartSize'=>empty($progressInfo['PartSize']) ? 0 : $progressInfo['PartSize'],
|
||||
'UploadPoint'=>$progressInfo['UploadPoint'], 'UploadAddress'=>$progressInfo['UploadAddress']
|
||||
);
|
||||
|
||||
$url = (self::$isEnableSSL ? 'https://' : 'http://') . self::VOD_REPORT_URL;
|
||||
HttpHelper::curl($url,'POST', $fields);
|
||||
|
||||
} catch (Exception $e) {
|
||||
AliyunVodLog::printLog("reportUploadProgress failed, ErrorMessage: %s\n", $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static function generateFilePartHash($clientId, $filePath, $fileSize)
|
||||
{
|
||||
try {
|
||||
$fp = @fopen(OssUtil::encodePath($filePath),"r");
|
||||
$len = $fileSize <= self::REPORT_FILE_HASH_READ_LEN ? $fileSize : self::REPORT_FILE_HASH_READ_LEN;
|
||||
$str = fread($fp, $len);
|
||||
fclose($fp);
|
||||
} catch (Exception $e) {
|
||||
$str = sprintf("%s|%s|%s", $clientId, $filePath, @filemtime($filePath));
|
||||
}
|
||||
return md5($str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class AliyunVodDownloader
|
||||
{
|
||||
public function __construct($saveLocalDir=null)
|
||||
{
|
||||
if (isset($saveLocalDir)) {
|
||||
$this->saveLocalDir = $saveLocalDir;
|
||||
}
|
||||
else {
|
||||
$this->saveLocalDir = dirname(__DIR__) . '/tmp_dlfiles/';
|
||||
}
|
||||
}
|
||||
|
||||
public function downloadFile($downloadUrl, $localFileName, $fileSize=null)
|
||||
{
|
||||
$localPath = $this->saveLocalDir . $localFileName;
|
||||
AliyunVodLog::printLog("Download %s To %s", $downloadUrl, $localPath);
|
||||
|
||||
if (isset($fileSize)) {
|
||||
$lsize = @filesize($localPath);
|
||||
if ($lsize > 0 and $lsize == $fileSize) {
|
||||
return $localPath;
|
||||
}
|
||||
}
|
||||
if (!is_dir($this->saveLocalDir)) {
|
||||
@mkdir($this->saveLocalDir, 0777, true);
|
||||
}
|
||||
|
||||
$sfp = @fopen($downloadUrl, "rb");
|
||||
if ($sfp === false) {
|
||||
throw new Exception("download file fail while reading ".$downloadUrl,
|
||||
AliyunVodError::VOD_ERR_FILE_DOWNLOAD);
|
||||
}
|
||||
|
||||
$dfp = @fopen(OssUtil::encodePath($localPath), "ab+");
|
||||
if ($sfp === false) {
|
||||
throw new Exception("download file fail while writing ".$localPath,
|
||||
AliyunVodError::VOD_ERR_FILE_DOWNLOAD);
|
||||
}
|
||||
while (!feof($sfp)) {
|
||||
$contents = fread($sfp,8 * 1024);
|
||||
fwrite($dfp, $contents);
|
||||
}
|
||||
|
||||
fclose($sfp);
|
||||
fclose($dfp);
|
||||
|
||||
return $localPath;
|
||||
}
|
||||
|
||||
public function getSaveLocalDir() {
|
||||
return $this->saveLocalDir;
|
||||
}
|
||||
|
||||
public function setSaveLocalDir($localDir) {
|
||||
return $this->saveLocalDir = $localDir;
|
||||
}
|
||||
|
||||
private $saveLocalDir = null;
|
||||
}
|
||||
|
||||
class AliyunVodError
|
||||
{
|
||||
const VOD_ERR_FILE_READ = 10000;
|
||||
const VOD_ERR_FILE_DOWNLOAD = 10001;
|
||||
const VOD_ERR_M3U8_FILE_REWRITE = 10002;
|
||||
const VOD_INVALID_M3U8_SLICE_FILE = 10003;
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* Class UploadAttachedMediaRequest
|
||||
*
|
||||
* Aliyun VoD's Upload Attached Media(such as watermark,subtitle files) Request class, which wraps parameters to upload an image into VoD.
|
||||
* Users could pass parameters to AliyunVodUploader, including File Path,Title,etc. via an UploadAttachedMediaRequest instance.
|
||||
* For more details, please check out the VoD API document: https://help.aliyun.com/document_detail/98467.html
|
||||
*/
|
||||
|
||||
class UploadAttachedMediaRequest
|
||||
{
|
||||
/**
|
||||
* UploadAttachedMediaRequest constructor.
|
||||
* @param $filePath
|
||||
* @param $businessType, optional values: "watermark", "subtitle" and and so on.
|
||||
* @param null $title
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct($filePath, $businessType, $title=null)
|
||||
{
|
||||
$this->setFilePath($filePath, $title);
|
||||
$this->businessType = $businessType;
|
||||
}
|
||||
|
||||
public function getFilePath() {
|
||||
return $this->filePath;
|
||||
}
|
||||
|
||||
public function setFilePath($filePath, $title=null) {
|
||||
$this->filePath = $filePath;
|
||||
$fns = AliyunVodUtils::getFileName($this->filePath);
|
||||
$this->fileName = $fns[0];
|
||||
$extName = AliyunVodUtils::getFileExtension($this->fileName);
|
||||
if (empty($extName)) {
|
||||
throw new Exception('filePath has no Extension', 'InvalidParameter');
|
||||
}
|
||||
$this->mediaExt = $extName;
|
||||
|
||||
if (isset($title)) {
|
||||
$this->title = $title;
|
||||
}
|
||||
else {
|
||||
if (!isset($this->title)) {
|
||||
$this->title = $fns[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getFileName() {
|
||||
return $this->fileName;
|
||||
}
|
||||
|
||||
public function getBusinessType() {
|
||||
return $this->businessType;
|
||||
}
|
||||
|
||||
public function getMediaExt() {
|
||||
return $this->mediaExt;
|
||||
}
|
||||
|
||||
public function getFileSize() {
|
||||
return $this->fileSize;
|
||||
}
|
||||
|
||||
public function setFileSize($fileSize) {
|
||||
$this->fileSize = $fileSize;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setTitle($title) {
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getCateId() {
|
||||
return $this->cateId;
|
||||
}
|
||||
|
||||
public function setCateId($cateId) {
|
||||
$this->cateId = $cateId;
|
||||
}
|
||||
|
||||
public function getTags() {
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
public function setTags($tags) {
|
||||
$this->tags = $tags;
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription($description) {
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
public function getStorageLocation() {
|
||||
return $this->storageLocation;
|
||||
}
|
||||
|
||||
public function setStorageLocation($storageLocation) {
|
||||
$this->storageLocation = $storageLocation;
|
||||
}
|
||||
|
||||
public function getUserData() {
|
||||
return $this->userData;
|
||||
}
|
||||
|
||||
public function setUserData($userData) {
|
||||
$this->userData = $userData;
|
||||
}
|
||||
|
||||
public function getAppId() {
|
||||
return $this->appId;
|
||||
}
|
||||
|
||||
public function setAppId($appId) {
|
||||
$this->appId = $appId;
|
||||
}
|
||||
|
||||
public function getWorkflowId() {
|
||||
return $this->workflowId;
|
||||
}
|
||||
|
||||
public function setWorkflowId($WorkflowId) {
|
||||
$this->workflowId = $WorkflowId;
|
||||
}
|
||||
|
||||
private $filePath = null;
|
||||
private $fileName = null;
|
||||
private $fileSize = null;
|
||||
private $businessType = null;
|
||||
private $mediaExt = null;
|
||||
private $title = null;
|
||||
private $cateId = null;
|
||||
private $tags = null;
|
||||
private $description = null;
|
||||
private $storageLocation = null;
|
||||
private $userData = null;
|
||||
private $appId = null;
|
||||
private $workflowId = null;
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* Class UploadImageRequest
|
||||
*
|
||||
* Aliyun VoD's Upload Image Request class, which wraps parameters to upload an image into VoD.
|
||||
* Users could pass parameters to AliyunVodUploader, including File Path,Title,etc. via an UploadImageRequest instance.
|
||||
* For more details, please check out the VoD API document: https://help.aliyun.com/document_detail/55619.html
|
||||
*/
|
||||
class UploadImageRequest
|
||||
{
|
||||
public function __construct($filePath, $title=null) {
|
||||
$this->setFilePath($filePath, $title);
|
||||
$this->imageType = 'default';
|
||||
|
||||
}
|
||||
|
||||
public function getFilePath() {
|
||||
return $this->filePath;
|
||||
}
|
||||
|
||||
public function setFilePath($filePath, $title=null) {
|
||||
$this->filePath = $filePath;
|
||||
$fns = AliyunVodUtils::getFileName($this->filePath);
|
||||
$this->fileName = $fns[0];
|
||||
$extName = AliyunVodUtils::getFileExtension($this->fileName);
|
||||
if (empty($extName)) {
|
||||
throw new Exception('filePath has no Extension', 'InvalidParameter');
|
||||
}
|
||||
$this->imageExt = $extName;
|
||||
|
||||
if (isset($title)) {
|
||||
$this->title = $title;
|
||||
}
|
||||
else {
|
||||
if (!isset($this->title)) {
|
||||
$this->title = $fns[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getFileName() {
|
||||
return $this->fileName;
|
||||
}
|
||||
|
||||
public function getImageType() {
|
||||
return $this->imageType;
|
||||
}
|
||||
|
||||
public function setImageType($imageType) {
|
||||
$this->imageType = $imageType;
|
||||
}
|
||||
|
||||
public function getImageExt() {
|
||||
return $this->imageExt;
|
||||
}
|
||||
|
||||
public function getMediaExt() {
|
||||
return $this->imageExt;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setTitle($title) {
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getCateId() {
|
||||
return $this->cateId;
|
||||
}
|
||||
|
||||
public function setCateId($cateId) {
|
||||
$this->cateId = $cateId;
|
||||
}
|
||||
|
||||
public function getTags() {
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
public function setTags($tags) {
|
||||
$this->tags = $tags;
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription($description) {
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
public function getStorageLocation() {
|
||||
return $this->storageLocation;
|
||||
}
|
||||
|
||||
public function setStorageLocation($storageLocation) {
|
||||
$this->storageLocation = $storageLocation;
|
||||
}
|
||||
|
||||
public function getUserData() {
|
||||
return $this->userData;
|
||||
}
|
||||
|
||||
public function setUserData($userData) {
|
||||
$this->userData = $userData;
|
||||
}
|
||||
|
||||
public function getAppId() {
|
||||
return $this->appId;
|
||||
}
|
||||
|
||||
public function setAppId($appId) {
|
||||
$this->appId = $appId;
|
||||
}
|
||||
|
||||
public function getWorkflowId() {
|
||||
return $this->workflowId;
|
||||
}
|
||||
|
||||
public function setWorkflowId($WorkflowId) {
|
||||
$this->workflowId = $WorkflowId;
|
||||
}
|
||||
|
||||
private $filePath = null;
|
||||
private $fileName = null;
|
||||
private $imageType = null;
|
||||
private $imageExt = null;
|
||||
private $title = null;
|
||||
private $cateId = null;
|
||||
private $tags = null;
|
||||
private $description = null;
|
||||
private $storageLocation = null;
|
||||
private $userData = null;
|
||||
private $appId = null;
|
||||
private $workflowId = null;
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* Class UploadVideoRequest
|
||||
*
|
||||
* Aliyun VoD's Upload Video Request class, which wraps parameters to upload a video into VoD.
|
||||
* Users could pass parameters to AliyunVodUploader, including File Path,Title,etc. via an UploadVideoRequest instance.
|
||||
* For more details, please check out the VoD API document: https://help.aliyun.com/document_detail/55407.html
|
||||
*/
|
||||
class UploadVideoRequest
|
||||
{
|
||||
/**
|
||||
* UploadVideoRequest constructor.
|
||||
* @param $filePath
|
||||
* @param null $title
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct($filePath, $title=null) {
|
||||
$this->setFilePath($filePath, $title);
|
||||
}
|
||||
|
||||
public function getFilePath() {
|
||||
return $this->filePath;
|
||||
}
|
||||
|
||||
public function setFilePath($filePath, $title=null) {
|
||||
$this->filePath = $filePath;
|
||||
$fns = AliyunVodUtils::getFileName($this->filePath);
|
||||
$this->fileName = $fns[0];
|
||||
$extName = AliyunVodUtils::getFileExtension($this->fileName);
|
||||
if (empty($extName)) {
|
||||
throw new Exception('filePath has no Extension', 'InvalidParameter');
|
||||
}
|
||||
$this->mediaExt = $extName;
|
||||
|
||||
if (isset($title)) {
|
||||
$this->title = $title;
|
||||
}
|
||||
else {
|
||||
if (!isset($this->title)) {
|
||||
$this->title = $fns[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function getMediaExt() {
|
||||
return $this->mediaExt;
|
||||
}
|
||||
|
||||
public function setTitle($title) {
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getFileName() {
|
||||
return $this->fileName;
|
||||
}
|
||||
|
||||
public function getCateId() {
|
||||
return $this->cateId;
|
||||
}
|
||||
|
||||
public function setCateId($cateId) {
|
||||
$this->cateId = $cateId;
|
||||
}
|
||||
|
||||
public function getTags() {
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
public function setTags($tags) {
|
||||
$this->tags = $tags;
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription($description) {
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
public function getCoverURL() {
|
||||
return $this->coverURL;
|
||||
}
|
||||
|
||||
public function setCoverURL($coverURL) {
|
||||
$this->coverURL = $coverURL;
|
||||
}
|
||||
|
||||
public function getTemplateGroupId() {
|
||||
return $this->templateGroupId;
|
||||
}
|
||||
|
||||
public function setTemplateGroupId($templateGroupId) {
|
||||
$this->templateGroupId = $templateGroupId;
|
||||
}
|
||||
|
||||
public function getIsShowWatermark() {
|
||||
return $this->isShowWatermark;
|
||||
}
|
||||
|
||||
// 关闭水印,仅用于配置全局水印且转码模板开启水印后,单次上传时关闭水印
|
||||
public function shutdownWatermark() {
|
||||
$this->isShowWatermark = false;
|
||||
}
|
||||
|
||||
public function getWatermarkSwitch() {
|
||||
return $this->isShowWatermark;
|
||||
}
|
||||
|
||||
public function getStorageLocation() {
|
||||
return $this->storageLocation;
|
||||
}
|
||||
|
||||
public function setStorageLocation($storageLocation) {
|
||||
$this->storageLocation = $storageLocation;
|
||||
}
|
||||
|
||||
public function getUserData() {
|
||||
return $this->userData;
|
||||
}
|
||||
|
||||
public function setUserData($userData) {
|
||||
$this->userData = $userData;
|
||||
}
|
||||
|
||||
public function getAppId() {
|
||||
return $this->appId;
|
||||
}
|
||||
|
||||
public function setAppId($appId) {
|
||||
$this->appId = $appId;
|
||||
}
|
||||
|
||||
public function getWorkflowId() {
|
||||
return $this->workflowId;
|
||||
}
|
||||
|
||||
public function setWorkflowId($WorkflowId) {
|
||||
$this->workflowId = $WorkflowId;
|
||||
}
|
||||
|
||||
private $filePath = null;
|
||||
private $title = null;
|
||||
private $fileName = null;
|
||||
private $mediaExt = null;
|
||||
private $cateId = null;
|
||||
private $tags = null;
|
||||
private $description = null;
|
||||
private $coverURL = null;
|
||||
private $templateGroupId = null;
|
||||
private $isShowWatermark = null;
|
||||
private $storageLocation = null;
|
||||
private $userData = null;
|
||||
private $appId = null;
|
||||
private $workflowId = null;
|
||||
}
|
||||
Reference in New Issue
Block a user