You are not logged in.

Dear visitor, welcome to krpano.com Forum. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

Douglas Rhiner

Intermediate

  • "Douglas Rhiner" started this thread

Posts: 141

Location: San Anselmo, CA

Occupation: Code-Slave

  • Send private message

1

Monday, July 18th 2022, 8:19pm

HLS, DASH and the VBRs conundrum

In the interest of giving back to this community from which I have learned sooo much, anyone interested in diving into the rabbit-hell-hole called VBRs delivery and seeing how we do it read on…

The “issue” with VBRs natively in KRPano is they don’t work, except for HLS/Apple devices.
DASH, what every other major browser uses for VBRs delivery uses requires a bridge to get it to work.
That is where dash.js comes in.

First, load dash.js
<script type="text/javascript" src="/node_modules/dashjs/dist/dash.all.min.js"></script>

Second, create the following function. The URL is the path to a dash.mpd file. It logs a few parameters so you know what's going on.
function initDash(url){
console.log('initDash...JS ' + url);
let video = krpano.get("plugin[video]”).videoDOM;
const player = dashjs.MediaPlayer().create();
player.updateSettings({
streaming: {
buffer: {
fastSwitchEnabled: true
},
abr: {
initialBitrate: { audio: -1, video: 10000 }
}
}
});

player.initialize(video, url, true);
player.on(dashjs.MediaPlayer.events["PLAYBACK_ENDED"], function () {
clearInterval(eventPoller);
clearInterval(bitrateCalculator);
});
var eventPoller = setTimeout(function () {
var streamInfo = player.getActiveStream().getStreamInfo();
var dashMetrics = player.getDashMetrics();
var dashAdapter = player.getDashAdapter();
if (dashMetrics && streamInfo) {
const periodIdx = streamInfo.index;
var repSwitch = dashMetrics.getCurrentRepresentationSwitch('video', true);
var bitrate = repSwitch ? Math.round(dashAdapter.getBandwidthForRepresentation(repSwitch.to, periodIdx) / 1000) : NaN;
console.log(bitrate + " Kbps interval");
}
}, 1000);
if (video.webkitVideoDecodedByteCount !== undefined) {
var lastDecodedByteCount = 0;
const bitrateInterval = 5;
var bitrateCalculator = setTimeout(function () {
var calculatedBitrate = (((video.webkitVideoDecodedByteCount - lastDecodedByteCount) / 1000) * 8) / bitrateInterval;
console.log( Math.round(calculatedBitrate) + " Kbps webkitVideoDecodedByteCount");
lastDecodedByteCount = video.webkitVideoDecodedByteCount;
}, bitrateInterval * 1000);
} else {
console.log('video.webkitVideoDecodedByteCount IS UNDEFINED !!!!!! ');
}
}

Third, create the initDash action.
<action name="initDash">
trace('initDash...action ', %1);
jscall('initDash("%1")')
</action>

Fourth, for the plugin referenced in initDash():
videourl.safari="<?php echo $base_path; ?>/HLS/master.m3u8"
videourl.chrome="<?php echo $base_path; ?>/DASH/dash.mpd"
videourl.edge="<?php echo $base_path; ?>/DASH/dash.mpd"
videourl.firefox="<?php echo $base_path; ?>/DASH/dash.mpd"
onloaded.chrome="initDash('<?php echo $base_path; ?>/DASH/dash.mpd')"
onloaded.edge="initDash('<?php echo $base_path; ?>/DASH/dash.mpd')"
onloaded.firefox="initDash('<?php echo $base_path; ?>/DASH/dash.mpd')"


That is the easy part. Creating the DASH "package" with all of the chunks and reference files is the complicated one. It takes time and computational resources.
We use FFMPEG on a custom built processing machine. I'm bound by NDA so I really can't let the cat completely out of the bag about how we pull this off.
However, here are some links that will get you headed in the right direction.
https://blog.zazu.berlin/internet-progra…ith-ffmpeg.html
https://knowledge.kaltura.com/help/best-…ng-2018-edition
https://docs.accurate.video/guides/encod…-dash-delivery/
https://ffmpeg.org/ffmpeg-formats.html

And here is an example of this in-action:
https://preview.xplorit.com/visit-centra…rifuge-overlook
Spin around and click "The Cellar" in any browser.
For Safari, you'd see *.ts and for everything else *.m4s files showing up in the Network tab of developer-tools

This post has been edited 1 times, last edit by "Douglas Rhiner" (Jul 18th 2022, 9:11pm)


Tuur

Sage

Posts: 3,824

Location: Netherlands

Occupation: Krpano custom coding / Virtual Tours / Photography / Musician / Recording engineer

  • Send private message

2

Monday, July 18th 2022, 10:32pm

Hi Douglas,

thanks for sharing!
Interesting stuff.
Never really tried something like this though.
Sad that it is such a pain in the a** to do some video streaming.

Tuur *thumbsup*

Douglas Rhiner

Intermediate

  • "Douglas Rhiner" started this thread

Posts: 141

Location: San Anselmo, CA

Occupation: Code-Slave

  • Send private message

3

Monday, July 18th 2022, 10:51pm

Tuur,

It truly is a PITA and I've turned this into a science-fair experiment. But the results are well worth it.
It does help if you have an NVIDIA GPU. You can leverage hardware decoding/encoding in the FFMEPEG commands which does speed things up DRASTICALLY. Our weak link in the system is upload speeds to s3.