paella-core
Version:
Multistream HTML video player
147 lines (107 loc) • 6.86 kB
Markdown
# Using standard HTML player if the video is compatible
## Definition of Native Stream
For `paella-core`, a native stream is a video whose video manifest contains only information that can be played directly by the browser using a native media player. For example, if it contains a single stream of a natively supported format, it does not contain slides, etc.
In these cases, we may want to use a native player, which will be more efficient and will not load the browser as much. This is especially so when we are going to have a page with a lot of videos.
There is another example where we may want to dispense with loading paella player: in cases where we only have an audio stream without slides. In this case, a native audio player will take less space on the screen.
paella-core provides an API to query all the data of the video manifest. This API also has some more advanced utilities. In this tutorial we are going to see how to replace `paella-core` with a native audio player, if the video manifest is supported.
## Check the video manifest compatibility
First, we need to check if the video manifest is compatible with native playback. In our case, we want to use a native player if these conditions are met:
- There is only one stream.
- The stream is audio only.
- It does not contain slides.
- It does not contain subtitles.
In any other case, it is worth loading the full Paella Player: for example, if we have an audio-only stream without slides, but it has subtitles, it would be interesting to load it with Paella Player to be able to see the subtitles.
To implement this, we will use the following APIs:
- `playerInstance.streams`: Gives access to the streams of the video manifest. It also contains a series of utility functions:
* `playerInstance.streams.isNativePlayable`: returns `true` if the video manifest contains a single stream that can also be played natively.
* `playerInstance.streams.isAudioOnly`: returns `true` if the video manifest contains an audio stream. It can also return `true` if the second stream is not of type `video`, for example, if it is a list of images.
* `playerInstance.streams.nativePlayer`: returns a DOM multimedia element configured with the stream that can be played natively, or `null` if the video manifest is not natively playable.
- `playerInstance.frameList`: Provides utilities for working with the slide list of the video manifest, such as getting an image for a given moment in time.
* `playerInstance.frameList.isEmpty`: returns `true` if the video manifest does not define a frame list.
- `playerInstance.captions`: Subtitle information from the video manifest. Keep in mind that if the subtitles are loaded in another way (for example, with a data plugin) this function will not return anything. This function only works with the subtitles defined in the video manifest.
With all of the above, we can define the following code to detect if we can use a native audio player:
```js
...
await player.loadManifest();
// The player manifest access functions will only be available after the manifest has been loaded.
if (player.streams.isNativelyPlayable &&
player.streams.isAudioOnly &&
player.frameList.isEmpty &&
(!player.captions || player.captions.length === 0))
{
const nativePlayer = player.streams.nativePlayer;
// TODO: load the native player
}
else {
// Add here the rest of the player loading code
player.addDictionary("es", ...);
player.addCustomIcon(...);
...
}
// We always load the stylesheet, since we are going to introduce styles for the native player as well.
await utils.loadStyle('style.css');
```
## Load the native player
Now we need to add the native player to the DOM tree of the web. First, we are going to modify a part of the HTML code. In the first tutorial, we created a container for the video player with inline styles to make the player fit the entire window. If we are going to change the player to a native player, we will probably want to modify these styles. So the first thing we will do is to remove the inline styles and move them to the stylesheet file.
First we modify the element of the video container, changing this:
```html
<div id="player-container" style="width: 100vw; height: 100vh"></div>
```
to this one:
```html
<div id="player-container"></div>
```
Then we add the CSS styles that we have removed from the DOM element to the `style.css` file:
```css
...
#player-container {
width: 100vw;
height: 100vh;
}
```
With these changes, the player should continue to work the same for non-native videos.
The last step is to add the native video player to the DOM tree and unload the Paella player to free up the resources it is using. The `player.streams.nativePlayer` attribute returns a media element that will be either `<video>` or `<audio>` depending on the case. In our case it will always be `<audio>`, since one of the conditions that we have contemplated to use a native player is that the video manifest is only audio.
The first thing we will do is to add the `controls` attribute to the element of the native player so that the browser adds the reproduction controls, that depending on the browser can be some or others, but they will always contain the play/pause button, a progress bar and some other element.
Next we unload the Paella player, we obtain the container through its `id` attribute, we eliminate all its content and we add the native player to it.
```js
...
if (player.streams.isNativelyPlayable &&
player.streams.isAudioOnly &&
player.frameList.isEmpty &&
(!player.captions || player.captions.length === 0))
{
const nativePlayer = player.streams.nativePlayer;
nativePlayer.setAttribute("controls","");
await player.unload();
const playerContainer = document.getElementById('player-container');
playerContainer.innerHTML = "";
playerContainer.appendChild(nativePlayer);
}
...
```
## Native player style
There is one last thing to do. As the code has been left we have the element of the video container that occupies the whole page, and in this example it can be indifferent, but if we had the player embedded in a web page it would be absurd that the container of the audio player occupies so much. To solve this, what we will do is to add a CSS class to the player container and modify its style by CSS so that it stops occupying so much space:
**main.js:**
```js
...
if (player.streams.isNativelyPlayable &&
...)
{
...
playerContainer.classList.add('native-player');
}
...
```
**style.css:**
```css
#player-container.native-player {
width: 100%;
height: auto;
margin-top: 20px;
margin-bottom: 20px;
}
#player-container.native-player > audio {
width: 100%;
}
```
Previous tutorial: [Using a sequence of images as video](image_sequence_video.md)