Skip to content

Commit

Permalink
Merge pull request #19 from Eyevinn/feat/updated-hls-interstitial-sup…
Browse files Browse the repository at this point in the history
…port

Feat: Update Hls-Interstitial Support
  • Loading branch information
Nfrederiksen authored Nov 29, 2024
2 parents f944696 + 2ecdcaa commit 04f4c66
Show file tree
Hide file tree
Showing 3 changed files with 914 additions and 101 deletions.
111 changes: 82 additions & 29 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const fetch = require("node-fetch");

exports.handler = async (event) => {
let response;
let prefix = '/stitch';
let prefix = "/stitch";
if (process.env.PREFIX) {
prefix = process.env.PREFIX;
}
Expand All @@ -23,8 +23,8 @@ exports.handler = async (event) => {
} else if (event.path === "/" && event.httpMethod === "GET") {
response = {
statusCode: 200,
body: "OK"
}
body: "OK",
};
} else {
response = generateErrorResponse({ code: 404 });
}
Expand Down Expand Up @@ -106,7 +106,7 @@ const handleOptionsRequest = async () => {
};

const handleCreateRequest = async (event) => {
const prefix = process.env.PREFIX ? process.env.PREFIX : '/stitch';
const prefix = process.env.PREFIX ? process.env.PREFIX : "/stitch";
try {
if (!event.body) {
return generateErrorResponse({ code: 400, message: "Missing request body" });
Expand Down Expand Up @@ -236,7 +236,7 @@ const getMasterManifest = async (encodedPayload, opts) => {
};

const rewriteMasterManifest = async (manifest, encodedPayload, opts) => {
const prefix = process.env.PREFIX ? process.env.PREFIX : '/stitch';
const prefix = process.env.PREFIX ? process.env.PREFIX : "/stitch";
let rewrittenManifest = "";
const lines = manifest.split("\n");
let bw = null;
Expand Down Expand Up @@ -336,36 +336,88 @@ const createVodFromPayload = async (encodedPayload, opts) => {
const hlsVod = new HLSSpliceVod(uri, vodOpts);
await hlsVod.load();
adpromises = [];
let id = payload.breaks.length + 1;
for (let i = 0; i < payload.breaks.length; i++) {
const b = payload.breaks[i];
if (opts && (opts.useInterstitial || opts.combineInterstitial)) {
const assetListPayload = {
assets: [{ uri: b.url, dur: b.duration / 1000 }],
};
const encodedAssetListPayload = encodeURIComponent(serialize(assetListPayload));
const baseUrl = process.env.ASSET_LIST_BASE_URL || "";
const assetListUrl = new URL(baseUrl + `/stitch/assetlist/${encodedAssetListPayload}`);

if (opts && (opts.useInterstitial || opts.combineInterstitial)) {
const assetListPayload = {
assets: [],
};

const GroupBreaks = (breaks) => {
let groupedBreaks = {};
breaks.forEach((b) => {
if (!groupedBreaks[b.pos]) {
groupedBreaks[b.pos] = [];
}
groupedBreaks[b.pos].push(b);
});
return groupedBreaks;
};

const breakGroupsDict = GroupBreaks(payload.breaks);
let _id = Object.keys(breakGroupsDict).length + 1;
for (let bidx = 0; bidx < Object.keys(breakGroupsDict).length; bidx++) {
let breakPosition = Object.keys(breakGroupsDict)[bidx];
const breakGroup = breakGroupsDict[breakPosition];
let breakDur = 0;
let interstitialOpts = {
plannedDuration: b.duration,
resumeOffset: 0,
};
if (b.pol !== undefined || b.ro !== undefined || opts.combineInterstitial) {
if (b.pol !== undefined) {
interstitialOpts.playoutLimit = b.pol;
let insertAtListPromises = [];
// Create the Asset List
for (let ad of breakGroup) {
const assetItem = {
uri: ad.url,
dur: ad.duration / 1000,
};
breakDur += ad.duration;
if (ad.pol !== undefined) {
interstitialOpts.playoutLimit = ad.pol;
}
if (b.ro !== undefined) {
interstitialOpts.resumeOffset = b.ro;
if (ad.cue !== undefined) {
interstitialOpts.cue = ad.cue;
}
if (ad.sn !== undefined) {
interstitialOpts.snap = ad.sn;
}
if (ad.ro !== undefined) {
interstitialOpts.resumeOffset = ad.ro;
}
if (ad.ro !== undefined) {
interstitialOpts.resumeOffset = ad.ro;
}
if (ad.re !== undefined) {
interstitialOpts.restrict = ad.re;
}
if (ad.cmv !== undefined) {
interstitialOpts.contentmayvary = ad.cmv;
}
if (ad.tlo !== undefined) {
interstitialOpts.timelineoccupies = ad.tlo;
}
if (ad.tls !== undefined) {
interstitialOpts.timelinestyle = ad.tls;
}
if (ad.cb !== undefined) {
interstitialOpts.custombeacon = ad.cb;
}
assetListPayload.assets.push(assetItem);
if (opts.combineInterstitial != undefined) {
insertAtListPromises.push(() => hlsVod.insertAdAt(ad.pos, ad.url));
interstitialOpts.resumeOffset = breakDur;
}
}
if (opts.combineInterstitial) {
adpromises.push(() => hlsVod.insertInterstitialAt(b.pos, `${--id}`, assetListUrl.href, true, interstitialOpts));
adpromises.push(() => hlsVod.insertAdAt(b.pos, b.url));
interstitialOpts.resumeOffset = b.duration;
} else {
adpromises.push(() => hlsVod.insertInterstitialAt(b.pos, `${--id}`, assetListUrl.href, true, interstitialOpts));
}
} else {
interstitialOpts.plannedDuration = breakDur;
const encodedAssetListPayload = encodeURIComponent(serialize(assetListPayload));
const baseUrl = process.env.ASSET_LIST_BASE_URL || "";
const assetListUrl = new URL(baseUrl + `/stitch/assetlist/${encodedAssetListPayload}`);
adpromises.push(() => hlsVod.insertInterstitialAt(breakPosition, `Ad-Break-${--_id}`, assetListUrl.href, true, interstitialOpts));
insertAtListPromises.forEach(i => {
adpromises.push(i);
})
}
} else {
for (let i = 0; i < payload.breaks.length; i++) {
const b = payload.breaks[i];
adpromises.push(() => hlsVod.insertAdAt(b.pos, b.url));
}
}
Expand All @@ -385,5 +437,6 @@ const createAssetListFromPayload = async (encodedPayload) => {
DURATION: asset.dur,
});
}
console.log("createAssetListFromPayload->", JSON.stringify(assetDescriptions, null, 2), 56001);
return { ASSETS: assetDescriptions };
};
Loading

0 comments on commit 04f4c66

Please sign in to comment.