|
17 | 17 |
|
18 | 18 | <html> |
19 | 19 | <head> |
20 | | - <title>Chromecast WebDriver Receiver</title> |
21 | | - <script src="https://www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script> |
| 20 | + <title>Chromecast WebDriver Receiver v2</title> |
22 | 21 | <style> |
23 | 22 |
|
24 | 23 | html, body, iframe { |
|
37 | 36 | </style> |
38 | 37 | <script> |
39 | 38 |
|
40 | | -// Expose cast.__platform__ asynchronously through postMessage. |
41 | | -// Cannot be used to proxy synchronous calls, but could be used for debugging |
42 | | -// or with an async shim and `await` on all calls from the client. |
43 | | -window.addEventListener('message', (event) => { |
44 | | - const data = event.data; |
45 | | - console.log('Top window received message:', data); |
46 | | - |
47 | | - if (data.type == 'cast.__platform__') { |
48 | | - const platform = cast.__platform__; |
49 | | - const command = platform[data.command]; |
50 | | - |
51 | | - const args = data.args; |
52 | | - try { |
53 | | - const result = command.apply(platform, args); |
54 | | - |
55 | | - const message = { |
56 | | - id: data.id, |
57 | | - type: data.type + ':result', |
58 | | - result: result, |
59 | | - }; |
60 | | - |
61 | | - console.log('Top window sending result:', message); |
62 | | - event.source.postMessage(message, '*'); |
63 | | - } catch (error) { |
64 | | - console.log('Failed:', error); |
65 | | - |
66 | | - const message = { |
67 | | - id: data.id, |
68 | | - type: data.type + ':error', |
69 | | - error: error.message, |
70 | | - }; |
71 | | - |
72 | | - console.log('Top window sending error:', message); |
73 | | - event.source.postMessage(message, '*'); |
74 | | - } |
75 | | - } |
76 | | -}); |
77 | | - |
78 | 39 | window.addEventListener('DOMContentLoaded', () => { |
79 | | - // Ignore the leading '?'. The rest is the URL. |
80 | | - const frameUrl = (location.search + location.hash).substr(1); |
81 | | - |
82 | | - const statusText = 'URL: ' + frameUrl; |
83 | | - |
84 | | - const context = cast.framework.CastReceiverContext.getInstance(); |
85 | | - context.start({ |
86 | | - statusText, |
87 | | - disableIdleTimeout: true, |
88 | | - }); |
89 | | - |
90 | | - // Some features must be explicitly allowed for an iframe. |
91 | | - // These are needed for media-related testing. |
92 | | - // TODO: Make this list configurable. |
93 | | - // See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy |
94 | | - const allowedFeatures = [ |
95 | | - 'autoplay', |
96 | | - 'encrypted-media', |
97 | | - 'fullscreen', |
98 | | - 'picture-in-picture', |
99 | | - 'sync-xhr', |
100 | | - ]; |
| 40 | + // Arbitrary parameters encoded in JSON in the URL. |
| 41 | + let parameters; |
| 42 | + try { |
| 43 | + // Ignore the leading '?'. The rest is JSON data. |
| 44 | + parameters = JSON.parse(decodeURI(location.search.substr(1))); |
| 45 | + } catch (error) { |
| 46 | + document.body.style.textAlign = 'center'; |
| 47 | + document.body.style.fontSize = '5vw'; |
| 48 | + document.body.style.marginTop = '2em'; |
| 49 | + document.body.innerText = 'FAILED TO DECODE JSON PARAMETERS'; |
| 50 | + return; |
| 51 | + } |
101 | 52 |
|
102 | | - window.frame.allow = allowedFeatures.join('; '); |
103 | | - window.frame.src = frameUrl; |
| 53 | + if (parameters.redirect) { |
| 54 | + // The preferred method is to redirect, but this requires that the |
| 55 | + // destination URL runs CAF. If it doesn't, this receiver app will time |
| 56 | + // out and fail. This won't work for every URL, but will work for Shaka |
| 57 | + // Player testing (v4.9+). This gives a flat environment for testing, with |
| 58 | + // direct access to things like EME and cast.__platform__. |
| 59 | + location.href = parameters.url; |
| 60 | + } else { |
| 61 | + // For any other URL, we host the destination URL in an iframe and load CAF |
| 62 | + // in this frame. |
| 63 | + |
| 64 | + const script = document.createElement('script'); |
| 65 | + script.src = 'https://www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js'; |
| 66 | + script.onload = () => { |
| 67 | + const statusText = 'URL: ' + parameters.url; |
| 68 | + const context = cast.framework.CastReceiverContext.getInstance(); |
| 69 | + context.start({ |
| 70 | + statusText, |
| 71 | + disableIdleTimeout: true, |
| 72 | + }); |
| 73 | + }; |
| 74 | + document.head.appendChild(script); |
| 75 | + |
| 76 | + // Some features must be explicitly allowed for an iframe. |
| 77 | + // These are needed for media-related testing. |
| 78 | + // See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy |
| 79 | + const allowedFeatures = [ |
| 80 | + 'autoplay', |
| 81 | + 'encrypted-media', |
| 82 | + 'fullscreen', |
| 83 | + 'picture-in-picture', |
| 84 | + 'sync-xhr', |
| 85 | + ]; |
| 86 | + |
| 87 | + const iframe = document.createElement('iframe'); |
| 88 | + iframe.allow = allowedFeatures.join('; '); |
| 89 | + iframe.src = parameters.url; |
| 90 | + document.body.appendChild(iframe); |
| 91 | + } |
104 | 92 | }); |
105 | 93 |
|
106 | 94 | </script> |
107 | 95 | </head> |
108 | | - <body> |
109 | | - <iframe id="frame"></iframe> |
110 | | - </body> |
| 96 | + <body></body> |
111 | 97 | </html> |
0 commit comments