From f4fe7e1b3eb509cb2aafde916ff778565018c6fe Mon Sep 17 00:00:00 2001 From: Nicholas Cook Date: Tue, 14 Jun 2022 17:06:57 -0700 Subject: [PATCH] =?UTF-8?q?docs(samples):=20add=20Video=20Stitcher=20VOD?= =?UTF-8?q?=20and=20live=20session=20code=20samples=20a=E2=80=A6=20(#9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(samples): add Video Stitcher VOD and live session code samples and tests * Remove async from slate and live session before and after hooks * clean out old slates and CDN keys * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * update SHA Co-authored-by: sofisl <55454395+sofisl@users.noreply.github.com> Co-authored-by: Owl Bot --- media/video-stitcher/createLiveSession.js | 66 +++++ media/video-stitcher/createVodSession.js | 58 ++++ media/video-stitcher/getLiveAdTagDetail.js | 57 ++++ media/video-stitcher/getLiveSession.js | 51 ++++ media/video-stitcher/getVodAdTagDetail.js | 57 ++++ media/video-stitcher/getVodSession.js | 51 ++++ media/video-stitcher/getVodStitchDetail.js | 57 ++++ media/video-stitcher/listLiveAdTagDetails.js | 54 ++++ media/video-stitcher/listVodAdTagDetails.js | 54 ++++ media/video-stitcher/listVodStitchDetails.js | 54 ++++ media/video-stitcher/test/stitcher.test.js | 267 ++++++++++++++++--- 11 files changed, 793 insertions(+), 33 deletions(-) create mode 100644 media/video-stitcher/createLiveSession.js create mode 100644 media/video-stitcher/createVodSession.js create mode 100644 media/video-stitcher/getLiveAdTagDetail.js create mode 100644 media/video-stitcher/getLiveSession.js create mode 100644 media/video-stitcher/getVodAdTagDetail.js create mode 100644 media/video-stitcher/getVodSession.js create mode 100644 media/video-stitcher/getVodStitchDetail.js create mode 100644 media/video-stitcher/listLiveAdTagDetails.js create mode 100644 media/video-stitcher/listVodAdTagDetails.js create mode 100644 media/video-stitcher/listVodStitchDetails.js diff --git a/media/video-stitcher/createLiveSession.js b/media/video-stitcher/createLiveSession.js new file mode 100644 index 0000000000..4b9ee5c0f3 --- /dev/null +++ b/media/video-stitcher/createLiveSession.js @@ -0,0 +1,66 @@ +/** + * Copyright 2022, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +function main(projectId, location, sourceUri, adTagUri, slateId) { + // [START video_stitcher_create_live_session] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // projectId = 'my-project-id'; + // location = 'us-central1'; + // sourceUri = 'https://storage.googleapis.com/my-bucket/main.mpd'; + // Single Inline Linear (https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags) + // (https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags) + // adTagUri = 'https://pubads.g.doubleclick.net/gampad/ads...'; + // slateId = 'my-slate'; + + // Imports the Video Stitcher library + const {VideoStitcherServiceClient} = + require('@google-cloud/video-stitcher').v1; + // Instantiates a client + const stitcherClient = new VideoStitcherServiceClient(); + + async function createLiveSession() { + // Construct request + const request = { + parent: stitcherClient.locationPath(projectId, location), + liveSession: { + sourceUri: sourceUri, + adTagMap: { + default: { + uri: adTagUri, + }, + }, + defaultSlateId: slateId, + }, + }; + + const [session] = await stitcherClient.createLiveSession(request); + console.log(`Live session: ${session.name}`); + console.log(`Play URI: ${session.playUri}`); + } + + createLiveSession(); + // [END video_stitcher_create_live_session] +} + +// node createLiveSession.js +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/media/video-stitcher/createVodSession.js b/media/video-stitcher/createVodSession.js new file mode 100644 index 0000000000..728a8b1a94 --- /dev/null +++ b/media/video-stitcher/createVodSession.js @@ -0,0 +1,58 @@ +/** + * Copyright 2022, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +function main(projectId, location, sourceUri, adTagUri) { + // [START video_stitcher_create_vod_session] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // projectId = 'my-project-id'; + // location = 'us-central1'; + // sourceUri = 'https://storage.googleapis.com/my-bucket/main.mpd'; + // See VMAP Pre-roll + // (https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags) + // adTagUri = 'https://pubads.g.doubleclick.net/gampad/ads...'; + + // Imports the Video Stitcher library + const {VideoStitcherServiceClient} = + require('@google-cloud/video-stitcher').v1; + // Instantiates a client + const stitcherClient = new VideoStitcherServiceClient(); + + async function createVodSession() { + // Construct request + const request = { + parent: stitcherClient.locationPath(projectId, location), + vodSession: { + sourceUri: sourceUri, + adTagUri: adTagUri, + }, + }; + const [session] = await stitcherClient.createVodSession(request); + console.log(`VOD session: ${session.name}`); + } + + createVodSession(); + // [END video_stitcher_create_vod_session] +} + +// node createVodSession.js +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/media/video-stitcher/getLiveAdTagDetail.js b/media/video-stitcher/getLiveAdTagDetail.js new file mode 100644 index 0000000000..bd0489cefd --- /dev/null +++ b/media/video-stitcher/getLiveAdTagDetail.js @@ -0,0 +1,57 @@ +/** + * Copyright 2022, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +function main(projectId, location, sessionId, adTagDetailId) { + // [START video_stitcher_get_live_ad_tag_detail] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // projectId = 'my-project-id'; + // location = 'us-central1'; + // sessionId = 'my-session-id'; + // adTagDetailId = 'my-ad-tag-detail-id'; + + // Imports the Video Stitcher library + const {VideoStitcherServiceClient} = + require('@google-cloud/video-stitcher').v1; + // Instantiates a client + const stitcherClient = new VideoStitcherServiceClient(); + + async function getLiveAdTagDetail() { + // Construct request + const request = { + name: stitcherClient.liveAdTagDetailPath( + projectId, + location, + sessionId, + adTagDetailId + ), + }; + const [adTagDetail] = await stitcherClient.getLiveAdTagDetail(request); + console.log(`Live ad tag detail: ${adTagDetail.name}`); + } + + getLiveAdTagDetail(); + // [END video_stitcher_get_live_ad_tag_detail] +} + +// node getLiveAdTagDetail.js +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/media/video-stitcher/getLiveSession.js b/media/video-stitcher/getLiveSession.js new file mode 100644 index 0000000000..99ea1c6016 --- /dev/null +++ b/media/video-stitcher/getLiveSession.js @@ -0,0 +1,51 @@ +/** + * Copyright 2022, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +function main(projectId, location, sessionId) { + // [START video_stitcher_get_live_session] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // projectId = 'my-project-id'; + // location = 'us-central1'; + // sessionId = 'my-session-id'; + + // Imports the Video Stitcher library + const {VideoStitcherServiceClient} = + require('@google-cloud/video-stitcher').v1; + // Instantiates a client + const stitcherClient = new VideoStitcherServiceClient(); + + async function getLiveSession() { + // Construct request + const request = { + name: stitcherClient.liveSessionPath(projectId, location, sessionId), + }; + const [session] = await stitcherClient.getLiveSession(request); + console.log(`Live session: ${session.name}`); + } + + getLiveSession(); + // [END video_stitcher_get_live_session] +} + +// node getLiveSession.js +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/media/video-stitcher/getVodAdTagDetail.js b/media/video-stitcher/getVodAdTagDetail.js new file mode 100644 index 0000000000..ec1fcdabea --- /dev/null +++ b/media/video-stitcher/getVodAdTagDetail.js @@ -0,0 +1,57 @@ +/** + * Copyright 2022, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +function main(projectId, location, sessionId, adTagDetailId) { + // [START video_stitcher_get_vod_ad_tag_detail] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // projectId = 'my-project-id'; + // location = 'us-central1'; + // sessionId = 'my-session-id'; + // adTagDetailId = 'my-ad-tag-detail-id'; + + // Imports the Video Stitcher library + const {VideoStitcherServiceClient} = + require('@google-cloud/video-stitcher').v1; + // Instantiates a client + const stitcherClient = new VideoStitcherServiceClient(); + + async function getVodAdTagDetail() { + // Construct request + const request = { + name: stitcherClient.vodAdTagDetailPath( + projectId, + location, + sessionId, + adTagDetailId + ), + }; + const [adTagDetail] = await stitcherClient.getVodAdTagDetail(request); + console.log(`VOD ad tag detail: ${adTagDetail.name}`); + } + + getVodAdTagDetail(); + // [END video_stitcher_get_vod_ad_tag_detail] +} + +// node getVodAdTagDetail.js +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/media/video-stitcher/getVodSession.js b/media/video-stitcher/getVodSession.js new file mode 100644 index 0000000000..9ad4fe3a01 --- /dev/null +++ b/media/video-stitcher/getVodSession.js @@ -0,0 +1,51 @@ +/** + * Copyright 2022, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +function main(projectId, location, sessionId) { + // [START video_stitcher_get_vod_session] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // projectId = 'my-project-id'; + // location = 'us-central1'; + // sessionId = 'my-session-id'; + + // Imports the Video Stitcher library + const {VideoStitcherServiceClient} = + require('@google-cloud/video-stitcher').v1; + // Instantiates a client + const stitcherClient = new VideoStitcherServiceClient(); + + async function getVodSession() { + // Construct request + const request = { + name: stitcherClient.vodSessionPath(projectId, location, sessionId), + }; + const [session] = await stitcherClient.getVodSession(request); + console.log(`VOD session: ${session.name}`); + } + + getVodSession(); + // [END video_stitcher_get_vod_session] +} + +// node getVodSession.js +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/media/video-stitcher/getVodStitchDetail.js b/media/video-stitcher/getVodStitchDetail.js new file mode 100644 index 0000000000..1480189787 --- /dev/null +++ b/media/video-stitcher/getVodStitchDetail.js @@ -0,0 +1,57 @@ +/** + * Copyright 2022, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +function main(projectId, location, sessionId, stitchDetailId) { + // [START video_stitcher_get_vod_stitch_detail] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // projectId = 'my-project-id'; + // location = 'us-central1'; + // sessionId = 'my-session-id'; + // stitchDetailId = 'my-stitch-detail-id'; + + // Imports the Video Stitcher library + const {VideoStitcherServiceClient} = + require('@google-cloud/video-stitcher').v1; + // Instantiates a client + const stitcherClient = new VideoStitcherServiceClient(); + + async function getVodStitchDetail() { + // Construct request + const request = { + name: stitcherClient.vodStitchDetailPath( + projectId, + location, + sessionId, + stitchDetailId + ), + }; + const [stitchDetail] = await stitcherClient.getVodStitchDetail(request); + console.log(`VOD stitch detail: ${stitchDetail.name}`); + } + + getVodStitchDetail(); + // [END video_stitcher_get_vod_stitch_detail] +} + +// node getVodStitchDetail.js +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/media/video-stitcher/listLiveAdTagDetails.js b/media/video-stitcher/listLiveAdTagDetails.js new file mode 100644 index 0000000000..0316d2eec7 --- /dev/null +++ b/media/video-stitcher/listLiveAdTagDetails.js @@ -0,0 +1,54 @@ +/** + * Copyright 2022, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +function main(projectId, location, sessionId) { + // [START video_stitcher_list_live_ad_tag_details] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // projectId = 'my-project-id'; + // location = 'us-central1'; + // sessionId = 'my-session-id'; + + // Imports the Video Stitcher library + const {VideoStitcherServiceClient} = + require('@google-cloud/video-stitcher').v1; + // Instantiates a client + const stitcherClient = new VideoStitcherServiceClient(); + + async function listLiveAdTagDetails() { + // Construct request + const request = { + parent: stitcherClient.liveSessionPath(projectId, location, sessionId), + }; + const iterable = await stitcherClient.listLiveAdTagDetailsAsync(request); + console.log('Live ad tag details:'); + for await (const response of iterable) { + console.log(response.name); + } + } + + listLiveAdTagDetails(); + // [END video_stitcher_list_live_ad_tag_details] +} + +// node listLiveAdTagDetails.js +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/media/video-stitcher/listVodAdTagDetails.js b/media/video-stitcher/listVodAdTagDetails.js new file mode 100644 index 0000000000..eaedc91be8 --- /dev/null +++ b/media/video-stitcher/listVodAdTagDetails.js @@ -0,0 +1,54 @@ +/** + * Copyright 2022, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +function main(projectId, location, sessionId) { + // [START video_stitcher_list_vod_ad_tag_details] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // projectId = 'my-project-id'; + // location = 'us-central1'; + // sessionId = 'my-session-id'; + + // Imports the Video Stitcher library + const {VideoStitcherServiceClient} = + require('@google-cloud/video-stitcher').v1; + // Instantiates a client + const stitcherClient = new VideoStitcherServiceClient(); + + async function listVodAdTagDetails() { + // Construct request + const request = { + parent: stitcherClient.vodSessionPath(projectId, location, sessionId), + }; + const iterable = await stitcherClient.listVodAdTagDetailsAsync(request); + console.log('VOD ad tag details:'); + for await (const response of iterable) { + console.log(response.name); + } + } + + listVodAdTagDetails(); + // [END video_stitcher_list_vod_ad_tag_details] +} + +// node listVodAdTagDetails.js +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/media/video-stitcher/listVodStitchDetails.js b/media/video-stitcher/listVodStitchDetails.js new file mode 100644 index 0000000000..6e84f40673 --- /dev/null +++ b/media/video-stitcher/listVodStitchDetails.js @@ -0,0 +1,54 @@ +/** + * Copyright 2022, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +function main(projectId, location, sessionId) { + // [START video_stitcher_list_vod_stitch_details] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + // projectId = 'my-project-id'; + // location = 'us-central1'; + // sessionId = 'my-session-id'; + + // Imports the Video Stitcher library + const {VideoStitcherServiceClient} = + require('@google-cloud/video-stitcher').v1; + // Instantiates a client + const stitcherClient = new VideoStitcherServiceClient(); + + async function listVodStitchDetails() { + // Construct request + const request = { + parent: stitcherClient.vodSessionPath(projectId, location, sessionId), + }; + const iterable = await stitcherClient.listVodStitchDetailsAsync(request); + console.log('VOD stitch details:'); + for await (const response of iterable) { + console.log(response.name); + } + } + + listVodStitchDetails(); + // [END video_stitcher_list_vod_stitch_details] +} + +// node listVodStitchDetails.js +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/media/video-stitcher/test/stitcher.test.js b/media/video-stitcher/test/stitcher.test.js index 66a0b99adb..fa109189a6 100644 --- a/media/video-stitcher/test/stitcher.test.js +++ b/media/video-stitcher/test/stitcher.test.js @@ -23,59 +23,101 @@ const {describe, it, before, after} = require('mocha'); const uniqueId = uuidv4().split('-')[0]; const bucketName = 'cloud-samples-data/media'; +const vodFileName = 'hls-vod/manifest.m3u8'; +const liveFileName = 'hls-live/manifest.m3u8'; const projectId = process.env.GCLOUD_PROJECT; const location = 'us-central1'; -const slateId = `nodejs-test-stitcher-slate-${uniqueId}`; +const slateIdPrefix = 'nodejs-test-stitcher-slate-'; +const slateId = `${slateIdPrefix}${uniqueId}`; const slateUri = `https://storage.googleapis.com/${bucketName}/ForBiggerEscapes.mp4`; const slateName = `/locations/${location}/slates/${slateId}`; -const akamaiCdnKeyId = `nodejs-test-stitcher-akamai-key-${uniqueId}`; +const akamaiCdnKeyIdPrefix = 'nodejs-test-stitcher-akamai-key-'; +const akamaiCdnKeyId = `${akamaiCdnKeyIdPrefix}${uniqueId}`; const akamaiCdnKeyName = `/locations/${location}/cdnKeys/${akamaiCdnKeyId}`; -const googleCdnKeyId = `nodejs-test-stitcher-google-key-${uniqueId}`; +const googleCdnKeyIdPrefix = 'nodejs-test-stitcher-google-key-'; +const googleCdnKeyId = `${googleCdnKeyIdPrefix}${uniqueId}`; const googleCdnKeyName = `/locations/${location}/cdnKeys/${googleCdnKeyId}`; const hostname = 'cdn.example.com'; const gCdnKeyname = 'gcdn-test-key'; const gCdnPrivateKey = 'VGhpcyBpcyBhIHRlc3Qgc3RyaW5nLg=='; const akamaiTokenKey = 'VGhpcyBpcyBhIHRlc3Qgc3RyaW5nLg=='; + +const vodUri = `https://storage.googleapis.com/${bucketName}/${vodFileName}`; +// VMAP Pre-roll (https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags) +const vodAdTagUri = + "'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='"; +const vodSessionPrefix = `/locations/${location}/vodSessions/`; + +const liveUri = `https://storage.googleapis.com/${bucketName}/${liveFileName}`; +// Single Inline Linear (https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags) +const liveAdTagUri = + "'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator='"; +const liveSessionPrefix = `/locations/${location}/liveSessions/`; + +const https = require('https'); const cwd = path.join(__dirname, '..'); -before(async () => { - // Delete the slate if it already exists - try { - execSync(`node deleteSlate.js ${projectId} ${location} ${slateId}`, { - cwd, +async function getPage(url) { + let data = ''; + return new Promise(resolve => { + https.get(url, res => { + res.on('data', chunk => { + data += chunk; + }); + res.on('end', () => { + resolve(data); + }); }); - } catch (err) { - // Ignore not found error - } - // Delete the Akamai CDN key if it already exists - try { - execSync( - `node deleteCdnKey.js ${projectId} ${location} ${akamaiCdnKeyId}`, - { - cwd, + }); +} + +before(() => { + // Delete existing test slates + const slates = execSync(`node listSlates.js ${projectId} ${location}`, {cwd}); + + slates + .toString() + .split(/\r?\n/) + .forEach(line => { + if (line.includes(`locations/${location}/slates/${slateIdPrefix}`)) { + this.nextId = line.split('/').pop(); + execSync( + `node deleteSlate.js ${projectId} ${location} ${this.nextId}`, + { + cwd, + } + ); } - ); - } catch (err) { - // Ignore not found error - } - // Delete the Google CDN key if it already exists - try { - execSync( - `node deleteCdnKey.js ${projectId} ${location} ${googleCdnKeyId}`, - { - cwd, + }); + + // Delete existing test CDN keys + const keys = execSync(`node listCdnKeys.js ${projectId} ${location}`, {cwd}); + + keys + .toString() + .split(/\r?\n/) + .forEach(line => { + if ( + line.includes( + `locations/${location}/cdnKeys/${googleCdnKeyIdPrefix}` + ) || + line.includes(`locations/${location}/cdnKeys/${akamaiCdnKeyIdPrefix}`) + ) { + this.nextId = line.split('/').pop(); + + execSync( + `node deleteCdnKey.js ${projectId} ${location} ${this.nextId}`, + { + cwd, + } + ); } - ); - } catch (err) { - // Ignore not found error - } + }); }); -after(async () => {}); - describe('Slate functions', () => { it('should create a slate', () => { const output = execSync( @@ -200,3 +242,162 @@ describe('CDN key functions', () => { assert.ok(output.includes('Deleted CDN key')); }); }); + +describe('VOD session functions', () => { + it('should create a VOD session', () => { + const output = execSync( + `node createVodSession.js ${projectId} ${location} ${vodUri} ${vodAdTagUri}`, + {cwd} + ); + assert.ok(output.includes(vodSessionPrefix)); + this.vodSessionId = output.toString().split('/').pop(); + this.vodSessionId = this.vodSessionId.replace(/\r?\n|\r/g, ''); + }); + + it('should get a VOD session', () => { + const output = execSync( + `node getVodSession.js ${projectId} ${location} ${this.vodSessionId}`, + {cwd} + ); + assert.ok(output.includes(`${vodSessionPrefix}${this.vodSessionId}`)); + }); + + // No list or delete methods for VOD sessions + + // Ad tag details + + it('should show a list of ad tag details for a VOD session', () => { + const output = execSync( + `node listVodAdTagDetails.js ${projectId} ${location} ${this.vodSessionId}`, + { + cwd, + } + ); + this.adTagDetailsNamePrefix = `${vodSessionPrefix}${this.vodSessionId}/vodAdTagDetails/`; + assert.ok(output.includes(this.adTagDetailsNamePrefix)); + this.vodAdTagDetailsId = output.toString().split('/').pop(); + this.vodAdTagDetailsId = this.vodAdTagDetailsId.replace(/\r?\n|\r/g, ''); + }); + + it('should get an ad tag detail', () => { + const output = execSync( + `node getVodAdTagDetail.js ${projectId} ${location} ${this.vodSessionId} ${this.vodAdTagDetailsId}`, + {cwd} + ); + assert.ok( + output.includes(`${this.adTagDetailsNamePrefix}${this.vodAdTagDetailsId}`) + ); + }); + + // Stitch details + + it('should show a list of stitch details for a VOD session', () => { + const output = execSync( + `node listVodStitchDetails.js ${projectId} ${location} ${this.vodSessionId}`, + { + cwd, + } + ); + this.stitchDetailsNamePrefix = `${vodSessionPrefix}${this.vodSessionId}/vodStitchDetails/`; + assert.ok(output.includes(this.stitchDetailsNamePrefix)); + this.stitchDetailsId = output.toString().split('/').pop(); + this.stitchDetailsId = this.stitchDetailsId.replace(/\r?\n|\r/g, ''); + }); + + it('should get a stitch detail', () => { + const output = execSync( + `node getVodStitchDetail.js ${projectId} ${location} ${this.vodSessionId} ${this.stitchDetailsId}`, + {cwd} + ); + assert.ok( + output.includes(`${this.stitchDetailsNamePrefix}${this.stitchDetailsId}`) + ); + }); +}); + +describe('Live session functions', () => { + before(() => { + // Delete the slate if it already exists + try { + execSync(`node deleteSlate.js ${projectId} ${location} ${slateId}`, { + cwd, + }); + } catch (err) { + // Ignore not found error + } + execSync( + `node createSlate.js ${projectId} ${location} ${slateId} ${slateUri}`, + {cwd} + ); + }); + + after(() => { + execSync(`node deleteSlate.js ${projectId} ${location} ${slateId}`, {cwd}); + }); + + it('should create and get a live session and list and get ad tag details', async function () { + let output = execSync( + `node createLiveSession.js ${projectId} ${location} ${liveUri} ${liveAdTagUri} ${slateId}`, + {cwd} + ); + assert.ok(output.includes(liveSessionPrefix)); + + let match = new RegExp('Live session:.(.*)', 'g').exec(output); + this.liveSessionId = match[1].toString().split('/').pop(); + this.liveSessionId = this.liveSessionId.replace(/\r?\n|\r/g, ''); + match = new RegExp('Play URI:.(.*)', 'g').exec(output); + this.playUri = match[1].replace(/\r?\n|\r/g, ''); + + output = execSync( + `node getLiveSession.js ${projectId} ${location} ${this.liveSessionId}`, + {cwd} + ); + assert.ok(output.includes(`${liveSessionPrefix}${this.liveSessionId}`)); + + // No list or delete methods for live sessions + + // Ad tag details + + // To get ad tag details, you need to curl the main manifest and + // a rendition first. This supplies media player information to the API. + // + // Curl the playUri first. The last line of the response will contain a + // renditions location. Curl the live session name with the rendition + // location appended. + + let data = await getPage(this.playUri); + assert.ok(data.includes('renditions/')); + + match = new RegExp('renditions/.*', 'g').exec(data); + this.renditions = match[0].replace(/\r?\n|\r/g, ''); + + // playUri will be in the following format: + // .../projects/{project}/locations/{location}/liveSessions/{session-id}/manifest.m3u8?signature=... + // Replace manifest.m3u8?signature=... with the /renditions location. + + const arr = this.playUri.split('/'); + arr.pop(); + const str = arr.join('/'); + this.renditionsUrl = `${str}/${this.renditions}`; + data = await getPage(this.renditionsUrl); + + output = execSync( + `node listLiveAdTagDetails.js ${projectId} ${location} ${this.liveSessionId}`, + {cwd} + ); + this.liveAdTagDetailsNamePrefix = `${liveSessionPrefix}${this.liveSessionId}/liveAdTagDetails/`; + assert.ok(output.includes(this.liveAdTagDetailsNamePrefix)); + this.liveAdTagDetailsId = output.toString().split('/').pop(); + this.liveAdTagDetailsId = this.liveAdTagDetailsId.replace(/\r?\n|\r/g, ''); + + output = execSync( + `node getLiveAdTagDetail.js ${projectId} ${location} ${this.liveSessionId} ${this.liveAdTagDetailsId}`, + {cwd} + ); + assert.ok( + output.includes( + `${this.liveAdTagDetailsNamePrefix}${this.liveAdTagDetailsId}` + ) + ); + }); +});