diff --git a/api/ClientRequest.js b/api/ClientRequest.js index d5e8c38..1de4d56 100644 --- a/api/ClientRequest.js +++ b/api/ClientRequest.js @@ -2,6 +2,7 @@ class ClientRequest { // Private fields #consent; #requestedDuration; + #skipoffset; #userId; #operatingSystem; #deviceType; @@ -18,6 +19,7 @@ class ClientRequest { constructor(params) { this.#consent = params.c || null; this.#requestedDuration = params.dur || null; + this.#skipoffset = params.skip || null; this.#userId = params.uid || null; this.#operatingSystem = params.os || null; this.#deviceType = params.dt || null; @@ -41,6 +43,7 @@ class ClientRequest { const properties = { Consent: this.#consent, RequestedDuration: this.#requestedDuration, + Skipoffset: this.#skipoffset, UserId: this.#userId, OperatingSystem: this.#operatingSystem, DeviceType: this.#deviceType, diff --git a/api/Session.js b/api/Session.js index c70ec26..ce36ae5 100644 --- a/api/Session.js +++ b/api/Session.js @@ -58,6 +58,7 @@ class Session { const vastObj = VastBuilder({ sessionId: this.sessionId, desiredDuration: params.dur || "0", + skipoffset: params.skip || null, adserverHostname: this.host, maxPodDuration: params.max || null, minPodDuration: params.min || null, diff --git a/api/routes.js b/api/routes.js index afcb6a2..42b9c1f 100644 --- a/api/routes.js +++ b/api/routes.js @@ -140,6 +140,11 @@ const vastSchema = () => ({ Linear: { type: "object", properties: { + skipoffset: { + type: "string", + example: "00:00:05", + xml: { attribute: true }, + }, Duration: { type: "string", example: "00:00:30", @@ -575,6 +580,11 @@ const schemas = { description: "Desired duration in seconds.", example: "60", }, + skip: { + type: "string", + description: "Skipoffset in seconds or percentage.", + example: "00:00:05 or 25%", + }, uid: { type: "string", description: "User ID.", diff --git a/utils/vast-maker.js b/utils/vast-maker.js index 224af6d..fb749fe 100644 --- a/utils/vast-maker.js +++ b/utils/vast-maker.js @@ -208,8 +208,9 @@ function AttachPodAds(vast, podAds, params) { } ); } + console.log("VAST params: ", params); mediaNode = mediaNode - .attachLinear({ skipoffset: "00:00:05" }) // skipoffset does not seem to exist on VAST 2.0 and lower, you could also have skipoffset in percentage + .attachLinear({skipoffset: isValidSkipOffset(params.skipoffset)}) // skipoffset does not seem to exist on VAST 2.0 and lower, you could also have skipoffset in percentage .attachTrackingEvents() .addTracking(`http://${params.adserverHostname}/api/v1/sessions/${params.sessionId}/tracking?${adId}=${podAds[i].id}_${i + 1}&progress=0`, { event: "start" }) .addTracking(`http://${params.adserverHostname}/api/v1/sessions/${params.sessionId}/tracking?${adId}=${podAds[i].id}_${i + 1}&progress=25`, { event: "firstQuartile" }) @@ -351,6 +352,15 @@ function indexOfSmallest(a) { return lowest; } +// Validate params.skipoffset is a valid VAST skipoffset value ("x%" or "hh:mm:ss"). +function isValidSkipOffset(skipoffset) { + // "hh:mm:ss" + const timeFormatRegex = /^(\d{2}):([0-5][0-9]):([0-5][0-9])$/; + // "x%" + const percentageFormatRegex = /^(100|[1-9]?[0-9])%$/; + return timeFormatRegex.test(skipoffset) || percentageFormatRegex.test(skipoffset) ? skipoffset: null; +} + function PopulatePod(_size, _min, _max, _ads, _chosenAds, _method, _targetDur) { // Base Case #1: Regardless of current Pod size, return if Pod duration is greater than _max! if (_chosenAds.length > 0) {