OLD | NEW |
1 <html> | 1 <html> |
2 <body onload="RunTest();"> | 2 <body onload="RunTest();"> |
3 <div id="player_container"></div> | 3 <div id="player_container"></div> |
| 4 <div id="logs"></div> |
4 </body> | 5 </body> |
5 | 6 |
6 <script type="text/javascript"> | 7 <script type="text/javascript"> |
7 // <audio> or <video> player element. | 8 // <audio> or <video> player element. |
8 var player; | 9 var player; |
| 10 var logs = document.getElementById('logs'); |
| 11 |
| 12 function Log(message) { |
| 13 logs.innerHTML = message + '<br>' + logs.innerHTML; |
| 14 console.log(message); |
| 15 } |
9 | 16 |
10 // Listen for |event| from |element|, set document.title = |event| upon event. | 17 // Listen for |event| from |element|, set document.title = |event| upon event. |
11 function InstallTitleEventHandler(element, event) { | 18 function InstallTitleEventHandler(element, event) { |
12 element.addEventListener(event, function(e) { | 19 element.addEventListener(event, function(e) { |
13 document.title = event.toUpperCase(); | 20 document.title = event.toUpperCase(); |
14 }, false); | 21 }, false); |
15 } | 22 } |
16 | 23 |
| 24 function InstallTitleErrorEventHandler(element, error_substr) { |
| 25 element.addEventListener('error', function(e) { |
| 26 // Element's error attribute must be populated. |
| 27 var mediaError = element.error; |
| 28 if (mediaError == null) { |
| 29 Log('ERROR: Null element error attribute while handling error event.'); |
| 30 Failed(); |
| 31 return; |
| 32 } |
| 33 |
| 34 Log('INFO: Element error message is ' + mediaError.message); |
| 35 |
| 36 if (error_substr != null && !mediaError.message.includes(error_substr)) { |
| 37 Log('ERROR: Element error message (' + mediaError.message + |
| 38 ') does not contain expected substring (' + error_substr + ')'); |
| 39 Failed(); |
| 40 return; |
| 41 } |
| 42 document.title = 'ERROR'; |
| 43 }, false); |
| 44 } |
| 45 |
17 function Failed() { | 46 function Failed() { |
18 document.title = 'FAILED'; | 47 document.title = 'FAILED'; |
19 return false; | 48 return false; |
20 } | 49 } |
21 | 50 |
22 function SeekTestStep(e) { | 51 function SeekTestStep(e) { |
23 player.removeEventListener('ended', SeekTestStep, false); | 52 player.removeEventListener('ended', SeekTestStep, false); |
24 | 53 |
25 // Test completes on the next ended event. | 54 // Test completes on the next ended event. |
26 InstallTitleEventHandler(player, 'ended'); | 55 InstallTitleEventHandler(player, 'ended'); |
27 | 56 |
28 player.currentTime = 0.9 * player.duration; | 57 player.currentTime = 0.9 * player.duration; |
29 player.play(); | 58 player.play(); |
30 } | 59 } |
31 | 60 |
32 function SeekTestTimeoutSetup() { | 61 function SeekTestTimeoutSetup() { |
33 if (player.currentTime < 2) | 62 if (player.currentTime < 2) |
34 return; | 63 return; |
35 | 64 |
36 player.removeEventListener('timeupdate', SeekTestTimeoutSetup, false); | 65 player.removeEventListener('timeupdate', SeekTestTimeoutSetup, false); |
37 SeekTestStep(); | 66 SeekTestStep(); |
38 } | 67 } |
39 | 68 |
40 // Uses URL query parameters to create an audio or video element using a given | 69 // Uses URL query parameters to create an audio or video element using a given |
41 // source. URL must be of the form: | 70 // source. URL must be of the form: |
42 // "player.html?[tag]=[media_url][&loop=[true/false]]". | 71 // "player.html?[tag]=[media_url][&loop=[true/false]][&error_substr=substr]". |
43 // | 72 // |
44 // Plays the media and waits for X seconds of playback or the ended event, at | 73 // Plays the media and waits for X seconds of playback or the ended event, at |
45 // which point the test seeks near the end of the file and resumes playback. | 74 // which point the test seeks near the end of the file and resumes playback. |
46 // Test completes when the second ended event occurs or an error event occurs at | 75 // Test completes when the second ended event occurs or an error event occurs at |
47 // any time. | 76 // any time. |
48 // There is an optional loop query parameter which when set to true, will cause | 77 // There is an optional loop query parameter, which when set to true will cause |
49 // the created media element to loop. | 78 // the created media element to loop. |
| 79 // There is an optional error_substr query parameter, which when set will cause |
| 80 // any error event handling to fail if the MediaError.message does not contain |
| 81 // the specified substring resulting from decodeURIComponent(). |
50 function RunTest() { | 82 function RunTest() { |
51 var url_parts = window.location.href.split('?'); | 83 var url_parts = window.location.href.split('?'); |
52 if (url_parts.length != 2) | 84 if (url_parts.length != 2) |
53 return Failed(); | 85 return Failed(); |
54 | 86 |
55 var tag = ''; | 87 var tag = ''; |
56 var media_url = ''; | 88 var media_url = ''; |
57 var loop = false; | 89 var loop = false; |
| 90 var error_substr = null; |
58 | 91 |
59 var query_params = url_parts[1].split('&'); | 92 var query_params = url_parts[1].split('&'); |
60 for (var query_param in query_params) { | 93 for (var query_param in query_params) { |
61 var query_parts = query_params[query_param].split('='); | 94 var query_parts = query_params[query_param].split('='); |
62 if (query_parts.length != 2) { | 95 if (query_parts.length != 2) { |
63 return Failed(); | 96 return Failed(); |
64 } | 97 } |
65 | 98 |
66 if (query_parts[0] == 'audio' || query_parts[0] == 'video') { | 99 if (query_parts[0] == 'audio' || query_parts[0] == 'video') { |
67 tag = query_parts[0]; | 100 tag = query_parts[0]; |
68 media_url = query_parts[1]; | 101 media_url = query_parts[1]; |
69 continue; | 102 continue; |
70 } | 103 } |
71 | 104 |
72 if (query_parts[0] == 'loop') { | 105 if (query_parts[0] == 'loop') { |
73 loop = (query_parts[1] == 'true'); | 106 loop = (query_parts[1] == 'true'); |
74 continue; | 107 continue; |
75 } | 108 } |
| 109 |
| 110 if (query_parts[0] == 'error_substr') { |
| 111 error_substr = decodeURIComponent(query_parts[1]); |
| 112 continue; |
| 113 } |
76 } | 114 } |
77 | 115 |
78 if (tag != 'audio' && tag != 'video') { | 116 if (tag != 'audio' && tag != 'video') { |
79 return Failed(); | 117 return Failed(); |
80 } | 118 } |
81 | 119 |
82 // Create player and insert into DOM. | 120 // Create player and insert into DOM. |
83 player = document.createElement(tag); | 121 player = document.createElement(tag); |
84 player.controls = true; | 122 player.controls = true; |
85 document.getElementById('player_container').appendChild(player); | 123 document.getElementById('player_container').appendChild(player); |
86 | 124 |
87 // We use loadeddata instead of loadedmetadata to ensure the decoder has | 125 // We use loadeddata instead of loadedmetadata to ensure the decoder has |
88 // completed initialization, even though we don't need to decode anything to | 126 // completed initialization, even though we don't need to decode anything to |
89 // get the size metadata. This is an unfortunate workaround for an Android | 127 // get the size metadata. This is an unfortunate workaround for an Android |
90 // framework bug (http://crbug.com/682387) where we have to avoid killing | 128 // framework bug (http://crbug.com/682387) where we have to avoid killing |
91 // the GPU process while the decoder is initializing. | 129 // the GPU process while the decoder is initializing. |
92 player.addEventListener('loadeddata', function(e) { | 130 player.addEventListener('loadeddata', function(e) { |
93 document.title = '' + player.videoWidth + ' ' + player.videoHeight; | 131 document.title = '' + player.videoWidth + ' ' + player.videoHeight; |
94 }); | 132 }); |
95 | 133 |
96 // Transition to the seek test after X seconds of playback or when the ended | 134 // Transition to the seek test after X seconds of playback or when the ended |
97 // event occurs, whichever happens first. | 135 // event occurs, whichever happens first. |
98 player.addEventListener('ended', SeekTestStep, false); | 136 player.addEventListener('ended', SeekTestStep, false); |
99 player.addEventListener('timeupdate', SeekTestTimeoutSetup, false); | 137 player.addEventListener('timeupdate', SeekTestTimeoutSetup, false); |
100 | 138 |
101 // Ensure we percolate up any error events. | 139 // Ensure we percolate up any error events, and optionally verify they contain |
102 InstallTitleEventHandler(player, 'error'); | 140 // the expected error substring in their message. |
| 141 InstallTitleErrorEventHandler(player, error_substr); |
103 | 142 |
104 // Starts the player. | 143 // Starts the player. |
105 player.loop = loop; | 144 player.loop = loop; |
106 player.src = media_url; | 145 player.src = media_url; |
107 player.play(); | 146 player.play(); |
108 } | 147 } |
109 </script> | 148 </script> |
110 </html> | 149 </html> |
OLD | NEW |