Skip to content

Commit

Permalink
Refresh manifest on validity changed event (#341)
Browse files Browse the repository at this point in the history
* refresh manifest on validity changed event, fix test state leakage
* update wording for test and add another
* log out the clamped seek time when seeking on a growing window
* use configurable-playback-ended branch of dash.js
* update deps
---------
Co-authored-by: Matt Stephenson <[email protected]>
  • Loading branch information
jlks authored Aug 20, 2024
1 parent 3e8aefa commit c2891a4
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 25 deletions.
31 changes: 15 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"typescript-eslint": "^7.2.0"
},
"dependencies": {
"dashjs": "github:bbc/dash.js#smp-v4.7.3-2",
"dashjs": "github:bbc/dash.js#smp-v4.7.3-3",
"smp-imsc": "github:bbc/imscJS#v1.0.3"
},
"repository": {
Expand Down
15 changes: 11 additions & 4 deletions src/playbackstrategy/msestrategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,11 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD

function onManifestValidityChange(event) {
DebugTool.info(`Manifest validity changed. Duration is: ${event.newDuration}`)
if (windowType === WindowTypes.GROWING) {
mediaPlayer.refreshManifest((manifest) => {
DebugTool.info(`Manifest Refreshed. Duration is: ${manifest.mediaPresentationDuration}`)
})
}
}

function onStreamInitialised() {
Expand Down Expand Up @@ -569,10 +574,12 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD
if (isNaN(mediaPresentationDuration)) {
mediaPlayer.seek(seekToTime)
} else {
DebugTool.info("Stream ended. Clamping seek point to end of stream")
mediaPlayer.seek(
getClampedTime(seekToTime, { start: getSeekableRange().start, end: mediaPresentationDuration })
)
const clampedSeekTime = getClampedTime(seekToTime, {
start: getSeekableRange().start,
end: mediaPresentationDuration,
})
DebugTool.info(`Stream ended. Clamping seek point to end of stream - seek point now: ${clampedSeekTime}`)
mediaPlayer.seek(clampedSeekTime)
}
})
}
Expand Down
45 changes: 41 additions & 4 deletions src/playbackstrategy/msestrategy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import PauseTriggers from "../models/pausetriggers"
const mockDashInstance = {
initialize: jest.fn(),
retrieveManifest: jest.fn(),
refreshManifest: jest.fn(),
getDebug: jest.fn(),
getSource: jest.fn(),
on: jest.fn(),
Expand Down Expand Up @@ -65,7 +66,7 @@ describe("Media Source Extensions Playback Strategy", () => {
let mseStrategy
let eventCallbacks
let dashEventCallback
const eventHandlers = {}
let eventHandlers
let playbackElement
let cdnArray = []
let mediaSources
Expand All @@ -92,6 +93,7 @@ describe("Media Source Extensions Playback Strategy", () => {

beforeEach(() => {
jest.clearAllMocks()
eventHandlers = {}
delete window.bigscreenPlayer

mediaElement = undefined
Expand All @@ -105,7 +107,8 @@ describe("Media Source Extensions Playback Strategy", () => {

mockDashInstance.on.mockImplementation((eventType, handler) => {
eventHandlers[eventType] = handler
dashEventCallback = (eventType, event) => eventHandlers[eventType].call(eventType, event)
dashEventCallback = (eventType, event) =>
eventHandlers[eventType] ? eventHandlers[eventType].call(eventType, event) : null
})

mockDashInstance.getDashMetrics.mockReturnValue({
Expand Down Expand Up @@ -1115,13 +1118,46 @@ describe("Media Source Extensions Playback Strategy", () => {
describe("onManifestLoaded", () => {
it("calls onManifestLoaded plugin with the manifest when dashjs loads it", () => {
const onManifestLoadedSpy = jest.spyOn(Plugins.interface, "onManifestLoaded")

setUpMSE(0, WindowTypes.SLIDING)
mseStrategy.load(null, 0)
dashEventCallback(dashjsMediaPlayerEvents.MANIFEST_LOADED, testManifestObject)

expect(onManifestLoadedSpy).toHaveBeenCalledWith(expect.any(Object))
})
})

describe("onManifestValidityChanged", () => {
beforeEach(() => {
mockDashInstance.refreshManifest.mockReset()
})

it("calls refreshManifest on mediaPlayer with a growing window", () => {
setUpMSE(0, WindowTypes.GROWING)
mseStrategy.load(null, 0)
dashEventCallback(dashjsMediaPlayerEvents.MANIFEST_VALIDITY_CHANGED, testManifestObject)

expect(mockDashInstance.refreshManifest).toHaveBeenCalledTimes(1)
})

it("does not call refreshManifest on mediaPlayer with a sliding window", () => {
setUpMSE(0, WindowTypes.SLIDING)

mseStrategy.load(null, 0)
dashEventCallback(dashjsMediaPlayerEvents.MANIFEST_VALIDITY_CHANGED, testManifestObject)

expect(mockDashInstance.refreshManifest).not.toHaveBeenCalled()
})

it("does not call refreshManifest on mediaPlayer with a static window", () => {
setUpMSE(0, WindowTypes.STATIC)

mseStrategy.load(null, 0)
dashEventCallback(dashjsMediaPlayerEvents.MANIFEST_VALIDITY_CHANGED, testManifestObject)

expect(mockDashInstance.refreshManifest).not.toHaveBeenCalled()
})
})

describe("onMetricAdded and onQualityChangeRendered", () => {
const mockEvent = {
mediaType: "video",
Expand Down Expand Up @@ -1454,7 +1490,7 @@ describe("Media Source Extensions Playback Strategy", () => {
describe("gap jumps", () => {
it("logs a seek triggered by a gap to the debugger", () => {
setUpMSE()

mseStrategy.load(null, 0)
dashEventCallback("gapCausedInternalSeek", { duration: 0.3, seekTime: 33.3 })

expect(DebugTool.gap).toHaveBeenCalledTimes(1)
Expand All @@ -1463,6 +1499,7 @@ describe("Media Source Extensions Playback Strategy", () => {

it("logs a seek to end triggered by a gap to the debugger", () => {
setUpMSE()
mseStrategy.load(null, 0)

dashEventCallback("gapCausedSeekToPeriodEnd", { duration: 0.3, seekTime: 33.3 })

Expand Down

0 comments on commit c2891a4

Please sign in to comment.