From 603ef5f85d1a0ad5a0f967c260a606f43c824062 Mon Sep 17 00:00:00 2001 From: Nfrederiksen Date: Thu, 28 Nov 2024 11:07:47 +0100 Subject: [PATCH] fix: revert special placement for interstitial tag with cues --- index.js | 69 ++++++++++------------------------------- spec/hls_splice_spec.js | 60 +++++++++++++++++------------------ 2 files changed, 47 insertions(+), 82 deletions(-) diff --git a/index.js b/index.js index e1aa59a..afb354d 100644 --- a/index.js +++ b/index.js @@ -482,12 +482,10 @@ class HLSSpliceVod { _insertInterstitialAtExtraMedia(offset, id, uri, isAssetList, extraAttrs, startDate, playlists, opts) { - let HAS_CUE_ATTR = false; if (opts && opts.cue) { const cueValue = _parseValidCueValues(opts.cue); if (cueValue) { extraAttrs += `,CUE="${cueValue}"`; - HAS_CUE_ATTR = true; } } @@ -508,37 +506,22 @@ class HLSSpliceVod { idx++; } } - if (HAS_CUE_ATTR) { - pos = playlist.items.PlaylistItem.length - 1; - } + let durationTag = ""; if (opts && opts.plannedDuration) { durationTag = `,DURATION=${opts.plannedDuration / 1000}`; } - if (HAS_CUE_ATTR) { - if (isAssetList) { - playlist.addPlaylistItem({ - daterange: `ID=${id},CLASS="com.apple.hls.interstitial",START-DATE="${startDate}"${durationTag},X-ASSET-LIST="${uri}"${extraAttrs}`, - }); - } else { - playlist.addPlaylistItem({ - daterange: `ID=${id},CLASS="com.apple.hls.interstitial",START-DATE="${startDate}"${durationTag},X-ASSET-URI="${uri}"${extraAttrs}`, - }); - } + let xAssetAttributeKey; + if (isAssetList) { + xAssetAttributeKey = "X-ASSET-LIST"; } else { - if (isAssetList) { - playlist.items.PlaylistItem[idx].set( - "daterange", - `ID=${id},CLASS="com.apple.hls.interstitial",START-DATE="${startDate}"${durationTag},X-ASSET-LIST="${uri}"${extraAttrs}` - ); - } else { - playlist.items.PlaylistItem[idx].set( - "daterange", - `ID=${id},CLASS="com.apple.hls.interstitial",START-DATE="${startDate}"${durationTag},X-ASSET-URI="${uri}"${extraAttrs}` - ); - } + xAssetAttributeKey = "X-ASSET-URI"; } + playlist.items.PlaylistItem[idx].set( + "daterange", + `ID=${id},CLASS="com.apple.hls.interstitial",START-DATE="${startDate}"${durationTag},${xAssetAttributeKey}="${uri}"${extraAttrs}` + ); } } } @@ -554,7 +537,6 @@ class HLSSpliceVod { custombeacon: undefined, cue: undefined, }) { - let HAS_CUE_ATTR = false; return new Promise((resolve, reject) => { if (this.bumperDuration) { @@ -568,7 +550,6 @@ class HLSSpliceVod { const cueValue = _parseValidCueValues(opts.cue); if (cueValue) { extraAttrs += `,CUE="${cueValue}"`; - HAS_CUE_ATTR = true; } } @@ -623,38 +604,22 @@ class HLSSpliceVod { } } - if (HAS_CUE_ATTR) { - pos = playlistSize - 1; - } - startDate = new Date(1 + Number(offset)).toISOString(); let durationTag = ""; if (opts && opts.plannedDuration) { durationTag = `,DURATION=${opts.plannedDuration / 1000}`; } + + let xAssetAttributeKey; if (isAssetList) { - if (HAS_CUE_ATTR) { - this.playlists[bw].addPlaylistItem({ - daterange: `ID=${id},CLASS="com.apple.hls.interstitial",START-DATE="${startDate}"${durationTag},X-ASSET-LIST="${uri}"${extraAttrs}`, - }); - } else { - this.playlists[bw].items.PlaylistItem[i].set( - "daterange", - `ID=${id},CLASS="com.apple.hls.interstitial",START-DATE="${startDate}"${durationTag},X-ASSET-LIST="${uri}"${extraAttrs}` - ); - } + xAssetAttributeKey = "X-ASSET-LIST"; } else { - if (HAS_CUE_ATTR) { - this.playlists[bw].addPlaylistItem({ - daterange: `ID=${id},CLASS="com.apple.hls.interstitial",START-DATE="${startDate}"${durationTag},X-ASSET-URI="${uri}"${extraAttrs}`, - }); - } else { - this.playlists[bw].items.PlaylistItem[i].set( - "daterange", - `ID=${id},CLASS="com.apple.hls.interstitial",START-DATE="${startDate}"${durationTag},X-ASSET-URI="${uri}"${extraAttrs}` - ); - } + xAssetAttributeKey = "X-ASSET-URI"; } + this.playlists[bw].items.PlaylistItem[i].set( + "daterange", + `ID=${id},CLASS="com.apple.hls.interstitial",START-DATE="${startDate}"${durationTag},${xAssetAttributeKey}="${uri}"${extraAttrs}` + ); } this._insertInterstitialAtExtraMedia(offset, id, uri, isAssetList, extraAttrs, startDate, this.playlistsAudio, opts); diff --git a/spec/hls_splice_spec.js b/spec/hls_splice_spec.js index 9b81093..0d344cf 100644 --- a/spec/hls_splice_spec.js +++ b/spec/hls_splice_spec.js @@ -508,7 +508,7 @@ describe("HLSSpliceVod", () => { mockVod .load(mockMasterManifest, mockMediaManifest) .then(() => { - return mockVod.insertInterstitialAt(18000, "001", "http://mock.com/asseturi", false, { + return mockVod.insertInterstitialAt(0, "001", "http://mock.com/asseturi", false, { resumeOffset: 10500, cue: "PRE,ONCE", }); @@ -516,8 +516,8 @@ describe("HLSSpliceVod", () => { .then(() => { const m3u8 = mockVod.getMediaManifest(4497000); const lines = m3u8.split("\n"); - expect(lines[29]).toEqual( - '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:18.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="PRE,ONCE",X-RESUME-OFFSET=10.5' + expect(lines[8]).toEqual( + '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:00.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="PRE,ONCE",X-RESUME-OFFSET=10.5' ); done(); }); @@ -528,7 +528,7 @@ describe("HLSSpliceVod", () => { mockVod .load(mockMasterManifest, mockMediaManifest) .then(() => { - return mockVod.insertInterstitialAt(18000, "001", "http://mock.com/asseturi", false, { + return mockVod.insertInterstitialAt(0, "001", "http://mock.com/asseturi", false, { resumeOffset: 10500, cue: "pre-once", }); @@ -536,8 +536,8 @@ describe("HLSSpliceVod", () => { .then(() => { const m3u8 = mockVod.getMediaManifest(4497000); const lines = m3u8.split("\n"); - expect(lines[12]).toEqual( - '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:18.001Z",X-ASSET-URI="http://mock.com/asseturi",X-RESUME-OFFSET=10.5' + expect(lines[8]).toEqual( + '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:00.001Z",X-ASSET-URI="http://mock.com/asseturi",X-RESUME-OFFSET=10.5' ); done(); }); @@ -548,7 +548,7 @@ describe("HLSSpliceVod", () => { mockVod .load(mockMasterManifest, mockMediaManifest) .then(() => { - return mockVod.insertInterstitialAt(18000, "001", "http://mock.com/asseturi", false, { + return mockVod.insertInterstitialAt(0, "001", "http://mock.com/asseturi", false, { resumeOffset: 10500, cue: "POST", }); @@ -556,8 +556,8 @@ describe("HLSSpliceVod", () => { .then(() => { const m3u8 = mockVod.getMediaManifest(4497000); const lines = m3u8.split("\n"); - expect(lines[29]).toEqual( - '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:18.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="POST",X-RESUME-OFFSET=10.5' + expect(lines[8]).toEqual( + '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:00.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="POST",X-RESUME-OFFSET=10.5' ); done(); }); @@ -1528,7 +1528,7 @@ describe("HLSSpliceVod with Demuxed Audio Tracks,", () => { mockVod .load(mockMasterManifest, mockMediaManifest, mockAudioManifest) .then(() => { - return mockVod.insertInterstitialAt(18000, "001", "http://mock.com/asseturi", false, { + return mockVod.insertInterstitialAt(0, "001", "http://mock.com/asseturi", false, { resumeOffset: 10500, cue: "PRE,ONCE", }); @@ -1536,13 +1536,13 @@ describe("HLSSpliceVod with Demuxed Audio Tracks,", () => { .then(() => { const m3u8 = mockVod.getMediaManifest(4497000); let lines = m3u8.split("\n"); - expect(lines[29]).toEqual( - '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:18.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="PRE,ONCE",X-RESUME-OFFSET=10.5' + expect(lines[8]).toEqual( + '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:00.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="PRE,ONCE",X-RESUME-OFFSET=10.5' ); const m3u8Audio = mockVod.getAudioManifest("stereo", "sv"); - lines = m3u8Audio.split("\n"); - expect(lines[29]).toEqual( - '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:18.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="PRE,ONCE",X-RESUME-OFFSET=10.5' + lines = m3u8Audio.split("\n"); + expect(lines[8]).toEqual( + '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:00.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="PRE,ONCE",X-RESUME-OFFSET=10.5' ); done(); }); @@ -1553,7 +1553,7 @@ describe("HLSSpliceVod with Demuxed Audio Tracks,", () => { mockVod .load(mockMasterManifest, mockMediaManifest, mockAudioManifest) .then(() => { - return mockVod.insertInterstitialAt(18000, "001", "http://mock.com/asseturi", false, { + return mockVod.insertInterstitialAt(0, "001", "http://mock.com/asseturi", false, { resumeOffset: 10500, cue: "ROST,TWICE", }); @@ -1561,13 +1561,13 @@ describe("HLSSpliceVod with Demuxed Audio Tracks,", () => { .then(() => { const m3u8 = mockVod.getMediaManifest(4497000); let lines = m3u8.split("\n"); - expect(lines[12]).toEqual( - '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:18.001Z",X-ASSET-URI="http://mock.com/asseturi",X-RESUME-OFFSET=10.5' + expect(lines[8]).toEqual( + '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:00.001Z",X-ASSET-URI="http://mock.com/asseturi",X-RESUME-OFFSET=10.5' ); const m3u8Audio = mockVod.getAudioManifest("stereo", "sv"); lines = m3u8Audio.split("\n"); - expect(lines[12]).toEqual( - '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:18.001Z",X-ASSET-URI="http://mock.com/asseturi",X-RESUME-OFFSET=10.5' + expect(lines[8]).toEqual( + '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:00.001Z",X-ASSET-URI="http://mock.com/asseturi",X-RESUME-OFFSET=10.5' ); done(); }); @@ -1578,7 +1578,7 @@ describe("HLSSpliceVod with Demuxed Audio Tracks,", () => { mockVod .load(mockMasterManifest, mockMediaManifest, mockAudioManifest) .then(() => { - return mockVod.insertInterstitialAt(18000, "001", "http://mock.com/asseturi", false, { + return mockVod.insertInterstitialAt(0, "001", "http://mock.com/asseturi", false, { resumeOffset: 10500, cue: "POST,THRICE", }); @@ -1586,13 +1586,13 @@ describe("HLSSpliceVod with Demuxed Audio Tracks,", () => { .then(() => { const m3u8 = mockVod.getMediaManifest(4497000); let lines = m3u8.split("\n"); - expect(lines[29]).toEqual( - '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:18.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="POST",X-RESUME-OFFSET=10.5' + expect(lines[8]).toEqual( + '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:00.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="POST",X-RESUME-OFFSET=10.5' ); const m3u8Audio = mockVod.getAudioManifest("stereo", "sv"); lines = m3u8Audio.split("\n"); - expect(lines[29]).toEqual( - '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:18.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="POST",X-RESUME-OFFSET=10.5' + expect(lines[8]).toEqual( + '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:00.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="POST",X-RESUME-OFFSET=10.5' ); done(); }); @@ -2165,7 +2165,7 @@ test-audio=256000-6.m4s`; mockVod .load(mockCmafMasterManifest, mockCmafMediaManifest, mockCmafAudioManifest) .then(() => { - return mockVod.insertInterstitialAt(18000, "001", "http://mock.com/asseturi", false, { + return mockVod.insertInterstitialAt(0, "001", "http://mock.com/asseturi", false, { resumeOffset: 10500, cue: "POST,ONCE", }); @@ -2173,13 +2173,13 @@ test-audio=256000-6.m4s`; .then(() => { const m3u8 = mockVod.getMediaManifest(4497000); let lines = m3u8.split("\n"); - expect(lines[129]).toEqual( - '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:18.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="POST,ONCE",X-RESUME-OFFSET=10.5' + expect(lines[10]).toEqual( + '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:00.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="POST,ONCE",X-RESUME-OFFSET=10.5' ); const m3u8Audio = mockVod.getAudioManifest("stereo", "sv"); lines = m3u8Audio.split("\n"); - expect(lines[195]).toEqual( - '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:18.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="POST,ONCE",X-RESUME-OFFSET=10.5' + expect(lines[10]).toEqual( + '#EXT-X-DATERANGE:ID="001",CLASS="com.apple.hls.interstitial",START-DATE="1970-01-01T00:00:00.001Z",X-ASSET-URI="http://mock.com/asseturi",CUE="POST,ONCE",X-RESUME-OFFSET=10.5' ); done(); });