@@ -4,8 +4,6 @@ import * as React from 'react'
44import { WebView } from 'react-native'
55import type { PlayState , HtmlAudioError } from './types'
66
7- const kstoEmbed = 'https://www.stolaf.edu/multimedia/play/embed/ksto.html'
8-
97type Props = {
108 playState : PlayState ,
119 onWaiting ?: ( ) => any ,
@@ -15,6 +13,9 @@ type Props = {
1513 onPause ?: ( ) => any ,
1614 onError ?: HtmlAudioError => any ,
1715 style : any ,
16+ useEmbeddedPlayer : boolean ,
17+ embeddedPlayerUrl : string ,
18+ streamSourceUrl : string ,
1819}
1920
2021type HtmlAudioState =
@@ -99,98 +100,111 @@ export class StreamPlayer extends React.PureComponent<Props> {
99100
100101 setRef = ( ref : WebView ) => ( this . _webview = ref )
101102
102- js = `
103- function ready(fn) {
104- if (document.readyState !== 'loading') {
105- fn();
106- } else if (document.addEventListener) {
107- document.addEventListener('DOMContentLoaded', fn);
108- } else {
109- document.attachEvent('onreadystatechange', function () {
110- if (document.readyState !== 'loading') {
111- fn();
112- }
113- });
114- }
115- };
116-
117- ready(function () {
118- var player = document.querySelector('audio');
119-
120- /*******
121- *******/
122-
123- document.addEventListener('message', function (event) {
124- switch (event.data) {
125- case 'play':
126- player.muted = false;
127- player.play().catch(error);
128- break;
129-
130- case 'pause':
131- player.pause();
132- break;
133- }
134- });
135-
136- /*******
137- *******/
138-
139- function message(data) {
140- window.postMessage(JSON.stringify(data));
141- }
142-
143- function send(event) {
144- message({type: event.type});
145- }
146-
147- function error(event) {
148- message({
149- type: event.type,
150- error: 'error',
151- });
152- }
153-
154- /*******
155- *******/
156-
157- /* "waiting" is fired when playback has stopped because of a temporary
158- * lack of data. */
159- player.addEventListener('waiting', send);
160-
161- /* "ended" is fired when playback or streaming has stopped because the
162- * end of the media was reached or because no further data is
163- * available. */
164- player.addEventListener('ended', send);
165-
166- /* "stalled" is fired when the user agent is trying to fetch media data,
167- * but data is unexpectedly not forthcoming. */
168- player.addEventListener('stalled', send);
169-
170- /* "playing" is fired when playback is ready to start after having been
171- * paused or delayed due to lack of data. */
172- player.addEventListener('playing', send);
173-
174- /* "pause" is fired when playback has been paused. */
175- player.addEventListener('pause', send);
176-
177- /* "play" is fired when playback has begun. */
178- player.addEventListener('play', send);
179-
180- /* "error" is fired when an error occurs. */
181- player.addEventListener('error', error);
182- });
183- `
103+ html = ( url : string ) => `
104+ <style>body {background-color: white;}</style>
105+ <title>Radio Stream</title>
106+
107+ <audio id="player" webkit-playsinline playsinline>
108+ <source src="${ url } " />
109+ </audio>
110+ `
111+
112+ js = ( selector : string = 'audio' ) => `
113+ function ready(fn) {
114+ if (document.readyState !== 'loading') {
115+ fn();
116+ } else if (document.addEventListener) {
117+ document.addEventListener('DOMContentLoaded', fn);
118+ } else {
119+ document.attachEvent('onreadystatechange', function () {
120+ if (document.readyState !== 'loading') {
121+ fn();
122+ }
123+ });
124+ }
125+ };
126+
127+ ready(function () {
128+ var player = document.querySelector('${ selector } ');
129+
130+ /*******
131+ *******/
132+
133+ document.addEventListener('message', function (event) {
134+ switch (event.data) {
135+ case 'play':
136+ player.muted = false;
137+ player.play().catch(error);
138+ break;
139+
140+ case 'pause':
141+ player.pause();
142+ break;
143+ }
144+ });
145+
146+ /*******
147+ *******/
148+
149+ function message(data) {
150+ window.postMessage(JSON.stringify(data));
151+ }
152+
153+ function send(event) {
154+ message({type: event.type});
155+ }
156+
157+ function error(event) {
158+ message({
159+ type: event.type,
160+ error: 'error',
161+ });
162+ }
163+
164+ /*******
165+ *******/
166+
167+ /* "waiting" is fired when playback has stopped because of a temporary
168+ * lack of data. */
169+ player.addEventListener('waiting', send);
170+
171+ /* "ended" is fired when playback or streaming has stopped because the
172+ * end of the media was reached or because no further data is
173+ * available. */
174+ player.addEventListener('ended', send);
175+
176+ /* "stalled" is fired when the user agent is trying to fetch media data,
177+ * but data is unexpectedly not forthcoming. */
178+ player.addEventListener('stalled', send);
179+
180+ /* "playing" is fired when playback is ready to start after having been
181+ * paused or delayed due to lack of data. */
182+ player.addEventListener('playing', send);
183+
184+ /* "pause" is fired when playback has been paused. */
185+ player.addEventListener('pause', send);
186+
187+ /* "play" is fired when playback has begun. */
188+ player.addEventListener('play', send);
189+
190+ /* "error" is fired when an error occurs. */
191+ player.addEventListener('error', error);
192+ });
193+ `
184194
185195 render ( ) {
186196 return (
187197 < WebView
188198 ref = { this . setRef }
189199 allowsInlineMediaPlayback = { true }
190- injectedJavaScript = { this . js }
200+ injectedJavaScript = { this . js ( ) }
191201 mediaPlaybackRequiresUserAction = { false }
192202 onMessage = { this . handleMessage }
193- source = { { uri : kstoEmbed } }
203+ source = {
204+ this . props . useEmbeddedPlayer
205+ ? { uri : this . props . embeddedPlayerUrl }
206+ : { html : this . html ( this . props . streamSourceUrl ) }
207+ }
194208 style = { this . props . style }
195209 />
196210 )
0 commit comments