Reputation: 82048
I am trying to get HLS video to work with videojs
and Google mid-roll ads. Fortunately, I can get the video mid-roll working. Unfortunately, I don't get the ad started or ad ended events.
Below is a combination of the videojs-http-streaming
example and the Google DAI example.
This is the markup I'm using.
<script type="text/javascript" src="//imasdk.googleapis.com/js/sdkloader/ima3_dai.js"></script>
<link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
<video-js id="my_video_1" class="vjs-default-skin"
muted controls preload="auto" width="640" height="268">
</video-js>
<div id="click"></div>
<script src="https://unpkg.com/video.js/dist/video.js"></script>
<script src="https://unpkg.com/@videojs/http-streaming/dist/videojs-http-streaming.js"></script>
And this is the script:
var player = videojs('my_video_1');
var TEST_ASSET_KEY = "sN_IYUG8STe1ZzhIIE_ksA";
var videoElement = document.getElementsByTagName('video')[0];
var streamManager = new google.ima.dai.api.StreamManager(videoElement);
var clickElement = document.getElementById('click');
streamManager.setClickElement(clickElement);
streamManager.addEventListener([
google.ima.dai.api.StreamEvent.Type.LOADED,
google.ima.dai.api.StreamEvent.Type.ERROR,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED
], function(t){console.log(t);
if(t.type == 'loaded') {
player.src(t.getStreamData().url);
player.play();
}
}, false);
var streamRequest = new google.ima.dai.api.LiveStreamRequest();
streamRequest.assetKey = TEST_ASSET_KEY;
streamRequest.apiKey = '';
streamManager.requestStream(streamRequest);
I expect the console to output:
{type: "loaded", ...
{type: "adBreakStarted", ...
but all I see is the {type: "loaded",
event.
How do I get all of the events to show up?
Upvotes: 0
Views: 1031
Reputation: 82048
Credit where credit is due. I figured this out thanks to this repository.
So, in order for Google to produce the expected events, it needs to be informed of the status of the video metadata. Specifically, it needs access to the ID3 tag from the video stream.
Unfortunately, it doesn't have a way to get this with the native HTMLVideoElement
. Instead, it needs to be informed of the information. In the case of jwplayer
and hls.js
it's simple (see below for the examples), but in the case of videojs
it's a little less straightforward. You need to listen to the metadata track.
// I placed this right above player.src(t.getStreamData().url); above
// basically, you're looking at all of the tracks as they're added
player.textTracks().on('addtrack', function (e) {
// find out if the new track is metadata
var track = e.track;
if (track.kind === 'metadata') {
// a cuechange event fires when the player crosses over an ID3 tag
track.on('cuechange', function () {
let elemTrack = track.activeCues[0];
if (elemTrack && elemTrack.value.data) {
var metadata = {};
metadata[elemTrack.value.key] = elemTrack.value.data;
metadata["duration"] = Infinity;
streamManager.onTimedMetadata(metadata);
}
});
}
});
If you are using JWPlayer, it's a little simpler:
jwplayer().on('meta', function(e) {
if (streamManager && e.metadata) {
streamManager.onTimedMetadata(e.metadata);
}
});
And hls.js
is also pretty basic
hls.on("hlsFragParsingMetadata",
function(event, data) {
if (streamManager && data) {
data.samples.forEach(function(sample) {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
}
);
Upvotes: 3