Skip to content

Commit 268a106

Browse files
authored
Merge pull request #113 from paulhiggs/add_CMCD
Add CMCD support and update to dah.js v5.0.0
2 parents f839e9d + 6c276b2 commit 268a106

7 files changed

Lines changed: 411 additions & 453 deletions

File tree

backend/servicelists/example.xml

Lines changed: 72 additions & 242 deletions
Large diffs are not rendered by default.

frontend/android/js/channel.js

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ Channel.prototype.getMediaPresentationApp = function (serviceInstance) {
149149
if (serviceInstance && serviceInstance.mediaPresentationApps) {
150150
for (i = 0; i < serviceInstance.mediaPresentationApps.length; i++) {
151151
mediaPresentationApp = serviceInstance.mediaPresentationApps[i];
152-
if (mediaPresentationApp.contentType == XML_MIME || mediaPresentationApp.contentType == XHTML_MIMR) {
152+
if (mediaPresentationApp.contentType == XML_MIME || mediaPresentationApp.contentType == XHTML_MIME) {
153153
return mediaPresentationApp.url;
154154
}
155155
}
@@ -174,6 +174,50 @@ Channel.prototype.checkAvailability = function () {
174174
this.availablityTimer = setTimeout(this.checkAvailability.bind(this), 60 * 1000);
175175
};
176176

177+
function UUIDv7() {
178+
// see https://stackoverflow.com/questions/71816194/uuidv6-v7-v8-in-javascript-browser
179+
return "tttttttt-tttt-7xxx-yxxx-xxxxxxxxxxxx"
180+
.replace(/[xy]/g, function (c) {
181+
const r = Math.trunc(Math.random() * 16);
182+
const v = c == "x" ? r : (r & 0x3) | 0x8;
183+
return v.toString(16);
184+
})
185+
.replace(/^[t]{8}-[t]{4}/, function () {
186+
const unixtimestamp = Date.now().toString(16).padStart(12, "0");
187+
return unixtimestamp.slice(0, 8) + "-" + unixtimestamp.slice(8);
188+
});
189+
}
190+
191+
function DASHjsVersion5(player) {
192+
var [major, minor, micro] = player.getVersion().split(".");
193+
return major >= 5;
194+
}
195+
196+
function playDASH(player, instance) {
197+
if (instance == null) {
198+
player.updateSettings({ streaming: { cmcd: { enabled: false } } });
199+
player.attachSource(null);
200+
return;
201+
}
202+
203+
if (instance.hasOwnProperty("CMCDinit") && instance.CMCDinit != null) {
204+
var cmcd_vars = { ...instance.CMCDinit };
205+
cmcd_vars.sid = UUIDv7();
206+
if (DASHjsVersion5(player)) {
207+
cmcd_vars.applyParametersFromMpd = false;
208+
cmcd_vars.includeInRequests = ["segment", "mpd"];
209+
} else {
210+
delete cmcd_vars.version;
211+
}
212+
player.updateSettings({
213+
streaming: { cmcd: cmcd_vars },
214+
});
215+
} else {
216+
player.updateSettings({ streaming: { cmcd: { enabled: false } } });
217+
}
218+
player.attachSource(instance.dashUrl);
219+
}
220+
177221
Channel.prototype.channelSelected = function () {
178222
var self = this;
179223
$("#notification").hide();
@@ -205,21 +249,21 @@ Channel.prototype.channelSelected = function () {
205249
} else if (self.isProgramAllowed()) {
206250
$("#parentalpin").hide();
207251
if (self.serviceInstance) {
208-
player.attachSource(self.serviceInstance.dashUrl);
252+
playDASH(player, self.serviceInstance);
209253
}
210254
} else {
211-
player.attachSource(null);
255+
playDASH(player, null);
212256
checkParentalPIN(
213257
"Enter parental PIN to watch service",
214258
function () {
215259
$("#notification").hide();
216260
try {
217261
if (player.getSource() != self.serviceInstance.dashUrl) {
218-
player.attachSource(self.serviceInstance.dashUrl);
262+
playDASH(player, self.serviceInstance);
219263
}
220264
} catch (e) {
221265
//player throws an error is there is no souce attached
222-
player.attachSource(self.serviceInstance.dashUrl);
266+
playDASH(player, self.serviceInstance);
223267
}
224268
},
225269
function () {
@@ -247,11 +291,11 @@ Channel.prototype.programChanged = function () {
247291
$("#notification").hide();
248292
try {
249293
if (player.getSource() != serviceInstance.dashUrl) {
250-
player.attachSource(serviceInstance.dashUrl);
294+
playDASH(player, serviceInstance);
251295
}
252296
} catch (e) {
253297
//player throws an error is there is no souce attached
254-
player.attachSource(serviceInstance.dashUrl);
298+
playDASH(player, serviceInstance);
255299
}
256300
} else {
257301
player.attachSource(null);
@@ -261,11 +305,11 @@ Channel.prototype.programChanged = function () {
261305
$("#notification").hide();
262306
try {
263307
if (player.getSource() != serviceInstance.dashUrl) {
264-
player.attachSource(serviceInstance.dashUrl);
308+
playDASH(player, serviceInstance);
265309
}
266310
} catch (e) {
267311
//player throws an error is there is no souce attached
268-
player.attachSource(serviceInstance.dashUrl);
312+
playDASH(player, serviceInstance);
269313
}
270314
},
271315
function () {
@@ -479,11 +523,11 @@ Channel.prototype.parentalRatingChanged = function (callback) {
479523
$("#notification").hide();
480524
try {
481525
if (player.getSource() != serviceInstance.dashUrl) {
482-
player.attachSource(serviceInstance.dashUrl);
526+
playDASH(player, serviceInstance);
483527
}
484528
} catch (e) {
485-
//player throws an error is there is no souce attached
486-
player.attachSource(serviceInstance.dashUrl);
529+
//player throws an error if there is no souce attached
530+
playDASH(player, serviceInstance);
487531
}
488532
} else {
489533
player.attachSource(null);
@@ -493,11 +537,11 @@ Channel.prototype.parentalRatingChanged = function (callback) {
493537
$("#notification").hide();
494538
try {
495539
if (player.getSource() != serviceInstance.dashUrl) {
496-
player.attachSource(serviceInstance.dashUrl);
540+
playDASH(player, serviceInstance);
497541
}
498542
} catch (e) {
499543
//player throws an error is there is no souce attached
500-
player.attachSource(serviceInstance.dashUrl);
544+
playDASH(player, serviceInstance);
501545
}
502546
},
503547
function () {

frontend/android/js/dvbi-mobile.js

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -709,31 +709,73 @@ function showStreamInfo() {
709709
function updateStreamInfo() {
710710
if (player) {
711711
try {
712+
document.getElementById("DASHjs_version").innerHTML = player.getVersion();
712713
var settings = player.getSettings();
713-
document.getElementById("live_settings").innerHTML =
714-
"Low latency mode:" +
715-
settings.streaming.lowLatencyEnabled +
716-
" Delay:" +
717-
settings.streaming.liveDelay +
718-
"<br/>Min drift:" +
719-
settings.streaming.liveCatchUpMinDrift +
720-
" Catchup Rate" +
721-
settings.streaming.liveCatchUpPlaybackRate;
722-
var audioTrack = player.getBitrateInfoListFor("audio")[player.getQualityFor("audio")];
723-
var videoTrack = player.getBitrateInfoListFor("video")[player.getQualityFor("video")];
724-
var bestAudio = player.getTopBitrateInfoFor("audio");
725-
var bestVideo = player.getTopBitrateInfoFor("video");
726-
if (audioTrack) {
727-
document.getElementById("audio_bitrate").innerHTML =
728-
audioTrack.bitrate / 1000 + "kbits (max:" + bestAudio.bitrate / 1000 + "kbits)";
729-
}
730-
if (videoTrack) {
731-
document.getElementById("video_bitrate").innerHTML =
732-
videoTrack.bitrate / 1000 + "kbits (max:" + bestVideo.bitrate / 1000 + "kbits)";
714+
715+
if (DASHjsVersion5(player)) {
716+
document.getElementById("live_settings").innerHTML =
717+
"Low latency mode:" +
718+
player.getLowLatencyModeEnabled() +
719+
" Delay:" +
720+
"INDEVv5" +
721+
"<br/>Min drift:" +
722+
"INDEVv5" +
723+
" Catchup Rate:" +
724+
"INDEVv5";
725+
726+
var audioTrack = player.getCurrentRepresentationForType("audio");
727+
var highestAudio = 0,
728+
audioReps = player.getRepresentationsByType("audio");
729+
for (var i = 0; i < audioReps.length; i++) {
730+
if (audioReps[i].bitrateInKbit > highestAudio) highestAudio = audioReps[i].bitrateInKbit;
731+
}
732+
document.getElementById("audio_bitrate").innerHTML = audioTrack
733+
? audioTrack.bitrateInKbit + "kbits (max:" + highestAudio + "kbits)"
734+
: "no-audio";
735+
736+
var videoTrack = player.getCurrentRepresentationForType("video");
737+
var highestVideo = 0,
738+
highestRes = null,
739+
videoReps = player.getRepresentationsByType("video");
740+
for (var j = 0; j < videoReps.length; j++) {
741+
if (videoReps[j].bitrateInKbit > highestVideo) {
742+
highestVideo = videoReps[j].bitrateInKbit;
743+
highestRes = videoReps[j].width + "x" + videoReps[j].height;
744+
}
745+
}
746+
document.getElementById("video_bitrate").innerHTML = videoTrack
747+
? videoTrack.bitrateInKbit + "kbits (max:" + highestVideo + "kbits)"
748+
: "no-video";
733749
document.getElementById("video_resolution").innerHTML =
734-
videoTrack.width + "x" + videoTrack.height + " (max:" + bestVideo.width + "x" + bestVideo.height + ")";
750+
videoTrack.width + "x" + videoTrack.height + (highestRes ? " (max:" + highestRes + ")" : "");
751+
752+
document.getElementById("live_latency").innerHTML = player.getCurrentLiveLatency() + "s";
753+
} else {
754+
document.getElementById("live_settings").innerHTML =
755+
"Low latency mode:" +
756+
settings.streaming.lowLatencyEnabled +
757+
" Delay:" +
758+
settings.streaming.liveDelay +
759+
"<br/>Min drift:" +
760+
settings.streaming.liveCatchUpMinDrift +
761+
" Catchup Rate:" +
762+
settings.streaming.liveCatchUpPlaybackRate;
763+
var audioTrack = player.getBitrateInfoListFor("audio")[player.getQualityFor("audio")];
764+
var videoTrack = player.getBitrateInfoListFor("video")[player.getQualityFor("video")];
765+
var bestAudio = player.getTopBitrateInfoFor("audio");
766+
var bestVideo = player.getTopBitrateInfoFor("video");
767+
if (audioTrack) {
768+
document.getElementById("audio_bitrate").innerHTML =
769+
audioTrack.bitrate / 1000 + "kbits (max:" + bestAudio.bitrate / 1000 + "kbits)";
770+
}
771+
if (videoTrack) {
772+
document.getElementById("video_bitrate").innerHTML =
773+
videoTrack.bitrate / 1000 + "kbits (max:" + bestVideo.bitrate / 1000 + "kbits)";
774+
document.getElementById("video_resolution").innerHTML =
775+
videoTrack.width + "x" + videoTrack.height + " (max:" + bestVideo.width + "x" + bestVideo.height + ")";
776+
}
777+
document.getElementById("live_latency").innerHTML = player.getCurrentLiveLatency() + "s";
735778
}
736-
document.getElementById("live_latency").innerHTML = player.getCurrentLiveLatency() + "s";
737779
} catch (e) {
738780
document.getElementById("audio_bitrate").innerHTML = "error";
739781
document.getElementById("video_bitrate").innerHTML = "error";

0 commit comments

Comments
 (0)