Twitch player isnt that bad, it's full reponsive when finishing the job as a frontend dev
- we want our TwitchPlayer reponsive
- at load
- at resize (web) rotate (mobile)
- we want to have the chat layout everTime it's possible
- we dont want the video layer to cut
What we got from Twitch API Embedding Everything (https://dev.twitch.tv/docs/embed/everything/)
<!-- Add a placeholder for the Twitch embed -->
<div id="twitch-embed"></div>
<!-- Load the Twitch embed JavaScript file -->
<script src="https://embed.twitch.tv/embed/v1.js"></script>
<!-- Create a Twitch.Embed object that will render within the "twitch-embed" element -->
<script type="text/javascript">
new Twitch.Embed("twitch-embed", {
width: 854,
height: 480,
channel: "monstercat",
// Only needed if this page is going to be embedded on other websites
parent: ["embed.example.com", "othersite.example.com"]
});
</script>
This player is full responsive, depending its width, it will fold/unfold to keep at best in every screen.
- With the layout option :
js layout: 'video-and-chat'
the player will provide the chat, right or down the video depending the width, to fit into the best view.
But at the moment, the player wont be responsive with resize (web) or rotate (mobile), we need to attach events to detect resizing or rotation.
- Nothing really hard here
const inject = document.createElement('script')
inject.type = "text/javascript"
inject.src = "https://embed.twitch.tv/embed/v1.js"
inject.onload = () => {
new Twitch.Embed("twitch-embed", {
width: 854,
height: 480,
channel: "monstercat",
layout: "video-and-chat",
// Only needed if this page is going to be embedded on other websites
parent: ["embed.example.com", "othersite.example.com"]
});
window.addEventListener('resize', () => {
...
})
}
document.getElementById("twitch-embed").append(inject)
- The hard one is about what will u resize, as the player is injected with a remote script.
- Inspecting our DOM, we can observe the final injections, script & iframe tag in our
<div id="twitch-embed"></div>
<div id="twitch-embed">
<script src="https://embed.twitch.tv/embed/v1.js"></script>
<iframe
src="https://embed.twitch.tv?autoplay=false&channel=radiojaune&height=400&layout=video-and-chat&parent=embed.example.com&parent=radiojaune.com&parent=localhost&referrer=http%3A%2F%2Flocalhost%3A3000%2F&width=800"
allowfullscreen=""
scrolling="no"
frameborder="0"
allow="autoplay; fullscreen"
title="Twitch"
sandbox="allow-modals allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
width="472.6666666666667"
height="485.5"></iframe>
</div>
- what we want what is :
- get sure to hit the Twitch Player
<iframe>
- attach our EventListeners
- Twitch.Embed.VIDEO_READY
- Twitch.Embed.VIDEO_PLAY
- 'resize'
- get sure to hit the Twitch Player
const embedDiv = document.getElementById("twitch-embed");
for (var i=0; i < embedDiv.getElementsByTagName("iframe").length; i++) {
if (embedDiv.getElementsByTagName("iframe")[i].title == "Twitch") {
...
}
}
- in my experience, such players are wanted on a basic (or not) landing page.
- watchin' for VIDEO_READY & VIDEO_PLAY is our key for any client-side design (opacity: 0.3 to 1 in this example, as i build my landing-page, with the payer to be on top of a canvas background)
- keep creative
embed.addEventListener(Twitch.Embed.VIDEO_READY, () => {
var player = embed.getPlayer();
player.play();
console.log("TwitchPlayer: VIDEO_READY");
});
embed.addEventListener(Twitch.Embed.VIDEO_PLAY, () => {
document.getElementById("twitch-embed").style.opacity = 1;
console.log("TwitchPlayer: VIDEO_PLAY");
});
-
As we are able to have pretty responsive resized (web) or rotated (mobile) Player, But as we're providing
layout: 'video-and-chat'
we can observe the video layer being cut under a 800px screen size ... -
Unfortunatly, layout isnt an iframe property, but a script argument : <iframe src="...tv?autoplay=false&channel=monstercat&height=400&layout=video-and-chat&parent=..."
-
we need to update, the best way we can (be sure to update once, not zounds) our iframe src tag, where js-layout options stand.
-
we will keep the original script arguments & only switch layout=...
const iframe = embedDiv.getElementsByTagName("iframe")[frameId]
if (
window.innerWidth < 800 &&
iframe.src.replace("layout=video-and-chat","layout=video") != iframe.src
) { // UPDATE ONCE (maybe 2)
iframe.src = iframe.src.replace("layout=video-and-chat","layout=video");
console.log("switching player src");
} else if (
window.innerWidth > 800 &&
iframe.src.replace("layout=video-and-chat","") == iframe.src
) { // UPDATE ONCE
iframe.src = iframe.src.replace("layout=video","layout=video-and-chat");
console.log("switching player src");
}
- Everythings full responsive TwitchPlayer
// SOME CONFIG VARS
const videoMinSize = 799
const playerWidthScreenRatio = 1.5;
const playerHeightScreenRatio = 2;
// TWITCH API SCRIPT INJECTION
const inject = document.createElement("script");
inject.type = "text/javascript";
inject.src = "https://embed.twitch.tv/embed/v1.js";
inject.onload = () => { startTwitch() };
document.getElementById("twitch-embed").append(inject);
// PLAYER INITIALISATION & DEDICATED LISTENERS
function startTwitch() {
embed = new Twitch.Embed("twitch-embed", {
width: (windowDimensions.width/1.5),
height: (windowDimensions.height/2),
channel: "monstercat",
layout: "video"+((windowDimensions.width>videoMinSize)?"-and-chat":""),
parent: ["embed.example.com", "othersite.example.com"]
});
// TWITCH API
embed.addEventListener(Twitch.Embed.VIDEO_READY, () => {
var player = embed.getPlayer();
player.play();
console.log("TwitchPlayer: VIDEO_READY");
});
embed.addEventListener(Twitch.Embed.VIDEO_PLAY, () => {
document.getElementById("twitch-embed").style.opacity = 1;
console.log("TwitchPlayer: VIDEO_PLAY");
});
// MORE RESPONSIVTY (WEB)
const embedDiv = document.getElementById("twitch-embed");
for (var i=0; i < embedDiv.getElementsByTagName("iframe").length; i++) {
// FIND THE RIGHT NODE
if (embedDiv.getElementsByTagName("iframe")[i].title == "Twitch") {
console.log("attaching resize Events on TwitchPlayer-frame["+i+"]");
const frameId = i;
window.addEventListener("resize", () => {
// IFRAME SIZES
embedDiv.getElementsByTagName("iframe")[frameId].width = window.innerWidth/playerWidthScreenRatio;
embedDiv.getElementsByTagName("iframe")[frameId].height = window.innerHeight/playerHeightScreenRatio;
const iframe = embedDiv.getElementsByTagName("iframe")[frameId]
// IFRAME SRC OPTIONS SWITCH
if (
window.innerWidth < 800 &&
iframe.src.replace("layout=video-and-chat","layout=video") != iframe.src
) { // UPDATE ONCE
iframe.src = iframe.src.replace("layout=video-and-chat","layout=video");
console.log("switching player src");
} else if (
window.innerWidth > 800 &&
iframe.src.replace("layout=video-and-chat","") == iframe.src
) { // UPDATE ONCE
iframe.src = iframe.src.replace("layout=video","layout=video-and-chat");
console.log("switching player src");
}
});
};
};
};
https://github.com/BorisTherin/ortf-land-astro-template/blob/main/src/components/TwitchPlayer.tsx