Skip to content

Instantly share code, notes, and snippets.

@adamsimp
Created May 4, 2020 19:31
Show Gist options
  • Save adamsimp/b58e85e009ffb08c6ad27f45286dadd2 to your computer and use it in GitHub Desktop.
Save adamsimp/b58e85e009ffb08c6ad27f45286dadd2 to your computer and use it in GitHub Desktop.
StarfruitTesting - Graham Media
<div id="app">
<div class="video-wrapper">
<span class="live-pill">Live</span>
<video
id="twitch-videojs"
class="video-js vjs-fluid vjs-big-play-centered"
autoplay
playsinline
></video>
<div class="quiz-wrap">
<div id="waiting"><span class="waiting-text float">Waiting for the next question</span></div>
<div id="quiz" class="card drop">
<div class="card-inner">
<h2 id="question"></h2>
<a href="#" id="A" class="answer"></a>
<a href="#" id="B" class="answer"></a>
<a href="#" id="C" class="answer"></a>
<a href="#" id="D" class="answer"></a>
</div>
</div>
</div>
</div>
</div>
const DEFAULT_STREAM = "https://usher.ttvnw.net/api/lvs/hls/lvs.592423023374.MARCH16.m3u8?allow_source=true&player_backend=mediaplayer";
// Initialize player
(function() {
// Register Twitch as playback technology for video.js
registerTwitchTechForVideoJs(videojs, {});
// Initialize video.js player and get Twitch player instance
const videojsPlayer = videojs("twitch-videojs", {
techOrder: ["TwitchWhiteLabel"]
});
const twitchPlayer = videojsPlayer.getTwitchPlayer();
window.videojsPlayer = videojsPlayer;
window.twitchPlayer = twitchPlayer;
// Show the "big play" button when the stream is paused
const videoContainerEl = document.querySelector("#twitch-videojs");
videoContainerEl.addEventListener("click", () => {
if (videojsPlayer.paused()) {
videoContainerEl.classList.remove("vjs-has-started");
} else {
videoContainerEl.classList.add("vjs-has-started");
}
});
// Enables Twitch's quality plugin
videojsPlayer.enableTwitchQualityPlugin();
// Set volume to 15%
videojsPlayer.volume(0.15);
// Logs low latency setting, latency value, and quality after
const PlayerState = videojsPlayer.getTwitchTech().PlayerState;
let interval;
twitchPlayer.addEventListener(PlayerState.PLAYING, () => {
interval = setInterval(() => {
console.log('-------------------');
console.log(`This stream is ${twitchPlayer.isLiveLowLatency() ? '' : 'not '}playing in ultra low latency mode`);
console.log(`You have been watching for ${twitchPlayer.getPosition().toFixed(2)}s`);
console.log(`Latency: ${twitchPlayer.getLiveLatency().toFixed(2)}s`);
console.log(`Quality: ${twitchPlayer.getQuality().name}`);
console.log('-------------------');
}, 10000);
});
twitchPlayer.addEventListener(PlayerState.IDLE, () => {
clearInterval(interval);
});
// Log errors
const PlayerEvent = videojsPlayer.getTwitchTech().PlayerEvent;
twitchPlayer.addEventListener(PlayerEvent.ERROR, (type, source) => {
console.warn('PlayerEvent.ERROR event', type, source);
});
// Cleanup
function cleanUp() {
$("#quiz").addClass("drop");
$(".answer").unbind("click").removeClass("correct").removeClass("wrong");
};
// Trigger quiz
function triggerQuiz(metadataText) {
let obj = JSON.parse(metadataText);
$(".card-inner").fadeOut("fast");
$("#question").text(obj.question);
$("#A").text(obj.answers[0]);
$("#B").text(obj.answers[1]);
$("#C").text(obj.answers[2]);
$("#D").text(obj.answers[3]);
$(".card-inner").fadeIn("fast");
$(".answer").click(function(){
if (this.text === obj.answers[obj.correctIndex]) {
$(this).addClass("correct");
} else {
$(this).addClass("wrong");
}
setTimeout(function(){
cleanUp();
$("#waiting").show();
}, 1050);
return false;
});
};
// Log and display timed metadata
twitchPlayer.addEventListener(PlayerEvent.METADATA, (metadata) => {
if (metadata.type === 'text/plain') {
const metadataText = metadata.data;
cleanUp();
$("#quiz").removeClass("drop").show();
$("#waiting").hide();
triggerQuiz(metadataText);
}
});
$("#quiz").hide();
$("#waiting").show();
// Play default stream
videojsPlayer.src(DEFAULT_STREAM);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.6.6/video.min.js"></script>
<script src="https://player.live-video.net/0.9.4/videojs-hls-tech.min.js"></script>
<script src="https://player.live-video.net/0.9.4/videojs-quality-plugin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
body {
overflow: hidden;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Ubuntu, "Helvetica Neue", sans-serif;
background: linear-gradient(180deg, #232f3e 75.66%, #503640 100%);
}
#app {
height: 100%;
display: grid;
place-items: center;
transition: all .25s ease-in;
}
.video-wrapper {
width: 65%;
max-width: 40vw;
position: relative;
display: flex;
flex-direction: column;
border-radius: 6px;
transition: all .25s ease-in;
}
.live-pill {
height: 20px;
position: absolute;
top: 6px;
left: 6px;
background: #ff0000;
color: #fff;
text-transform: uppercase;
font-size: 13px;
padding: 2px 12px 0 12px;
box-shadow: 0 2px 6px rgba(0,0,0,.4);
border-radius: 20px;
z-index: 2;
}
video {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
border-radius: 8px;
transition: all .25s ease-in;
}
.video-js {
border-radius: 8px;
transition: all .25s ease-in;
}
.quiz-wrap {
min-height: 460px;
position: relative;
transition: all .25s ease-in;
}
.card {
margin: 0 20px;
padding: 20px;
position: relative;
top: -10px;
background: #fff;
border-radius: 20px;
box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.1);
transition: all 1s cubic-bezier(1,-0.56,0,1);
transform: translate3d(0,0,0) scale(1);
backface-visibility: hidden;
z-index: 1;
}
.card.drop {
opacity: 0;
transform: translate3d(0,500px,-20px) scale(.92) rotate(-25deg);
}
h2 {
font-size: 25px;
text-align: center;
padding-bottom: 20px;
}
.answer {
height: 50px;
line-height: 50px;
font-size: 20px;
display: flex;
text-decoration: none;
border: 1px solid #d5dbdb;
border-radius: 50px;
padding: 5px 24px;
margin: 10px 0;
background: #fafafa;
color: #545b64;
font-weight: medium;
transition: all 0.05s ease-in-out;
}
.answer:hover {
background: #ebebebe0;
}
.answer:active {
background: #ff9900;
border: 1px solid #eb5f07;
color: #fff;
}
.answer.correct {
background: #25a702;
border: 1px solid #1d8102;
color: #fff;
animation: blink .45s infinite;
}
.answer.wrong {
background: #d13212;
border: 1px solid #b7290d;
color: #fff;
animation: blink .45s infinite;
}
#waiting {
top: 100px;
left: 0;
right: 0;
position: absolute;
display: flex;
align-items: center;
}
.waiting-text {
width: 100%;
display: block;
text-align: center;
font-size: 18px;
color: #D5DBDB;
}
.float {
transform: translatey(0px);
animation: float 6s ease-in-out infinite;
}
@keyframes blink {
50% {
opacity: 0.8;
}
}
@keyframes float {
0% {
transform: translatey(0px);
}
50% {
transform: translatey(-20px);
}
100% {
transform: translatey(0px);
}
}
@media (min-width: 320px) and (max-width: 767px) {
.video-wrapper {
width: 92%;
max-width: 92%;
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.6.6/video-js.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment