Skip to content

Commit f83edd7

Browse files
Support setting and getting of playback bitrate (#391)
* initial commit * rename method signature and params * updated tests
1 parent 5362700 commit f83edd7

6 files changed

Lines changed: 138 additions & 1 deletion

File tree

src/bigscreenplayer.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,24 @@ function BigscreenPlayer() {
471471
*/
472472
getPlaybackRate: () => playerComponent && playerComponent.getPlaybackRate(),
473473

474+
/**
475+
* Set constrained bitrate given a min/max range and mediakind.
476+
*/
477+
setBitrateConstraint: (mediaKind, minBitrateKbps, maxBitrateKbps) => {
478+
if (playerComponent) {
479+
playerComponent.setBitrateConstraint(mediaKind, minBitrateKbps, maxBitrateKbps)
480+
}
481+
},
482+
483+
/**
484+
* Returns current playback bitrate for media kind.
485+
*/
486+
getPlaybackBitrate: (mediaKind) => {
487+
if (playerComponent) {
488+
return playerComponent.getPlaybackBitrate(mediaKind)
489+
}
490+
},
491+
474492
/**
475493
* Returns the media asset's current time in seconds.
476494
* @function

src/bigscreenplayer.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ describe("Bigscreen Player", () => {
116116
isAudioDescribedAvailable: jest.fn(),
117117
isAudioDescribedEnabled: jest.fn(),
118118
setAudioDescribed: jest.fn(),
119+
setBitrateConstraint: jest.fn(),
120+
getPlaybackBitrate: jest.fn(),
119121
}
120122

121123
jest.spyOn(PlayerComponent, "getLiveSupport").mockReturnValue(LiveSupport.SEEKABLE)
@@ -1669,4 +1671,35 @@ describe("Bigscreen Player", () => {
16691671
expect(DebugTool.getDebugLogs).toHaveBeenCalledTimes(1)
16701672
})
16711673
})
1674+
1675+
describe("Set and get playback bitrate", () => {
1676+
const mediaKind = "video"
1677+
const minBitrateKbps = 100
1678+
const maxBitrateKbps = 200
1679+
1680+
it("should set bitrate on the strategy", async () => {
1681+
await asyncInitialiseBigscreenPlayer(createPlaybackElement(), bigscreenPlayerData)
1682+
bigscreenPlayer.setBitrateConstraint(mediaKind, minBitrateKbps, maxBitrateKbps)
1683+
1684+
expect(mockPlayerComponentInstance.setBitrateConstraint).toHaveBeenLastCalledWith(
1685+
mediaKind,
1686+
minBitrateKbps,
1687+
maxBitrateKbps
1688+
)
1689+
})
1690+
1691+
it("should not set the bitrate if playerComponent is not initialised", async () => {
1692+
bigscreenPlayer.setBitrateConstraint(mediaKind, minBitrateKbps, maxBitrateKbps)
1693+
1694+
expect(mockPlayerComponentInstance.setBitrateConstraint).not.toHaveBeenCalled()
1695+
})
1696+
1697+
it("should return the bitrate given a media kind", async () => {
1698+
await asyncInitialiseBigscreenPlayer(createPlaybackElement(), bigscreenPlayerData)
1699+
mockPlayerComponentInstance.getPlaybackBitrate.mockReturnValue(100)
1700+
bigscreenPlayer.getPlaybackBitrate(mediaKind)
1701+
1702+
expect(mockPlayerComponentInstance.getPlaybackBitrate()).toBe(100)
1703+
})
1704+
})
16721705
})

src/playbackstrategy/msestrategy.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ function MSEStrategy(
415415

416416
const bitrateInfoList = mediaPlayer.getBitrateInfoListFor(mediaKind)
417417

418-
return bitrateInfoList[index].bitrate ?? 0
418+
return bitrateInfoList?.[index].bitrate ?? 0
419419
}
420420

421421
function onQualityChangeRequested(event) {
@@ -995,6 +995,26 @@ function MSEStrategy(
995995
}
996996
}
997997

998+
/*
999+
* Set constrained audio or video bitrate
1000+
*/
1001+
function setBitrateConstraint(mediaKind, minBitrateKbps, maxBitrateKbps) {
1002+
mediaPlayer.updateSettings({
1003+
streaming: {
1004+
abr: {
1005+
minBitrate: {
1006+
audio: mediaKind === MediaKinds.AUDIO ? minBitratKbps : -1,
1007+
video: mediaKind === MediaKinds.VIDEO ? minBitrateKbps : -1,
1008+
},
1009+
maxBitrate: {
1010+
audio: mediaKind === MediaKinds.AUDIO ? maxBitrateKbps : -1,
1011+
video: mediaKind === MediaKinds.VIDEO ? maxBitrateKbps : -1,
1012+
},
1013+
},
1014+
},
1015+
})
1016+
}
1017+
9981018
return {
9991019
transitions: {
10001020
canBePaused: () => true,
@@ -1039,6 +1059,8 @@ function MSEStrategy(
10391059
setCurrentTime,
10401060
setPlaybackRate: (rate) => mediaPlayer.setPlaybackRate(rate),
10411061
getPlaybackRate: () => mediaPlayer.getPlaybackRate(),
1062+
setBitrateConstraint,
1063+
getPlaybackBitrate: (mediaKind) => currentPlaybackBitrateInKbps(mediaKind),
10421064
}
10431065
}
10441066

src/playbackstrategy/msestrategy.test.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ function createMockDashInstance() {
8989
setInitialMediaSettingsFor: jest.fn(),
9090
setAutoPlay: jest.fn(),
9191
setProtectionData: jest.fn(),
92+
setBitrateConstraint: jest.fn(),
93+
getPlaybackBitrate: jest.fn(),
9294
}
9395
}
9496

@@ -1915,4 +1917,23 @@ describe("Media Source Extensions Playback Strategy", () => {
19151917
expect(mockDashInstance.attachTTMLRenderingDiv).toHaveBeenCalledWith(subtitlesElement)
19161918
})
19171919
})
1920+
1921+
describe("Playback bitrate", () => {
1922+
it("setBitrateConstraint should call media player updateSettings", () => {
1923+
const mseStrategy = MSEStrategy(mockMediaSources, MediaKinds.VIDEO, playbackElement)
1924+
mseStrategy.load(null, 0)
1925+
mseStrategy.setBitrateConstraint("video", 100, 200)
1926+
1927+
expect(mockDashInstance.updateSettings).toHaveBeenCalled()
1928+
})
1929+
1930+
it("getPlaybackBitrate returns the current playback bitrate in kbps", () => {
1931+
const mseStrategy = MSEStrategy(mockMediaSources, MediaKinds.VIDEO, playbackElement)
1932+
mseStrategy.load(null, 0)
1933+
mockDashInstance.getBitrateInfoListFor.mockReturnValue([{ bitrate: 100000 }])
1934+
const bitrate = mseStrategy.getPlaybackBitrate("video")
1935+
1936+
expect(bitrate).toBe(100)
1937+
})
1938+
})
19181939
})

src/playercomponent.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,14 @@ function PlayerComponent(
447447
fatalError = undefined
448448
}
449449

450+
function setBitrateConstraint(mediaKind, minBitrateKbps, maxBitrateKbps) {
451+
playbackStrategy?.setBitrateConstraint(mediaKind, minBitrateKbps, maxBitrateKbps)
452+
}
453+
454+
function getPlaybackBitrate(mediaKind) {
455+
return playbackStrategy?.getPlaybackBitrate(mediaKind)
456+
}
457+
450458
return {
451459
play,
452460
pause,
@@ -467,6 +475,8 @@ function PlayerComponent(
467475
isAudioDescribedEnabled,
468476
setAudioDescribed,
469477
setSubtitles,
478+
setBitrateConstraint,
479+
getPlaybackBitrate,
470480
}
471481
}
472482

src/playercomponent.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ function createMockPlaybackStrategy(liveSupport = LiveSupport.SEEKABLE, extraFie
5656
isAudioDescribedEnabled: jest.fn(),
5757
setAudioDescribedOn: jest.fn(),
5858
setAudioDescribedOff: jest.fn(),
59+
setBitrateConstraint: jest.fn(),
60+
getPlaybackBitrate: jest.fn(),
5961
...extraFields,
6062
}
6163
}
@@ -1611,4 +1613,35 @@ describe("Player Component", () => {
16111613
expect(mockStrategy.tearDown).toHaveBeenCalledTimes(1)
16121614
})
16131615
})
1616+
1617+
describe("Set and get playback bitrate", () => {
1618+
it("setBitrateConstraint calls the the strategy to update settings", async () => {
1619+
const playerComponent = new PlayerComponent(
1620+
createPlaybackElement(),
1621+
bigscreenPlayerData,
1622+
mockMediaSources,
1623+
jest.fn(),
1624+
jest.fn()
1625+
)
1626+
await jest.runOnlyPendingTimersAsync()
1627+
playerComponent.setBitrateConstraint("video", 100, 200)
1628+
1629+
expect(mockStrategy.setBitrateConstraint).toHaveBeenCalledWith("video", 100, 200)
1630+
})
1631+
1632+
it("getPlaybackBitrate returns the strategy playback bitrate", async () => {
1633+
mockStrategy.getPlaybackBitrate.mockReturnValueOnce(100)
1634+
const playerComponent = new PlayerComponent(
1635+
createPlaybackElement(),
1636+
bigscreenPlayerData,
1637+
mockMediaSources,
1638+
jest.fn(),
1639+
jest.fn()
1640+
)
1641+
await jest.runOnlyPendingTimersAsync()
1642+
1643+
expect(playerComponent.getPlaybackBitrate()).toBe(100)
1644+
expect(mockStrategy.getPlaybackBitrate).toHaveBeenCalledTimes(1)
1645+
})
1646+
})
16141647
})

0 commit comments

Comments
 (0)