Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions iframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,20 @@
} = JSON.parse(UrlQueryData);

function sendMessageToRN(msg) {
window.ReactNativeWebView.postMessage(JSON.stringify(msg));

if (window.ReactNativeWebView) {
// React Native WebView
window.ReactNativeWebView.postMessage(JSON.stringify(msg));
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: An interesting quirk is that adding targetOrigin here will break Android native.

} else if (window.parent) {
// This is from expo web iframe.
//
// We set cross origin to so that this will work on differnet origin.
// We don't expect any sensitive data to be sent.
window.parent.postMessage(JSON.stringify(msg), '*');
} else {
console.error('Not running in Iframe, cannot postMessage.');
return;
}
}

let metaString = '';
Expand Down Expand Up @@ -147,6 +160,8 @@
document.addEventListener('mozfullscreenchange', onFullScreenChange);
document.addEventListener('webkitfullscreenchange', onFullScreenChange);

// NOTE: the 3rd parameter is needed for Android Webview.
// https://github.com/react-native-webview/react-native-webview/issues/356
window.addEventListener('message', function (event) {
const {data} = event;

Expand Down Expand Up @@ -182,7 +197,7 @@
} catch (error) {
console.error('Error parsing data', event, error);
}
});
}, true);
</script>
</body>
</html>
13 changes: 12 additions & 1 deletion src/YoutubeIframe.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ const YoutubeIframe = (props, ref) => {
}

const message = JSON.stringify({eventName, meta});
webViewRef.current.postMessage(message);

// NOTE: we set cross origin to so that this will work for webView for
// website hosted across different origin.
webViewRef.current.postMessage(message, '*');
},
[playerReady],
);
Expand Down Expand Up @@ -193,6 +196,14 @@ const YoutubeIframe = (props, ref) => {
break;
case 'playerStateChange':
onChangeState(PLAYER_STATES[message.data]);
if (message.data === -1) {
// unstartred state is -1
// We will not normally "change" to this state, but it can happen
// if autoplay is not supported.
console.warn(
'[rn-youtube-iframe] Player unstarted - autoplay may be blocked.',
);
}
break;
case 'playerReady':
onReady();
Expand Down
2 changes: 1 addition & 1 deletion website/static/iframe_v2.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctypehtml><meta name="viewport"content="width=device-width,"><style>body{margin:0}.container{position:relative;width:100%;height:0;padding-bottom:56.25%}.video{position:absolute;top:0;left:0;width:100%;height:100%}</style><div class="container"><div class="video"id="player"></div></div><script>const randomPlayerId="player"+Date.now();document.getElementById("player").id=randomPlayerId;const parsedUrl=new URL(window.location.href),UrlQueryData=parsedUrl.searchParams.get("data"),{end:end,list:list,color:color,start:start,rel_s:rel_s,loop_s:loop_s,listType:listType,playerLang:playerLang,playlist:playlist,videoId_s:videoId_s,controls_s:controls_s,cc_lang_pref_s:cc_lang_pref_s,contentScale_s:contentScale_s,allowWebViewZoom:allowWebViewZoom,modestbranding_s:modestbranding_s,iv_load_policy:iv_load_policy,preventFullScreen_s:preventFullScreen_s,showClosedCaptions_s:showClosedCaptions_s}=JSON.parse(UrlQueryData);function sendMessageToRN(e){window.ReactNativeWebView.postMessage(JSON.stringify(e))}let metaString="";contentScale_s&&(metaString+=`initial-scale=${contentScale_s}, `),allowWebViewZoom||(metaString+=`maximum-scale=${contentScale_s}`);const viewport=document.querySelector("meta[name=viewport]");viewport.setAttribute("content","width=device-width, "+metaString);var tag=document.createElement("script");tag.src="https://www.youtube.com/iframe_api";var player,firstScriptTag=document.getElementsByTagName("script")[0];function onYouTubeIframeAPIReady(){player=new YT.Player(randomPlayerId,{width:"1000",height:"1000",videoId:videoId_s,playerVars:{end:end,rel:rel_s,list:list,color:color,loop:loop_s,start:start,playsinline:1,hl:playerLang,playlist:playlist,listType:listType,controls:controls_s,fs:preventFullScreen_s,cc_lang_pref:cc_lang_pref_s,iv_load_policy:iv_load_policy,modestbranding:modestbranding_s,cc_load_policy:showClosedCaptions_s},events:{onReady:onPlayerReady,onError:onPlayerError,onStateChange:onPlayerStateChange,onPlaybackRateChange:onPlaybackRateChange,onPlaybackQualityChange:onPlaybackQualityChange}})}function onPlayerError(e){sendMessageToRN({eventType:"playerError",data:e.data})}function onPlaybackRateChange(e){sendMessageToRN({eventType:"playbackRateChange",data:e.data})}function onPlaybackQualityChange(e){sendMessageToRN({eventType:"playerQualityChange",data:e.data})}function onPlayerReady(e){sendMessageToRN({eventType:"playerReady"})}function onPlayerStateChange(e){sendMessageToRN({eventType:"playerStateChange",data:e.data})}firstScriptTag.parentNode.insertBefore(tag,firstScriptTag);var isFullScreen=!1;function onFullScreenChange(){isFullScreen=document.fullscreenElement||document.msFullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement,sendMessageToRN({eventType:"fullScreenChange",data:Boolean(isFullScreen)})}document.addEventListener("fullscreenchange",onFullScreenChange),document.addEventListener("msfullscreenchange",onFullScreenChange),document.addEventListener("mozfullscreenchange",onFullScreenChange),document.addEventListener("webkitfullscreenchange",onFullScreenChange),window.addEventListener("message",function(e){var{data:e}=e;switch(e){case"playVideo":player.playVideo();break;case"pauseVideo":player.pauseVideo();break;case"muteVideo":player.mute();break;case"unMuteVideo":player.unMute()}})</script>
<!doctypehtml><meta name="viewport"content="width=device-width,"><style>body{margin:0}.container{position:relative;width:100%;height:0;padding-bottom:56.25%}.video{position:absolute;top:0;left:0;width:100%;height:100%}</style><div class="container"><div class="video"id="player"></div></div><script>const randomPlayerId="player"+Date.now();document.getElementById("player").id=randomPlayerId;const parsedUrl=new URL(window.location.href),UrlQueryData=parsedUrl.searchParams.get("data"),{end:end,list:list,color:color,start:start,rel_s:rel_s,loop_s:loop_s,listType:listType,playerLang:playerLang,playlist:playlist,videoId_s:videoId_s,controls_s:controls_s,cc_lang_pref_s:cc_lang_pref_s,contentScale_s:contentScale_s,allowWebViewZoom:allowWebViewZoom,modestbranding_s:modestbranding_s,iv_load_policy:iv_load_policy,preventFullScreen_s:preventFullScreen_s,showClosedCaptions_s:showClosedCaptions_s}=JSON.parse(UrlQueryData);function sendMessageToRN(e){window.ReactNativeWebView?window.ReactNativeWebView.postMessage(JSON.stringify(e)):window.parent?window.parent.postMessage(JSON.stringify(e),"*"):console.error("Not running in Iframe, cannot postMessage.")}let metaString="";contentScale_s&&(metaString+=`initial-scale=${contentScale_s}, `),allowWebViewZoom||(metaString+=`maximum-scale=${contentScale_s}`);const viewport=document.querySelector("meta[name=viewport]");viewport.setAttribute("content","width=device-width, "+metaString);var tag=document.createElement("script");tag.src="https://www.youtube.com/iframe_api";var player,firstScriptTag=document.getElementsByTagName("script")[0];function onYouTubeIframeAPIReady(){player=new YT.Player(randomPlayerId,{width:"1000",height:"1000",videoId:videoId_s,playerVars:{end:end,rel:rel_s,list:list,color:color,loop:loop_s,start:start,playsinline:1,hl:playerLang,playlist:playlist,listType:listType,controls:controls_s,fs:preventFullScreen_s,cc_lang_pref:cc_lang_pref_s,iv_load_policy:iv_load_policy,modestbranding:modestbranding_s,cc_load_policy:showClosedCaptions_s},events:{onReady:onPlayerReady,onError:onPlayerError,onStateChange:onPlayerStateChange,onPlaybackRateChange:onPlaybackRateChange,onPlaybackQualityChange:onPlaybackQualityChange}})}function onPlayerError(e){sendMessageToRN({eventType:"playerError",data:e.data})}function onPlaybackRateChange(e){sendMessageToRN({eventType:"playbackRateChange",data:e.data})}function onPlaybackQualityChange(e){sendMessageToRN({eventType:"playerQualityChange",data:e.data})}function onPlayerReady(e){sendMessageToRN({eventType:"playerReady"})}function onPlayerStateChange(e){sendMessageToRN({eventType:"playerStateChange",data:e.data})}firstScriptTag.parentNode.insertBefore(tag,firstScriptTag);var isFullScreen=!1;function onFullScreenChange(){isFullScreen=document.fullscreenElement||document.msFullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement,sendMessageToRN({eventType:"fullScreenChange",data:Boolean(isFullScreen)})}document.addEventListener("fullscreenchange",onFullScreenChange),document.addEventListener("msfullscreenchange",onFullScreenChange),document.addEventListener("mozfullscreenchange",onFullScreenChange),document.addEventListener("webkitfullscreenchange",onFullScreenChange),window.addEventListener("message",function(a){var{data:e}=a;try{var{eventName:n,meta:t}=JSON.parse(e);switch(n){case"playVideo":player.playVideo();break;case"pauseVideo":player.pauseVideo();break;case"muteVideo":player.mute();break;case"unMuteVideo":player.unMute();break;case"setVolume":player.setVolume(t.volume);break;case"setPlaybackRate":player.setPlaybackRate(t.playbackRate)}}catch(e){console.error("Error parsing data",a,e)}},!0)</script>