Skip to content

Instantly share code, notes, and snippets.

@webalphatv
Created April 29, 2022 17:36
Show Gist options
  • Save webalphatv/5defa36929c9a5f2ea1df052dc081d2a to your computer and use it in GitHub Desktop.
Save webalphatv/5defa36929c9a5f2ea1df052dc081d2a to your computer and use it in GitHub Desktop.
JW Player Click-to-Play Video Wall
<script src="//content.jwplatform.com/libraries/SAHhwvZq.js"></script>
<div class="video-wall">
<div class="header-bar">Discover Videos</div>
<div class="row-flex-6">
<div class="column">
<div class="thumb large"></div>
<div class="row-flex-2">
<div class="thumb"></div>
<div class="thumb"></div>
</div>
</div>
<div class="column">
<div class="row-flex-2">
<div class="thumb"></div>
<div class="thumb"></div>
</div>
<div class="thumb large"></div>
</div>
</div>
<div class="row-flex-6">
<div class="column">
<div class="thumb large"></div>
<div class="row-flex-2">
<div class="thumb"></div>
<div class="thumb"></div>
</div>
</div>
<div class="column">
<div class="row-flex-2">
<div class="thumb"></div>
<div class="thumb"></div>
</div>
<div class="thumb large"></div>
</div>
</div>
</div>

JW Player Click-to-Play Video Wall

Setup and play a video with a single click on a thumbnail within a responsive image grid powered by JW Player.

A Pen by Kim Hart on CodePen.

License.

// Request playlist data
(function() {
var httpRequest = new XMLHttpRequest();
if (!httpRequest) {
return false;
}
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
var json = JSON.parse(httpRequest.response);
getThumbnails(json);
} else {
console.log(httpRequest.statusText);
}
}
}
httpRequest.open('GET', '//cdn.jwplayer.com/v2/playlists/0FDAGB12');
httpRequest.send();
})();
// Render thumbnails into grid layout
var thumbs = document.querySelectorAll('.thumb');
var player;
function getThumbnails(data) {
var playlist = data.playlist;
thumbs.forEach(function(thumb, i) {
var video = playlist[i];
var titleText = document.createElement('div');
titleText.className = 'title-text';
titleText.innerHTML = video.title;
thumb.appendChild(titleText);
thumb.setAttribute('id', video.mediaid + 1);
thumb.style.backgroundImage = "url('" + video.image + "')";
thumb.addEventListener('click', function(e) {
handleActivePlayer(e, video);
});
})
};
// On click, destroy existing player, setup new player in target div
function handleActivePlayer(e, video) {
var activeDiv = e.target;
if (player) {
player.remove();
}
thumbs.forEach(function(thumb) {
thumb.classList.remove('active');
})
activeDiv.classList.add('active');
// Chain .play() onto player setup (rather than autostart: true)
player = jwplayer(activeDiv.id).setup({
file: '//content.jwplatform.com/manifests/' + video.mediaid + '.m3u8'
}).play();
// Destroy the player and replace with thumbnail
player.on('complete', function() {
player.remove();
player = null;
});
}
@import url('https://fonts.googleapis.com/css?family=Quicksand:500');
/* keeps the player from applying margin to bottom when clicked */
.demo-layout-content .jwplayer {
margin-bottom: 0;
}
.video-wall {
font-family: 'Quicksand', sans-serif;
font-weight: 500;
display: flex;
margin: 0 auto;
flex-direction: column;
background: #000;
}
.header-bar {
background-color: #000;
color: #fff;
font-size: 24px;
justify-content: center;
text-transform: uppercase;
height: 60px;
display: flex;
align-items: center;
padding: 10px 20px;
}
.row-flex-2,
.row-flex-6 {
display: flex;
justify-content: center;
}
.column {
display: flex;
flex-direction: column;
}
.thumb {
min-width: 250px;
min-height: 140.63px;
position: relative;
opacity: 1;
background-size: calc(100% + 60px);
background-repeat: no-repeat;
transition: background-size .3s ease-in-out;
-webkit-transition: background-size .3s ease-in-out;
-ms-transition: background-size .3s ease-in;
-o-transition: background-size .3s ease-in;
cursor: pointer;
border: 1px solid #000;
}
.thumb.large {
min-width: 500px;
min-height: 281.25px;
}
.title-text {
color: #fff;
text-align: left;
font-size: 16px;
padding: 10px;
position: absolute;
bottom: -20px;
opacity: 0;
pointer-events: none;
transition: all .2s ease-in-out .1s;
-webkit-transition: all .2s ease-in-out .1s;
-ms-transition: all .2s ease-in-out .1s;
-o-transition: all .2s ease-in-out .1s;
}
.thumb.large .title-text {
font-size: 20px;
padding: 10px;
}
.thumb:hover {
background-size: calc(100% + 40px);
}
.thumb:hover .title-text {
opacity: 1;
bottom: 0;
}
@media screen and (max-width: 1082px) {
.video-wall {
width: 750px;
}
.row-flex-6 {
flex-wrap: wrap;
width: 100%;
}
.row-flex-2 {
flex-wrap: wrap;
width: 50%;
}
.column {
flex-flow: row;
width: 100%;
}
.thumb {
width: 100%;
}
}
@media screen and (max-width: 815px) {
.video-wall {
width: 600px;
}
.column {
flex-flow: column;
}
.row-flex-2 {
flex-flow: row;
width: 100%;
}
.thumb {
min-height: 168px;
}
.thumb.large {
min-height: 338px;
}
}
@media screen and (max-width: 815px) {
.video-wall {
width: 600px;
}
.column {
flex-flow: column;
}
.row-flex-2 {
flex-flow: row;
width: 100%;
}
.thumb {
min-height: 168px;
}
.thumb.large {
min-height: 338px;
}
}
@media screen and (max-width: 665px) {
.video-wall {
width: 500px;
}
.thumb {
min-height: 140px;
}
.thumb.large {
min-height: 281px;
}
}
@media screen and (max-width: 560px) {
.video-wall {
width: 400px;
}
.row-flex-2 {
flex-flow: column;
}
.thumb,
.thumb.large {
min-width: 400px;
min-height: 225px;
}
.thumb .title-text,
.thumb.large .title-text {
opacity: 1;
bottom: 0;
font-size: 20px;
}
}
@media screen and (max-width: 400px) {
.video-wall {
width: 300px;
}
.thumb,
.thumb.large {
min-width: 300px;
min-height: 168.75px;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment