videojs / videojs-contrib-ads

A Tool for Building Video.js Ad Plugins
http://videojs.github.io/videojs-contrib-ads/
Other
384 stars 257 forks source link

How to disable playMiddleware ? #371

Closed Pong420 closed 6 years ago

Pong420 commented 6 years ago

Hi, I am using play promise to force player play automatically, but the promise is blocked by playMiddleware

Would be great to have an option to disable playMiddleware

incompl commented 6 years ago

I believe you can get the promise by calling play after it is blocked. @ldayananda is that right?

ldayananda commented 6 years ago

@Pong420 The play promise should still be available as the value returned by player.play().

Do you mean that playback in general is being blocked while ads are loading? If so, waiting until playback is no longer blocked and then calling player.play() as @incompl suggested should work.

Pong420 commented 6 years ago

Hi,

I need a play promise before ad start. Here is my simple workflow.

player.ready(function(){

    var callback = function () {
        player.waitingPromise = false;
        player.trigger("playpromise");
    }

    var playPromise = player.play(); // <--- playPromise will be null if 6.1.0 is used
    if (playPromise !== undefined && playPromise !== null) {
        playPromise
            .then(callback)
            .catch(function () {
                player.muted(true)
                callback()
            });

    } else {
        callback()
    }

})

player.ima({
    //... some config
    adsManagerLoadedCallback: function () {

        var supportPlaysinline = !videojs.browser.IS_IOS || player.playsinline();
        var canAutoPlay = !player.paused() || (player.muted() && supportPlaysinline);

        if (canAutoPlay) {
            player.ima.playAdBreak();
        } else if (player.waitingPromise !== false) {
            player.one("playpromise", function () {
                player.ima.playAdBreak();
            })
        } else {
            player.one("timeupdate", function () {
                player.ima.playAdBreak();
            })
        }

    }
})

demo pages: 6.1.0 6.0.1

With verison 6.0.1, player can play automatically on Safari, but verison 6.1.0 can't

incompl commented 6 years ago

I was talking to @ldayananda and it seems like what you want is to wait until after the play event before getting the play promise. For example:

player.on('play', () => {
  var playPromise = player.play();

  playPromise.then(() => {
    // play succeeded
  })
  .catch(() => {
    // play failed
  });
});
incompl commented 6 years ago

I started an autoplay page in the documentation to help with this.

ldayananda commented 6 years ago

Thanks for your sample @Pong420, that helped me understand your usecase.

After talking to @incompl about this for some time, we came to the conclusion that using the same video element to check for autoplay restrictions is likely to not work well. My recommendation is to use another small file to test the browser’s capabilities and use the results to decide whether to mute your player or not. This project might be useful as it performs the testing portion of this solution.

The purpose of the playMiddleware is to block content from playing while videojs-contrib-ads determines whether there are ads waiting to play or not. In 6.0.1, this was done using the cancelContentPlay feature that calls player.pause() quickly after player.play() is called, which is why the play promise is available in that version. However, cancelContentPlay has disadvantages in that it is possible to see some of the content before an ad plays, and that a pause event will occur on most browsers due to calling pause. Since these issues do not occur in playMiddleware, we believe it is a better solution and do not plan to add an option to disable it.

Pong420 commented 6 years ago

Sorry for the late reply and thank you for your suggestion.