From 09b6fdfc3e41b4e42ef072bbdec50627cf1086b5 Mon Sep 17 00:00:00 2001 From: Nicholas Cook Date: Mon, 26 Aug 2024 14:45:46 -0700 Subject: [PATCH] feat(VideoStitcher): add samples and test for VOD config; update VOD session creation (#2042) --- media/videostitcher/src/create_vod_config.php | 80 ++++++++ .../videostitcher/src/create_vod_session.php | 13 +- media/videostitcher/src/delete_vod_config.php | 63 ++++++ media/videostitcher/src/get_vod_config.php | 58 ++++++ media/videostitcher/src/list_vod_configs.php | 60 ++++++ media/videostitcher/src/update_vod_config.php | 80 ++++++++ .../videostitcher/test/videoStitcherTest.php | 180 +++++++++++++++--- 7 files changed, 496 insertions(+), 38 deletions(-) create mode 100644 media/videostitcher/src/create_vod_config.php create mode 100644 media/videostitcher/src/delete_vod_config.php create mode 100644 media/videostitcher/src/get_vod_config.php create mode 100644 media/videostitcher/src/list_vod_configs.php create mode 100644 media/videostitcher/src/update_vod_config.php diff --git a/media/videostitcher/src/create_vod_config.php b/media/videostitcher/src/create_vod_config.php new file mode 100644 index 0000000000..079d9536cd --- /dev/null +++ b/media/videostitcher/src/create_vod_config.php @@ -0,0 +1,80 @@ +locationName($callingProjectId, $location); + + $vodConfig = (new VodConfig()) + ->setSourceUri($sourceUri) + ->setAdTagUri($adTagUri); + + // Run VOD config creation request + $request = (new CreateVodConfigRequest()) + ->setParent($parent) + ->setVodConfigId($vodConfigId) + ->setVodConfig($vodConfig); + $operationResponse = $stitcherClient->createVodConfig($request); + $operationResponse->pollUntilComplete(); + if ($operationResponse->operationSucceeded()) { + $result = $operationResponse->getResult(); + // Print results + printf('VOD config: %s' . PHP_EOL, $result->getName()); + } else { + $error = $operationResponse->getError(); + // handleError($error) + } +} +// [END videostitcher_create_vod_config] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/media/videostitcher/src/create_vod_session.php b/media/videostitcher/src/create_vod_session.php index 7d9bd604e1..f36c2c5807 100644 --- a/media/videostitcher/src/create_vod_session.php +++ b/media/videostitcher/src/create_vod_session.php @@ -36,25 +36,20 @@ * * @param string $callingProjectId The project ID to run the API call under * @param string $location The location of the session - * @param string $sourceUri Uri of the media to stitch; this URI must - * reference either an MPEG-DASH manifest - * (.mpd) file or an M3U playlist manifest - * (.m3u8) file. - * @param string $adTagUri The Uri of the ad tag + * @param string $vodConfigId The name of the VOD config to use for the session */ function create_vod_session( string $callingProjectId, string $location, - string $sourceUri, - string $adTagUri + string $vodConfigId ): void { // Instantiate a client. $stitcherClient = new VideoStitcherServiceClient(); $parent = $stitcherClient->locationName($callingProjectId, $location); + $vodConfig = $stitcherClient->vodConfigName($callingProjectId, $location, $vodConfigId); $vodSession = new VodSession(); - $vodSession->setSourceUri($sourceUri); - $vodSession->setAdTagUri($adTagUri); + $vodSession->setVodConfig($vodConfig); $vodSession->setAdTracking(AdTracking::SERVER); // Run VOD session creation request diff --git a/media/videostitcher/src/delete_vod_config.php b/media/videostitcher/src/delete_vod_config.php new file mode 100644 index 0000000000..e4084d99b6 --- /dev/null +++ b/media/videostitcher/src/delete_vod_config.php @@ -0,0 +1,63 @@ +vodConfigName($callingProjectId, $location, $vodConfigId); + $request = (new DeleteVodConfigRequest()) + ->setName($formattedName); + $operationResponse = $stitcherClient->deleteVodConfig($request); + $operationResponse->pollUntilComplete(); + if ($operationResponse->operationSucceeded()) { + // Print status + printf('Deleted VOD config %s' . PHP_EOL, $vodConfigId); + } else { + $error = $operationResponse->getError(); + // handleError($error) + } +} +// [END videostitcher_delete_vod_config] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/media/videostitcher/src/get_vod_config.php b/media/videostitcher/src/get_vod_config.php new file mode 100644 index 0000000000..2a44fcc2b1 --- /dev/null +++ b/media/videostitcher/src/get_vod_config.php @@ -0,0 +1,58 @@ +vodConfigName($callingProjectId, $location, $vodConfigId); + $request = (new GetVodConfigRequest()) + ->setName($formattedName); + $vodConfig = $stitcherClient->getVodConfig($request); + + // Print results + printf('VOD config: %s' . PHP_EOL, $vodConfig->getName()); +} +// [END videostitcher_get_vod_config] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/media/videostitcher/src/list_vod_configs.php b/media/videostitcher/src/list_vod_configs.php new file mode 100644 index 0000000000..a18cd60f9c --- /dev/null +++ b/media/videostitcher/src/list_vod_configs.php @@ -0,0 +1,60 @@ +locationName($callingProjectId, $location); + $request = (new ListVodConfigsRequest()) + ->setParent($parent); + $response = $stitcherClient->listVodConfigs($request); + + // Print the VOD config list. + $vodConfigs = $response->iterateAllElements(); + print('VOD configs:' . PHP_EOL); + foreach ($vodConfigs as $vodConfig) { + printf('%s' . PHP_EOL, $vodConfig->getName()); + } +} +// [END videostitcher_list_vod_configs] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/media/videostitcher/src/update_vod_config.php b/media/videostitcher/src/update_vod_config.php new file mode 100644 index 0000000000..9288fb47e0 --- /dev/null +++ b/media/videostitcher/src/update_vod_config.php @@ -0,0 +1,80 @@ +vodConfigName($callingProjectId, $location, $vodConfigId); + $vodConfig = new VodConfig(); + $vodConfig->setName($formattedName); + $vodConfig->setSourceUri($sourceUri); + $updateMask = new FieldMask([ + 'paths' => ['sourceUri'] + ]); + + // Run VOD config update request + $request = (new UpdateVodConfigRequest()) + ->setVodConfig($vodConfig) + ->setUpdateMask($updateMask); + $operationResponse = $stitcherClient->updateVodConfig($request); + $operationResponse->pollUntilComplete(); + if ($operationResponse->operationSucceeded()) { + $result = $operationResponse->getResult(); + // Print results + printf('Updated VOD config: %s' . PHP_EOL, $result->getName()); + } else { + $error = $operationResponse->getError(); + // handleError($error) + } +} +// [END videostitcher_update_vod_config] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); diff --git a/media/videostitcher/test/videoStitcherTest.php b/media/videostitcher/test/videoStitcherTest.php index 8b671f2136..f2cf92f9db 100644 --- a/media/videostitcher/test/videoStitcherTest.php +++ b/media/videostitcher/test/videoStitcherTest.php @@ -24,10 +24,12 @@ use Google\Cloud\Video\Stitcher\V1\Client\VideoStitcherServiceClient; use Google\Cloud\Video\Stitcher\V1\DeleteCdnKeyRequest; use Google\Cloud\Video\Stitcher\V1\DeleteLiveConfigRequest; +use Google\Cloud\Video\Stitcher\V1\DeleteVodConfigRequest; use Google\Cloud\Video\Stitcher\V1\DeleteSlateRequest; use Google\Cloud\Video\Stitcher\V1\GetLiveSessionRequest; use Google\Cloud\Video\Stitcher\V1\ListCdnKeysRequest; use Google\Cloud\Video\Stitcher\V1\ListLiveConfigsRequest; +use Google\Cloud\Video\Stitcher\V1\ListVodConfigsRequest; use Google\Cloud\Video\Stitcher\V1\ListSlatesRequest; use PHPUnit\Framework\TestCase; @@ -79,9 +81,16 @@ class videoStitcherTest extends TestCase private static $inputBucketName = 'cloud-samples-data'; private static $inputVodFileName = '/media/hls-vod/manifest.m3u8'; + private static $updatedInputVodFileName = '/media/hls-vod/manifest.mpd'; + private static $vodUri; + private static $updatedVodUri; + private static $vodAgTagUri = 'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpreonly&ciu_szs=300x250%2C728x90&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&correlator='; + private static $vodConfigId; + private static $vodConfigName; + private static $vodSessionId; private static $vodSessionName; private static $vodAdTagDetailId; @@ -105,11 +114,13 @@ public static function setUpBeforeClass(): void self::deleteOldSlates(); self::deleteOldCdnKeys(); self::deleteOldLiveConfigs(); + self::deleteOldVodConfigs(); self::$slateUri = sprintf('https://storage.googleapis.com/%s%s', self::$bucket, self::$slateFileName); self::$updatedSlateUri = sprintf('https://storage.googleapis.com/%s%s', self::$bucket, self::$updatedSlateFileName); self::$vodUri = sprintf('https://storage.googleapis.com/%s%s', self::$inputBucketName, self::$inputVodFileName); + self::$updatedVodUri = sprintf('https://storage.googleapis.com/%s%s', self::$inputBucketName, self::$updatedInputVodFileName); self::$liveUri = sprintf('https://storage.googleapis.com/%s%s', self::$inputBucketName, self::$inputLiveFileName); } @@ -427,8 +438,79 @@ public function testDeleteLiveConfig() $this->assertStringContainsString('Deleted live config', $output); } + public function testCreateVodConfig() + { + self::$vodConfigId = sprintf('php-test-vod-config-%s-%s', uniqid(), time()); + # API returns project number rather than project ID so + # don't include that in $vodConfigName since we don't have it + self::$vodConfigName = sprintf('/locations/%s/vodConfigs/%s', self::$location, self::$vodConfigId); + + $output = $this->runFunctionSnippet('create_vod_config', [ + self::$projectId, + self::$location, + self::$vodConfigId, + self::$vodUri, + self::$vodAgTagUri + ]); + $this->assertStringContainsString(self::$vodConfigName, $output); + } + + /** @depends testCreateVodConfig */ + public function testListVodConfigs() + { + $output = $this->runFunctionSnippet('list_vod_configs', [ + self::$projectId, + self::$location + ]); + $this->assertStringContainsString(self::$vodConfigName, $output); + } + + /** @depends testListVodConfigs */ + public function testUpdateVodConfig() + { + $output = $this->runFunctionSnippet('update_vod_config', [ + self::$projectId, + self::$location, + self::$vodConfigId, + self::$updatedVodUri + ]); + $this->assertStringContainsString(self::$vodConfigName, $output); + } + + /** @depends testUpdateVodConfig */ + public function testGetVodConfig() + { + $output = $this->runFunctionSnippet('get_vod_config', [ + self::$projectId, + self::$location, + self::$vodConfigId + ]); + $this->assertStringContainsString(self::$vodConfigName, $output); + } + + /** @depends testGetVodConfig */ + public function testDeleteVodConfig() + { + $output = $this->runFunctionSnippet('delete_vod_config', [ + self::$projectId, + self::$location, + self::$vodConfigId + ]); + $this->assertStringContainsString('Deleted VOD config', $output); + } + public function testCreateVodSession() { + # Create a temporary VOD config for the VOD session (required) + $tempVodConfigId = sprintf('php-test-vod-config-%s-%s', uniqid(), time()); + $this->runFunctionSnippet('create_vod_config', [ + self::$projectId, + self::$location, + $tempVodConfigId, + self::$vodUri, + self::$vodAgTagUri + ]); + # API returns project number rather than project ID so # don't include that in $vodSessionName since we don't have it self::$vodSessionName = sprintf('/locations/%s/vodSessions/', self::$location); @@ -436,13 +518,19 @@ public function testCreateVodSession() $output = $this->runFunctionSnippet('create_vod_session', [ self::$projectId, self::$location, - self::$vodUri, - self::$vodAgTagUri + $tempVodConfigId ]); $this->assertStringContainsString(self::$vodSessionName, $output); self::$vodSessionId = explode('/', $output); self::$vodSessionId = trim(self::$vodSessionId[(count(self::$vodSessionId) - 1)]); self::$vodSessionName = sprintf('/locations/%s/vodSessions/%s', self::$location, self::$vodSessionId); + + # Delete the temporary VOD config + $this->runFunctionSnippet('delete_vod_config', [ + self::$projectId, + self::$location, + $tempVodConfigId + ]); } /** @depends testCreateVodSession */ @@ -639,15 +727,17 @@ private static function deleteOldSlates(): void $oneHourInSecs = 60 * 60 * 1; foreach ($slates as $slate) { - $tmp = explode('/', $slate->getName()); - $id = end($tmp); - $tmp = explode('-', $id); - $timestamp = intval(end($tmp)); - - if ($currentTime - $timestamp >= $oneHourInSecs) { - $deleteSlateRequest = (new DeleteSlateRequest()) - ->setName($slate->getName()); - $stitcherClient->deleteSlate($deleteSlateRequest); + if (str_contains($slate->getName(), 'php-test-')) { + $tmp = explode('/', $slate->getName()); + $id = end($tmp); + $tmp = explode('-', $id); + $timestamp = intval(end($tmp)); + + if ($currentTime - $timestamp >= $oneHourInSecs) { + $deleteSlateRequest = (new DeleteSlateRequest()) + ->setName($slate->getName()); + $stitcherClient->deleteSlate($deleteSlateRequest); + } } } } @@ -665,15 +755,17 @@ private static function deleteOldCdnKeys(): void $oneHourInSecs = 60 * 60 * 1; foreach ($keys as $key) { - $tmp = explode('/', $key->getName()); - $id = end($tmp); - $tmp = explode('-', $id); - $timestamp = intval(end($tmp)); - - if ($currentTime - $timestamp >= $oneHourInSecs) { - $deleteCdnKeyRequest = (new DeleteCdnKeyRequest()) - ->setName($key->getName()); - $stitcherClient->deleteCdnKey($deleteCdnKeyRequest); + if (str_contains($key->getName(), 'php-test-')) { + $tmp = explode('/', $key->getName()); + $id = end($tmp); + $tmp = explode('-', $id); + $timestamp = intval(end($tmp)); + + if ($currentTime - $timestamp >= $oneHourInSecs) { + $deleteCdnKeyRequest = (new DeleteCdnKeyRequest()) + ->setName($key->getName()); + $stitcherClient->deleteCdnKey($deleteCdnKeyRequest); + } } } } @@ -691,15 +783,45 @@ private static function deleteOldLiveConfigs(): void $oneHourInSecs = 60 * 60 * 1; foreach ($liveConfigs as $liveConfig) { - $tmp = explode('/', $liveConfig->getName()); - $id = end($tmp); - $tmp = explode('-', $id); - $timestamp = intval(end($tmp)); - - if ($currentTime - $timestamp >= $oneHourInSecs) { - $deleteLiveConfigRequest = (new DeleteLiveConfigRequest()) - ->setName($liveConfig->getName()); - $stitcherClient->deleteLiveConfig($deleteLiveConfigRequest); + if (str_contains($liveConfig->getName(), 'php-test-')) { + $tmp = explode('/', $liveConfig->getName()); + $id = end($tmp); + $tmp = explode('-', $id); + $timestamp = intval(end($tmp)); + + if ($currentTime - $timestamp >= $oneHourInSecs) { + $deleteLiveConfigRequest = (new DeleteLiveConfigRequest()) + ->setName($liveConfig->getName()); + $stitcherClient->deleteLiveConfig($deleteLiveConfigRequest); + } + } + } + } + + private static function deleteOldVodConfigs(): void + { + $stitcherClient = new VideoStitcherServiceClient(); + $parent = $stitcherClient->locationName(self::$projectId, self::$location); + $listVodConfigsRequest = (new ListVodConfigsRequest()) + ->setParent($parent); + $response = $stitcherClient->listVodConfigs($listVodConfigsRequest); + $vodConfigs = $response->iterateAllElements(); + + $currentTime = time(); + $oneHourInSecs = 60 * 60 * 1; + + foreach ($vodConfigs as $vodConfig) { + if (str_contains($vodConfig->getName(), 'php-test-')) { + $tmp = explode('/', $vodConfig->getName()); + $id = end($tmp); + $tmp = explode('-', $id); + $timestamp = intval(end($tmp)); + + if ($currentTime - $timestamp >= $oneHourInSecs) { + $deleteVodConfigRequest = (new DeleteVodConfigRequest()) + ->setName($vodConfig->getName()); + $stitcherClient->deleteVodConfig($deleteVodConfigRequest); + } } } }