Count events on the stats page
Track player events and display counts on the stats page. Add a toggle to force Flash mode.
Showing
2 changed files
with
136 additions
and
69 deletions
... | @@ -45,6 +45,12 @@ | ... | @@ -45,6 +45,12 @@ |
45 | } | 45 | } |
46 | </style> | 46 | </style> |
47 | 47 | ||
48 | <script> | ||
49 | if (window.location.search === '?flash') { | ||
50 | videojs.options.techOrder = ['flash']; | ||
51 | } | ||
52 | </script> | ||
53 | |||
48 | </head> | 54 | </head> |
49 | <body> | 55 | <body> |
50 | <div class="info"> | 56 | <div class="info"> |
... | @@ -64,20 +70,35 @@ | ... | @@ -64,20 +70,35 @@ |
64 | type="application/x-mpegURL"> | 70 | type="application/x-mpegURL"> |
65 | </video> | 71 | </video> |
66 | <section class="stats"> | 72 | <section class="stats"> |
67 | <h2>Player Stats</h2> | 73 | <div class="player-stats"> |
68 | <dl> | 74 | <h2>Player Stats</h2> |
69 | <dt>Current Time:</dt> | 75 | <dl> |
70 | <dd class="current-time-stat">0</dd> | 76 | <dt>Current Time:</dt> |
71 | <dt>Buffered:</dt> | 77 | <dd class="current-time-stat">0</dd> |
72 | <dd class="buffered-stat">-</dd> | 78 | <dt>Buffered:</dt> |
73 | <dt>Seekable:</dt> | 79 | <dd class="buffered-stat">-</dd> |
74 | <dd><span class="seekable-start-stat">-</span> - <span class="seekable-end-stat">-</span></dd> | 80 | <dt>Seekable:</dt> |
75 | <dt>Video Bitrate:</dt> | 81 | <dd><span class="seekable-start-stat">-</span> - <span class="seekable-end-stat">-</span></dd> |
76 | <dd class="video-bitrate-stat">0 kbps</dd> | 82 | <dt>Video Bitrate:</dt> |
77 | <dt>Measured Bitrate:</dt> | 83 | <dd class="video-bitrate-stat">0 kbps</dd> |
78 | <dd class="measured-bitrate-stat">0 kbps</dd> | 84 | <dt>Measured Bitrate:</dt> |
79 | </dl> | 85 | <dd class="measured-bitrate-stat">0 kbps</dd> |
80 | <h3>Bitrate Switching</h3> | 86 | </dl> |
87 | </div> | ||
88 | <div class="event-counts"> | ||
89 | <h2>Event Counts</h2> | ||
90 | <dl> | ||
91 | <dt>Play:</dt> | ||
92 | <dd class="play-count">0</dd> | ||
93 | <dt>Playing:</dt> | ||
94 | <dd class="playing-count">0</dd> | ||
95 | <dt>Seeking:</dt> | ||
96 | <dd class="seeking-count">0</dd> | ||
97 | <dt>Seeked:</dt> | ||
98 | <dd class="seeked-count">0</dd> | ||
99 | </dl> | ||
100 | </div> | ||
101 | <h3 class="bitrate-switching">Bitrate Switching</h3> | ||
81 | <div class="switching-stats"> | 102 | <div class="switching-stats"> |
82 | Once the player begins loading, you'll see information about the | 103 | Once the player begins loading, you'll see information about the |
83 | operation of the adaptive quality switching here. | 104 | operation of the adaptive quality switching here. |
... | @@ -90,66 +111,96 @@ | ... | @@ -90,66 +111,96 @@ |
90 | <script> | 111 | <script> |
91 | videojs.options.flash.swf = '../../node_modules/videojs-swf/dist/video-js.swf'; | 112 | videojs.options.flash.swf = '../../node_modules/videojs-swf/dist/video-js.swf'; |
92 | // initialize the player | 113 | // initialize the player |
93 | var player = videojs('video'); | 114 | var player = videojs('video').ready(function() { |
94 | 115 | ||
95 | // ------------ | 116 | // ------------ |
96 | // Player Stats | 117 | // Player Stats |
97 | // ------------ | 118 | // ------------ |
98 | 119 | ||
99 | var currentTimeStat = document.querySelector('.current-time-stat'); | 120 | var currentTimeStat = document.querySelector('.current-time-stat'); |
100 | var bufferedStat = document.querySelector('.buffered-stat'); | 121 | var bufferedStat = document.querySelector('.buffered-stat'); |
101 | var seekableStartStat = document.querySelector('.seekable-start-stat'); | 122 | var seekableStartStat = document.querySelector('.seekable-start-stat'); |
102 | var seekableEndStat = document.querySelector('.seekable-end-stat'); | 123 | var seekableEndStat = document.querySelector('.seekable-end-stat'); |
103 | var videoBitrateState = document.querySelector('.video-bitrate-stat'); | 124 | var videoBitrateState = document.querySelector('.video-bitrate-stat'); |
104 | var measuredBitrateStat = document.querySelector('.measured-bitrate-stat'); | 125 | var measuredBitrateStat = document.querySelector('.measured-bitrate-stat'); |
105 | 126 | ||
106 | player.on('timeupdate', function() { | 127 | player.on('timeupdate', function() { |
107 | currentTimeStat.textContent = player.currentTime().toFixed(1); | 128 | currentTimeStat.textContent = player.currentTime().toFixed(1); |
108 | }); | 129 | }); |
130 | |||
131 | window.setInterval(function() { | ||
132 | var bufferedText = '', oldStart, oldEnd, i; | ||
133 | |||
134 | // buffered | ||
135 | var buffered = player.buffered(); | ||
136 | if (buffered.length) { | ||
137 | bufferedText += buffered.start(0) + ' - ' + buffered.end(0); | ||
138 | } | ||
139 | for (i = 1; i < buffered.length; i++) { | ||
140 | bufferedText += ', ' + buffered.start(i) + ' - ' + buffered.end(i); | ||
141 | } | ||
142 | bufferedStat.textContent = bufferedText; | ||
143 | |||
144 | // seekable | ||
145 | var seekable = player.seekable(); | ||
146 | if (seekable && seekable.length) { | ||
147 | |||
148 | oldStart = seekableStartStat.textContent; | ||
149 | if (seekable.start(0).toFixed(1) !== oldStart) { | ||
150 | seekableStartStat.textContent = seekable.start(0).toFixed(1); | ||
151 | } | ||
152 | oldEnd = seekableEndStat.textContent; | ||
153 | if (seekable.end(0).toFixed(1) !== oldEnd) { | ||
154 | seekableEndStat.textContent = seekable.end(0).toFixed(1); | ||
155 | } | ||
156 | } | ||
109 | 157 | ||
110 | player.on('progress', function() { | 158 | // bitrates |
111 | var bufferedText = '', oldStart, oldEnd, i; | 159 | var playlist = player.tech_.hls.playlists.media(); |
112 | 160 | if (playlist && playlist.attributes && playlist.attributes.BANDWIDTH) { | |
113 | // buffered | 161 | videoBitrateState.textContent = (playlist.attributes.BANDWIDTH / 1024).toLocaleString(undefined, { |
114 | var buffered = player.buffered(); | 162 | maximumFractionDigits: 1 |
115 | if (buffered.length) { | 163 | }) + ' kbps'; |
116 | bufferedText += buffered.start(0) + ' - ' + buffered.end(0); | ||
117 | } | ||
118 | for (i = 1; i < buffered.length; i++) { | ||
119 | bufferedText += ', ' + buffered.start(i) + ' - ' + buffered.end(i); | ||
120 | } | ||
121 | bufferedStat.textContent = bufferedText; | ||
122 | |||
123 | // seekable | ||
124 | var seekable = player.seekable(); | ||
125 | if (seekable && seekable.length) { | ||
126 | |||
127 | oldStart = seekableStartStat.textContent; | ||
128 | if (seekable.start(0).toFixed(1) !== oldStart) { | ||
129 | seekableStartStat.textContent = seekable.start(0).toFixed(1); | ||
130 | } | 164 | } |
131 | oldEnd = seekableEndStat.textContent; | 165 | if (player.tech_.hls.bandwidth) { |
132 | if (seekable.end(0).toFixed(1) !== oldEnd) { | 166 | measuredBitrateStat.textContent = (player.tech_.hls.bandwidth / 1024).toLocaleString(undefined, { |
133 | seekableEndStat.textContent = seekable.end(0).toFixed(1); | 167 | maximumFractionDigits: 1 |
168 | }) + ' kbps'; | ||
134 | } | 169 | } |
135 | } | 170 | }, 1000); |
136 | 171 | ||
137 | // bitrates | 172 | var trackEventCount = function(eventName, selector) { |
138 | var playlist = player.tech_.hls.playlists.media(); | 173 | var count = 0, element = document.querySelector(selector); |
139 | if (playlist && playlist.attributes && playlist.attributes.BANDWIDTH) { | 174 | player.on(eventName, function() { |
140 | videoBitrateState.textContent = (playlist.attributes.BANDWIDTH / 1024).toLocaleString(undefined, { | 175 | count++; |
141 | maximumFractionDigits: 1 | 176 | element.innerHTML = count; |
142 | }) + ' kbps'; | 177 | }); |
143 | } | 178 | }; |
144 | if (player.tech_.hls.bandwidth) { | 179 | trackEventCount('play', '.play-count'); |
145 | measuredBitrateStat.textContent = (player.tech_.hls.bandwidth / 1024).toLocaleString(undefined, { | 180 | trackEventCount('playing', '.playing-count'); |
146 | maximumFractionDigits: 1 | 181 | trackEventCount('seeking', '.seeking-count'); |
147 | }) + ' kbps'; | 182 | trackEventCount('seeked', '.seeked-count'); |
148 | } | 183 | |
184 | videojs.Hls.displayStats(document.querySelector('.switching-stats'), player); | ||
185 | videojs.Hls.displayCues(document.querySelector('.segment-timeline'), player); | ||
149 | }); | 186 | }); |
150 | 187 | ||
151 | videojs.Hls.displayStats(document.querySelector('.switching-stats'), player); | 188 | // ----------- |
152 | videojs.Hls.displayCues(document.querySelector('.segment-timeline'), player); | 189 | // Tech Switch |
190 | // ----------- | ||
191 | |||
192 | var techSwitch = document.createElement('a'); | ||
193 | techSwitch.className = 'tech-switch'; | ||
194 | if (player.el().querySelector('video')) { | ||
195 | techSwitch.href = window.location.origin + window.location.pathname + '?flash'; | ||
196 | techSwitch.appendChild(document.createTextNode('Switch to the Flash tech')); | ||
197 | } else { | ||
198 | techSwitch.href = window.location.origin + window.location.pathname; | ||
199 | techSwitch.appendChild(document.createTextNode('Stop forcing Flash')); | ||
200 | } | ||
201 | |||
202 | document.body.insertBefore(techSwitch, document.querySelector('.stats')); | ||
203 | |||
153 | </script> | 204 | </script> |
154 | </body> | 205 | </body> |
155 | </html> | 206 | </html> | ... | ... |
1 | .tech-switch { | ||
2 | padding: 8px 0 0; | ||
3 | display: block; | ||
4 | } | ||
5 | |||
6 | .player-stats, .event-counts { | ||
7 | box-sizing: border-box; | ||
8 | padding: 8px; | ||
9 | float: left; | ||
10 | width: 50%; | ||
11 | } | ||
12 | |||
13 | h3.bitrate-switching { | ||
14 | clear: both; | ||
15 | } | ||
16 | |||
1 | .axis text, | 17 | .axis text, |
2 | .cue text { | 18 | .cue text { |
3 | font: 12px sans-serif; | 19 | font: 12px sans-serif; | ... | ... |
-
Please register or sign in to post a comment