alibabacloud/vod-20170321
The official Alibaba Cloud VOD (ApsaraVideo Video-on-Demand) SDK for PHP, generated from the 2017-03-21 OpenAPI spec. Provides typed request/response classes for uploading, transcoding, playback, and managing video and audio assets with Alibaba Cloud credentials.
Install and inspect
composer require alibabacloud/vod-20170321
This is a machine-generated OpenAPI client, not a hand-written wrapper. Pulling it in also brings alibabacloud/darabonba-openapi, alibabacloud/tea-utils and alibabacloud/openapi-util — those are the packages that actually do request signing, retries and HTTP. Check the php constraint in vendor/alibabacloud/vod-20170321/composer.json before committing to it on an older runtime.
Where to look first
vendor/alibabacloud/vod-20170321/src/Vod.php — every method is <operationName> plus <operationName>WithOptions. This is your authoritative operation list.vendor/alibabacloud/vod-20170321/src/Models/ — one *Request.php / *Response.php per operation, with @var docblocks naming the exact PHP-cased field (e.g. VideoList, PlayInfoList, AuthInfoTimeout). Guessing field names wastes more time than grepping this folder.Minimal call
use AlibabaCloud\SDK\Vod\V20170321\Vod;
use AlibabaCloud\SDK\Vod\V20170321\Models\GetVideoListRequest;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
use Darabonba\OpenApi\Models\Config;
$config = new Config([
'accessKeyId' => config('services.aliyun.key'),
'accessKeySecret' => config('services.aliyun.secret'),
]);
$config->endpoint = 'vod.cn-shanghai.aliyuncs.com'; // regional, not the global one
$client = new Vod($config);
$runtime = new RuntimeOptions([
'connectTimeout' => 5000,
'readTimeout' => 10000,
'autoretry' => true,
'maxAttempts' => 3,
]);
$response = $client->getVideoListWithOptions(
new GetVideoListRequest(['pageNo' => 1, 'pageSize' => 20]),
$runtime
);
foreach ($response->body->videoList->video ?? [] as $video) {
// $video->videoId, $video->title, $video->status, $video->duration
}
First real use case: upload. VOD never takes bytes over its own API. CreateUploadVideo issues an upload ticket (an OSS bucket/object key plus short-lived STS credentials); you then push the file to OSS yourself. That two-step is the core mental model for everything else in this package.
$r = $client->createUploadVideoWithOptions(new CreateUploadVideoRequest([
'title' => 'Q3 All-Hands',
'fileName' => 'q3-all-hands.mp4',
]), $runtime);
$videoId = $r->body->videoId;
$uploadAddr = json_decode(base64_decode($r->body->uploadAddress), true); // Bucket, Endpoint, ObjectKey
$uploadAuth = json_decode(base64_decode($r->body->uploadAuth), true); // AccessKeyId, Secret, SecurityToken
$oss = new \OSS\OssClient(
$uploadAuth['AccessKeyId'],
$uploadAuth['AccessKeySecret'],
$uploadAddr['Endpoint'],
false,
$uploadAuth['SecurityToken']
);
$oss->uploadFile($uploadAddr['Bucket'], $uploadAddr['ObjectKey'], $localPath);
If that's working end-to-end (ticket → OSS put → GetVideoInfo shows Status: Normal), you've validated credentials, endpoint, region and the whole upload lifecycle in one go.
Bind one client, one place. Construct Config + Vod once in a service provider and resolve it from the container. Creating a client per call is cheap but scatters credentials and endpoint logic across the codebase.
$this->app->singleton(Vod::class, fn () => new Vod(tap(new Config([
'accessKeyId' => config('services.aliyun.key'),
'accessKeySecret' => config('services.aliyun.secret'),
]))->setEndpoint(config('services.aliyun.vod_endpoint'))));
Wrap the SDK behind your own gateway. The generated models are noisy and nullable-riddled. Define a small interface (createUpload(), playAuth(), playInfo(), deleteVideo()) returning your own DTOs. This is the single highest-value decision you'll make with this package: it keeps Vod out of controllers, makes tests trivial (fake the interface), and lets you swap to a signed HTTP call or the Java SDK later without touching domain code.
Upload ticket flow. CreateUploadVideo → upload to OSS → poll GetVideoInfo until Status leaves Uploading, or (better) subscribe to the FileUploadComplete / TranscodeComplete event via SetMessageCallback and react to the webhook. Tickets expire — RefreshUploadVideo re-issues credentials for the same videoId/object, so implement refresh-and-resume for large files or flaky networks rather than starting a new upload.
Playback: pick the right call.
GetVideoPlayAuth → short opaque PlayAuth string for Alibaba Cloud's web/Android/iOS player SDK. Default validity is very short (order of 100 seconds); pass AuthInfoTimeout to extend, and fetch it at play time, not at page render.GetPlayInfo → concrete URLs (PlayURL, Format, Definition, Bitrate, Encrypt) for your own player or for downloads. Set ResultType to Multiple to get every rendition, and filter by Formats (mp4, m3u8) to cut response size.PlayURL is time-limited. Never persist play URLs in the database or cache them past their window.Media library management. GetVideoList / SearchMedia for listing, UpdateVideoInfo for metadata, DeleteVideo for removal, CreateUploadImage / CreateUploadAttachedMedia for non-video assets, category APIs for taxonomy. SearchMedia is the flexible one — filter by MediaType, CreationTime, Status, CateId, Tags — but it's cursor-based: keep the returned ScrollToken and loop, don't assume PageNo/PageSize works the same way as GetVideoList.
Transcoding. Transcode is driven by template groups. SubmitTranscodeJobs returns a job id; poll GetTranscodeTask (or rely on the TranscodeComplete callback). Template group ids belong in config, not in code — ops will want to change them without a deploy.
Callbacks. SetMessageCallback registers a public HTTP(S) URL (plus optionally an MNS queue). VOD POSTs JSON with an event EventType and a VideoId/StreamId payload. Treat every callback as at-least-once: de-duplicate on EventType + VideoId + timestamp, return 200 fast, and do the heavy work in a queue. Add a shared secret to the callback path or restrict by IP — the default notification is not signed for you.
Content moderation. CreateAudit / GetAuditHistory for automated and manual review. Run it as a pipeline stage between upload-complete and "publishable", not inline in the upload request.
Testing. Because the client is generated and monolithic, don't mock Vod directly. Your gateway interface plus a fake implementation covers 90% of tests; for the remaining integration cases, hit a sandbox account in CI and assert on RequestId-scoped behaviour.
WithOptions or bust. The bare getVideoList()-style methods use internal defaults you can't tune. Always call ...WithOptions($request, $runtime) so you control timeouts and retries.UploadAuth and UploadAddress are base64-encoded JSON strings, not arrays or objects. json_decode(base64_decode($x), true) — two levels, and the base64 is easy to forget.vod.cn-shanghai.aliyuncs.com, vod.ap-southeast-1.aliyuncs.com, etc. The wrong region gives confusing InvalidVideo.NotFound errors for videos that exist. Put it in config next to the region and keep them in sync.TeaUnableRetryError, not a typed VOD exception. Catch it, then inspect getErrorInfo() (contains Code, Message, RequestId), getLastException() and getLastRequest(). Model-validation failures throw TeaError instead — differentiate, because retrying a validation error is pointless.RequestId. It's in the response body and in the error info. Without it, Alibaba Cloud support cannot trace anything.Throttling / Throttling.User codes mean back off. Keep autoretry on for idempotent reads; turn it off for CreateUploadVideo and SubmitTranscodeJobs unless you're certain duplicates are harmless (they usually just orphan assets, but they do bill).Duration, Size, Bitrate, Width/Height are strings in the JSON. Cast before arithmetic or you'll get silent string comparisons.$response->body->videoList->video is null when empty, not []. ?? [] everywhere, or wrap the body in a normaliser.Vod.php will find an upload method. aliyun-sdk-oss with the returned STS token is the standard path; Alibaba Cloud also publishes dedicated VOD upload SDKs for some languages with multipart/resume built in — check whether one exists for your runtime before hand-rolling multipart.AliyunVodFullAccess (or narrower) is the minimum. For per-user uploads, generate scoped STS tokens and pass them through Config rather than shipping long-lived keys to app servers.2017-03-21, which is not the package version). Field renames and newly-added nullable properties do happen; read the diff on upgrade and run your integration tests.aliyun-php-sdk-vod / DefaultAcsClient / AlibabaCloud\Vod\..., that's the older package. The two can coexist on disk but not in one class; migrate deliberately.How can I help you explore Laravel packages today?