Classic

A classic video playlist

Here we use the playlist plugin to implement a custom designed playlist in a manual installation. During playback the playlist entries are positioned in the bottom left corner of the screen. CSS code.
#classic {
/* player (and playlist) background */
background-color: #333;
background-image: url("//flowplayer.org/media/img/demos/playlist/bakers.jpg");
-webkit-background-size: cover;
-moz-background-size: cover;
background-size: cover;
}
#classic .fp-playlist {
/* playlist */
position: absolute;
bottom: 32%;
left: 11%;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
transition: all 0.5s;
z-index: 12;
-webkit-box-shadow: 0 0 30px #333;
-moz-box-shadow: 0 0 30px #333;
box-shadow: 0 0 30px #333;
}
#classic .fp-playlist a {
/* playlist entry */
float: left;
width: 170px;
height: 170px;
margin: 0 5px;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
transition: all 0.5s;
border: 4px solid #333;
background: url("//flowplayer.org/media/img/demos/playlist/thumbs.jpg") -1px -1px no-repeat;
}
#classic .fp-playlist a:hover,
#classic .fp-playlist a.is-active {
border-color: #fff;
}
#classic .fp-playlist #thumb2 {
background-position: -197px -1px;
}
#classic .fp-playlist #thumb3 {
background-position: -393px -1px;
}
#classic .fp-playlist #thumb4 {
background-position: -589px -1px;
}
#classic.is-ready .fp-playlist,
#classic.is-loading .fp-playlist {
bottom: 6%;
left: 1%;
}
#classic.is-ready .fp-playlist a,
#classic.is-loading .fp-playlist a {
width: 70px;
height: 70px;
}
@media (max-width: 900px) {
#classic .fp-playlist a {
width: 130px;
height: 130px;
}
}
@media (max-width: 700px) {
#classic .fp-playlist a {
width: 100px;
height: 100px;
}
}
@media (max-width: 570px) {
#classic .fp-playlist a {
width: 55px;
height: 55px;
}
}

CSS
// wait until DOM is ready
$(function () {
 
// manual installation into container element with id="classic"
$("#classic").flowplayer({
customPlaylist: true,
splash: true,
ratio: 9/16,
hlsQualities: [-1, 1, 3, 6, 7]
});
 
});

JavaScript
<div id="classic" class="is-closeable">
 
<video>
<source type="application/x-mpegurl"
src="//edge.flowplayer.org/night3.m3u8">
<source type="video/mp4"
src="//edge.flowplayer.org/night3.mp4">
</video>
 
<div class="fp-playlist">
<a href="//edge.flowplayer.org/night3.mp4" id="thumb1"></a>
<a href="//edge.flowplayer.org/night5.mp4" id="thumb2"></a>
<a href="//edge.flowplayer.org/night6.mp4" id="thumb3"></a>
<a href="//edge.flowplayer.org/night1.mp4" id="thumb4"></a>
</div>
 
</div>

HTML

view standalone page

Dots

Let small dots do the job

Helsinki railway station

Where young people get drunk

One of the central meeting points for really young people. You can see parents looking after their children.

Mannerheimintie

The main street in Helsinki

The street that crosses the central Helsinki. Expensive stores and skateboarding at Kiasma.

KOM-teatteri

Finland's Theatre of Socialist Action

An aesthetically sophisticated and vigorous meeting point. Represents the alternative theatre movement in Finland.

Stockmann store

So that people can buy stuff

Consumers shop to satisfy their emotional needs. This is where people go in Helsinki.

The playlist plugin assigns an indexed class name on the root element. By using this class we can display different kinds of HTML based on the active clip. CSS code. We also hide the configured clip titles here in favour of the verbose information, but the titles will be shown when the player is shared on another site. Try it.
#dots {
background-color: #333;
background-image: url("//flowplayer.org/media/img/demos/playlist/railway_station.jpg");
}
#dots hgroup {
/* info box */
background-color: rgba(0,0,0,0.7);
position: absolute;
top: 3%;
left: 2%;
width: 250px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
padding: 15px;
margin: 0;
color: #999;
display: none;
opacity: 0;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
-webkit-transition: opacity 0.5s;
-moz-transition: opacity 0.5s;
transition: opacity 0.5s;
z-index: 1;
}
#dots hgroup h1 {
font-size: larger;
}
#dots hgroup h2 {
color: #fff;
font-weight: bold;
line-height: 1.5;
}
#dots .fp-title {
/* only show titles when player is embedded on other sites */
display: none;
}
#dots .fp-playlist {
/* small dots on bottom right */
position: absolute;
bottom: 10%;
right: 2%;
opacity: 0;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
z-index: 12;
-webkit-transition: opacity 1s 0.5s;
-moz-transition: opacity 1s 0.5s;
transition: opacity 1s 0.5s;
}
#dots .fp-playlist a {
width: 20px;
height: 20px;
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
border-radius: 20px;
display: block;
float: left;
margin-right: 8px;
background-color: #fff;
cursor: pointer;
border: 1px solid #000;
}
#dots .fp-playlist a:hover {
background-color: #ddd;
}
#dots .fp-playlist a.is-active {
background-color: #000 !important;
}
#dots.is-mouseover hgroup,
#dots.is-mouseover .fp-playlist {
opacity: 1;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
-webkit-transition-delay: 0;
-moz-transition-delay: 0;
transition-delay: 0;
}
#dots.video0 .info0 {
display: block;
}
#dots.video1 .info1 {
display: block;
}
#dots.video2 .info2 {
display: block;
}
#dots.video3 .info3 {
display: block;
}
@media (max-width: 600px) {
#dots hgroup {
width: 300px;
}
#dots hgroup h1 {
font-size: 25px;
}
}

CSS
// wait until DOM is ready
$(function () {
 
// manual installation into container element with id="dots"
$("#dots").flowplayer({
splash: true,
ratio: 9/16,
customPlaylist: true
});
 
});

JavaScript
<div id="dots">
 
<!-- the data-title attribute will shown when the player is embedded -->
<video data-title="Helsinki railway station">
<source type="application/x-mpegurl"
src="//edge.flowplayer.org/night7.m3u8">
<source type="video/mp4"
src="//edge.flowplayer.org/night7.mp4">
</video>
 
<!-- the verbose info is shown on this page -->
<hgroup class="info0">
<h1>Helsinki railway station</h1>
<h2>Where young people get drunk</h2>
<h3>One of the central meeting points for really young people. You can
see parents looking after their children.</h3>
</hgroup>
 
<hgroup class="info1">
<h1>Mannerheimintie</h1>
<h2>The main street in Helsinki</h2>
<h3>The street that crosses the central Helsinki. Expensive stores and
skateboarding at Kiasma.</h3>
</hgroup>
 
<hgroup class="info2">
<h1>KOM-teatteri</h1>
<h2>Finland's Theatre of Socialist Action</h2>
<h3>An aesthetically sophisticated and vigorous meeting point.
Represents the alternative theatre movement in Finland.</h3>
</hgroup>
 
<hgroup class="info3">
<h1>Stockmann store</h1>
<h2>So that people can buy stuff</h2>
<h3>Consumers shop to satisfy their emotional needs. This is where
people go in Helsinki.</h3>
</hgroup>
 
<!-- the data-title attributes will shown when the player is embedded -->
<div class="fp-playlist">
<a href="//edge.flowplayer.org/night7.mp4" id="dot1"
data-title="Helsinki railway station"></a>
 
<a href="//edge.flowplayer.org/night5.mp4" id="dot5"
data-title="The main street in Helsinki"></a>
 
<a href="//edge.flowplayer.org/night6.mp4" id="dot3"
data-title="Finland's Theatre of Socialist Action"></a>
 
<a href="//edge.flowplayer.org/night4.mp4" id="dot4"
data-title="Stockmann store"></a>
</div>
 
</div>

HTML

view standalone page

Javascript playlists

More dynamic, more control

Each of the boxes below provide the title and description of a video. You can select the videos and press the "Load playlist" button to load Flowplayer with a playlist from your selection.

Click to select the videos for the playlist

  • Helsinki railway station

    One of the central meeting points for really young people. You can see parents looking after their children.

  • The main street in Helsinki

    The street that crosses the central Helsinki. Expensive stores and skateboarding at Kiasma.

  • Finland's Socialist Theatre

    An aesthetically sophisticated meeting point. Represents the alternative theatre movement in Finland.

  • Stockmann store

    Consumers shop to satisfy their emotional needs. This is where people go in Helsinki.

Load playlist »
The playlist plugin allows the entire playlist configuration to be presented from Javascript. This makes it extremely easy to handle situations where the playlist needs to be fetched by making an API call.
#jsplaylistdemo {
margin: 0 auto;
height: 600px;
}
#jsplaylistdemo #jsplaylistdemovideos {
text-align: center;
margin: 12px auto 0;
}
#jsplaylistdemo #jsplaylistdemovideos .notes {
font-size: 14px;
margin: 0 0 39px;
}
#jsplaylistdemo #jsplaylistdemovideos h2 {
font-size: 20px;
color: #777;
font-weight: normal;
line-height: 24px;
margin: 0;
padding: 0;
}
#jsplaylistdemo #jsplaylistdemovideos h3 {
color: #999;
font-weight: bold;
margin: 4px;
}
#jsplaylistdemo #jsvideocontainer {
text-align: center;
}
#jsplaylistdemo #jsplaylist {
background-color: #333;
margin-bottom: 200px;
}
#jsplaylistdemo #jsplaylist .fp-prev,
#jsplaylistdemo #jsplaylist .fp-next {
position: absolute;
bottom: -112px;
background: url("//flowplayer.org/media/img/demos/playlist/buttons.png") no-repeat;
z-index: 99;
cursor: pointer;
color: #333;
font-size: 14px;
text-decoration: none;
}
#jsplaylistdemo #jsplaylist .fp-prev {
left: 0;
padding-left: 16px;
background-position: 0 -200px;
}
#jsplaylistdemo #jsplaylist .fp-prev:hover {
background-position: 0 -300px;
color: #016682;
}
#jsplaylistdemo #jsplaylist .fp-next {
right: 0;
padding-right: 16px;
background-position: 28px -400px;
}
#jsplaylistdemo #jsplaylist .fp-next:hover {
background-position: 28px -500px;
color: #016682;
}
#jsplaylistdemo #jsplaylist .fp-playlist {
position: absolute;
text-align: center;
bottom: -142px;
z-index: 2;
width: 100%;
}
#jsplaylistdemo #jsplaylist .fp-playlist a {
width: 5em;
height: 5em;
-webkit-border-radius: 5em;
-moz-border-radius: 5em;
border-radius: 5em;
display: inline-block;
margin: 0 12px;
background-color: #ededed;
cursor: pointer;
}
#jsplaylistdemo #jsplaylist .fp-playlist a:hover {
background-color: #016682;
}
#jsplaylistdemo #jsplaylist .fp-playlist a.is-active {
background-color: #57bed4 !important;
}
#jsplaylistdemo ul {
margin: 0;
margin-bottom: 20px;
padding: 0;
-webkit-column-count: 2;
-moz-column-count: 2;
column-count: 2;
}
#jsplaylistdemo li {
background-color: #ededed;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
border: 1px solid #ededed;
list-style-type: none;
margin: 20px 12px;
padding: 12px;
display: inline-block;
cursor: pointer;
height: 120px;
width: 220px;
overflow: hidden;
}
#jsplaylistdemo li.selected {
background-color: #262626;
border: 1px solid #212121;
color: #ccc;
}
#jsplaylistdemo li:hover {
background-color: #ccc;
border: 1px solid #ededed;
}
#jsplaylistdemo li:hover.selected {
background-color: #262626;
}
#jsplaylistdemo a.button {
background-color: #262626;
padding: 12px 24px;
width: 160px;
margin: 0 auto;
line-height: 1;
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
border-radius: 20px;
color: #fff;
cursor: pointer;
text-decoration: none;
font-size: 16px;
display: block;
}
#jsplaylistdemo a.button:hover {
background-color: #ccc;
color: #000;
}
#jsplaylistdemo {
width: 560px;
overflow: hidden;
position: relative;
margin: 0 auto;
padding: 20px 0;
}
#jsplaylistdemo #jscontainer {
width: 2000px;
}
#jsplaylistdemo #jsplaylistdemovideos,
#jsplaylistdemo #jsvideocontainer {
width: 560px;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
transition: all 0.5s;
position: absolute;
top: 0;
}
#jsplaylistdemo #jsplaylistdemovideos {
left: -600px;
}
#jsplaylistdemo #jsplaylistdemovideos.show {
left: 0;
}
#jsplaylistdemo #jsvideocontainer {
left: 600px;
}
#jsplaylistdemo #jsvideocontainer.show {
left: 0;
}
@media (max-width: 579px) {
#jsplaylistdemo {
width: 320px;
height: 260px;
}
#jsplaylistdemo #jsplaylistdemovideos .notes {
display: none;
}
#jsplaylistdemo #jsplaylistdemovideos ul {
-webkit-column-count: 1;
-moz-column-count: 1;
column-count: 1;
}
#jsplaylistdemo #jsplaylistdemovideos li {
margin: 8px 20px;
padding: 4px;
display: inline-block;
height: auto;
width: 240px;
}
#jsplaylistdemo #jsplaylistdemovideos li p {
display: none;
}
#jsplaylistdemo #jsplaylistdemovideos h2 {
font-size: 16px;
}
#jsplaylistdemo #jsplaylistdemovideos,
#jsplaylistdemo #jsvideocontainer {
width: 95%;
margin: 0 auto;
padding: 0px;
}
#jsplaylistdemo #jsplaylist {
margin-bottom: 80px;
}
#jsplaylistdemo #jsplaylist .fp-prev,
#jsplaylistdemo #jsplaylist .fp-next {
bottom: -56px;
}
#jsplaylistdemo #jsplaylist .fp-playlist {
bottom: -64px;
}
#jsplaylistdemo #jsplaylist .fp-playlist a {
width: 2em;
height: 2em;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
}
#jsplaylistdemo #jsplaylistdemovideos {
left: -340px;
}
#jsplaylistdemo #jsplaylistdemovideos.show {
left: 0px;
}
#jsplaylistdemo #jsvideocontainer {
left: 340px;
}
#jsplaylistdemo #jsvideocontainer.show {
left: 0px;
}
}

CSS
<div id="jsplaylistdemo">
<div id="jscontainer">
<div id="jsplaylistdemovideos" class="show">
 
<p class="notes">
Each of the boxes below provide the title and description
of a video. You can select the videos and press the
"Load playlist" button to load Flowplayer with a playlist
from your selection.
</p>
 
<h2>Click to select the videos for the playlist</h2>
<ul>
<li class="selected">
<h3>Helsinki railway station</h3>
<p>
One of the central meeting points for really
young people. You can see parents looking after
their children.
</p>
</li>
<li>
<h3>The main street in Helsinki</h3>
<p>
The street that crosses the central Helsinki. Expensive
stores and skateboarding at Kiasma.
</p>
</li>
<li class="selected">
<h3>Finland's Socialist Theatre</h3>
<p>
An aesthetically sophisticated meeting point.
Represents the alternative theatre movement in Finland.
</p>
</li>
<li>
<h3>Stockmann store</h3>
<p>
Consumers shop to satisfy their emotional needs. This is
where people go in Helsinki.
</p>
</li>
</ul>
<a id="loadPlaylist" class="button">Load playlist &raquo;</a>
</div>
 

<div id="jsvideocontainer">
<!--
Empty container, all videos come from
javascript playlist configuration.
-->
<div id="jsplaylist">
<a class="fp-prev">Prev</a>
<a class="fp-next">Next</a>
</div>
<a id="selectPlaylist" class="button">&laquo; Change playlist</a>
</div>
</div>
</div>
 

<script>
/*
List of video sources.
 
In real world scenarios, the following list and the informational
content above could be returned from an API call.
 
This demo shows how such scenarios could be handled using flowplayer
to provide dynamic video playlists.
 
*/
 
var allVideos = [{
sources: [{
type: 'video/webm',
src: "//edge.flowplayer.org/night7.webm"
}, {
type: 'video/mp4',
src: "//edge.flowplayer.org/night7.mp4"
}, {
type: 'video/flash',
src: "mp4:night7"
}]
}, {
sources: [{
type: 'video/webm',
src: "//edge.flowplayer.org/night5.webm"
}, {
type: 'video/mp4',
src: "//edge.flowplayer.org/night5.mp4"
}, {
type: 'video/flash',
src: "mp4:night5"
}]
}, {
sources: [{
type: 'video/webm',
src: "//edge.flowplayer.org/night6.webm"
}, {
type: 'video/mp4',
src: "//edge.flowplayer.org/night6.mp4"
}, {
type: 'video/flash',
src: "mp4:night6"
}]
}, {
sources: [{
type: 'video/webm',
src: "//edge.flowplayer.org/night4.webm"
}, {
type: 'video/mp4',
src: "//edge.flowplayer.org/night4.mp4"
}, {
type: 'video/flash',
src: "mp4:night4"
}]
}];
 
var jsPlaylistApi;
 
var clipSelector = document.getElementById("jsplaylistdemovideos"),
clipFields = clipSelector.getElementsByTagName("li"),
playerWrapper = document.getElementById("jsvideocontainer"),
i;
 
var refreshPlaylist = function() {
 
var playlistVideos = [], i;
 
/*
 
Populates the `playlistVideos` with the user
selected videos.
 
If there is more than one selection, it calls
`flowplayer` to reinitialize the playlist.
 
*/
 
for (i = 0; i < clipFields.length; i += 1) {
if (clipFields[i].className == "selected") {
playlistVideos.push(allVideos[i]);
}
}
 
if (!playlistVideos.length) {
return false;
}
 
if (!jsPlaylistApi) { // initial load
/*
install the player and get handle on its api
 
the player must be unloadable because it will be hidden
on playlist refresh: use a splash setup
*/
 
jsPlaylistApi = flowplayer('#jsplaylist', {
ratio: 9/16,
customPlaylist: true,
playlist: playlistVideos,
splash: true,
rtmp: {
url: "rtmp://s3b78u0kbtx79q.cloudfront.net/cfx/st"
}
});
 
} else {
jsPlaylistApi.setPlaylist(playlistVideos);
}
 
return true;
};
 

for (i = 0; i < clipFields.length; i += 1) {
// retrieve clip titles dynamically from page
allVideos[i].title = clipFields[i].getElementsByTagName("h3")[0].innerHTML;
 
clipFields[i].onclick = function () {
if (this.className == "selected") {
this.removeAttribute("class");
} else {
this.className = "selected";
}
};
}
 
document.getElementById("loadPlaylist").onclick = function () {
if (refreshPlaylist()) {
playerWrapper.className = "show";
clipSelector.removeAttribute("class");
jsPlaylistApi.play(0);
}
};
 
document.getElementById("selectPlaylist").onclick = function () {
jsPlaylistApi.unload();
playerWrapper.removeAttribute("class");
clipSelector.className = "show";
};
</script>

HTML

view standalone page

Grid

A space saver

Here are multiple players side by side and the active player is styled differently. The animation is made with CSS transitions. No playlist plugins in use here. Unlike other demos this one is not responsive and only works on screens that are wider than 982px. Here is the CSS code. Because the video files follow a consistent and convenient naming scheme the players can be installed in a JavaScript loop over the empty container elements.
#grid {
/* wrapper element for all players */
background: url("//flowplayer.org/media/img/demos/playlist/grid.jpg") 0 0 no-repeat;
/* sprite dimensions 982x420 */
width: 982px;
/* height + 6px bottom separator */
height: 426px;
margin: 0 1px;
position: relative;
}
#grid .flowplayer {
/* 980 / 4 colums */
width: 245px;
/* 420 / 3 rows */
height: 140px;
position: absolute;
margin: 0;
padding: 0;
}
#grid .flowplayer.is-splash .fp-ui {
background-position: 0 -100em;
}
#grid .flowplayer.is-mouseover.is-splash .fp-ui {
background-position: center;
}
#grid .flowplayer.is-ready,
#grid .flowplayer.is-loading {
/* hard-coded 16:9 player size (not working smoothly on smaller devices) */
width: 704px;
height: 396px;
background: #333 !important;
top: 15px !important;
left: 139px !important;
z-index: 20;
-webkit-box-shadow: 0 0 20px #000;
-moz-box-shadow: 0 0 20px #000;
box-shadow: 0 0 20px #000;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
transition: all 0.5s;
}
#grid #player0 {
top: 0px;
left: 1px;
}
#grid #player1 {
top: 0px;
left: 246px;
}
#grid #player2 {
top: 0px;
left: 491px;
}
#grid #player3 {
top: 0px;
left: 736px;
}
#grid #player4 {
top: 140px;
left: 1px;
}
#grid #player5 {
top: 140px;
left: 246px;
}
#grid #player6 {
top: 140px;
left: 491px;
}
#grid #player7 {
top: 140px;
left: 736px;
}
#grid #player8 {
top: 280px;
left: 1px;
}
#grid #player9 {
top: 280px;
left: 246px;
}
#grid #player10 {
top: 280px;
left: 491px;
}
#grid #player11 {
top: 280px;
left: 736px;
}

CSS
<!-- no need for playlist plugin -->
<div id="grid" class="demo">
 
<div class="is-closeable"></div>
<div class="is-closeable"></div>
<div class="is-closeable"></div>
<div class="is-closeable"></div>
<div class="is-closeable"></div>
<div class="is-closeable"></div>
<div class="is-closeable"></div>
<div class="is-closeable"></div>
<div class="is-closeable"></div>
<div class="is-closeable"></div>
<div class="is-closeable"></div>
<div class="is-closeable"></div>

</div>
 
<script>
var installGridPlayers = function () {
var i,
containerCollection = document.getElementById("grid").getElementsByTagName("div"),
containers = [],
 
getVideoName = function (i) {
/*
we do not have 12 videos available
so repeat videos named night1 thru night6
fill grid with 6 videos by clamping index count between 0 and 5
*/
return "night" + (i % 6 + 1);
};
 

// convert html collection into array
for (i = 0; i < containerCollection.length; i += 1) {
containers.push(containerCollection[i]);
}
 
for (i = 0; i < containers.length; i += 1) {
// inject id for CSS positioning
containers[i].id = "player" + i;
 
/*
if videos are not as conveniently named as here
either add a container attribute which maps easily to the filenames
or do not loop through containers
and install each player explicitly by container id
*/
flowplayer(containers[i], {
ratio: false,
splash: true,
rtmp: {
url: "rtmp://s3b78u0kbtx79q.cloudfront.net/cfx/st"
},
clip: {
sources: [
{ type: "video/webm",
src: "//edge.flowplayer.org/" + getVideoName(i) + ".webm" },
{ type: "video/mp4",
src: "//edge.flowplayer.org/" + getVideoName(i) + ".mp4" },
{ type: "video/flash", src: "mp4:" + getVideoName(i) }
]
}
});
 
}
 
};
 

installGridPlayers();
</script>

JavaScript

view standalone page | alternative grid playlist

More playlist demos available at our demo area.