Jekyll One

Fulltext Search

J1 VideoPlayer is a complete video player engine built on top of VideoJS. It gives every video the same good-looking, skinnable player, and it adds a full playlist on top: a searchable, sortable list of videos that the viewer can play, rate, and continue from where they left off. It plays two kinds of video: native videos (files such as mp4, webm or ogv that you host yourself) and YouTube videos.

10-30 Minutes to read.

How It Works

You do not need to write any JavaScript to use it. You describe your players in a few simple YAML files and J1 builds the HTML for you. You can put multiple players on one page and each one keeps its own separate playlist and its own settings. The rest of this manual explains every setting you can change, the shape of a playlist file, and — for advanced users — the JavaScript methods the module exposes.

Before diving into the settings, it helps to know the four pieces that make up a J1 VideoPlayer. You never touch most of them directly, but knowing they exist makes every later section easier to follow.

The configuration (YAML)

Three small text files describe your players: what they are called, which playlist they load, and how they look and behave. This is the part you edit. It is covered in Configuration.

The HTML

J1 reads your configuration and automatically writes the HTML for each player — the video area, the playlist panel, and the edit panel. You do not write this by hand.

The JavaScript core

A module called videoPlayer starts Video.js, wires up the buttons, and manages the playlist. It also loads a few helper plugins (skip buttons, next/previous buttons, zoom). Advanced users can call it directly; see Methods.

The playlist store

Each player keeps its playlist in the browser’s local storage. That is why a viewer’s ratings, and the position they stopped at, are still there the next time they open the page.

Native and YouTube Videos

A single playlist can mix both kinds of video:

Native video

A video file that you host on your own web server (for example an mp4). The player loads it directly. This is the most reliable option and works offline / on private sites. The file address goes in the entry’s src field.

YouTube video

A video that lives on YouTube. You give the player the YouTube link and it plays the video through Video.js. The poster image is taken from YouTube automatically.

Both kinds are configured in one place: the players.native block (see Player Options (videoJS)). The older players.youtube block still exists in the defaults file, but it is only kept for other J1 modules that read it — the VideoPlayer itself no longer uses it.

Several Players on a Page

You can place as many players on a page as you like. Every player has its own id (a short name such as player_1), its own playlist, and its own settings. Nothing leaks from one player to another: a video you add to player_1 never shows up in player_2, and a setting you change for one player never changes another. Internally each player is a separate instance of the module, created through a factory function — exactly the same idea Video.js uses. This is explained in Notes on Implementation.

Configuration

Almost everything you will ever change lives in YAML configuration files. YAML is a plain-text format for settings: a name, a colon, and a value. You do not need to know any programming to edit it.

Configuration Files

Settings come from three files that are merged together in order. Later files win, so you only have to write down what you want to change.

Table 1. Configuration files
File What it is for

_data/modules/defaults/videoPlayer.yml

The defaults. Every possible option with a sensible value and a comment explaining it. You normally leave this file alone and read it as a reference.

_data/modules/videoPlayer.yml

Your global settings. Anything you put here overrides the defaults for all players. This is where you switch the module on with enabled: true.

_data/modules/videoPlayer_control.yml

Your per-player settings. This file lists each player separately, so you can give every player its own id, its own playlist, and its own look.

The merge chain is: defaults → overridden by global settings → overridden by per-player settings. The merge works per key: a per-player videoJS: block only needs the keys you want to change; every missing key falls back to the global settings and then to the defaults. You never have to copy a whole block.

General Options

These live at the top of the settings and control the module as a whole.

Table 2. General options
Option Default Description

enabled

false

Master on/off switch for the module. Set it to true in your global videoPlayer.yml to turn the player on.

playlist_url_base

/assets/data/apps/videoPlayer/playlists/lists

The folder where your ready-made playlist files live. A short file name in a preload list is looked up in this folder.

xhr_data_path

/assets/data/videoPlayer

The folder the module reads its generated data from.

UI Elements

The ui_elements: block controls which controls (buttons and switches) of a player are shown at all. Each key stands for one visible element and takes true (show it) or false (hide it).

The two header buttons can be switched on and off per player: set the key in the defaults for everyone, in your global videoPlayer.yml for all players of your site, or inside one player’s entry in videoPlayer_control.yml for that player only. As everywhere else, the most specific setting wins.

Table 3. UI elements
Option Default Description

ui_elements.show_playlist_button

true

The Show/Hide Playlist button on the left of the header bar. When set to false the button is not rendered for this player; the header title stays centred and starts empty.

ui_elements.edit_playlist_button

true

The Manage Playlists button on the right of the header bar. When set to false the button is not rendered, so the viewer cannot open the edit panel of this player.

ui_elements.search

true

The search box above the playlist.

ui_elements.sort

true

The sort control of the playlist.

ui_elements.modeSwitch

true

The switch that flips the playlist between the list and the cards layout.

ui_elements.mergeSwitch

true

The merge switch. When on, importing another playlist adds its videos to the current one instead of replacing it.

ui_elements.loop

false

The loop switch that repeats the playlist from the top when the last video finishes.

The playlist-panel controls (search, sort, and the switches) also manage themselves: they hide automatically while the playlist is empty and appear as soon as it has content. The loop switch is extra careful — it only appears when every item in the list belongs to a series, because looping only makes sense for a complete series. Sort options that would do nothing (for example sorting by rating when no video is rated yet) are hidden as well.

Playlist Options

The playlist: block controls the playlist panel that sits under each player.

Table 4. Playlist options
Option Default Description

playlist.enabled

true

Show the playlist panel. Turn it off for a plain single-video player.

playlist.close_on_play

false

Close the playlist panel automatically as soon as a video starts playing.

playlist.pip

false

Allow picture-in-picture: a small floating video window that keeps playing while the viewer scrolls or switches tabs.

playlist.type

list

The starting layout of the playlist: list (compact rows) or cards (a grid of preview cards).

playlist.cards.perRow

2

How many cards to show per row when the playlist is in cards mode. Each player can have its own value.

Player Options (videoJS)

The videoJS: block controls the video engine itself: how a video starts, how fast it can play, and how poster (preview) images are made.

Table 5. Basic player options
Option Default Description

videoJS.autoStart

true

Start playing as soon as a video is loaded.

videoJS.preloadVideo

true

Let the browser fetch the video ahead of time so playback starts quickly.

videoJS.playbackRates.enabled

true

Offer a speed menu on the player.

videoJS.playbackRates.values

[ 0.25, 0.5, 1, 1.5, 2 ]

The speeds available in that menu (1 is normal speed).

The players.native block sets the behaviour of the player itself. Despite its name it is used for both video kinds — native files and YouTube videos play through the same settings. The most useful keys are shown below.

Table 6. Native player options
Option Default Description

autoplay

true

Play as soon as the video is ready.

controls

true

Show the player’s control bar.

fluid

true

Make the player responsive so it fills the width of its container.

preload

auto

How eagerly to load the video: auto, metadata, or none.

playsinline

true

On iPhones, play inside the page instead of forcing full screen.

default_poster

/assets/image/icon/videojs/videojs-poster.png

The image shown before a video plays, when no other poster is available.

sourceOrder

[ mp4 ]

The order in which video file types are tried. Add more types (for example [ mp4, webm, ogv ]) when you host the same video in several formats.

Automatic Poster Images

A poster is the still image shown before a video plays. For native videos, J1 VideoPlayer can create the poster for you by grabbing a frame from the start of the video. This is controlled by videoJS.poster.autoGenerate.

Table 7. Poster auto-generation
Option Default Description

enabled

true

Turn automatic poster creation on or off.

capturePosition

5

Which second of the video to grab the frame from. If this is 0 or less, captureFraction is used instead.

captureFraction

10

A percentage of the video’s length to use as the capture point (used only when capturePosition is 0 or less).

maxWidth

540

The poster is shrunk to at most this many pixels wide (the shape is kept).

mimeType

webp

The image type to save: jpeg, png, or webp.

quality

0.8

Image quality from 0 to 1 (used for jpeg and webp).

For YouTube videos you never need this: the poster is fetched straight from YouTube’s own thumbnail service.

Plugin Options

Video.js gains extra buttons through small plugins. J1 VideoPlayer ships a handful, switched on and off under videoJS.plugins:.

Table 8. Plugins
Plugin What it does

playlist

The playlist engine. autoadvance plays the next video when one ends, and autoadvance_delay sets the pause (in seconds) between them.

skipButtons

Adds skip forward and skip back buttons around the play button. forward and backward set how many seconds each skip jumps.

nextPrevButtons

Adds next and previous buttons to jump between playlist items.

zoomButtons

Adds zoom / rotate controls for the video image.

hotKeys

Keyboard shortcuts (for example the arrow keys to seek). Off by default.

Per-Player Settings

The videoPlayer_control.yml file is where you actually create players. It holds a list of players, and each entry describes one player. Keys you do not set fall back to the global settings and then the defaults.

Table 9. Per-player keys
Key Description

enabled

Whether this player is built at all.

id

The player’s unique name (for example player_1). It must be unique on the page and is used to build all of the player’s element ids.

description

A human-friendly label for the player.

playlist.preload

A list of playlist files to load into this player on page load. A short file name is looked up in playlist_url_base; a full URL or a path starting with / is used as-is. See Playlist and Preloading.

ui_elements

Show or hide this player’s controls, for example ui_elements.edit_playlist_button: false to remove the Manage Playlists button from this player only. See UI Elements.

videoJS, playlist, toolbox, …​

Any option from the sections above, applied to this player only.

Per-player videoJS settings really are per-player. Every player resolves its own autoStart, its own playbackRates, its own plugins, and so on. Two players on the same page can, for example, offer different speed menus. You only write the keys you want to change; everything else is inherited.

A control file with one fully customised player looks like this:

settings:
  players:
    - player:
      enabled:            true
      id:                 player_tiny_desk_concerts
      description:        NPR Tiny Desk Concerts
      # hide the edit button for this player only
      ui_elements:
        edit_playlist_button: false
      # this player gets its own speed menu
      videoJS:
        autoStart:        true
        playbackRates:
          enabled:        true
          values:         [ 0.5, 1, 1.5, 2 ]
      playlist:
        preload:          [ tinydesk-concerts.json ]
        cards:
          perRow:         4

The Player on the Page

You do not write the player’s HTML — J1 generates it from your configuration. Still, it helps to know the parts a viewer sees, because the settings above map onto them.

The Header Bar

Every player has a slim header bar with three slots:

Show / Hide Playlist button (left)

Opens and closes the playlist panel. It is disabled and greyed out until a playlist is loaded.

Title (centre)

A short label, for example the title of the running video.

Manage Playlists button (right)

Opens the edit panel, where the viewer can add, import, export, or clear videos.

Either button can be hidden per player through the ui_elements keys show_playlist_button and edit_playlist_button (see UI Elements). The header keeps its three-slot layout even when a button is hidden, so the title always stays centred.

The Video Area

Below the header is the video itself. Before anything is loaded, a friendly placeholder (the VideoJS logo) is shown in its place.

The Playlist Panel

When opened, the playlist panel shows:

  • a search box to filter the list as you type;

  • a sort control to reorder the list;

  • a list / cards switch to change the layout;

  • a merge switch that decides whether importing adds to or replaces the list;

  • a loop switch to repeat the playlist (shown only for series);

  • the videos themselves, each with its poster, title, author, and a star rating.

Which of these appear depends on the matching options in the ui_elements: block, and the controls hide themselves while the playlist is empty.

The Edit Panel

The edit panel is where content is managed. It offers:

  • a box to paste a video link (for example a YouTube URL) to add one video;

  • an Import control to load a ready-made playlist from the server;

  • Export Playlist to save the current playlist to a file;

  • Import Playlist to load a playlist from a file on the viewer’s computer;

  • Clear Playlist to empty the list.

Playlist Items

A playlist is simply a list of items, and each item is a small block of information about one video. When you write a playlist file by hand, or read one that was exported, this is the shape of each item.

Only videoId is truly required; every other field has a sensible default and can be left out.

Table 10. Playlist item fields
Field Type Description

videoId

text

Required. A unique id for this item. For YouTube this is usually the video’s id; for native videos any unique string works.

title

text

The video’s title, shown in the list.

author

text

The channel or author name.

description

text

A longer description. It is searchable.

category

text

A category label used for grouping and search.

tags

list

A list of tag words, for example [ music, live ].

type

text

The video’s MIME type. Defaults to video/mp4.

src

text

The address of the native video file. Leave empty for YouTube items.

videoLink

text

The canonical link. For YouTube this is the YouTube URL; for native videos it is usually the same as src.

infoLink

text

An optional link to a page with more information.

poster

text

The preview image URL. For YouTube it is filled in automatically; for native videos it can be generated (see Automatic Poster Images).

duration

number

The length of the video in seconds.

issueDate

text

The publish date of the video.

episode

number

An episode number, if the video is part of a series.

series

number

A series number.

rating

number

A star rating from 0 to 5. The viewer can set this in the panel.

lastPosition

number

The second the viewer last stopped at, so playback can resume there.

watchDate

text

When the item was last watched (set automatically).

createDate

text

When the item was added (set automatically).

creator

text

Always videoPlayer for items the module creates.

A single item in a playlist file looks like this:

{
  "videoId":     "abcXYZ12345",
  "title":       "Tiny Desk Concert",
  "author":      "NPR Music",
  "description": "A short live set recorded at the office.",
  "category":    "music",
  "tags":        [ "live", "acoustic" ],
  "type":        "video/mp4",
  "videoLink":   "https://www.youtube.com/watch?v=abcXYZ12345",
  "poster":      "",
  "duration":    920,
  "rating":      0
}

A playlist file may be either a plain array of items ([ { …​ }, { …​ } ]) or an object with a playlist key ({ "playlist": [ { …​ } ] }). The module reads both shapes.

Playlist and Preloading

Ready-made playlist files are ordinary .json files kept in the folder set by playlist_url_base. To have a player load one (or several) on page load, list the file names under that player’s playlist.preload key:

playlist:
  preload: [ tinydesk-concerts.json, carpool-karaoke.json ]

Preloading is safe to repeat. On every page load the module merges the file into the player’s playlist: it adds any videos that are not there yet and leaves everything else — including the viewer’s own additions, ratings, and watch positions — untouched. Nothing is ever duplicated or overwritten. Preloading only fills the list; it does not start playing on its own.

Methods

Most pages need no JavaScript at all — the configuration files already cover normal use. The methods below are for advanced users who want to build custom controls, load videos after the page has loaded, or read the player’s state. The module follows the same shape as Video.js. You get a player through a factory function, and then work with that player object.

The Module Factory

videoPlayer(id, options) is the main entry point. It creates the player for id the first time you call it and returns the existing one on later calls (this is called "create-or-get"). Options given for a player that already exists are ignored.

// create or fetch the player named 'player_1'
const vp = videoPlayer('player_1', options);
Table 11. Module functions
Function Description

videoPlayer(id, options)

Create the player for id, or return it if it already exists.

videoPlayer.getPlayer(id)

Return the player for id, or null if it does not exist. Never creates one.

videoPlayer.getPlayers()

Return the registry object holding every live player, keyed by id.

videoPlayer.VERSION

The module’s version string.

videoPlayer.players

A direct reference to the same registry getPlayers() returns.

Older code may use videoPlayer.createInstance(id), getInstance(id), hasInstance(id), listInstances(), or removeInstance(id). These still work but are deprecated aliases for the functions above. New code should use the factory, getPlayer(), getPlayers(), and dispose().

A Player Instance

The object returned by the factory represents one player. It carries a few accessors and, most importantly, its playlistManager.

Table 12. Instance members
Member Description

vp.id()

The player’s id.

vp.options()

The options the player was created with.

vp.getPlayerID()

The active player id used internally to scope elements.

vp.playlistManager

The object that manages this player’s playlist (see below).

vp.closePlaylist()

Close the playlist panel.

vp.closeEditPlaylist()

Close the edit panel.

vp.dispose()

Remove the player from the registry so its id can be created again.

Working with Playlists

The playlist is managed by vp.playlistManager. Its methods are grouped below by what they do. Anywhere you see videoId, it is the videoId field of a playlist item.

Adding and Updating Videos

Table 13. Add / update
Method Description

addEntry(entry)

Add a video to the playlist from an item object.

createEntry(entry)

Create a playlist item early (from what is known at load time) and store it.

enrichEntry(videoId, meta, force)

Fill in details that only arrive later — the real title, author, poster, or measured length. By default it only fills empty fields; pass force = true to overwrite.

updateEntryRating(videoId, rating)

Set the star rating (0-5) for an item.

updateEntryPosition(videoId, positionSeconds)

Remember where the viewer stopped, so playback can resume.

updateWatchDate(videoId)

Mark an item as watched now.

updateEntryFields(videoId, fields)

Update several fields of an item at once.

Removing Videos

Table 14. Remove
Method Description

deleteEntry(videoId)

Remove a single video from the playlist.

clearPlaylist()

Remove every video from the playlist.

Reading the Playlist

Table 15. Read
Method Description

load()

Return the whole playlist as an array of items.

getEntry(videoId)

Return one item.

getEntryPosition(videoId)

Return the saved resume position (in seconds) for an item.

getNextVideoId(currentVideoId)

Return the id of the video that follows the given one.

Playing Videos

Table 16. Playback
Method Description

playEntry(videoId)

Load and play the given video.

embedRunVideo(videoId, mode)

Load a video into the player (the lower-level call playEntry() uses).

autoLoadFirstEntryOnReload()

Load the first item of the playlist automatically when the page reloads.

Importing, Exporting, and Preloading

Table 17. Import / export
Method Description

importFromUrl(url)

Load a playlist file from a web address into the playlist.

importFromFile()

Load a playlist from a file chosen on the viewer’s computer.

exportToFile(filename)

Save the current playlist to a .json file.

backupToFile(filename)

Save a backup copy of the current playlist to a file.

preloadPlaylists(preloadList, baseUrl, playerId)

Merge one or more configured playlist files into the player on load. This is what the playlist.preload setting triggers behind the scenes.

Searching and Sorting

Table 18. Search / sort
Method Description

buildSearchIndex()

Build the search index for the current playlist.

searchPlaylist(query)

Filter the playlist by a search term.

clearSearch()

Clear the current search and show the whole list again.

sortPlaylist(criterion)

Reorder the list, for example by watchDate or rating.

Rendering the Panel

Table 19. Render
Method Description

renderCurrent()

Redraw the playlist panel to match the stored playlist.

setActiveItem(videoId)

Mark an item as the one currently playing (it is highlighted).

clearActiveItem()

Remove the "currently playing" highlight from all items.

Setup Methods

These are normally called by the adapter that starts the player. You rarely call them yourself.

Table 20. Setup
Method Description

setAdapterOptions(options)

Hand the merged configuration to the playlist manager.

setPlayerID(id)

Tell the manager which player it belongs to, so it uses the right storage and the right HTML elements.

Notes on Implementation

This section explains a few design choices. You do not need them for daily use, but they help when something behaves unexpectedly on a page with several players.

One Instance Per Player

The module is built the same way as Video.js. Calling videoPlayer(id) returns a separate instance for each id, kept in a shared registry. Each instance owns its own state, its own playlist manager, and its own event handlers. There is no hidden "default" player that everything shares — that older design caused several players to fight over one set of settings, so it was removed.

Per-Player Settings Win

Whenever a player needs one of its videoJS settings, it looks in a fixed order: first the options handed to its own factory call (that is, the merged per-player configuration), then the page-global options, and only then an internal fallback. In short: the setting closest to the player wins. This is why two players on one page can autostart differently, offer different speed menus, or run different plugins.

Each Player Has Its Own Storage

Because every player keeps its playlist in the browser’s local storage, the module gives each player its own storage name by adding the player id to it (for example playlist_player_1). This is why a video added to one player never appears in another. The same scoping applies to the small UI preferences — whether the playlist was last shown as a list or as cards, the merge switch, the loop switch, and the last search mode are all remembered per player.

Native and YouTube Share One Path

Both native and YouTube videos play through the same Video.js player. The module looks at the item’s link to decide which one it is: a YouTube link is recognised and played through YouTube; anything else is treated as a native file and loaded from its src. Posters follow the same rule — YouTube posters come from YouTube, native posters are generated from the video. The player settings for both kinds come from the players.native block.

The Cards View Is a Web Component

The cards layout of the playlist is rendered by a small, modern web component (built with Lit). It draws each video as a card and updates only the card that changed — rating one video or deleting one entry never redraws the whole grid. It renders into the normal page (light DOM), so all existing styles and click handling keep working. You never interact with it directly; the mode switch and playlist.type control it for you.

Preloading Is Non-Destructive

Preloading always merges. It never overwrites the viewer’s existing list, and running it again on the next reload never creates duplicates. This is why it is safe to keep a preload list in your configuration permanently.

Examples

The examples below are complete, working configurations. Copy one into your videoPlayer_control.yml and adjust the ids and playlist file names.

J1 VideoPlayer is mobile-friendly. On touch devices the player and its buttons respond to taps, and the layout follows the width of the page so it looks right on phones and tablets.

Player With a Preloaded Playlist

This is the simplest useful setup: a single player that loads a ready-made playlist file on page load and shows it as a grid of cards, four per row.

settings:
  players:
    # --------------------------------------------------------------------------
    # Tiny Desk Concerts
    #
    - player:
      enabled:                          true
      id:                               player_tiny_desk_concerts
      description:                      NPR Tiny Desk Concerts
      ui_elements:
        edit_playlist_button:           false
      videoJS:
        autoStart:                      true
        playbackRates:
          enabled:                      true
          values:                       [ 0.5, 1, 1.5, 2 ]
        plugins:
          playlist:
            enabled:                    true
      playlist:
        preload:                        [ tinydesk-concerts.json ]
        cards:
          perRow:                       4

Tiny Desk Concerts is a popular, award-winning video series featuring live music performances at an actual office desk, hosted by NPR Music. Started in 2008 by radio host Bob Boilen and producer Stephen Thompson. The show has grown from a small platform for folk and indie artists into a worldwide pop-culture hit.

Tiny Desk Concerts

Multiple Players on a Page

Each player has its own id, its own preloaded playlist, and its own card layout. They do not share anything.

settings:
  players:
    - player:
      enabled:      true
      id:           player_1
      description:  NPR Tiny Desk Concerts
      playlist:
        preload:    [ tinydesk-concerts.json ]
        cards:
          perRow:   4
    - player:
      enabled:      true
      id:           player_2
      description:  Carpool Karaoke
      playlist:
        preload:    [ carpool-karaoke.json ]
        cards:
          perRow:   3

Hiding a Header Button

A "read-only" player: the viewer can watch and browse the preloaded playlist, but the Manage Playlists button is hidden, so the playlist cannot be changed from the page. The player also gets its own, shorter speed menu.

settings:
  players:
    - player:
      enabled:      true
      id:           player_tiny_desk_concerts
      description:  NPR Tiny Desk Concerts
      ui_elements:
        edit_playlist_button: false
      videoJS:
        autoStart:  true
        playbackRates:
          enabled:  true
          values:   [ 0.5, 1, 1.5, 2 ]
      playlist:
        preload:    [ tinydesk-concerts.json ]
        cards:
          perRow:   4

A Small Playlist File

A playlist file that mixes one YouTube video and one native video. Save it in your playlist_url_base folder and reference it from a preload list.

[
  {
    "videoId":     "abcXYZ12345",
    "title":       "Live at the Tiny Desk",
    "author":      "NPR Music",
    "description": "A short acoustic set.",
    "category":    "music",
    "tags":        [ "live", "acoustic" ],
    "videoLink":   "https://www.youtube.com/watch?v=abcXYZ12345",
    "duration":    920,
    "rating":      0
  },
  {
    "videoId":     "promo-clip-01",
    "title":       "Product Tour",
    "author":      "Our Team",
    "description": "A self-hosted introduction video.",
    "category":    "howto",
    "tags":        [ "intro" ],
    "type":        "video/mp4",
    "src":         "/assets/video/product-tour.mp4",
    "videoLink":   "/assets/video/product-tour.mp4",
    "duration":    140,
    "rating":      0
  }
]

Adding a Video From JavaScript

For a custom button, you can add and play a video yourself. First get the player, then use its playlist manager.

// get the running player named 'player_1'
const vp = videoPlayer.getPlayer('player_1');
if (vp) {
  // add a video to the playlist
  vp.playlistManager.addEntry({
    videoId:   'abcXYZ12345',
    title:     'Live at the Tiny Desk',
    author:    'NPR Music',
    videoLink: 'https://www.youtube.com/watch?v=abcXYZ12345'
  });
  // then play it
  vp.playlistManager.playEntry('abcXYZ12345');
}