# Click to Play

For browsers that don't allow auto playing video, a user action is required to make the `play` call. There are two click to play scenarios:

Type | Description
--- | ---
Synchronous Play | Play video directly off of a user action
Asynchronous Play | Play video after performing an asynchronous task first

Currently the browsers which require a user action for un-muted auto play are:

- Desktop Chrome 66+
- Mobile Chrome
- Safari (Desktop and iOS)

## Synchronous Play

The user must physically click or tap a UI element to initiate playback via `play` (see example). The simplest implementation is:

    <button onclick="player.play('//content.m3u8');">
        Click Me
    </button>

Alternatively this can be done inside of an event handler:

    var button = document.getElementById("custom-play-button");

    button.addEventListener("click", function(event) {
        player.play("//content.m3u8");
    });

## Asynchronous Play

Sometimes asynchronous operations need to be performed before the play command is called. Unfortunately this is not considered a direct user action and auto play will fail:

    button.addEventListener("click", function(event) {
        doAsyncWork(function(result) {
            // This does not count as a user action and will not auto play
            player.play("//content.m3u8");
        });
    });

To handle this scenario there are two possible options:

1. Default - The default page listener provided by the player will handle most asynchronous situations
2. User Action - In some cases it's necessary to explicitly trigger a user action before doing asynchronous work

### Default

By default we provide an internal mechanism called `listenForAction` which adds a global event listener to detect a user action on the first click. (see example). This should handle most of the asynchronous flow scenarios.

### User Action

Sometimes it's necessary to explicitly register a user action in the video player before doing asynchronous work. The first case is when the `listenForAction` option has been disabled,

    var player = TOP.createAndInitPlayer({
        ...
        config: {
            player: {
                autoPlayOptions: {
                    listenForAction: false // default is true
                }
            }
        },
    }

    button.addEventListener('click', function(event) {
        doAsyncWork(function() {
            // This will not play
            player.play(vodContent);
        });
    });

The second case is when the event listener that triggers the asynchronous work is preventing propagation,

    button.addEventListener('click', function(event) {
        event.stopPropagation();

        doAsyncWork(function() {
            // This will not play
            player.play(vodContent);
        });
    });

To handle any additional use cases which require a workaround, as well as for the two exceptions above, the `player.userAction` API was created. Call this directly after a user action to prime the video:

    button.addEventListener("click", function(event) {
        player.userAction(event);

        doAsyncWork(function(result) {
            // This will play
            player.play("//content.m3u8");
        });
    });

For the full implementation see the example

Note - It does appear that generic browser behavior does allow for asynchronous callbacks executing in 1 second or less to also count as user triggered actions. This behavior should not be relied on though and the above methods should be preferred when handling asynchronous cases.