# Introduction

**Fluid Player is a free video player for your website.** Drop it onto any page, point it at your video, and you're done. It works on phones, tablets, and desktops, runs ads if you want them to, and stays out of the way of the rest of your site.

You don't need an engineering team to set it up - if you can paste a few lines of HTML, you can be running in about two minutes. And if you'd rather not touch code at all, there's an official WordPress plugin.

💡 **In a hurry?** → [**Quick setup**](/integration/quick-setup) gets you a working player in five minutes flat.

***

### **What you can do with it**

Rather than a flat feature list, **here's what Fluid Player actually does for you** and your site.

#### **💰Make money from your videos**

If you sell ads - or you'd like to - Fluid Player has full ad support built in.

* **Run ads before, during, and after your videos** - pre-roll, mid-roll, and post-roll slots.
* **Video ads and banner ads** - both full-screen video ads (linear) and smaller banner overlays in GIF, JPG, or PNG (non-linear).
* **Works with any ad network** - uses the industry-standard VAST format, so it plugs into the ad provider you already use.
* **Chain multiple ad networks** - VAST Wrappers let you route through ad exchanges.
* **Interactive ad support** - VPAID ads (linear, non-linear, and switching from non-linear to linear) work out of the box.
* **Custom call-to-action text during ads** -  drive viewers to your landing page.

New to ad serving? [See **What is VAST** below.](#what-is-vast)

#### **🎨 Looks right on your site**

* **Built-in design** - comes with a clean, modern skin that's easy to customize.
* **Use the browser's default look** - if you'd rather match the native feel.
* **Add your own logo** - brand the player with your image.
* **Subtitles** - captions for accessibility and reach.
* **Timeline preview** - thumbnail previews when viewers hover the progress bar.

#### **👀 Keeps viewers watching**

* **Mini Player** - when viewers scroll past your video, it shrinks into a floating window so they can keep watching.
* **Suggested Videos** - show related videos after one ends, to keep the session going.
* **Quality options** - offer HD, SD, or whatever versions you have; viewers pick what works best.
* **HLS quality switching** - including an Auto mode (the default) that adapts to the viewer's connection speed.
* **Autoplay control** - fine-grained control over what plays automatically.

#### **⚡ Fast and dependable**

* **Lightweight** - small footprint, won't slow your pages down.
* **Responsive** - adapts to phones, tablets, and desktops.
* **Works in every modern browser** - current Chrome, Firefox, Safari, Edge.
* **Multiple players on one page** - embed as many videos as you like.
* **Hosted on a CDN** - no need to host scripts yourself (though you can if you prefer).
* **Keyboard shortcuts** - configurable per key, for accessibility.

***

### **Get started in 30 seconds**

#### **Step 1: Add a video to your page**

```html
<video id="example-player">
    <source src="video.mp4" type="video/mp4" />
</video>
```

The `id` attribute is what tells Fluid Player which video to enhance - make sure it's there.

#### **Step 2: Load Fluid Player and start it**

```html
<script src="https://cdn.fluidplayer.com/v3/current/fluidplayer.min.js"></script>
<script>
    var player = fluidPlayer('example-player');
</script>
```

That's it. Refresh your page - you should see the Fluid Player skin replace the browser's default video controls.

***

### **Pick your path**

Most people landing here fall into one of a few groups. Pick the one that sounds like you:

* **Running WordPress?** → Use the[ Fluid Player WordPress plugin](/integration/wordpress) - no code needed.
* **Have your own site and want to add it yourself?** → [Quick setup ](/integration/quick-setup)walks through the install.
* **Setting up video ads?** →[ Advertisements](/configuration/advertisements) cover VAST tags, ad slots, and VPAID.
* **Building a web app or custom product?** → Head to the[ Developer guide](/api/controls-api) for the full API, events, and controls.

***

### **What is VAST?**

If you're planning to run ads on your videos, you'll see "VAST" mentioned a lot - here's the short version.

**VAST stands for Video Ad Serving Template.** It's a standard from the IAB (Interactive Advertising Bureau) that lets ad networks and video players communicate in a shared language.

In practice, **VAST is what makes Fluid Player work with any ad provider** - your own ad server, ad networks, ad exchanges, all of them. You point Fluid Player at a VAST tag (a URL your ad provider gives you), and Fluid Player handles the rest: fetching the ad, playing it, tracking views and clicks, and resuming your video when the ad ends.

You don't need to understand the technical details to use it - just paste the VAST tag your ad provider gives you into the configuration.

**For the full specification**, see the[ IAB VAST documentation](https://iabtechlab.com/standards/vast/).

***

### **License**

Fluid Player is released under the **MIT License** - free to use commercially or non-commercially, including in closed-source products.&#x20;

See the[ License page](https://docs.fluidplayer.com/about/license) for the full terms.

***

### **Where next?**

> 💡 **Ready to set it up?** → [**Quick setup**](/integration/quick-setup)**.**
>
> 📖 **Want to see every option?** → [**Configuration**](/configuration/layout)**.**
>
> 💬 **Need help?** → [**Help & support**](/about/help)**.**


# Quick setup

This page walks you through adding Fluid Player to your website. There are two ways to do it:

* **The CDN approach** - paste a `<script>` tag and you're done. **Best for most websites**, no installation needed.
* **The NPM approach** - install the package via NPM. **For developers using a build tool like Webpack or Vite.**

**Pick whichever matches your setup. If you're not sure, the CDN approach is the right choice.**

> ℹ️ **Running WordPress?** You don't need to do any of this - **install the** [**Fluid Player WordPress plugin**](/integration/wordpress) **instead.**

***

### **Option 1: Use the CDN (recommended)**

A CDN is a service that hosts the Fluid Player files for you, so you don't have to download or install anything. You just link to them from your page.

#### **Step 1: Add a video to your page**

If you don't already have one, add a `<video>` tag where you want the player to appear:

```html
<video id="example-player">
    <source src="video.mp4" type="video/mp4" />
</video>
```

The `id` attribute is what tells Fluid Player which video to enhance - make sure it's there.

#### **Step 2: Load Fluid Player and start it**

Just before the closing `</body>` tag of your page, add the Fluid Player script and a one-line initializer. Your finished page should look like this:

```html
<!-- The video, somewhere in your page -->
<video id="example-player">
    <source src="video.mp4" type="video/mp4" />
</video>

<!-- Just before </body> -->
<script src="https://cdn.fluidplayer.com/v3/current/fluidplayer.min.js"></script>
<script>
    var player = fluidPlayer('example-player');
</script>
```

That's it. Refresh your page - you should see the Fluid Player skin replace the browser's default video controls.

> ✅ **As of v3.0.0**, the CDN build includes the CSS automatically. You don't need a separate `<link>` tag for stylesheets.

#### **Pinning to a specific version**

The URL above (`/v3/current/`) always serves the latest v3 release - recommended for most cases. If you'd rather lock to a specific version so it never changes underneath you, use:

```html
<script src="https://cdn.fluidplayer.com/3.0.0/fluidplayer.min.js"></script>
```

***

### **Option 2: Install via NPM**

Use this approach if you're building a JavaScript application with a bundler like Webpack, Vite, or Rollup.

#### **Install the package**

Run one of these in your project root (where `package.json` lives):

**Using npm:**

```bash
npm install fluid-player@^3.0.0
```

**Using yarn:**

```bash
yarn add fluid-player@^3.0.0
```

#### Import the JavaScript

Wherever you want to use Fluid Player in your code:

```javascript
import fluidPlayer from 'fluid-player';
```

#### Import the CSS

The NPM build does not bundle CSS — you need to import it separately. How you do that depends on your bundler. For a Webpack project using `~` as the `node_modules` import prefix:

```css
@import "~fluid-player/src/css/fluidplayer.css";
```

Refer to your bundler's documentation if you're using a different tool.

***

### Adding multiple quality options

If you have your video in different qualities (1080p, 720p, etc.), you can let viewers pick. Add multiple `<source>` tags — Fluid Player will show a quality selector in the player controls.

```html
<video id="my-video" controls style="width: 640px; height: 360px;">
    <source src="vid_1080p.mp4" title="1080p" type="video/mp4" />
    <source src="vid_720p.mp4" title="720p" type="video/mp4" />
    <source src="vid_480p.mp4" title="480p" type="video/mp4" />
</video>
```

The `title` attribute is what shows up in the quality menu.

#### Marking a source as HD

To highlight high-definition options visually, add `data-fluid-hd` to the `<source>` tag. The HD label uses your player's primary color by default.

```html
<video id="my-video" controls style="width: 640px; height: 360px;">
    <source data-fluid-hd src="vid_1080p.mp4" title="1080p" type="video/mp4" />
    <source data-fluid-hd src="vid_720p.mp4" title="720p" type="video/mp4" />
    <source src="vid_480p.mp4" title="480p" type="video/mp4" />
</video>
```

If you'd rather use a different color for the HD label, override it in your own CSS - the relevant class is `fp_hd_source`:

```css
.fp_hd_source { color: yellow !important; }
```

***

### Customizing the player

Fluid Player accepts a configuration object as a second argument. This is where you set up appearance, ad behavior, and almost everything else.

```html
<video id="my-video" controls style="width: 640px; height: 360px;">
    <source src="vid.mp4" type="video/mp4" />
</video>

<script type="text/javascript">
var player = fluidPlayer(
    'my-video',
    {
        layoutControls: {
            // Parameters to customise the look and feel of the player
        },
        vastOptions: {
            // Parameters to customise how the ads are displayed and behave
        }
    }
);
</script>
```

For the full list of options, see the [**Configuration reference**](/configuration/layout).

***

### Reference: the initializer

```javascript
var player = fluidPlayer(target [, options]);
```

**`target`** *(required)* - tells Fluid Player which video to attach to. You can pass either:

* The `id` of your `<video>` tag as a string, e.g. `'my-video'`, or
* The video element directly, e.g. `document.getElementById('my-video')`

**`options`** *(optional)* - a configuration object. See [**Configuration**](/configuration/layout) for the full list.

> ⚠️ **Heads up:** If you pass the video element directly and it doesn't already have an `id` attribute, Fluid Player will add one automatically. If your code relies on the element not having an id, set one yourself before calling `fluidPlayer()`.

***

### Where next?

> 💡 **Set up ads** → [**Advertisements**](/configuration/advertisements)**.**
>
> 🎨 **Customize the look** → [**Layout configuration**](/configuration/layout)**.**
>
> 📝 **Add subtitles** → [**Subtitles**](/configuration/subtitles)**.**


# Using Fluid Player with Vue.js

Fluid Player works with Vue.js out of the box. To start using Fluid Player in your Vue.js project, you will need to:

* install Fluid Player using Yarn or NPM as outlined [here](/integration/quick-setup#integration-using-npm); and
* import Fluid Player module and attach it to video element of your choosing.

You can see an example of how to integrate Fluid Player and Vue.js in the example bellow. This is a simplified example to get you going quickly. Follow Vue.js best practices on how to create reusable components depending on the needs of your project.

**IMPORTANT:** switching sources dynamically is not supported. You are **required** to redraw the component OR to recreate the Fluid Player instance to change sources or other player configuration.

```html
<template>
    <div class="fluid-component">
        <video ref="myVideoPlayer">
            <source src='https://cdn.fluidplayer.com/videos/valerian-1080p.mkv'
                    data-fluid-hd
                    title="1080p"
                    type='video/mp4'/>
        </video>
    </div>
</template>

<script>
    import fluidPlayer from 'fluid-player';

    export default {
        name: 'FluidPlayer',
        props: {},
        data() {
            return {
                player: null
            }
        },
        mounted() {
            this.player = fluidPlayer(this.$refs.myVideoPlayer);
        },
        destroyed() {
            if (!this.player) {
                return;
            }

            this.player.destroy();
        }
    }
</script>

<style>
    @import "fluid-player/src/css/fluidplayer.css";

    div.fluid-component, div.fluid-component > video {
        width: 100%;
        height: 100%;
    }
</style>
```

**Note**: Safari does not support playback of .mkv files. To view this file type, consider using a different browser that supports the .mkv format.


# Using Fluid Player with React

Fluid Player works with React out of the box. To start using Fluid Player in your React project, you will need to:

* install Fluid Player using Yarn or NPM as outlined [here](/integration/quick-setup#integration-using-npm); and
* import Fluid Player module and attach it to video element of your choosing.

You can see an example of how to integrate Fluid Player and React in the example below. This is a simplified example to get you going quickly. Follow React best practices on how to create reusable components depending on the needs of your project.

**IMPORTANT:** switching sources dynamically is not supported. You are **required** to redraw the component OR to recreate the Fluid Player instance to change sources or other player configuration.

#### App.css

```css
@import "~fluid-player/src/css/fluidplayer.css";
```

#### App.js

```jsx
import fluidPlayer from 'fluid-player'
import './App.css';
import {useEffect, useRef} from "react";

function App() {
  let self = useRef(null);
  let player = null;

  useEffect(() => {
      if (!player) {
        player = fluidPlayer(self.current, {});
      }
  });

  return (
      <>
        <video ref={self}>
          <source src='https://cdn.fluidplayer.com/videos/valerian-1080p.mkv'
                  data-fluid-hd
                  title='1080p'
                  type='video/mp4'/>
        </video>
      </>
  );
}

export default App;
```

**Note**: Safari does not support playback of .mkv files. To view this file type, consider using a different browser that supports the .mkv format.


# Using Fluid Player with Angular

Fluid Player works with Angular out of the box. To start using Fluid Player in your Angular project, you will need to:

* install Fluid Player using Yarn or NPM as outlined [here](/integration/quick-setup#integration-using-npm); and
* import Fluid Player module and attach it to video element of your choosing.

You can see an example of how to integrate Fluid Player and Angular in the example below. This is a simplified example to get you going quickly. Follow Angular best practices on how to create reusable components depending on the needs of your project.

{% hint style="warning" %}
**IMPORTANT:** switching sources dynamically is not supported. You are **required** to redraw the component OR to recreate the Fluid Player instance to change sources or other player configuration.
{% endhint %}

#### app.component.html

```html
<video #ref>
    <source
            src="https://cdn.fluidplayer.com/videos/valerian-1080p.mkv"
            data-fluid-hd
            title="1080p"
            type="video/mp4"
    >
</video>
```

{% hint style="info" %}
**Note**: Safari does not support playback of .mkv files. To view this file type, consider using a different browser that supports the .mkv format.
{% endhint %}

#### app.component.ts

```typescript
import {AfterViewChecked, Component, ElementRef, ViewChild} from '@angular/core';
import fluidPlayer from 'fluid-player';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewChecked {

  fluidPlayer: any;

  @ViewChild('ref') ref!: ElementRef;

  ngAfterViewChecked() {
    if (!this.fluidPlayer) {
      this.fluidPlayer = fluidPlayer(this.ref.nativeElement);
    }
  }
}
```

#### angular.json

Inside the `options` property:

```json
{
  ...
  "styles": [\
    "src/styles.css",\
    "node_modules/fluid-player/src/css/fluidplayer.css"\
  ],
  ...
}
```


# Wordpress

Fluid Player offers a plugin for Wordpress as a way to quickly integrate your content with Fluid Player.

The plugin always use the latest Fluid Player version.

The recommended approach to use the plugin shortcode is as follows:

```
[fluid-player-extended]

    [fluid-player-options]
        {
            layoutControls: {},
            vastOptions: {}
        }
    [/fluid-player-options]

    [fluid-player-multi-res-video]
        [\
            {"label": "720", "url": "https://cdn.fluidplayer.com/videos/valerian-720p.mkv"},\
        ]
    [/fluid-player-multi-res-video]

[/fluid-player-extended]
```

{% hint style="warning" %}
Safari does not support playback of .mkv files. To view this file type, consider using a different browser that supports the .mkv format.
{% endhint %}

You can find more information at the [wordpress.org plugin page](https://wordpress.org/plugins/fluid-player/#installation).


# Layout

There are optional parameters that can be used to customise the Fluid Player.\
None of the options are required but can be tailored to better suit your own design.

Layout controls relate to the functionality and styling of the player itself.\
The full list of *layoutControls* are below:

```javascript
fluidPlayer(
   'my-video',
    {
        layoutControls: {
            primaryColor:           false,
            playButtonShowing:      true,
            playPauseAnimation:     true,
            fillToContainer:        false,
            autoPlay:               false,
            preload:                false,
            mute:                   false,
            doubleclickFullscreen:  true,
            subtitlesEnabled:       false,
            keyboardControl:        true,
            layout:                 'default',
            allowDownload:          false,
            playbackRateEnabled:    false,
            allowTheatre:           true,
            title:                  false,
            loop:                   false,
            roundedCorners:         0,
            logo: {
                imageUrl:           null,
                position:           'top left',
                clickUrl:           null,
                opacity:            1
            },
            controlBar: {
                autoHide:           true,
                autoHideTimeout:    3,
                animated:           true,
                playbackRates:      ['x2', 'x1.5', 'x1', 'x0.5']
            },
            timelinePreview:        {},
            htmlOnPauseBlock: {
                html:               null,
                height:             null,
                width:              null
            },
            playerInitCallback:     (function() {}),
            miniPlayer: {
                enabled: true,
                width: 400,
                height: 225
            },
            autoRotateFullScreen: false,
        }
    }
);
```

### primaryColor

Primary color affects the following areas of the Fluid Player:

* Play button showing before video play ( **Default:** grey)
* Play and pause animations and video toggle ( **Default:** grey)
* Video played progress bar ( **Default:** white)
* User defined [ad text](#adtext) ( **Default:** black)

Changing this parameter will change all the above areas to the color specified.\
In the below screenshot we have used the following:

```javascript
fluidPlayer(
   'my-video',
    {
        layoutControls: {
            primaryColor: "#28B8ED"
        }
    }
);
```

![](/files/e740f258742242c0a90a4201113b1e834cbd1fc2) ![](/files/53bfffe1ccb1cd0d069b35c54372a7a20ab01b0c)

### posterImage

The poster attribute for videos allows an image to be shown before the video plays. This can be set as a Fluid Player parameter.\
By default it will be set to false, and show no image.

```javascript
fluidPlayer(
   'my-video',
    {
        layoutControls: {
            posterImage: 'path/to/my/image.jpg' // Default false
        }
    }
);
```

### posterImageSize

To change the size of the poster image you can use the `posterImageSize` property, with the values `cover`, `contain` our `auto`.\
To read more about each value check the [background-size MDN page](https://developer.mozilla.org/en-US/docs/Web/CSS/background-size#values).

```javascript
fluidPlayer(
   'my-video',
    {
        layoutControls: {
            posterImageSize: 'cover' // Default `contain`
        }
    }
);
```

### playButtonShowing

By default the play button will show in the middle of the player. To hide the button this option can be set to **false**.\
When this option is set to **false** the video controls will show by default.

```javascript
fluidPlayer(
   'my-video',
    {
        layoutControls: {
            playButtonShowing: false // Default true
        }
    }
);
```

### playPauseAnimation

There is a Play / Pause animation that can be disabled using this parameter. By default this parameter is set to **true**

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            playPauseAnimation: false // Default true
        }
    }
);
```

![](/files/1281b985460d3689c8673f01f359279a8794ba67)

### fillToContainer

If the Fluid Player is placed into a container on your page you can use this parameter to fill to the size of that container.\
Set this parameter to **true** to set the width and height to 100%.

{% hint style="warning" %}
It is important to ensure that the container has a defined width and height, otherwise the player will not have a fixed size.
{% endhint %}

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            fillToContainer: true // Default true
        }
    }
);
```

### roundedCorners

This parameter defines the rounded corners for the video player. You can pass either a number or a string:

* **Number**: Automatically converts to pixels (`px`). For example, `10` becomes `10px`.
* **String**: Can include any valid CSS unit for `border-radius` (e.g., `%`, `em`, `rem`, `px`, etc.). If the string can be parsed as a number (e.g., `"10"`), it defaults to `px`.

This allows full flexibility to use any value supported by the CSS `border-radius` property.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            roundedCorners: 0 // Default 0
        }
    }
);
```

### autoPlay

By default this parameter is set to **false**. When set to **true** the video will play automatically when the page loads.\
Please note that this feature may not work on certain browser versions and depends on their AutoPlay Policies.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            autoPlay: true // Default false
        }
    }
);
```

### preload

Sets the preload parameter on video tag. By default this parameter is set to **`'auto'`**.

Note: To change the preload configuration for `hls.js` and `dash.js`, you need to change the configuration for each module.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            preload: 'auto' // Default 'auto'
        }
    }
);
```

### mute

Set this parameter to **true** to have the video muted by default.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            mute: true // Default false
        }
    }
);
```

### doubleclickFullscreen

Set this parameter to **true** to have double click to toggle fullscreen

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            doubleclickFullscreen: true, // Default true
        }
    }
);
```

### subtitlesEnabled

Set this parameter to **true** to have subtitles, provided track information given. You can read more about subtitles [here](/configuration/subtitles).

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            subtitlesEnabled: true, // Default false
        }
    }
);
```

### keyboardControl

The following key commands are usable by **Default:**

* **Space/Enter:** Pause/Play video playback
* **Left/Right arrow:** Go back/forward 5 seconds
* **Home/End:** Go to beginning/end of video
* **Numbers 0-9:** Skip to a particular section of the video (e.g., 5 goes to the video midpoint)
* **Up/Down arrow:** Increase/Decrease volume 5%
* **m key:** Mute/Unmute video volume
* **f key:** Go to Full Screen mode

If you wish to disable these options set *keyboardControl* to **false**

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            keyboardControl: false // Default true
        }
    }
);
```

### title

Set this parameter to have the title displayed on your video. Disabled by default.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            title: 'My video title' // Default false
        }
    }
);
```

### loop

Set this parameter to have the video loop. Disabled by default.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            loop: true // Default false
        }
    }
);
```

### logo

The *logo* option allows you to show an image overlaid in the corner of the player. There are 4 options that can be set to configure this logo.

* **imageUrl:** The location of the image to show. ( **Default:** null)
* **position:** Where on the player the logo will show. The options are **top left**, **top right**, **bottom left** or **bottom right**. ( **Default:** 'top left')
* **clickUrl:** If you want the logo to be a link to another page you can set the landing page with this parameter. ( **Default:** null)
* **opacity:** This will toggle the opacity styling option of the logo. ( **Default:** 1)
* **mouseOverImageUrl:** You can specify a separate image to show on mouseover of the logo. ( **Default:** null)
* **imageMargin:** The margin on the logo can be specified using this parameter. ( **Default:** '2px')
* **hideWithControls:** If you want the logo to only appear along with the video controls you can set this parameter to **true**. ( **Default:** false)
* **showOverAds:** The logo will not show during in-stream ads by default, but you can specify the logo to show during ads using this parameter. ( **Default:** false)

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            logo: {
                imageUrl: 'https://www.routetomylogo.com/logo.jpg', // Default null
                position: 'top right', // Default 'top left'
                clickUrl: 'https://www.landingpage.com/welcome', // Default null
                opacity: 0.8, // Default 1
                mouseOverImageUrl: 'image/on/hover.jpg', // Default null
                imageMargin: '10px', // Default '2px'
                hideWithControls: true, // Default false
                showOverAds: 'true' // Default false
            }
        }
    }
);
```

![](/files/73c88209e28612b1f3981d788dd1eb4c4d5cf98f)

### controlBar

The control bar will hide when the mouse is inactive after a certain amount of time.\
There are three options for this parameter:

* **autoHide:** Configure whether or not to hide the controls. ( **Default:** false)
* **autoHideTimeout:** How long, in seconds, before the controls will hide. ( **Default:** 3)
* **animated:** If set to false the controls disappear instantly. True be default, will mean the controls fade out. ( **Default:** true)
* **playbackRates:** Allow customization of the playback rates. If `playbackRateEnabled` set to `true` the available options can be set with this property. ( **Default:**`['x2', 'x1.5', 'x1', 'x0.5']`)

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            controlBar: {
                autoHide: true, // Default false
                autoHideTimeout: 5, // Default 3
                animated: false, // Default true
                playbackRates: ['x2', 'x1']
            }
        }
    }
);
```

### timelinePreview

Thumbnail preview is discussed more [here](/configuration/previews).

Sets the timeline preview, visible when hovering over the progress bar.\
The provided file contains the thumbnail images used for the preview.\
The type sets the format of the file. Currently only the VTT format is supported.\
The timeline preview only works if the default layout is chosen (see above).

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            timelinePreview: {
                file: 'thumbnails.vtt',
                type: 'VTT'
            }
        }
    }
);
```

![](/files/d0ffaf270a7f3d8485d31ba50d3ad63d69cfee62)

### htmlOnPauseBlock

Defined HTML to be displayed in the center of the player when the user pauses the video. Note: Clicking on the HTML area triggers a play event.\
If you don't need that behaviour then add **e.stopPropagation()** to your event. There are three options for this parameter.

* **html:** The HTML to display.
* **height:** The height of the HTML to show. An integer representation of the pixel size.
* **width:** The width of the HTML to show. An integer representation of the pixel size.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            htmlOnPauseBlock: {
                html: '<b>Paused</b>', // Default null
                height: 50, // Default null
                width: 100 // Default null
            }
        }
    }
);
```

![](/files/073088ee0acdf3da8cc3af5e5e2a0d1dbc8cb2a6)

### layout

The default layout is **default**. It provides own skin to the player.\
Optionally you can define your own custom layout with CSS.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            layout: 'default' // Default 'default'
        }
    }
);
```

### allowDownload

False by default, this option will allow users to download the video shown in the Fluid Player.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            allowDownload: true // Default false
        }
    }
);
```

### playbackRateEnabled

Fluid Player allows the users to change the playback rate / speed of the video. By default, this option is disabled.\
To enable this option use the following:

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            playbackRateEnabled: true // Default false
        }
    }
);
```

Please note, the customization of playback rates is allowed with `layoutControls.controlBar.playbackRates` property. [See details here.](#controlBar)

### allowTheatre

Theatre mode alters the size of the player, showing a full screen width and 60% screen height player instead.\
This overlays whatever is behind the player, but allows the users to scroll through the page as normal. This is enabled by default, but can be set to false.\
Theatre mode will be hidden if Fluid Player is loaded in an iframe.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            allowTheatre: false // Default true
        }
    }
);
```

### theatreAdvanced

The default theatre mode is designed to be as generic as possible. If you wish to implement a more custom solution for theatre mode this provides a way to do so.\
You can specify the id of an element on the page, most likely a container div which the player is in, and a class to apply to it when theatre mode is enabled.\
If the element cannot be found then the default theatre mode will activate.

An example scenario; the player is placed in a container on the page, set to [fillToContainer](#filltocontainer), which you want to expand on theatre mode.\
You pass in that containers id and the class to apply to it. This class can have css applied which will alter the container, and therefore the player itself.\
When theatre mode is pressed the parent container has the class applied and removed accordingly.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            theatreAdvanced: { // default false
                theatreElement: 'container-id',
                classToApply: 'my-theatre-class'
            }
        }
    }
);
```

As theatre mode often requires other elements on the page to move / hide we have added listener events for [theatreModeOn](/api/event-api#theatremodeon) and [theatreModeOff](/api/event-api#theatremodeoff).\
This allows you to easily execute additional functionality when toggling theatre mode.

### theatreSettings

The dimensions and alignment of the player while in theatre mode are configurable.\
The **width** and **height** can be specified in either **%** or **px**. The default for these settings are 100% & 60% respectively.\
The **marginTop** will be the pixel value of space between the top of the screen and the player, which is 0 by default.\
**align** can be used to float the player **left**, **right** or **center**, defaulted to **center**

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            theatreSettings: {
                width:     '60%', // Default '100%'
                height:    '400px', // Default '60%'
                marginTop: 50, // Default 0
                horizontalAlign:     'center' // 'left', 'right' or 'center'
            }
        }
    }
);
```

### playerInitCallback

This callback function can be used to execute custom code when the player in initialised.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            playerInitCallback: (function() { console.log('player loaded!') })
        }
    }
);
```

### persistentSettings

If a user changes the **volume**, **quality**, **speed** or **theatre mode** of the video these settings will persist on following page loads for the player.\
If you do not want these settings to persist for the user you can set them to false, as shown below.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            persistentSettings: {
                volume:  false, // Default true
                quality: false, // Default true
                speed:   false, // Default true
                theatre: false // Default true
            }
        }
    }
);
```

### captions

This option enables you to customise the control buttons default caption.

* play
* pause
* mute
* unmute
* fullscreen
* exit fullscreen

```javascript
fluidPlayer(
    'my-video',
    {
        captions: {
            play: 'Play',
            pause: 'Pause',
            mute: 'Mute',
            unmute: 'Unmute',
            fullscreen: 'Fullscreen',
            exitFullscreen: 'Exit Fullscreen'
        }
    }
);
```

**Note**: The captions object is in the root of the Fluid Player configurations options, **not** in `layoutControls`.

### controlForwardBackward

This configuration options allows you to choose if you want to show "skip buttons" allowing users\
to fast-forward / fast-replay the video content.

You can also toggle double tapping to move the video backward / forward by 10 seconds in touch devices by setting the\
`doubleTapMobile` property.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            controlForwardBackward: {
                show: true, // Default: false,
                doubleTapMobile: false // Default: true
            }
        }
    }
);
```

### contextMenu

Context menu configuration option allows you to control built in context menu of the player. There are two configuration\
options within this configuration block.

* `controls` - a boolean option to enable or disable default playback controls\
  in the context menu.
* `links` - a list of objects containing `href` property to indicate target URL and a `label` property\
  to indicate the display label of the link.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            contextMenu: {
                controls: true,
                links: [
                    {
                        href: 'https://wikipedia.org',
                        label: 'Wikipedia'
                    }
                ]
            }
        }
    }
);
```

### Custom icons style

You can override the default icons using CSS.

* play
* pause
* volume
* mute
* video source
* fullscreen mode
* exit fullscreen mode
* playback rate
* download
* theatre mode

```css
.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_play:before {
    background: url(/images/example.svg) no-repeat !important;
    background-position: 0px 0px !important;
} /* play */

.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_pause:before {
    background: url(/images/example.svg) no-repeat !important;
    background-position: 0px 0px !important;
} /* pause */

.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_volume:before {
    background: url(/images/example.svg) no-repeat !important;
    background-position: 0px 0px !important;
} /* volume */

.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_mute:before {
    background: url(/images/example.svg) no-repeat !important;
    background-position: 0px 0px !important;
} /* mute */

.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_video_source:before {
    background: url(/images/example.svg) no-repeat !important;
    background-position: 0px 0px !important;
} /* video source */

.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_fullscreen:before {
    background: url(/images/example.svg) no-repeat !important;
    background-position: 0px 0px !important;
} /* fullscreen mode */

.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_fullscreen_exit:before {
    background: url(/images/example.svg) no-repeat !important;
    background-position: 0px 0px !important;
} /* exit fullscreen mode*/

.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_playback_rate:before {
    background: url(/images/example.svg) no-repeat !important;
    background-position: 0px 0px !important;
} /* playback rate */

.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_download:before {
    background: url(/images/example.svg) no-repeat !important;
    background-position: 0px 0px !important;
} /* download */

.fluid_video_wrapper.fluid_player_layout_default .fluid_controls_container .fluid_button.fluid_button_theatre:before {
    background: url(/images/example.svg) no-repeat !important;
    background-position: 0px 0px !important;
} /* theatre mode */
```

### miniPlayer

Fluid Player has a dedicated Mini Player mode that can be triggered by the pressing `i` on the keyboard, or by clicking\
the Mini Player button on the control bar of the video.

When activated the Mini Player appears in the corner of the screen, and follows the page as the user scrolls.

The `miniPlayer` object can be used to change the behaviour of the Mini Player. You can enable or disable the Mini\
Player by toggling the `enabled` property.

The `width` and `height` properties can be used to change the size of the Mini Player. For mobile devices the Mini\
Player uses the `widthMobile` property.

The text of the placeholder element that appears where the player was when the Mini Player is toggled can be changed by\
the `placeholderText` property.

The `position` property changes the corner of the screen that the Mini Player will appear.

The `autoToggle` property makes the Mini Player activate as soon as the main video player leaves the screen.

Following is an example configuration with the **default values** for `miniPlayer`.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            miniPlayer: {
                enabled: true,
                width: 400, // px unit
                height: 225, // px unit
                widthMobile: 40, // vw unit
                placeholderText: 'Playing in Miniplayer',
                position: 'bottom right', // 'top left', 'top right', 'bottom left', 'bottom right'
                autoToggle: false,
            }
        }
    }
);
```

### Automated Landscape for Mobile (iOS only)

Set an automated full-screen mode on the player for landscape view on mobile devices. This is applicable only when the player is in view.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            autoRotateFullScreen: true,
        }
    }
);
```


# Advertisements

There are optional parameters that can be used to customise the Fluid Player ad serving.

No parameters are required and will default if not passed through.

VAST options relate to the ads served and how the player handles them.

These options are specifically for when ads are shown in the player.

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            adList:                     {},
            skipButtonCaption:          'Skip ad in [seconds]',
            skipButtonClickCaption:     'Skip ad <span class="skip_button_icon"></span>',
            adText:                     null,
            adTextPosition:             'top left',
            adCTAText:                  'Visit now!',
            adCTATextPosition:          'bottom right',
            vastTimeout:                5000,
            showPlayButton:             false,
            maxAllowedVastTagRedirects: 1,

            vastAdvanced: {
                vastLoadedCallback:       (function() {}),
                noVastVideoCallback:      (function() {}),
                vastVideoSkippedCallback: (function() {}),
                vastVideoEndedCallback:   (function() {})
            }
        }
    }
);
```

### adList

Setup one or multiple VAST tag. For each of the tags there are multiple options.

Please note the VAST tag XML response `Content-Type` must be either `application/xml` or `text/xml`.

* **roll (mandatory):** The available timeline positions: *preRoll*, *midRoll*, *postRoll*, *onPauseRoll*.
* **vastTag (mandatory):** The url of the VAST XML (Please find the supported tags/attributes vastLinear.xml)
* **timer (only for mid-roll):** The timer property schedules when the ad should show. There are two ways to define this:
  * **\[seconds]:** The number of seconds until the ad begins. Example: *timer: 10*
  * **\[percentage]:** The percentage of the video to show before the ad begins. Example: *timer: 50%*
* **fallbackVastTags (Optional):** An array which holds the Vast Urls, if Url in vastTag fails then player will try with these.
* **adText (Optional for linear ads):** The [adText section](#adtext) describes the ability to set text to appear on ads. By using this parameter in the **adList** you can specify unique text per ad.
* **adTextPosition (Optional for linear ads):** Only relevent if **adText** is in use. This allows you to set the position of **adText** per ad.
* **adClickable (Optional for linear ads):** Disable opening the landing page in a new tab when the player is clicked, and keep play pause functionality.

We can set **multiple&#x20;*****midRoll*****&#x20;with the same timer value**, also **multiple&#x20;*****preRoll*****,&#x20;*****postRoll*****&#x20;and&#x20;*****onPauseRoll*** can be set. See the example below:

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            adList: [
                {
                    roll: 'preRoll',
                    vastTag: 'vastPreRoll_1.xml',
                    adText: 'Advertising supports us directly'
                },
                {
                    roll: 'preRoll', //multiple preRoll Ads
                    vastTag: 'vastPreRoll_2.xml',
                    adText: 'Advertising supports us directly'
                },
                {
                    roll: 'midRoll',
                    vastTag: 'vastMidRoll_1.xml',
                    timer: 8
                },
                {
                    roll: 'midRoll',
                    vastTag: 'vastMidRoll_2.xml',
                    // In case vastTag fails, the player will fallback to one of the valid tags from this array
                    fallbackVastTags: ['vastMidRoll_3.xml', 'vastMidRoll_4.xml'],
                    // multiple ads for the same time
                    timer: 8
                },
                {
                    roll: 'midRoll',
                    vastTag: 'vastMidRoll_2.xml',
                    timer: 10,
                    adClickable: false // Default true
                },
                {
                    roll: 'postRoll',
                    vastTag: 'vastPostRoll.xml',
                    adText: 'Thanks for watching',
                    adTextPosition: 'top right'
                }
            ]
        }
    }
);
```

* **vAlign** (only for nonLinear, optional): The available vertical positions for nonLinear Ads: top, middle, bottom. Default: bottom.
* **nonLinearDuration** (only for nonLinear, optional): The number of seconds until the nonLinear Ad will be shown. If not set nor the minSuggestedDuration attribute of VAST XML than wont close until end of video.
* **size** (only for nonLinear, optional): The dimension of the Ad. Supported sizes: 468x60, 300x250, 728x90

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            adList: [
                {
                    roll: 'onPauseRoll',
                    vastTag: 'vastNonLinear.xml',
                    vAlign: 'top',
                    nonlinearDuration: 10,
                    size: '300x250'
                }
            ]
        }
    }
);
```

### skipButtonCaption

The text to display the countdown during an ad. The **\[seconds]** placeholder is used for the second countdown.\
(**Default:** "Skip ad in \[seconds]")

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            skipButtonCaption: 'Wait [seconds] more second(s)'
        }
    }
);
```

### skipButtonClickCaption

This defines the text to show when the countdown is finished and the user can skip to the main video.\
(**Default:** 'Skip ad ')

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            skipButtonClickCaption: 'Watch main video <span class="skip_button_icon"></span>'
        }
    }
);
```

### adText

Custom text can be shown when an in-stream ad plays. This text appears in the top left corner of the player and will be set to the primary colour.

Has additional `adTextPosition` parameter, that can have values, like 'top right', 'top left', 'bottom right', 'bottom left'.

Ad text and position can also be set on a [per ad basis](#adlist).

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            adText: 'Advertising helps us keep the lights on', // Default null,
            adTextPosition: 'top left' // Default 'top left'
        }
    }
);
```

![](/files/e7ca9c502e1dfa83da2fe03243eec23b8d8199f5)

### adCTAText

The landing page of the advertisement will show in the `adCTAText` area. You can add custom text above this URL, or you choose to disable this.

The screenshot below shows how it will appear by default, and the code below shows how to alter or disable it.

Has additional `adCTATextPosition` parameter, that can have values, like 'top right', 'top left', 'bottom right', 'bottom left'.

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            // adCTAText: 'Subscribe now!', // Default "Visit now!",
            // adCTATextPosition: 'bottom left', //Default 'bottom right'
            adCTAText: false // Disable adCTAText
        }
    }
);
```

The CTA text can also be taken from the VAST XML that is set through `adCTATextVast` parameter. So, if this parameter is set to true, it will use the text provided in the VAST XML. Incase the VAST XML text is empty or this parameter is not set, it will fallback to the default set in `adCTAText`.

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            adCTAText: 'Subscribe now!', // Default "Visit now!",
            adCTATextPosition: 'bottom left', //Default 'bottom right’,
            adCTATextVast: true, // Enabled. To use the CTA text as provided in the VAST XML.
        }
    }
);
```

![](/files/1df2b82832122346a0ab8fabd2a2454b87716fa9)

### vastTimeout

This parameter lets you set the time, in milliseconds, to wait for the VAST to load. (**Default:** 5000)

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            vastTimeout: 1000 // Default 5000
        }
    }
);
```

### vastAdvanced

We can specify the callback functions on the different VAST events.

* **vastLoadedCallback:** When the VAST has loaded.
* **noVastVideoCallback:** When there is no VAST video.
* **vastVideoSkippedCallback:** If the ad is skipped.
* **vastVideoEndedCallback:** When the ad has ended.

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            vastAdvanced: {
                vastLoadedCallback:       (function() { console.log("Here one event") }),
                noVastVideoCallback:      (function() { console.log("Here another") }),
                vastVideoSkippedCallback: (function() { console.log("Here one more") }),
                vastVideoEndedCallback:   (function() { console.log("Here's the last") })
            }
        }
    }
);
```

### showPlayButton

Option to show play button icon after ad video has stopped. By default this parameter will be set to **false**, but can be enabled as shown below.

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            showPlayButton: true // Default false
        }
    }
);
```

### maxAllowedVastTagRedirects

Fluid Player supports VAST wrappers through .The `maxAllowedVastTagRedirects` sets the maximum allowed redirects (wrappers).

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            maxAllowedVastTagRedirects: 1 // Default 3
        }
    }
);
```

### adClickable

Clicking the player while an in-stream ad is showing will open open the landing page in a new tab.

If you wish to disable this, and only allow opening the landing page via the [call to action](#adctatext), you can use the **adClickable** parameter.

This can be set for all in-stream ads or per ad listed. For details on how to add it per ad please see the [adlist](#adlist) section.

```javascript
fluidPlayer(
   'my-video',
    {
        vastOptions: {
            adClickable: false // Default true
        }
    }
);
```

### VPAID

Unlike regular VAST ads, VPAID is very dynamic and interactive.

For more info <https://www.iab.com/guidelines/digital-video-player-ad-interface-definition-vpaid-2-0/>

To enable loading VPAID ads **allowVPAID** option has to be set to true (false by default).

Player supports VPAID version 2.0

```javascript
fluidPlayer(
    'video-vpaid-ads',
    {
        vastOptions: {
            allowVPAID: true, // Default false.
            adList: [
                {
                    roll: 'preRoll',
                    vastTag: './vastxmls/vpaid_linear.xml'
                },
                {
                    roll: 'midRoll',
                    vastTag: './vastxmls/vpaid_nonlinear.xml',
                    timer: 5
                },
            ]
        }
    }
);
```

### VAST tracking

The following events are supported by Fluid Player.

* start
* firstQuartile
* midpoint
* thirdQuartile
* complete
* progress
* impression
* clickTracking
* iconClickTrough


# Previews

### Adding Preview Thumbnails

Preview thumbnails can be added to the Fluid Player video, to show when the progress bar is hovered over.\
When these are added they will replace the time that normally shows.\
This is a common feature that allows users to easily navigate around through the video.\
Below is an example video showing the thumbnails.

### VTT Format

The format used is WebVTT, a HTML5 standard. Details in the WebVTT format can be found [here](https://w3c.github.io/webvtt/).\
When used for thumbnails, VTT files contain links to the thumbnail images or the position of a single sprite image. These images can be in JPG, PNG or GIF format.\
The image and times in which to point to that image are defined in the file, the contents of which should contain the following:

* The range the tooltip thumbnail represents. Note the range needs to be in (HH:)MM:SS.MMM format.
* The URL to the tooltip thumbnail for this range. The URL is relative to the VTT file (not to the page or player), much like images included in CSS sheets.

#### Example VTT File - Separate Images

If the images are stored separately the .vtt file contents would look similar to what's shown below.\
Note that we see *thumbnail1.jpg*, *thumbnail2.jpg* and *thumbnail3.jpg*

```
WEBVTT

00:00:00.000 --> 00:00:05.000
thumbnail1.jpg

00:00:05.000 --> 00:00:10.000
thumbnail2.jpg

00:00:10.000 --> 00:00:15.000
thumbnail3.jpg
```

#### Example VTT File - Sprite Image

Storing the images in the one file can save on space and complexity.\
If the images are stored in the one image file, the contents of our .vtt would look similar to what's shown below.

```
WEBVTT

00:00:00.000 --> 00:00:02.000
thumbnails.jpg#xywh=0,0,120,68

00:00:02.000 --> 00:00:04.000
thumbnails.jpg#xywh=120,0,120,68

00:00:04.000 --> 00:00:06.000
thumbnails.jpg#xywh=240,0,120,68

00:00:06.000 --> 00:00:08.000
thumbnails.jpg#xywh=360,0,120,68

00:00:08.000 --> 00:00:10.000
thumbnails.jpg#xywh=480,0,120,68
```

### Adding to Fluid Player

To configure Fluid Player to use your VTT file, you can set is as the optional parameter **timelinePreview** under **layoutControls**.\
Provided the file is correct, the below code will set the thumbnail previews.\
The sprite image paths (thumbnails.jpg) are relative to root url in the VTT file.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            timelinePreview: {
                file: 'thumbnails.vtt',
                // spriteRelativePath: true, //Default false
                // sprite: 'thumbnails.jpg',
                type: 'VTT'
            }
        }
    }
);
```

You can make the sprite paths relative to the VTT file with the `spriteRelativePath` setting.\
In this case the `thumbnails.jpg#xywh=480,0,120,68` image path will be relative to `thumbs/` as a result `thumbs/thumbnails.jpg`

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            timelinePreview: {
                file: 'thumbs/thumbnails.vtt',
                spriteRelativePath: true,
                type: 'VTT'
            }
        }
    }
);
```

Optionally if the thumbnails image is not defined in thumbnails.vtt or want to overwrite than you may set `sprite` property.\
Please note, in this case the spriteRelativePath won't have any affect.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            timelinePreview: {
                file: 'thumbnails/thumbnails.vtt',
                sprite: 'thumbnails/thumbnails.jpg',
                type: 'VTT'
            }
        }
    }
);
```

### static Format

If the WebVTT format doesn't suit you, the thumbnails can be defined statically.

#### Example static configuration

The `startTime` and `endTime` properties are defined in seconds:

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            timelinePreview: {
                type: 'static',
                frames: [\
                   {\
                        startTime: 0,\
                        endTime: 0.5,\
                        image: '/thumbnails/thumbnails.jpg',\
                        x: 0,\
                        y: 0,\
                        w: 200,\
                        h: 84\
                    },\
                    ...\
                ]
            }
        }
    }
);
```


# Subtitles

Subtitles are text derived from either a transcript or screenplay of the dialog or commentary in films, television programs, video games, and the like, usually displayed at the bottom of the screen.

### VTT format

```
WEBVTT

1
00:00:15.000 --> 00:00:18.000 align:start
At the left we can see...

2
00:00:18.167 --> 00:00:20.083 align:middle
At the right we can see the...

3
00:00:20.083 --> 00:00:22.000
...the head-snarlers

4
00:00:22.000 --> 00:00:24.417 align:end
Everything is safe. Perfectly safe.

5
00:00:24.583 --> 00:00:27.083
Emo?
```

### Adding to Fluid Player

To configure Fluid Player to use your VTT file, set the optional `subtitlesEnabled` parameter under `layoutControls`.

Provide subtitle URLs in `<track>` tags under `kind='metadata'`.

Please make sure that you **do not specify** `kind='subtitles'`, because that doesn't work in some browsers.

```html
<video id="my-video" controls>
    <source src="video.mp4" type="video/mp4"/>
    <track label="English" kind="metadata" srclang="en" src="/subtitles/english.vtt" default>
    <track label="Deutsch" kind="metadata" srclang="de" src="/subtitles/deutsch.vtt">
</video>

<script type="application/javascript">
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            subtitlesEnabled: true
        }
    }
);
</script>
```

### subtitlesOnByDefault

Set this parameter to **true** to have subtitles on by default. This parameter is by default already set to **true**.

```javascript
fluidPlayer(
    'my-video',
    {
        layoutControls: {
            subtitlesOnByDefault: false, // Default true
        }
    }
);
```

### Font Size Options

Fluid Player supports subtitle font size controls, enhancing accessibility and viewer experience by allowing text size adjustments. Users can customize subtitle size in two convenient ways:

#### Method 1: Keyboard Shortcuts

While viewing content, users can quickly adjust subtitle size using simple keyboard shortcuts:

* Press the `+` key to increase subtitle font size
* Press the `-` key to decrease subtitle font size

#### Method 2: Font Size Submenu

A dedicated Font Size submenu is available in the subtitles/captions control panel. This menu provides precise control with predefined percentage options:

* 50%
* 75%
* 100% (Default)
* 150%
* 200%


# VR (experimental)

The player supports monoscopic (equirectangular) videos with 360-degree view.

With the possibility to render them as a 360 panorama or in "cardboard mode" if the cardboard icon is clicked. To enable the VR feature **showCardBoardView** has to be set to true.

```html
<video id='vr-video' crossorigin="anonymous">
    <source src='monoscopicvideo.mp4' title='1080p'  type="video/mp4"  />
</video>

<script>
fluidPlayer(
    'vr-video',
    {
        layoutControls: {
            showCardBoardView: true,
            showCardBoardJoystick: true
        }
    }
);
</script>
```

### Ads

Currently we can show only 360degree video ads.

Ads need to be served under VAST, with attribute **mediaType="360"** in tag.\
Non-linear ads are not supported.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<VAST version="3.0">
  <Ad id="1">
    <InLine>
      <AdSystem>example1</AdSystem>
      <AdTitle/>
      <Impression id="example1"><![CDATA[https://example1.com/view?tracking_event=impression&idzone=9999999]]></Impression>
      <Impression id="example12"><![CDATA[https://example1.com/view2?tracking_event=impression&idzone=9999999]]></Impression>
      <Creatives>
        <Creative sequence="1" id="1">
          <Linear skipoffset="00:00:03">
            <TrackingEvents>
              <Tracking event="progress" offset="00:00:01.000"><![CDATA[https://example1.com/view?tracking_event=progress&progress=00:00:01.000&idzone=9999999]]></Tracking>
              <Tracking event="progress" offset="00:00:02.000"><![CDATA[https://example1.com/view?tracking_event=progress&progress=00:00:02.000&idzone=9999999]]></Tracking>
              <Tracking event="progress" offset="00:00:05.000"><![CDATA[https://example1.com/view?tracking_event=progress&progress=00:00:05.000&idzone=9999999]]></Tracking>
              <Tracking event="progress" offset="00:00:05.000"><![CDATA[https://example1.com/view2?tracking_event=progress&progress=00:00:05.000&idzone=9999999]]></Tracking>
              <Tracking event="progress" offset="00:00:09.000"><![CDATA[https://example1.com/view?tracking_event=progress&progress=00:00:09.000&idzone=9999999]]></Tracking>
              <Tracking event="start"><![CDATA[https://example1.com/view?tracking_event=start&idzone=9999999]]></Tracking>
              <Tracking event="firstQuartile"><![CDATA[https://example1.com/view?tracking_event=firstQuartile&idzone=9999999]]></Tracking>
              <Tracking event="midpoint"><![CDATA[https://example1.com/view?tracking_event=midpoint&idzone=9999999]]></Tracking>
              <Tracking event="midpoint"><![CDATA[https://example1.com/view2?tracking_event=midpoint&idzone=9999999]]></Tracking>
              <Tracking event="midpoint"><![CDATA[https://example1.com/view3?tracking_event=midpoint&idzone=9999999]]></Tracking>
              <Tracking event="thirdQuartile"><![CDATA[https://example1.com/view?tracking_event=thirdQuartile&idzone=9999999]]></Tracking>
              <Tracking event="complete"><![CDATA[https://example1.com/view?tracking_event=complete&idzone=9999999]]></Tracking>
            </TrackingEvents>
            <VideoClicks>
              <ClickThrough><![CDATA[https://example1.com/]]></ClickThrough>
              <ClickTracking><![CDATA[https://example1.com/view?tracking_event=click&idzone=9999999]]></ClickTracking>
              <ClickTracking><![CDATA[https://example1.com/view2?tracking_event=click&idzone=9999999]]></ClickTracking>
            </VideoClicks>
            <MediaFiles>
              <MediaFile delivery="progressive" type="video/mp4" mediaType="360"><![CDATA[https://player.omnivirt.com/2015/12/18/12/51/14/435bc71d-2a24-4b51-a696-edbb46804273/infiniti-720p-medium.mp4]]></MediaFile>
            </MediaFiles>
          </Linear>
        </Creative>
      </Creatives>
    </InLine>
  </Ad>
</VAST>
```


# Suggested videos

At the end of the video, the player will show a grid of up to 12 videos (depending on the device), to entice the viewer to watch more videos and extend viewing sessions.

{% tabs %}
{% tab title="Desktop" %}
![](/files/37e4377ede1565987bed0948ce9e880f7e25f363)
{% endtab %}

{% tab title="Mobile" %}
![](/files/1f5faa6afc21f9f986c7a0edc5f777ddc0ccc43c)
{% endtab %}
{% endtabs %}

### Configuration

Configuring the Suggested Videos feature is easy. The main requirement is to provide a URL that returns a JSON file. This can be a static .json file or an API call that returns an array of 12 videos.

When using an API, query parameters can be utilized to pass data of the current video, such as tags, to create a more accurate and personalized grid of suggested videos.

```js
fluidPlayer(
  'my-video',
  {
    suggestedVideos: {
      configUrl: 'https://www.example.com/api/suggested_videos_example.json',
    }
  }
)
```

### JSON example

The Suggested Videos feature expects an array of 12 videos to be displayed in a 4x3 grid format. This is a JSON example of all the data you can pass through per video. The required keys are `id`, `sources`, `thumbnail`, and `title`.

In the configUrl, a new URL that returns a JSON file with 12 new suggested videos can be provided.

**Note**: To enable subtitles for the player, these must be activated in the [`layoutControls`](/configuration/subtitles#adding-to-fluid-player). Simply providing subtitles is not sufficient.

```json
[
    {
        "id": 0,
        "sources": [
            {
                "url": "https://cdn.example.com/videos/example.mp4",
                "mimeType": "video/mp4",
                "resolution": "720p",
                "hd": "true"
            },
            {
                "url": "https://cdn.example.com/videos/example.mp4",
                "mimeType": "video/mp4",
                "resolution": "480p"
            }
        ],
        "thumbnailUrl": "https://cdn.example.com/thumbnails/example.jpg",
        "title": "A new horizon",
        "subtitles": [
            {
                "label": "English",
                "url": "https://cdn.example.com/subtitles/english.vtt",
                "lang": "en"
            },
            {
                "label": "Deutsch",
                "url": "https://cdn.example.com/deutsch.vtt",
                "lang": "de",
                "default": true
            }
        ],
        "configUrl" : "https://www.example.com/api/new_suggested_videos_example.json"
    },
    ...
]
```

### Thumbnail Recommendations

Fluid Player expects thumbnails to have a **16x9** aspect ratio. Thumbnails in other formats can be used, but a background color will be added to fill the space. For the best appearance, it is recommended to use the **16x9** aspect ratio.

![](/files/a244a464f4173220889e87e9b48bb45dae301ec7)


# Advanced configuration

Advanced configuration allows you to interact with the building blocks of the player itself.

## Modules

Module configuration is a set of runtime callbacks you can use to further configure modular components of the Fluid Player, such as streaming.

These callbacks can be called more than once during player initialization and normal lifecycle of the player.

```js
fluidPlayer(
  'my-video',
  {
    modules: {
      configureHls: (options) => {
        return options;
      },
      onBeforeInitHls: (hls) => {
      },
      onAfterInitHls: (hls) => {
      },
      configureDash: (options) => {
        return options;
      },
      onBeforeInitDash: (dash) => {
      },
      onAfterInitDash: (dash) => {
      }
    }
  }
)
```

### configureHls

This callback allows you to configure HLS.js options. This callback receives one argument - object with default HLS options set by the Fluid Player itself. It must return a single object - final configuration options for the HLS instance. You can modify this object as you see fit. See [hls.js](https://github.com/video-dev/hls.js) documentation for more information about the available configuration options.

### onBeforeInitHls

This callback is called immediately before an instance of HLS.js is initialized from Fluid Player perspective - before the HLS.js is attached to the player with chosen source.

This callback accepts one argument - the instance of HLS.js object.

### onAfterInitHls

This callback is called immediately after an instance of HLS.js is initialized from Fluid Player perspective - after the HLS.js is attached to the player with chosen source.

This callback accepts one argument - the instance of HLS.js object.

### configureDash

This callback allows you to configure Dash.js options. This callback receives one argument - object with default Dash options set by the Fluid Player itself. It must return a single object - final configuration options for the Dash instance. You can modify this object as you see fit. See [Dash.js](https://github.com/Dash-Industry-Forum/dash.js/wiki) documentation for more information about the available configuration options.

### onBeforeInitDash

This callback is called immediately before an instance of Dash.js is initialized from Fluid Player perspective - before the Dash.js method `initialize` is called.

This callback accepts one argument - the instance of Dash.js object.

### onAfterInitDash

This callback is called immediately after an instance of Dash.js is initialized from Fluid Player perspective - after the Dash.js method `initialize` is called.

This callback accepts one argument - the instance of Dash.js object.

## XHR configuration

XHR configuration is a set of runtime callbacks allowing you to modify and customize all HTTP requests sent by Fluid Player and its native modules.

You can use these configuration callbacks to modify the behavior and configuration of the requests.

**Important:** these callbacks DO NOT apply to requests made by third party modules, such as Dash.js, HLS.js and similar. You need to use the native configuration callbacks of those modules specifically.

```js
fluidPlayer(
  'my-video',
  {
    onBeforeXMLHttpRequestOpen: (request) => {
    },
    onBeforeXMLHttpRequest: (request) => {
    },
  }
)
```

### onBeforeXMLHttpRequestOpen

This callback is called immediately before the `XMLHttpRequest#open` method is called. It receives one argument - an instance of `XMLHttpRequest` about to be sent.

### onBeforeXMLHttpRequest

This callback is called immediately before the `XMLHttpRequest#send` method is called. It receives one argument - an instance of `XMLHttpRequest` about to be sent.

*Last updated on 6/22/2020*


# Controls API

You can use the following functions to manage user controls of Fluid Player after initialisation.

### Play

To play the Fluid Player use the **play()** function on our *player* object

```javascript
player.play();
```

### Pause

To pause the Fluid Player use the **pause()** function on our *player* object

```javascript
player.pause();
```

### SkipTo

The **skipTo(seconds)** function takes in a parameter of the time (in seconds) to move the video to. In our below example we'll skip to 30 seconds into the video.

```javascript
player.skipTo(30);
```

### SetPlaybackSpeed

The **setPlaybackSpeed(speed)** function takes in a speed parameter. The default speed is **1**, and the speeds are relative to this.

If we wanted to double the speed we'd use **2**, and half speed would be **0.5**. The below example will double the speed of the video.

```javascript
player.setPlaybackSpeed(2);
```

### SetVolume

The **setVolume(volume)** function takes in a volume parameter. The max volume is **1**, and the volumes to set are relative to this.

To half the volume we would use **setVolume(0.5)**, and to mute the player we would use **setVolume(0)**. The below example will mute the video.

```javascript
player.setVolume(0);
```

### toggleControlBar

We can show and hide the control bar when necessary. This function takes in a **true** or **false** value.

If we pass **true** the control bar will show and remain showing at all times.

If we pass **false** we hide the control bar and it returns to it's standard behaviour, showing on hover or pause.

```javascript
player.toggleControlBar(true);
```

### toggleFullScreen

Using **toggleFullScreen(boolean)** we can set the video to fullscreen. **true** will set the player to fullscreen, and **false** will set the player back to normal.

```javascript
player.toggleFullScreen(true);
```

### toggleMiniPlayer

Using **toggleMiniPlayer(boolean)** we can toggle the player to Mini Player mode. **true** will set the player to Mini Player, and **false** will set the player back to normal.

```javascript
player.toggleMiniPlayer(true);
```


# Utility API

You can use functions documented here to alter the behaviour of Fluid Player after initialisation as well as to access different features and internals of Fluid Player itself.

### setHtmlOnPauseBlock

If we wanted to set or change the HTML that's set for this we can do it using the following.

**html**: This is HTML we want to show when the player in paused

**width**: The width (in pixels) of the container for this HTML

**height**: The height (in pixels) of the container for this HTML

```javascript
player.setHtmlOnPauseBlock({html: "<i>This video is paused</i>", width: 100, height: 50});
```

### destroy

Destroy this instance of Fluid Player. Use this method to remove Fluid Player instance from the page.

```javascript
player.destroy();
```

### dashInstance

Access the current instance of [DASH.js](https://github.com/Dash-Industry-Forum/dash.js). Returns `null` if DASH streamer is not in use.

**NOTE:** avoid storing object reference returned by this function. It is possible for this object to change during lifecycle of the Fluid Player instance.

```javascript
player.dashInstance();
```

### hlsInstance

Access the current instance of [HLS.js](https://github.com/video-dev/hls.js/). Returns `null` if HLS streamer is not in use.

**NOTE:** avoid storing object reference returned by this function. It is possible for this object to change during lifecycle of the Fluid Player instance.

```javascript
player.hlsInstance();
```


# Event API

You can use events documented here to listen for state changes to Fluid Player once it has been initialized.

You can bind to events as shown in the example below.

```javascript
var player = fluidPlayer('video-id');

player.on('play', function() {
  //... Your code here
});

player.on('pause', function() {
  //... Your code here
});
```

#### Additional Information

For **every** event fired by Fluid Player, an additional argument is added as the last argument of the callback function.\
This argument contains information about the player's state at the moment the event occurred.

**Example with all possible values:**

```javascript
player.on('play', function(additionalInfo) {
  const {
    mediaSourceType,  // Possible values: 'source' for your main video source, and 'preRoll', 'midRoll', 'postRoll' for Linear ad playback.
  } = additionalInfo;
});
```

By listening to `mediaSourceType`, you can bind specific behavior to events on the main video or linear ads, such as pre-rolls, mid-rolls, or post-rolls.\
Each event will also return all information from the JavaScript event in the additional info.

### Events

#### play

The **on('play', function(additionalInfo){})** can be used to handle the play event for the Fluid Player.

```javascript
player.on('play', function(additionalInfo){ console.log('Video is playing'); });
```

#### playing

The **on('playing', function(event, additionalInfo){})** can be used to handle the playing event for the Fluid Player.

```javascript
player.on('playing', function(event, additionalInfo){ console.log('Video is now playing'); });
```

#### pause

The **on('pause', function(additionalInfo){})** can be used to handle the pause event for the Fluid Player.

```javascript
player.on('pause', function(additionalInfo){ console.log('Video is now paused'); });
```

#### ended

The **on('ended', function(additionalInfo){})** can be used to handle the ended for the Fluid Player.

```javascript
player.on('ended', function(additionalInfo){ console.log('Video is now ended'); });
```

#### seeked

The **on('seeked', function(additionalInfo){})** can be used to handle the seeked for the Fluid Player.

```javascript
player.on('seeked', function(additionalInfo){ console.log('Video is now seeked'); });
```

#### theatreModeOn

The **on('theatreModeOn', function(event, additionalInfo){})** can be used to execute specific functionality when theatre mode is enabled.

```javascript
player.on('theatreModeOn', function(event, additionalInfo){ console.log('Theatre mode is enabled'); });
```

#### theatreModeOff

The **on('theatreModeOff', function(event, additionalInfo){})** can be used to execute specific functionality when theatre mode is disabled.

```javascript
player.on('theatreModeOff', function(event, additionalInfo){ console.log('Theatre mode is disabled'); });
```

#### timeupdate

Fluid Player emits `timeupdate` event when the time indicated by the `currentTime` attribute of the HTML5 player has been updated.

The event frequency is dependent on the system load, but will be thrown between about 4Hz and 66Hz (assuming the event handlers don't take longer than 250ms to run).

This event receives 1 argument - current time position of the main video content.

```javascript
player.on('timeupdate', function(time, additionalInfo){ console.log(time); });
```

#### miniPlayerToggle

Triggers a `CustomEvent` when the Mini Player is toggled on or off. The `isToggledOn` property holds the new state of the Mini Player.

```javascript
player.on('miniPlayerToggle', function (event, additionalInfo) { console.log(event.detail.isToggledOn) });
```


# Streaming support

Streaming is multimedia that is constantly received by, and presented to, an end-user while being delivered by a provider.

Fluid Player supports MPEG-DASH and HLS streaming. These both work by splitting the content into segments.

Segments contain video or audio content, and are selected based on the highest bit rate available.

This is to ensure there are as few stalls and re-buffers as possible. More details on streaming can be found [here.](https://en.wikipedia.org/wiki/Streaming_media#Protocols)

*Last updated on 5/20/2020*


# HTTP Live Streaming (HLS)

HTTP Live Streaming (also known as HLS) is an HTTP-based media streaming communications protocol implemented by Apple Inc. as part of its QuickTime, Safari, OS X, and iOS software.

This definition taken from the [HLS wikipedia page](https://en.wikipedia.org/wiki/HTTP_Live_Streaming).

It works similarly to DASH by breaking the content into chunks and serving it one segment at a time, potentially with no final chunk.

Live Streaming will be signaled by a Live Indicator displayed along with the Control bar.

Fluid Player makes use of [hls.js](https://github.com/video-dev/hls.js) to play `.m3u8` files. Once an `.m3u8` file is set as the source, Fluid Player will play it, as can be seen in the example below. For browsers that have native support for HLS, Fluid Player will not use `hls.js`.

```html
<video id='hls-video'>
    <source src='stream_hls.m3u8' type='application/x-mpegURL'/>
</video>

<script>
fluidPlayer(
    'hls-video',
    {
        layoutControls: {
            fillToContainer: true
        }
    }
);
</script>
```

If your browser natively supports HLS, Fluid Player will not utilize [hls.js](https://github.com/video-dev/hls.js). However, if you prefer to use hls.js despite native support, you can override it by enabling the following flag.

```html
<video id='hls-video'>
    <source src='stream_hls.m3u8' type='application/x-mpegURL'/>
</video>

<script>
fluidPlayer(
    'hls-video',
    {
        hls: {
            overrideNative: true
        }
    }
);
</script>
```

## HTTP Live Streaming with VAST

Fluid Player supports HTTP Live Streaming with VAST tags. For `.m3u8` files to be played, the VAST `MediaFile` tag must have the following attributes:

* `delivery` should be set as `streaming`
* `type` should be set as `application/vnd.apple.mpegurl`

For example:

```xml
<MediaFile id="1" delivery="streaming" type="application/vnd.apple.mpegurl" width="480" height="640">
    <![CDATA[ https://example.com/stream_hls.m3u8 ]]>
</MediaFile>
```

## Customizing HLS

Fluid Player has hooks that support `hls.js` configuration. A full list of configurable properties can be found in the [official `hsl.js` API docs](https://github.com/video-dev/hls.js/blob/master/docs/API.md).

Below is an example of a configuration where you can set the maximum buffer length and streaming quality with which the video will be started.

```javascript
fluidPlayer('fluid-player', {
    modules: {
        configureHls: (options) => {
            return {
                maxMaxBufferLength: 30, // Max length of buffered video in seconds
                startLevel: 4, // Starting quality level - 4 is usually Full HD (1080p), but this can change by source
                ...options,
            }
        },
        onBeforeInitHls: (hls) => {
            hls.startLevel = 4; // Programatically set start quality level
        },
        onAfterInitHls: (hls) => {
            hls.nextLevel = 4 // Programatically set quality level for next segment
        },
    }
});
```

For more information on using hooks see the [Advanced configuration](/configuration/advanced-configuration) page.

## Built in video quality switcher with auto option

Fluid Player automatically populates the video quality switcher with the available levels from the file and adds an `auto` option.

{% hint style="warning" %}
**Important note**: To ensure the video quality switcher is consistently enabled, you must override the use of native HLS. To find out how to do this, you can click [here](#override-native)
{% endhint %}


# MPEG-DASH

Dynamic Adaptive Streaming over HTTP (DASH), also known as MPEG-DASH, is a streaming technique compatible with Fluid Player.

A media presentation description (MPD) file contains segmented information. The individual segments are described in [this article](https://www.brendanlong.com/the-structure-of-an-mpeg-dash-mpd.html).

Segments contain information regarding the times, URL, resolution, bit rates etc, which informs the player what to serve to the client depending on the bandwidth availability.

Full details on the MPEG-DASH protocol can be found on the [wikipedia](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP).

Live Streaming will be signaled by a Live Indicator displayed along with the Control bar.

Fluid Player makes use of [Dash.js](https://github.com/Dash-Industry-Forum/dash.js) to play MPD files. Once an `.mpd` file is set as the source the Fluid Player will play it, as can be seen in the below example.

```html
<video id='dash-video'>
    <source src='stream_dash.mpd' type='application/dash+xml'/>
</video>

<script>
fluidPlayer(
    'dash-video',
    {
        layoutControls: {
            fillToContainer: true
        }
    }
);
</script>
```

## Customizing MPEG-DASH

Fluid Player has hooks that support `dashjs` configuration, a full list of configurable properties can be found in the [official `dashjs` API docs](http://cdn.dashjs.org/latest/jsdoc/index.html).

Below is an example of a configuration where you can set the maximum buffer length and streaming quality with which the video will be started.

```javascript
fluidPlayer('fluid-player', {
    modules: {
        configureDash: (options) => {
            return {
                stableBufferTime: 30, // Max length of buffered video in seconds
                initialBufferLevel: 4, // Starting quality level
                ...options,
            }
        },
        onBeforeInitDash: (dash) => {
            dash.setQualityFor('video', 4); // Programatically set quality level for next segment
        },
        onAfterInitDash: (dash) => {
            dash.setQualityFor('video', 4); // Programatically set quality level for next segment
        },
    }
});
```

For more information on using hooks see the [Advanced configuration](/configuration/advanced-configuration) page.


# Help

If you have a technical issue or question, please report a issue on [GitHub](https://github.com/fluid-player/fluid-player)


# Changelog

You can view the full changelog on our GitHub repository - <https://github.com/fluid-player/fluid-player/blob/master/CHANGELOG.md>


# License

Copyright © 2026 EXOGROUP and contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


