更新时间:2024-12-12 GMT+08:00
PHP
分段上传PHP语言的示例代码,如下所示:
<?php
namespace HuaweiCloud\SDK\Vod\V1\Model;
use DOMDocument;
use DOMException;
use Exception;
require_once "vendor/autoload.php";
use HuaweiCloud\SDK\Core\Auth\BasicCredentials;
use HuaweiCloud\SDK\Core\Http\HttpConfig;
use HuaweiCloud\SDK\Vod\V1\VodClient;
// 区域
const region_north1 = 'cn-north-1';
const region_north4 = 'cn-north-4';
const region_east2 = 'cn-east-2';
// ak/sk
const ak = "";
const sk = "";
const projectId = "";
const endpoint = "https://vod." . region_north4 . ".myhuaweicloud.com";
// 设置缓冲区大小,每次读取文件分段的大小,根据情况自行设定
// 1M
const bufferSize = 1024 * 1024;
main();
/*
* 分段上传示例
*/
function main(): void
{
// 本地要上传的媒资路径
$filePath = "";
// 上传媒资文件
partUpload($filePath);
}
/**
* 分段上传
* @param $filePath 传文件的本地路径
* @return void
*/
function partUpload(string $filePath)
{
$handle = fopen($filePath, "r");
if(!$handle){
throw new Exception("无法打开文件!");
}
try {
$fileName = basename($filePath);
// 此处仅以MP4文件示例,其他格式可以参考官网说明
$fileType = "MP4";
$fileContentType = "video/mp4";
// 1.初始化鉴权并获取vodClient
$vodClient = createVodClient();
echo "开始创建媒资:" . $fileName . "\n";
// 2.创建点播媒资
$assetResponse = createAsset($vodClient, $fileName, $fileName, $fileType);
// 3.获取初始化上传任务授权
$initAuthResponse = initPartUploadAuthority($vodClient, $assetResponse, $fileContentType);
// 4.初始化上传任务
$uploadId = initPartUpload($initAuthResponse->getSignStr(), $fileContentType);
// 文件分段计数
$partNumber = 1;
// 7.读取文件内容,循环5-6步上传所有分段
while (!feof($handle)) {
$content = fread($handle, bufferSize);
// 先md5,再base64
$md5Hash = md5($content);
echo "md5:". $md5Hash ."\n";
$hexString = hex2bin($md5Hash);
$contentMd5 = base64_encode($hexString);
echo "该文件第" . $partNumber . "段contentMd5:" . $contentMd5 . "\n";
// 5.获取上传分段的授权
$partUploadAuthorityResponse = getPartUploadAuthority($vodClient, $fileContentType, $assetResponse, $contentMd5, $uploadId, $partNumber);
// 6.上传分段
uploadPartFile($partUploadAuthorityResponse->getSignStr(), $content, $contentMd5);
//段号自增
$partNumber++;
}
fclose($handle);
// 8.获取已上传分段的授权
$listPartUploadAuthorityResponse = listUploadedPartAuthority($vodClient, $assetResponse, $uploadId);
// 9.获取已上传的分段
$partInfo = listUploadedPart($listPartUploadAuthorityResponse->getSignStr());
// 10.获取合并段授权
$mergePartUploadAuthorityResponse = mergeUploadedPartAuthority($vodClient, $assetResponse, $uploadId);
// 11.合并上传分段
mergeUploadedPart($mergePartUploadAuthorityResponse->getSignStr(), $partInfo);
// 12.确认媒资上传
confirmUploaded($vodClient, $assetResponse);
echo "创建媒资结束 assetId:" . $assetResponse->getAssetId() . "\n";
} catch (Exception $e) {
echo $e;
}
}
/**
* 1.构建鉴权
* @return VodClient
*/
function createVodClient(): VodClient
{
$credentials = new BasicCredentials(ak, sk, projectId);
$config = HttpConfig::getDefaultConfig();
$config->setIgnoreSslVerification(true);
$client = VodClient::newBuilder(new VodClient)
->withHttpConfig($config)
->withEndpoint(endpoint)
->withCredentials($credentials)
->build();
return $client;
}
/**
* 2.创建媒资
* @param VodClient $vodClient
* @param string $videoName
* @param string $title
* @param string $videoType
* @return CreateAssetByFileUploadResponse $response
*/
function createAsset(VodClient $vodClient, string $videoName, string $title, string $videoType): CreateAssetByFileUploadResponse
{
$request = new CreateAssetByFileUploadRequest();
$body = new CreateAssetByFileUploadReq();
$body->setVideoName($videoName);
$body->setTitle($title);
$body->setVideoType($videoType);
$request->setBody($body);
$response = $vodClient->createAssetByFileUpload($request);
echo $response . "\n";
return $response;
}
/**
* 3.获取初始化上传任务授权
* @param VodClient $client
* @param CreateAssetByFileUploadResponse $assetResponse
* @param string $fileContentType
* @return ShowAssetTempAuthorityResponse
*/
function initPartUploadAuthority(VodClient $client, CreateAssetByFileUploadResponse $assetResponse, string $fileContentType): ShowAssetTempAuthorityResponse
{
echo "获取初始化上传任务授权 initPartUploadAuthority start\n";
$request = new ShowAssetTempAuthorityRequest();
// 设置参数
$request->setHttpVerb("POST");
$request->setBucket($assetResponse->getTarget()->getBucket());
$request->setObjectKey($assetResponse->getTarget()->getObject());
$request->setContentType($fileContentType);
// 发送初始化请求
$response = $client->showAssetTempAuthority($request);
echo "获取初始化上传任务授权 end; response:" . $response . "\n\n";
return $response;
}
/**
* 4.初始化分段上传
* @param string $signStr
* @param string $contentType
* @return string|null
*/
function initPartUpload(string $signStr, string $contentType): string
{
echo "初始化分段上传 initPartUpload start\n";
// 初始化cURL会话
$ch = curl_init();
//设置cURL选项
curl_setopt($ch, CURLOPT_URL, $signStr);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: " . $contentType // 设置请求头
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //验证curl对等证书(一般只要此项)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //检查服务器SSL证书中是否存在一个公用名
curl_setopt($ch, CURLOPT_SSLVERSION, 0); //传递一个包含SSL版本的长参数。
// 执行cURL会话
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'cURL Error: ' . curl_error($ch);
} else {
// 打印响应内容
echo $response;
}
echo $response . "\n";
$initDom = new DOMDocument();
$initDom->loadXML($response);
curl_close($ch);
$UploadIdNode = $initDom->getElementsByTagName("UploadId");
$uploadId = $UploadIdNode->item(0)->nodeValue;
echo "初始化分段上传 initPartUpload end; UploadId:" . $uploadId . "\n\n";
return $uploadId;
}
/**
* 5.获取分段上传授权
* @param VodClient $client
* @param string $fileContentType
* @param CreateAssetByFileUploadResponse $assetResponse
* @param string $contentMd5
* @param string $uploadId
* @param int $partNumber
* @return ShowAssetTempAuthorityResponse
*/
function getPartUploadAuthority(VodClient $client, string $fileContentType, CreateAssetByFileUploadResponse $assetResponse,
string $contentMd5, string $uploadId, int $partNumber): ShowAssetTempAuthorityResponse
{
echo "获取分段上传授权 getPartUploadAuthority start; partNumber:" . $partNumber . "\n";
$request = new ShowAssetTempAuthorityRequest();
$request->setHttpVerb("PUT");
$request->setBucket($assetResponse->getTarget()->getBucket());
$request->setObjectKey($assetResponse->getTarget()->getObject());
$request->setContentType($fileContentType);
$request->setContentMd5($contentMd5);
$request->setUploadId($uploadId);
$request->setPartNumber($partNumber);
$response = $client->showAssetTempAuthority($request);
echo "获取分段上传授权 getPartUploadAuthority end; partNumber:" . $partNumber . "\n";
return $response;
}
/**
* 6.上传分段
* @param string $signStr
* @param string $fileByte
* @param string $contentMd5
* @return void
* @throws Exception
*/
function uploadPartFile(string $signStr, $fileByte, string $contentMd5)
{
echo "上传分段 uploadPartFile start\n";
// echo $fileByte . "\n";
// 初始化cURL会话
$ch = curl_init();
// 设置cURL选项
curl_setopt($ch, CURLOPT_URL, $signStr);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $fileByte);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-MD5: " . $contentMd5,
"Content-Type: application/octet-stream"
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //验证curl对等证书(一般只要此项)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //检查服务器SSL证书中是否存在一个公用名
curl_setopt($ch, CURLOPT_SSLVERSION, 0); //传递一个包含SSL版本的长参数。
// 执行cURL会话
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'cURL Error: ' . curl_error($ch);
// 打印响应内容
echo $response . "\n";
throw new Exception("上传失败!");
}
// 关闭会话
curl_close($ch);
echo "上传分段 uploadPartFile end;\n\n";
}
/**
* 8.获取列举已上传段的授权
* @param VodClient $client
* @param CreateAssetByFileUploadResponse $assetResponse
* @param string $uploadId
* @return ShowAssetTempAuthorityResponse
*/
function listUploadedPartAuthority(VodClient $client, CreateAssetByFileUploadResponse $assetResponse, string $uploadId):ShowAssetTempAuthorityResponse
{
echo "获取列举已上传段的授权 listUploadedPartAuthority start\n";
$request = new ShowAssetTempAuthorityRequest();
$request->setHttpVerb("GET");
$request->setBucket($assetResponse->getTarget()->getBucket());
$request->setObjectKey($assetResponse->getTarget()->getObject());
$request->setUploadId($uploadId);
$response = $client->showAssetTempAuthority($request);
echo "列举已上传段的授权 listUploadedPartAuthority end; response:" . $response . "\n";
return $response;
}
/**
* 9.查询已上传的分段
* @param string $signStr
* @return false|string
* @throws DOMException
*/
function listUploadedPart(string $signStr): false|string
{
echo "查询已上传的分段 listUploadedPart start\n";
$partNumberMarker = 0;
$compDom = new DOMDocument();
$root = $compDom->createElement("CompleteMultipartUpload");
$compDom->appendChild($root);
while(true)
{
// 初始化cURL会话
$ch = curl_init();
// 设置cURL选项
curl_setopt($ch, CURLOPT_URL, $signStr . "&part-number-marker=" . $partNumberMarker);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //验证curl对等证书(一般只要此项)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //检查服务器SSL证书中是否存在一个公用名
curl_setopt($ch, CURLOPT_SSLVERSION, 0); //传递一个包含SSL版本的长参数。
// 执行cURL会话
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'cURL Error: ' . curl_error($ch);
} else {
// 打印响应内容
echo $response . "\n";
}
// 关闭cURL会话
curl_close($ch);
$listDom = new DOMDocument();
$listDom->loadXML($response);
$nextPartNumberMarkerNode = $listDom->getElementsByTagName("NextPartNumberMarker");
$partNodes = $listDom->getElementsByTagName("Part");
foreach($partNodes as $partNode)
{
$partNumberNode = $partNode->getElementsByTagName("PartNumber");
$partNumber = $partNumberNode->item(0)->nodeValue;
// echo $partNumber . "\n";
$eTagNode = $partNode->getElementsByTagName("ETag");
$eTag = $eTagNode->item(0)->nodeValue;
// echo $eTag . "\n";
try{
$part = $compDom->createElement("Part");
$part->appendChild($compDom->createElement("PartNumber", $partNumber));
$part->appendChild($compDom->createElement("ETag", $eTag));
$root->appendChild($part);
} catch (DOMException $e){
echo $e->getMessage();
}
}
$partNumberMarker = $nextPartNumberMarkerNode->item(0)->nodeValue;
if($partNumberMarker % 1000 != 0 || $partNumberMarker == 0)
{
break;
}
}
$partInfo = $compDom->saveXML();
echo $partInfo . "\n";
echo "查询已上传的分段 listUploadedPart end\n\n";
return $partInfo;
}
/**
* 10.获取合并段授权
* @param VodClient $client
* @param CreateAssetByFileUploadResponse $assetResponse
* @param string $uploadId
* @return ShowAssetTempAuthorityResponse
*/
function mergeUploadedPartAuthority(VodClient $client, CreateAssetByFileUploadResponse $assetResponse, string $uploadId):ShowAssetTempAuthorityResponse
{
echo "获取合并段授权 mergeUploadedPartAuthority start\n";
$request = new ShowAssetTempAuthorityRequest();
$request->setHttpVerb("POST");
$request->setBucket($assetResponse->getTarget()->getBucket());
$request->setObjectKey($assetResponse->getTarget()->getObject());
$request->setUploadId($uploadId);
$response = $client->showAssetTempAuthority($request);
echo "获取合并段授权 mergeUploadedPartAuthority end; response:" . $response . "\n";
return $response;
}
/**
* 11.合并分段
* @param string $signStr
* @param string $partInfo
* @return void
*/
function mergeUploadedPart(string $signStr, string $partInfo)
{
echo "合并分段 mergeUploadedPart start\n";
// 初始化cURL会话
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $signStr);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $partInfo);
// 请求消息头中增加"Content-Type",值设置为"application/xml"
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/xml"
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //验证curl对等证书(一般只要此项)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //检查服务器SSL证书中是否存在一个公用名
curl_setopt($ch, CURLOPT_SSLVERSION, 0); //传递一个包含SSL版本的长参数。
// 执行cURL会话
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'cURL Error: ' . curl_error($ch);
} else {
// 打印响应内容
echo $response . "\n";
}
// 关闭会话
curl_close($ch);
echo "合并分段 mergeUploadedPart end\n";
}
/**
* 12.确认上传完成
* @param VodClient $client
* @param CreateAssetByFileUploadResponse $assetResponse
* @return void
*/
function confirmUploaded(VodClient $client, CreateAssetByFileUploadResponse $assetResponse): void
{
echo "确认上传完成 confirmUploadedPart start\n";
$request = new ConfirmAssetUploadRequest();
$body = new ConfirmAssetUploadReq();
$body->setStatus("CREATED");
$body->setAssetId($assetResponse->getAssetId());
$request->setBody($body);
$response = $client->confirmAssetUpload($request);
echo "上传完成 confirmUploadedPart end; response:" . $response . "\n";
}
父主题: 分段上传代码示例