| <html> |
| <body onload="RunTest();"> |
| <div id="player_container"></div> |
| <div id="logs"></div> |
| </body> |
| |
| <script type="text/javascript"> |
| // <audio> or <video> player element. |
| var player; |
| var logs = document.getElementById('logs'); |
| |
| function Log(message) { |
| logs.innerHTML = message + '<br>' + logs.innerHTML; |
| console.log(message); |
| } |
| |
| // Listen for |event| from |element|, set document.title = |event| upon event. |
| function InstallTitleEventHandler(element, event) { |
| element.addEventListener(event, function(e) { |
| document.title = event.toUpperCase(); |
| }, false); |
| } |
| |
| function InstallTitleErrorEventHandler(element, error_substr) { |
| element.addEventListener('error', function(e) { |
| // Element's error attribute must be populated. |
| var mediaError = element.error; |
| if (mediaError == null) { |
| Log('ERROR: Null element error attribute while handling error event.'); |
| Failed(); |
| return; |
| } |
| |
| Log('INFO: Element error message is ' + mediaError.message); |
| |
| if (error_substr != null && !mediaError.message.includes(error_substr)) { |
| Log('ERROR: Element error message (' + mediaError.message + |
| ') does not contain expected substring (' + error_substr + ')'); |
| Failed(); |
| return; |
| } |
| document.title = 'ERROR'; |
| }, false); |
| } |
| |
| function Failed() { |
| document.title = 'FAILED'; |
| return false; |
| } |
| |
| function SeekTestStep(e) { |
| player.removeEventListener('ended', SeekTestStep, false); |
| |
| // Test completes on the next ended event. |
| InstallTitleEventHandler(player, 'ended'); |
| |
| player.currentTime = 0.9 * player.duration; |
| player.play(); |
| } |
| |
| function SeekTestTimeoutSetup() { |
| if (player.currentTime < 2) |
| return; |
| |
| player.removeEventListener('timeupdate', SeekTestTimeoutSetup, false); |
| SeekTestStep(); |
| } |
| |
| // Uses URL query parameters to create an audio or video element using a given |
| // source. URL must be of the form: |
| // "player.html?[tag]=[media_url][&loop=[true/false]][&error_substr=substr]". |
| // |
| // Plays the media and waits for X seconds of playback or the ended event, at |
| // which point the test seeks near the end of the file and resumes playback. |
| // Test completes when the second ended event occurs or an error event occurs at |
| // any time. |
| // There is an optional loop query parameter, which when set to true will cause |
| // the created media element to loop. |
| // There is an optional error_substr query parameter, which when set will cause |
| // any error event handling to fail if the MediaError.message does not contain |
| // the specified substring resulting from decodeURIComponent(). |
| function RunTest() { |
| var url_parts = window.location.href.split('?'); |
| if (url_parts.length != 2) |
| return Failed(); |
| |
| var tag = ''; |
| var media_url = ''; |
| var loop = false; |
| var error_substr = null; |
| |
| var query_params = url_parts[1].split('&'); |
| for (var query_param in query_params) { |
| var query_parts = query_params[query_param].split('='); |
| if (query_parts.length != 2) { |
| return Failed(); |
| } |
| |
| if (query_parts[0] == 'audio' || query_parts[0] == 'video') { |
| tag = query_parts[0]; |
| media_url = query_parts[1]; |
| continue; |
| } |
| |
| if (query_parts[0] == 'loop') { |
| loop = (query_parts[1] == 'true'); |
| continue; |
| } |
| |
| if (query_parts[0] == 'error_substr') { |
| error_substr = decodeURIComponent(query_parts[1]); |
| continue; |
| } |
| } |
| |
| if (tag != 'audio' && tag != 'video') { |
| return Failed(); |
| } |
| |
| // Create player and insert into DOM. |
| player = document.createElement(tag); |
| player.controls = true; |
| document.getElementById('player_container').appendChild(player); |
| |
| // We use loadeddata instead of loadedmetadata to ensure the decoder has |
| // completed initialization, even though we don't need to decode anything to |
| // get the size metadata. This is an unfortunate workaround for an Android |
| // framework bug (http://crbug.com/682387) where we have to avoid killing |
| // the GPU process while the decoder is initializing. |
| player.addEventListener('loadeddata', function(e) { |
| document.title = '' + player.videoWidth + ' ' + player.videoHeight; |
| }); |
| |
| // Transition to the seek test after X seconds of playback or when the ended |
| // event occurs, whichever happens first. |
| player.addEventListener('ended', SeekTestStep, false); |
| player.addEventListener('timeupdate', SeekTestTimeoutSetup, false); |
| |
| // Ensure we percolate up any error events, and optionally verify they contain |
| // the expected error substring in their message. |
| InstallTitleErrorEventHandler(player, error_substr); |
| |
| // Starts the player. |
| player.loop = loop; |
| player.src = media_url; |
| player.play(); |
| } |
| </script> |
| </html> |