diff --git a/integrationExamples/videoModule/eventsUI/eventsUI.css b/integrationExamples/videoModule/eventsUI/eventsUI.css new file mode 100644 index 00000000000..ccfe17ca4c6 --- /dev/null +++ b/integrationExamples/videoModule/eventsUI/eventsUI.css @@ -0,0 +1,205 @@ +html { + width: 100%; +} +body { + background: #ccc; + margin: 20px 5px; + font: 42px/60px Helvetica, Arial, sans-serif; + min-width: 320px; + max-width: 1920px; +} +#player:first-child { + width: 100%; +} + +#player { + margin: auto; + background: rgba(0, 0, 20, 0.8); +} +#eventsLog.group-player-disabled .group-player, +#eventsLog.group-media-disabled .group-media, +#eventsLog.group-ads-disabled .group-ads, +#eventsLog.group-auction-disabled .group-auction, +#eventsLog.group-adRequest-disabled .group-adRequest, +#eventsLog.group-adBreak-disabled .group-adBreak, +#eventsLog.group-related-disabled .group-related, +#eventsLog.group-ping-disabled .group-ping, +#eventsLog.group-unknown-disabled .group-unknown, +#eventsLog.group-quickPeek-disabled .group-quickPeek, +#eventsLog.group-provider-disabled .group-provider, +#eventsLog.group-video-disabled .group-video { + display: none; +} +.input-field { + padding: 0 0.25em; + margin: 0 0 0 4px; + border: 0; + background-color: #232323; + color: #F8F8F8; +} +.input-field:invalid { + text-decoration: underline; + text-decoration-color: red; +} +#eventsLog .sequence > .pre.filter-not-matched { + display: none; + opacity: 0.2; +} +a.button { + -webkit-appearance: button; + cursor: pointer; + margin: 2px; + background: #ccc; + border-color: rgb(216, 216, 216) rgb(209, 209, 209) rgb(186, 186, 186); + border-style: solid; + border-width: 1px; + padding: 1px 7px 2px; + color: inherit; + text-decoration: inherit; + user-select: none; +} +.right { + float: right; +} +.disabled { + opacity: 0.5; +} +.nav.disabled { + user-select: none; + cursor: default; +} +.block { + margin: 5px; + background-color: #eee; +} +div.mode-player { + background: #acc; +} +div.mode-ads { + background: #fea; +} +div.sequence { + display: block; +} +.group-player { + background: #acc; +} +.group-media { + background: #fa6; +} +.group-ads { + background: #fcc; +} +.group-auction { + background: #228; + color: #eee; +} +pre { + margin: 0; +} +div.toggle-block pre { + margin: 1px 3px; +} +.events-block { + min-height: 1440px; +} +.events-block .pre, +.toggle-block pre { + display: inline-block; + padding: 0 5px; + margin: 1px 3px 1px 20px; + border-radius: 5px; + font-family: monospace; + white-space: pre; +} +.pre.group-ads, +.pre.group-media, +.pre.group-player, +.pre.group-auction, +.pre.event-ready { + display: inline-block; + padding: 0 5px; + margin: 1px 3px 1px 20px; + border-radius: 5px; + font-family: monospace; + white-space: pre; +} + +.list-events.events-block .pre.group-player, +.list-events.events-block .pre.group-media, +.list-events.events-block .pre.group-ads, +.list-events.events-block .pre.group-auction { + display: block; + margin: 0; + padding: 1px 10px; + border-radius: 0; +} + +.pre.event-playlistItem { + margin: 1px 3px 1px 10px; +} +.pre.event-adBreakStart, +.pre.event-adBreakEnd { + margin: 1px 3px 1px 20px; +} +.pre.event-adBreakStart, +.pre.event-ready, +.pre.event-adImpression, +.pre.event-adError, +.pre.event-adWarning { + font-weight: 800; +} +.pre pre { + display: inline; + margin: 0 0 0 20px; +} +.toggle { + cursor: pointer; + user-select: none; +} +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; +} +button { + overflow: visible; + padding: 1px 7px 2px; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; + margin: 2px; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} + +@media only screen and (min-device-width : 320px) and (max-device-width : 768px) { + body { + font-size: 2vw; + line-height: 3vw; + } +} diff --git a/integrationExamples/videoModule/eventsUI/eventsUI.js b/integrationExamples/videoModule/eventsUI/eventsUI.js new file mode 100644 index 00000000000..618a4774765 --- /dev/null +++ b/integrationExamples/videoModule/eventsUI/eventsUI.js @@ -0,0 +1,181 @@ +"use strict"; + +let sequenceCount = 0; +const eventLogGroups = {}; +const Uint8Array = window.Uint8Array; +const TimeRanges = window.TimeRanges; + +function stringify(value, replacer, space) { + try { + return truncate(JSON.stringify(value, replacer || stringifyReplacer(value), space), 100000); + } catch (error) { + return `[${error}]`; + } +} + +function truncate(str, length) { + return (str && str.length) > length ? (str.substr(0, length) + + '\n... Event truncated due to length (see console for complete output)') : str; +} + +function stringifyReplacer(parentValue) { + const references = []; + const safeResults = []; + let complexity = 0; + return function stringifyKeyValue(key, value) { + if (typeof value === 'object') { + if (value === null || value instanceof Date || value instanceof RegExp) { + return value; + } + if (!!Uint8Array && value instanceof Uint8Array) { + // Stub values of Arrays with more than 1000 items + let str = ('' + value); + str = (str.length > 40 ? (str.substr(0, 40) + '...(see console)') : str); + return `Uint8Array(${value.length}) [${str}]`; + } + if (!!TimeRanges && value instanceof TimeRanges) { + const ranges = []; + for (let i = 0; i < value.length; i++) { + ranges[i] = `start(${i}) = ${value.start(i)} end(${i}) = ${value.end(i)}`; + } + return `TimeRanges(${value.length}) [${ranges}]`; + } + if (value === parentValue && complexity > 0) { + return ''; + } + const referenceIndex = references.indexOf(value); + if (referenceIndex !== -1) { + // Duplicate reference found + const safe = safeResults[referenceIndex]; + if (safe) { + return safe; + } + try { + // Test for circular references + JSON.stringify(value); + } catch (error) { + return (safeResults[referenceIndex] = '<' + value + '...(see console)>'); + } + safeResults[referenceIndex] = value; + } + if (complexity++ > 10000) { + return ''; + } + references.push(value); + return value; + } + if (typeof value === 'function') { + return `${value}`; + } + return value; + }; +} + +function createEventSequenceElement(eventGroup) { + const element = document.createElement('div'); + element.classList.add('sequence', `mode-${eventGroup}`); + element.setAttribute('data-sequence', `${sequenceCount++}`); + return element; +} + +function appendSequenceElement(container, element) { + container.appendChild(element); +} + +function textContentGrouped(inEvent, group) { + if (group) { + return `${inEvent} (${group[inEvent]})`; + } + return inEvent; +} + +function appendEvent(container, currentEventType, currentEventGroup, data) { + const div = document.createElement('div'); + div.classList.add('group-' + currentEventGroup, 'event-' + currentEventType, 'pre'); + div.textContent = textContentGrouped(currentEventType); + div.setAttribute('title', `${currentEventGroup} event "${currentEventType}"`); + div.setAttribute('tabindex', '0'); + const theData = Object.assign({}, data); + div.onclick = div.onkeyup = function(e) { + if (e && e.keyCode && e.keyCode !== 13) { + return; + } + + console.log(theData); + div.textContent = ((div.expanded = !div.expanded)) ? + textContentExpanded(currentEventType, [theData]) : textContentGrouped(currentEventType); + if (e) { + e.preventDefault(); + } + return [theData]; + }; + container.appendChild(div); + return div; +} + +function textContentExpanded(inEvent, allData) { + return `${inEvent} (${allData.map((item, i) => + (allData.length > 1 ? `[${i}] = ` : '') + stringify(item, null, 4)).join('\n')})`; +} + +function incrementEvent(group, currentEventType, currentEventGroup, div, datum) { + group[currentEventType]++; + div.textContent = textContentGrouped(currentEventType, group); + const logPreviousEvents = div.onclick; + const scopedDatum = Object.assign({}, datum); + div.onclick = div.onkeyup = function(e) { + if (e && e.keyCode && e.keyCode !== 13) { + return; + } + + const allData = logPreviousEvents(); + allData.push(scopedDatum); + console.log(scopedDatum); + div.textContent = (div.expanded) ? textContentExpanded(currentEventType, allData) : textContentGrouped(currentEventType, group); + if (e) { + e.preventDefault(); + } + return allData; + }; +} + +function getGenericEventHandler() { + const logContainer = document.querySelector('#eventsLog'); + let currentEventGroup = ''; + let currentEventType = ''; + let lastEvent = ''; + let lastGroup; + const genericEventHandler = function(e, type, eventGroup) { + currentEventGroup = eventGroup; + currentEventType = type; + + let group = eventLogGroups[eventGroup]; + if (!group || group !== lastGroup) { + const beforeReadyElement = createEventSequenceElement(currentEventGroup); + appendSequenceElement(logContainer, beforeReadyElement); + group = eventLogGroups[currentEventGroup] = { + eventGroup: currentEventGroup, + event: currentEventType, + container: logContainer, + eventElement: beforeReadyElement + }; + lastGroup = lastGroup || group; + } + if (lastEvent === currentEventType && !(/^(?:meta|hlsBufferAppend)/).test(currentEventType)) { + incrementEvent(group, currentEventType, currentEventGroup, group.pre, e); + } else { + const eventElement = createEventSequenceElement(currentEventGroup); + group[currentEventType] = 1; + group.eventElement = eventElement; + group.lastEventGroup = currentEventGroup; + group.pre = appendEvent(eventElement, currentEventType, currentEventGroup, e); + appendSequenceElement(group.container, eventElement); + } + lastEvent = currentEventType; + lastGroup = group; + }; + + return genericEventHandler; +} + +window.getGenericEventHandler = getGenericEventHandler; diff --git a/integrationExamples/videoModule/jwplayer/eventsUI.html b/integrationExamples/videoModule/jwplayer/eventsUI.html new file mode 100644 index 00000000000..69ace5f6c2b --- /dev/null +++ b/integrationExamples/videoModule/jwplayer/eventsUI.html @@ -0,0 +1,295 @@ + + + + + + + + + JW Player Event UI + + + + + + + +
+
+
+ +
+ + + + diff --git a/integrationExamples/videoModule/videojs/eventsUI.html b/integrationExamples/videoModule/videojs/eventsUI.html new file mode 100644 index 00000000000..04e0ca9eaf8 --- /dev/null +++ b/integrationExamples/videoModule/videojs/eventsUI.html @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + Video.JS Event UI + + + + + + + +
+ + +
+ +
+ + + +