Video format plugins
The video format plugins provide the necessary APIs to implement plugins that can play video in different formats. A video format is composed by two elements:
- A video player: adds the player to the Paella Player DOM tree, and implements the playback functions. such as play, pause, volume, etc.
- A video plugin: is a special type of plugin used to provide Paella Player with the necessary information aboout the format that the video player can play. It is also used as a factory to create the video player instance.
Video player
Section titled “Video player”import { VideoPlugin, Video} from '@asicupv/paella-core';
export class MyVideoPlayer extends Video {
constructor(player, parent, isMainAudio) { super(player, { tag: 'video', // Define here the DOM element type of the player parent });
// if !isMainAudio you should mute the audio this.isMainAudio = isMainAudio; }
// Implement the following functions and properties async play() { ... }
async pause() { ... }
async duration() {... }
async currentTime() { ... }
async setCurrentTime(t) { ... }
async volume() { ... }
async setVolume(v) { ... }
async paused() { ... }
async playbackRate() { ... }
async setPlaybackRate() { ... }
async getQualities() { ... }
async setQuality(q) { ... }
get currentQuality() { ... }
async getDimensions() { ... }
async supportsMultiaudio() { ... }
async getAudioTracks() { ... }
async setCurrentAudioTrack(t) { ... }
get currentAudioTrack() { ... }
// This function is called when the player loads, and it should // make everything ready for video playback to begin. async loadStreamData(streamData) { ... }
get isEnabled() { ... }
async enable() { ... }
async disable() { ... }}
...Some remarks about Video class:
getQualities(): returns an array ofVideoQualityItemobjects, or an empty array if the video format does not support multi quality.- To set a quality level, you must pass a
VideoQualityItemfrom the above array to thesetQuality(q)function. getAudioTracks()returns an array ofAudioTrackDataobjects, or null if the video format does not support multi quality. More information on videos with multiple audio tracks can be found in this document.- To set an audio track, you must pass an
AudioTrackDataitem of the above array to thesetCurrentAudioTrack(t)function. get currentAudioTrack()returns theAudioTrackDataobject for the current audio track.
Video plugin
Section titled “Video plugin”import VideoPlugin, { Video } from 'paella-core/js/core/VideoPlugin';
... MyVideoPlayer definition
export default class MyVideoPlugin extends VideoPlugin { get streamType() { return "streamType"; }
async isCompatible() { return true; }
async getVideoInstance(playerContainer, isMainAudio) { new MyVideoPlayer(this.player, playerContainer, isMainAudio); }}Video plugin priorities
Section titled “Video plugin priorities”To determine the loading order of the video plugins, the order attribute of the configuration is used, so that if there are several plugins compatible with a stream, the one with the lowest value will be loaded first.
{ ... "plugins": { "es.upv.paella.mp4VideoFormat": { "enabled": true, "order": 1, }, "es.upv.paella.hlsVideoFormat": { "enabled": true, "order": 0, }, }}The enable/disable video API
Section titled “The enable/disable video API”If we have more than one video stream in the video manifest, it is possible for the user to select a layout of only one video. In this case, one of the two videos would be hidden. The enable/disable API is used to allow a video plugin to disable the downloading of data from a video when it is to be hidden, and enable it again when it is to be shown again.
This API is composed of two functions and one attribute:
isEnabled (read): it must return true or false depending on the current video status. This value must return the internal video status, that is handled by the other two functions of the API:async enable():paella-corecalls this plugin function when the video needs to be enabled. If we implement this API, we are responsible for returning a valid state in theisEnabledattribute.async disable():paella-corecalls this plugin function when the video needs to be disabled. If we implement this API, we are responsible for returning a valid state in theisEnabledattribute. Note that if the stream is the main audio, we may not want to disable it, as (depending on the underlying technology) we are likely to lose the audio as well. For example, if the stream is anmp4video, we can`t disable the video without also losing the audio.
Load URL API (paella-core >= 1.11)
Section titled “Load URL API (paella-core >= 1.11)”URL upload API allow you to upload videos without the need to set a manifest, directly through the URLs of the video files.
await myPlayer.loadUrl([ "presenter.mp4", "presentation.mp4"]);For more information, see the loadUrl() function of the Paella class.
Through this method, paella-core will be in charge of generating a valid manifest from the URLs. To generate the video manifest it is necessary that the video plugins include some extra information, since it is the video plugins that are in charge of generating the piece of the video manifest corresponding to the streams.
These functions are implemented in the video plugin optionally, but it is obviously mandatory to implement them if we want to provide URL upload support for a new video format.
Suppose we are developing a plugin for HTML5 video, supporting ogv and webm formats:
...
export default class HTML5VideoPlugin extends VideoPlugin { get streamType() { return "html5Video"; }
async isCompatible() { return isChromiumOrMozilla(); }
async getVideoInstance(playerContainer, isMainAudio) { new HTML5VideoPlayer(this.player, playerContainer, isMainAudio); }}To support the loading of this type of URLs we would have to implement the following functions:
getCompatibleFileExtensions(): Returns the list of file extensions supported by the plugin in the stream information.getManifestData(fileUrls): Devuelve el trozo de manifest correspondiente con el contenido de la propiedadstreams.
export default class HTML5VideoPlayer extends VideoPlugin { ... getCompatibleFileExtensions() { return ["mp4","m4v","ogg","ogv","webm"]; }
getManifestData(fileUrls) { return { html5Video: fileUrls.map(url => ({ src: url, mimetype: getMimetype(url) })) } }}Utilities
Section titled “Utilities”The JavaScript volume API is not available on some devices, such as iPad and iPhones, because the operating system restricts these actions to the physical volume buttons. You can check if the device supports the volume API using the async isVolumeApiAvailable() function.
This function is available in the Video base class:
import { Video, VideoPlugin } from 'paella-core';
export class MyMp4VideoPlugin extends Video { ... async setVolume(v) { if (await this.isVolumeApiAvailable()) { this.video.volume = v; return true; } else { return false; } } ...}You can also import the standalone version of this function. This is very useful, for example, to implement UI plugins:
import { ButtonPlugin, isVolumeApiAvailable } from 'paella-core';
export default class MyMutePlugin extends ButtonPlugin { async isEnabled() { const e = await super.isEnabled(); if (e) { return await isVolumeApiAvailable(); } return false; } ...}