From c3cd2528b2141018bb00053a569406be0866be46 Mon Sep 17 00:00:00 2001 From: Nfrederiksen Date: Tue, 21 Mar 2023 15:26:34 +0100 Subject: [PATCH 1/3] fix: option to filter video variants to load - and release prev vod when done in load after --- index.js | 306 ++++++++++++++++++++++++-------------------- spec/hlsvod_spec.js | 15 +++ 2 files changed, 182 insertions(+), 139 deletions(-) diff --git a/index.js b/index.js index 9596f89..51e6bdb 100644 --- a/index.js +++ b/index.js @@ -44,12 +44,16 @@ class HLSVod { this.header = header; this.lastUsedDiscSeq = null; this.sequenceAlwaysContainNewSegments = false; + this.targetProfiles = []; if (opts && opts.sequenceAlwaysContainNewSegments) { this.sequenceAlwaysContainNewSegments = opts.sequenceAlwaysContainNewSegments; } if (opts && opts.forcedDemuxMode) { this.forcedDemuxMode = opts.forcedDemuxMode; } + if (opts && opts.targetProfiles) { + this.targetProfiles = opts.targetProfiles; + } this.videoSequencesCount = 0; this.audioSequencesCount = 0; this.defaultAudioGroupAndLang = null; @@ -88,6 +92,7 @@ class HLSVod { audioSequencesCount: this.audioSequencesCount, mediaStartExecessTime: this.mediaStartExecessTime, audioCodecsMap: this.audioCodecsMap, + targetProfiles: this.targetProfiles, }; return JSON.stringify(serialized); } @@ -129,6 +134,7 @@ class HLSVod { this.audioSequencesCount = de.audioSequencesCount; this.mediaStartExecessTime = de.mediaStartExecessTime; this.audioCodecsMap = de.audioCodecsMap; + this.targetProfiles = de.targetProfiles; } /** @@ -169,9 +175,20 @@ class HLSVod { let mediaManifestUrl = urlResolve(baseUrl, streamItem.get("uri")); if (streamItem.get("bandwidth")) { - let usageProfile = { - bw: streamItem.get("bandwidth"), - }; + let bw = streamItem.get("bandwidth"); + let usageProfile; + let selectedBw = this.targetProfiles.length > 0 ? this._getNearestBandwidthInList(bw, this.targetProfiles) : bw; + if (this.targetProfiles.length > 0 && (!this.usageProfile.length || !this.usageProfile.map((up) => up.bw).includes(selectedBw))) { + usageProfile = { + bw: bw, + }; + } else if (this.targetProfiles.length > 0) { + continue; + } else { + usageProfile = { + bw: bw, + }; + } if (streamItem.get("resolution")) { usageProfile.resolution = streamItem.get("resolution")[0] + "x" + streamItem.get("resolution")[1]; } @@ -188,127 +205,132 @@ class HLSVod { } } } - Promise.all(mediaManifestPromises).then(() => { - for (let i = 0; i < m3u.items.StreamItem.length; i++) { - const streamItem = m3u.items.StreamItem[i]; - if (streamItem.get("audio")) { - let audioGroupId = streamItem.get("audio"); - if (!HAS_AUDIO_DEFAULTS && !this.audioSegments[audioGroupId]) { - this.audioSegments[audioGroupId] = {}; - } - const audioCodecs = streamItem.get("codecs").split(",").find(c => { - return c.match(/^mp4a/) || c.match(/^ac-3/) || c.match(/^ec-3/); - }); - - debug(`Lookup media item for '${audioGroupId}'`); - - // # Needed for the case when loading after another VOD. - const previousVODLanguages = HAS_AUDIO_DEFAULTS - ? Object.keys(this.audioSegments[this.defaultAudioGroupAndLang.audioGroupId]) - : Object.keys(this.audioSegments[audioGroupId]); - - let audioGroupItems = m3u.items.MediaItem.filter((item) => { - return item.get("type") === "AUDIO" && item.get("group-id") === audioGroupId; - }); - // # Find all langs amongst the mediaItems that have this group id. - // # It extracts each mediaItems language attribute value. - // # ALSO initialize in this.audioSegments a lang. property whos value is an array [{seg1}, {seg2}, ...]. - let audioLanguages = audioGroupItems.map((item) => { - let itemLang; - if (!item.get("language")) { - itemLang = item.get("name"); - } else { - itemLang = item.get("language"); - } - // Initialize lang. in new group. - if (!HAS_AUDIO_DEFAULTS && !this.audioSegments[audioGroupId][itemLang]) { - this.audioSegments[audioGroupId][itemLang] = []; - } - if (!this.audioCodecsMap[audioCodecs]) { - this.audioCodecsMap[audioCodecs] = {}; + Promise.all(mediaManifestPromises) + .then(() => { + for (let i = 0; i < m3u.items.StreamItem.length; i++) { + const streamItem = m3u.items.StreamItem[i]; + if (streamItem.get("audio")) { + let audioGroupId = streamItem.get("audio"); + if (!HAS_AUDIO_DEFAULTS && !this.audioSegments[audioGroupId]) { + this.audioSegments[audioGroupId] = {}; } - const itemChannels = item.get("channels") ? item.get("channels") : "2"; - this.audioCodecsMap[audioCodecs][itemChannels] = audioGroupId; - return (item = itemLang); - }); + const audioCodecs = streamItem + .get("codecs") + .split(",") + .find((c) => { + return c.match(/^mp4a/) || c.match(/^ac-3/) || c.match(/^ec-3/); + }); - // # Inject "default" language's segments to every new language relative to previous VOD. - // # For the case when this is a VOD following another, every language new or old should - // # start with some segments from the previous VOD's last sequence. - const newLanguages = audioLanguages.filter((lang) => { - return !previousVODLanguages.includes(lang); - }); - // # Only inject if there were prior tracks. - if (previousVODLanguages.length > 0 && !HAS_AUDIO_DEFAULTS) { - for (let i = 0; i < newLanguages.length; i++) { - const newLanguage = newLanguages[i]; - const defaultLanguage = this._getFirstAudioLanguageWithSegments(audioGroupId); - this.audioSegments[audioGroupId][newLanguage] = [...this.audioSegments[audioGroupId][defaultLanguage]]; - } - } + debug(`Lookup media item for '${audioGroupId}'`); - // # Need to clean up langs. loaded from prev. VOD that current VOD doesn't have. - // # Necessary, for the case when getLiveMediaSequenceAudioSegments() tries to - // # access an audioGroup's language that the current VOD never had. A False-Positive. - if (!HAS_AUDIO_DEFAULTS) { - let allLangs = Object.keys(this.audioSegments[audioGroupId]); - let toRemove = []; - allLangs.map((junkLang) => { - if (!audioLanguages.includes(junkLang)) { - toRemove.push(junkLang); + // # Needed for the case when loading after another VOD. + const previousVODLanguages = HAS_AUDIO_DEFAULTS + ? Object.keys(this.audioSegments[this.defaultAudioGroupAndLang.audioGroupId]) + : Object.keys(this.audioSegments[audioGroupId]); + + let audioGroupItems = m3u.items.MediaItem.filter((item) => { + return item.get("type") === "AUDIO" && item.get("group-id") === audioGroupId; + }); + // # Find all langs amongst the mediaItems that have this group id. + // # It extracts each mediaItems language attribute value. + // # ALSO initialize in this.audioSegments a lang. property whos value is an array [{seg1}, {seg2}, ...]. + let audioLanguages = audioGroupItems.map((item) => { + let itemLang; + if (!item.get("language")) { + itemLang = item.get("name"); + } else { + itemLang = item.get("language"); + } + // Initialize lang. in new group. + if (!HAS_AUDIO_DEFAULTS && !this.audioSegments[audioGroupId][itemLang]) { + this.audioSegments[audioGroupId][itemLang] = []; } + if (!this.audioCodecsMap[audioCodecs]) { + this.audioCodecsMap[audioCodecs] = {}; + } + const itemChannels = item.get("channels") ? item.get("channels") : "2"; + this.audioCodecsMap[audioCodecs][itemChannels] = audioGroupId; + return (item = itemLang); }); - toRemove.map((junkLang) => { - delete this.audioSegments[audioGroupId][junkLang]; + + // # Inject "default" language's segments to every new language relative to previous VOD. + // # For the case when this is a VOD following another, every language new or old should + // # start with some segments from the previous VOD's last sequence. + const newLanguages = audioLanguages.filter((lang) => { + return !previousVODLanguages.includes(lang); }); - } + // # Only inject if there were prior tracks. + if (previousVODLanguages.length > 0 && !HAS_AUDIO_DEFAULTS) { + for (let i = 0; i < newLanguages.length; i++) { + const newLanguage = newLanguages[i]; + const defaultLanguage = this._getFirstAudioLanguageWithSegments(audioGroupId); + this.audioSegments[audioGroupId][newLanguage] = [...this.audioSegments[audioGroupId][defaultLanguage]]; + } + } - // # For each lang, find the lang playlist uri and do _loadAudioManifest() on it. - for (let j = 0; j < audioLanguages.length; j++) { - let audioLang = audioLanguages[j]; - let audioUri = audioGroupItems[j].get("uri"); - if (!audioUri) { - //# if mediaItems dont have uris - let audioVariant = m3u.items.StreamItem.find((item) => { - return !item.get("resolution") && item.get("audio") === audioGroupId; + // # Need to clean up langs. loaded from prev. VOD that current VOD doesn't have. + // # Necessary, for the case when getLiveMediaSequenceAudioSegments() tries to + // # access an audioGroup's language that the current VOD never had. A False-Positive. + if (!HAS_AUDIO_DEFAULTS) { + let allLangs = Object.keys(this.audioSegments[audioGroupId]); + let toRemove = []; + allLangs.map((junkLang) => { + if (!audioLanguages.includes(junkLang)) { + toRemove.push(junkLang); + } + }); + toRemove.map((junkLang) => { + delete this.audioSegments[audioGroupId][junkLang]; }); - if (audioVariant) { - audioUri = audioVariant.get("uri"); - } } - if (audioUri) { - let audioManifestUrl = urlResolve(baseUrl, audioUri); - if (!audioGroups[audioGroupId]) { - audioGroups[audioGroupId] = {}; + + // # For each lang, find the lang playlist uri and do _loadAudioManifest() on it. + for (let j = 0; j < audioLanguages.length; j++) { + let audioLang = audioLanguages[j]; + let audioUri = audioGroupItems[j].get("uri"); + if (!audioUri) { + //# if mediaItems dont have uris + let audioVariant = m3u.items.StreamItem.find((item) => { + return !item.get("resolution") && item.get("audio") === audioGroupId; + }); + if (audioVariant) { + audioUri = audioVariant.get("uri"); + } } - // # Prevents 'loading' an audio track with same GroupID and LANG. - // # otherwise it just would've loaded OVER the latest occurrent of the LANG in GroupID. - if (!audioGroups[audioGroupId][audioLang]) { - let targetGroup = audioGroupId; - let targetLang = audioLang; - audioGroups[audioGroupId][audioLang] = true; - if (HAS_AUDIO_DEFAULTS) { - targetGroup = this.defaultAudioGroupAndLang.audioGroupId; - targetLang = this.defaultAudioGroupAndLang.audioLanguage; - debug(`Loading Audio manifest onto Default GroupID=${targetGroup} and Language=${targetLang}`); + if (audioUri) { + let audioManifestUrl = urlResolve(baseUrl, audioUri); + if (!audioGroups[audioGroupId]) { + audioGroups[audioGroupId] = {}; + } + // # Prevents 'loading' an audio track with same GroupID and LANG. + // # otherwise it just would've loaded OVER the latest occurrent of the LANG in GroupID. + if (!audioGroups[audioGroupId][audioLang]) { + let targetGroup = audioGroupId; + let targetLang = audioLang; + audioGroups[audioGroupId][audioLang] = true; + if (HAS_AUDIO_DEFAULTS) { + targetGroup = this.defaultAudioGroupAndLang.audioGroupId; + targetLang = this.defaultAudioGroupAndLang.audioLanguage; + debug(`Loading Audio manifest onto Default GroupID=${targetGroup} and Language=${targetLang}`); + } + audioManifestPromises.push(this._loadAudioManifest(audioManifestUrl, targetGroup, targetLang, _injectAudioManifest)); + } else { + debug(`Audio manifest for language "${audioLang}" from '${audioGroupId}' in already loaded, skipping`); } - audioManifestPromises.push(this._loadAudioManifest(audioManifestUrl, targetGroup, targetLang, _injectAudioManifest)); } else { - debug(`Audio manifest for language "${audioLang}" from '${audioGroupId}' in already loaded, skipping`); + debug(`No media item for '${audioGroupId}' in "${audioLang}" was found, skipping`); } - } else { - debug(`No media item for '${audioGroupId}' in "${audioLang}" was found, skipping`); } + } else if (this.forcedDemuxMode) { + reject(new Error("The vod is not a demux vod")); } - } else if (this.forcedDemuxMode) { - reject(new Error("The vod is not a demux vod")); } - } - debug("Codec to Audio Group Id mapping"); - debug(this.audioCodecsMap); + debug("Codec to Audio Group Id mapping"); + debug(this.audioCodecsMap); - return Promise.all(audioManifestPromises) - }).then(this._cleanupUnused.bind(this)) + return Promise.all(audioManifestPromises); + }) + .then(this._cleanupUnused.bind(this)) .then(this._createMediaSequences.bind(this)) .then(resolve) .catch((err) => { @@ -355,10 +377,12 @@ class HLSVod { this.load(_injectMasterManifest, _injectMediaManifest, _injectAudioManifest) .then(() => { previousVod.releasePreviousVod(); + this.previousVod = null; resolve(); }) .catch((err) => { previousVod.releasePreviousVod(); + this.previousVod = null; reject(err); }); } catch (exc) { @@ -555,7 +579,7 @@ class HLSVod { if (!this.audioCodecsMap[audioCodecs]) { return undefined; } - Object.keys(this.audioCodecsMap[audioCodecs]).map(channelsKey => { + Object.keys(this.audioCodecsMap[audioCodecs]).map((channelsKey) => { if (channelsKey === channels) { audioGroupId = this.audioCodecsMap[audioCodecs][channelsKey]; } @@ -566,8 +590,8 @@ class HLSVod { getAudioCodecsAndChannelsForGroupId(groupId) { let audioCodecs; let channels; - Object.keys(this.audioCodecsMap).map(codecKey => { - Object.keys(this.audioCodecsMap[codecKey]).map(channelsKey => { + Object.keys(this.audioCodecsMap).map((codecKey) => { + Object.keys(this.audioCodecsMap[codecKey]).map((channelsKey) => { if (this.audioCodecsMap[codecKey][channelsKey] === groupId) { audioCodecs = codecKey; channels = channelsKey; @@ -655,10 +679,13 @@ class HLSVod { for (let i = 0; i < this.mediaSequences[seqIdx].segments[bw].length; i++) { const v = this.mediaSequences[seqIdx].segments[bw][i]; if (v) { - m3u8 += segToM3u8(v, i, - this.mediaSequences[seqIdx].segments[bw].length, - this.mediaSequences[seqIdx].segments[bw][i+1], - previousSegment); + m3u8 += segToM3u8( + v, + i, + this.mediaSequences[seqIdx].segments[bw].length, + this.mediaSequences[seqIdx].segments[bw][i + 1], + previousSegment + ); previousSegment = v; } } @@ -707,8 +734,7 @@ class HLSVod { for (let i = 0; i < mediaSeqAudioSegments.length; i++) { const v = mediaSeqAudioSegments[i]; if (v) { - m3u8 += segToM3u8(v, i, mediaSeqAudioSegments.length, - mediaSeqAudioSegments[i+1], previousSegment); + m3u8 += segToM3u8(v, i, mediaSeqAudioSegments.length, mediaSeqAudioSegments[i + 1], previousSegment); previousSegment = v; } } @@ -1786,7 +1812,7 @@ class HLSVod { } this.mediaStartExecessTime = Math.abs(remain); } - + for (let i = 0; i < m3u.items.PlaylistItem.length; i++) { if (this.splices[spliceIdx]) { nextSplicePosition = this.splices[spliceIdx].position; @@ -1899,13 +1925,13 @@ class HLSVod { let cue = cueOut || cueIn || cueOutCont || assetData ? { - out: typeof cueOut !== "undefined", - cont: typeof cueOutCont !== "undefined" ? cueOutCont : null, - scteData: typeof scteData !== "undefined" ? scteData : null, - in: cueIn ? true : false, - duration: duration, - assetData: typeof assetData !== "undefined" ? assetData : null, - } + out: typeof cueOut !== "undefined", + cont: typeof cueOutCont !== "undefined" ? cueOutCont : null, + scteData: typeof scteData !== "undefined" ? scteData : null, + in: cueIn ? true : false, + duration: duration, + assetData: typeof assetData !== "undefined" ? assetData : null, + } : null; let q = { duration: playlistItem.get("duration"), @@ -1971,30 +1997,30 @@ class HLSVod { _similarSegItemDuration(audioPlaylistItems) { let totalAudioDuration = 0; let audioCount = 0; - audioPlaylistItems.map(seg => { + audioPlaylistItems.map((seg) => { if (seg.get("duration")) { audioCount++; totalAudioDuration += seg.get("duration"); } - }) + }); const avgAudioDuration = totalAudioDuration / audioCount; const bandwidths = Object.keys(this.segments); if (bandwidths.length === 0) { return true; } - const videoSegList = this.segments[bandwidths[0]] + const videoSegList = this.segments[bandwidths[0]]; let totalVideoDuration = 0; let videoCount = 0; - videoSegList.map(seg => { + videoSegList.map((seg) => { if (seg.duration) { videoCount++; totalVideoDuration += seg.duration; } - }) + }); const avgVideoDuration = totalVideoDuration / videoCount; const diff = Math.abs(avgVideoDuration - avgAudioDuration); - if (diff > 0.250) { + if (diff > 0.25) { return false; } return true; @@ -2018,12 +2044,14 @@ class HLSVod { let keys = undefined; // Remove segments in the beginning if we have a start time offset if (this.startTimeOffset != null) { - let remain = this._similarSegItemDuration(m3u.items.PlaylistItem) ? this.startTimeOffset : (this.startTimeOffset + this.mediaStartExecessTime); + let remain = this._similarSegItemDuration(m3u.items.PlaylistItem) + ? this.startTimeOffset + : this.startTimeOffset + this.mediaStartExecessTime; let count = 0; while (remain > 0) { let removed; - if (m3u.items.PlaylistItem[0].get("duration") * 1000 < remain ) { + if (m3u.items.PlaylistItem[0].get("duration") * 1000 < remain) { removed = m3u.items.PlaylistItem.shift(); count++; } @@ -2098,13 +2126,13 @@ class HLSVod { let cue = cueOut || cueIn || cueOutCont || assetData ? { - out: typeof cueOut !== "undefined", - cont: typeof cueOutCont !== "undefined" ? cueOutCont : null, - scteData: typeof scteData !== "undefined" ? scteData : null, - in: cueIn ? true : false, - duration: duration, - assetData: typeof assetData !== "undefined" ? assetData : null, - } + out: typeof cueOut !== "undefined", + cont: typeof cueOutCont !== "undefined" ? cueOutCont : null, + scteData: typeof scteData !== "undefined" ? scteData : null, + in: cueIn ? true : false, + duration: duration, + assetData: typeof assetData !== "undefined" ? assetData : null, + } : null; let q = { duration: playlistItem.get("duration"), diff --git a/spec/hlsvod_spec.js b/spec/hlsvod_spec.js index 69ea611..6b3ee6f 100644 --- a/spec/hlsvod_spec.js +++ b/spec/hlsvod_spec.js @@ -59,6 +59,21 @@ describe("HLSVod standalone", () => { }); }); + it("mesures serialized data size", (done) => { + mockVod = new HLSVod("http://mock.com/mock.m3u8"); + mockVod2 = new HLSVod("http://mock.com/mock.m3u8", null, 0, 0, null, { targetProfile: [354000, 819000]}) + mockVod.load(mockMasterManifestNoUri, mockMediaManifest3, mockAudioManifest).then(() => { + mockVod2.load(mockMasterManifestNoUri, mockMediaManifest3, mockAudioManifest).then(() => { + const serialized = mockVod.toJSON() + const size = Buffer.byteLength(JSON.stringify(serialized)) + expect(size).toBe(10); + const serialized2 = mockVod2.toJSON() + const size2 = Buffer.byteLength(JSON.stringify(serialized)) + expect(size2).toBe(10); + done(); + }); + }); + it("return the correct loaded segments", (done) => { mockVod = new HLSVod("http://mock.com/mock.m3u8"); mockVod.load(mockMasterManifest, mockMediaManifest).then(() => { From 64eca96772e8c28c9e2603e5eda3a8ac97f16c8a Mon Sep 17 00:00:00 2001 From: lauta Date: Tue, 21 Mar 2023 17:13:15 +0100 Subject: [PATCH 2/3] some optimazation and tests --- index.js | 40 ++++++++++++++++++++++++---------------- spec/hlsvod_spec.js | 43 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/index.js b/index.js index 51e6bdb..5789184 100644 --- a/index.js +++ b/index.js @@ -54,6 +54,10 @@ class HLSVod { if (opts && opts.targetProfiles) { this.targetProfiles = opts.targetProfiles; } + this.storePreviousVod = false; + if (opts && opts.storePreviousVod) { + this.storePreviousVod = opts.storePreviousVod; + } this.videoSequencesCount = 0; this.audioSequencesCount = 0; this.defaultAudioGroupAndLang = null; @@ -377,12 +381,16 @@ class HLSVod { this.load(_injectMasterManifest, _injectMediaManifest, _injectAudioManifest) .then(() => { previousVod.releasePreviousVod(); - this.previousVod = null; + if (!this.storePreviousVod) { + this.releasePreviousVod() + } resolve(); }) .catch((err) => { previousVod.releasePreviousVod(); - this.previousVod = null; + if (!this.storePreviousVod) { + this.releasePreviousVod + } reject(err); }); } catch (exc) { @@ -1925,13 +1933,13 @@ class HLSVod { let cue = cueOut || cueIn || cueOutCont || assetData ? { - out: typeof cueOut !== "undefined", - cont: typeof cueOutCont !== "undefined" ? cueOutCont : null, - scteData: typeof scteData !== "undefined" ? scteData : null, - in: cueIn ? true : false, - duration: duration, - assetData: typeof assetData !== "undefined" ? assetData : null, - } + out: typeof cueOut !== "undefined", + cont: typeof cueOutCont !== "undefined" ? cueOutCont : null, + scteData: typeof scteData !== "undefined" ? scteData : null, + in: cueIn ? true : false, + duration: duration, + assetData: typeof assetData !== "undefined" ? assetData : null, + } : null; let q = { duration: playlistItem.get("duration"), @@ -2126,13 +2134,13 @@ class HLSVod { let cue = cueOut || cueIn || cueOutCont || assetData ? { - out: typeof cueOut !== "undefined", - cont: typeof cueOutCont !== "undefined" ? cueOutCont : null, - scteData: typeof scteData !== "undefined" ? scteData : null, - in: cueIn ? true : false, - duration: duration, - assetData: typeof assetData !== "undefined" ? assetData : null, - } + out: typeof cueOut !== "undefined", + cont: typeof cueOutCont !== "undefined" ? cueOutCont : null, + scteData: typeof scteData !== "undefined" ? scteData : null, + in: cueIn ? true : false, + duration: duration, + assetData: typeof assetData !== "undefined" ? assetData : null, + } : null; let q = { duration: playlistItem.get("duration"), diff --git a/spec/hlsvod_spec.js b/spec/hlsvod_spec.js index 6b3ee6f..ddd6a97 100644 --- a/spec/hlsvod_spec.js +++ b/spec/hlsvod_spec.js @@ -59,18 +59,43 @@ describe("HLSVod standalone", () => { }); }); - it("mesures serialized data size", (done) => { + fit("mesures serialized data size (with targetProfiles)", (done) => { mockVod = new HLSVod("http://mock.com/mock.m3u8"); - mockVod2 = new HLSVod("http://mock.com/mock.m3u8", null, 0, 0, null, { targetProfile: [354000, 819000]}) + mockVod2 = new HLSVod("http://mock.com/mock.m3u8", null, 0, 0, null, { targetProfiles: [354000, 819000] }) mockVod.load(mockMasterManifestNoUri, mockMediaManifest3, mockAudioManifest).then(() => { mockVod2.load(mockMasterManifestNoUri, mockMediaManifest3, mockAudioManifest).then(() => { - const serialized = mockVod.toJSON() - const size = Buffer.byteLength(JSON.stringify(serialized)) - expect(size).toBe(10); - const serialized2 = mockVod2.toJSON() - const size2 = Buffer.byteLength(JSON.stringify(serialized)) - expect(size2).toBe(10); - done(); + const serialized = mockVod.toJSON() + const size = Buffer.byteLength(JSON.stringify(serialized)) + expect(size).toBe(134844); + const serialized2 = mockVod2.toJSON() + const size2 = Buffer.byteLength(JSON.stringify(serialized2)) + expect(size2).toBe(68258); + expect(size).not.toBe(size2) + done(); + }); + }); + }); + + fit("mesures serialized data size (store previous)", (done) => { + mockVod = new HLSVod("http://mock.com/mock.m3u8"); + mockVod2 = new HLSVod("http://mock.com/mock.m3u8", null, 0, 0, null, { storePreviousVod: false }) + mockVod3 = new HLSVod("http://mock.com/mock.m3u8", null, 0, 0, null, { storePreviousVod: true }) + mockVod.load(mockMasterManifestNoUri, mockMediaManifest3, mockAudioManifest).then(() => { + mockVod2.loadAfter(mockVod, mockMasterManifestNoUri, mockMediaManifest3, mockAudioManifest).then(() => { + mockVod3.loadAfter(mockVod, mockMasterManifestNoUri, mockMediaManifest3, mockAudioManifest).then(() => { + const serialized = mockVod.toJSON() + const size = Buffer.byteLength(JSON.stringify(serialized)) + expect(size).toBe(134844); + const serialized2 = mockVod2.toJSON() + const size2 = Buffer.byteLength(JSON.stringify(serialized2)) + expect(size2).toBe(477520); + const serialized3 = mockVod3.toJSON() + const size3 = Buffer.byteLength(JSON.stringify(serialized3)) + expect(size3).toBe(633554); + expect(size2).not.toBe(size3) + done(); + }); + }); }); }); From e68d45d25a29e4951de29a91abb0ee0b07bdf463 Mon Sep 17 00:00:00 2001 From: lauta Date: Tue, 21 Mar 2023 18:05:15 +0100 Subject: [PATCH 3/3] removed test artifacts --- spec/hlsvod_spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/hlsvod_spec.js b/spec/hlsvod_spec.js index ddd6a97..cbeb5b1 100644 --- a/spec/hlsvod_spec.js +++ b/spec/hlsvod_spec.js @@ -59,7 +59,7 @@ describe("HLSVod standalone", () => { }); }); - fit("mesures serialized data size (with targetProfiles)", (done) => { + it("mesures serialized data size (with targetProfiles)", (done) => { mockVod = new HLSVod("http://mock.com/mock.m3u8"); mockVod2 = new HLSVod("http://mock.com/mock.m3u8", null, 0, 0, null, { targetProfiles: [354000, 819000] }) mockVod.load(mockMasterManifestNoUri, mockMediaManifest3, mockAudioManifest).then(() => { @@ -76,7 +76,7 @@ describe("HLSVod standalone", () => { }); }); - fit("mesures serialized data size (store previous)", (done) => { + it("mesures serialized data size (store previous)", (done) => { mockVod = new HLSVod("http://mock.com/mock.m3u8"); mockVod2 = new HLSVod("http://mock.com/mock.m3u8", null, 0, 0, null, { storePreviousVod: false }) mockVod3 = new HLSVod("http://mock.com/mock.m3u8", null, 0, 0, null, { storePreviousVod: true })