googleads / videojs-ima

IMA SDK Plugin for Video.js
Apache License 2.0
450 stars 284 forks source link

CurrentTime is always 0 on android chrome - BUG #936

Closed damjan25 closed 4 years ago

damjan25 commented 4 years ago

Why is video.currentTime always 0 on Android Chrome ? For example if you open this example of videojs + ima and ad some test ad tag into it, everything works as expected if you try it on iphone X emulator, but when you swap to pixel 2 emulator, then the currentTime is always 0 https://googleads.github.io/videojs-ima/examples/advanced/

And if you try to reset ad video with setting video.CurrentTime = 0 it doesn't do anything in android chrome (but it works in ios chrome)

document.querySelector("video").currentTime

For example if I mock navigator.userAgent on "android chrome" getter then everything works perfectly

ContextProvider.getWindow().navigator.__defineGetter__('userAgent', function(){
      return 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'; // customized user agent
    });

version videojs: 7.8.4 Version IMA: 3.4 OS: Android Browser: Chrome

Kiro705 commented 4 years ago

Hello @damjan25 ,

Is it possible to use the videoJS method currentTime()? When I have tested with that it seems to work for both Android and iOS mobile web.

damjan25 commented 4 years ago

I just tried again and this function returns correct currentTime on ios chrome but it always returns 0 on Android chrome :thinking:

My local test env is similar to this => https://googleads.github.io/videojs-ima/examples/advanced/ with test vast tag

Kiro705 commented 4 years ago

To double check, there are two different players being discussed here.

  1. document.querySelector("video") may return the video element.
  2. videojs('video_player_id', options) returns the instance of the videoJS player.

I want to make sure you are using the second player.

In addition, I want to clarify, the current time being returned here is for the content video, and not the ad video.

I am still not seeing the 0 time on Android. However, are you able to reproduce this same issue using just a videoJS player, with no IMA integration? If that is the case, it may be a bug with videoJS.

damjan25 commented 4 years ago

Yes I ran currentTime() func on videojs instance. If I try it with just videojs it works on both platforms

Kiro705 commented 4 years ago

Hello @damjan25 ,

I am still unable to reproduce the issue with currentTime() returning 0. Please see the screen shot from my attempt. Below is the code I used in the example. I tried to keep it as close to the advanced example as possible. The logging is created by the following addition at line 79

setInterval(function() {
        console.log(this.player.currentTime());
}.bind(this), 1000);

Please let me know if I am missing anything to help reproduce the issue, or if you have any questions.

import videojs from 'video.js';
import 'videojs-contrib-ads';
import 'videojs-ima';

var Ads = function() {
    const options = {
        autoplay: false,
        controls: true,
        muted: false,
        height: 360,
        width: 480,
        preload: 'auto',
        sources: [{
            // src: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
            src: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4',
            // src: 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8',
            // type: 'application/x-mpegURL',
        }]
    };

    this.player = videojs('vid_player', options);

    // Start ads when the video player is clicked, but only the first time it's
    // clicked.
    this.startEvent = 'click';
    if (navigator.userAgent.match(/iPhone/i) ||
        navigator.userAgent.match(/iPad/i) ||
        navigator.userAgent.match(/Android/i)) {
      this.startEvent = 'touchend';
    }

    this.wrapperDiv = document.getElementById('vid_player');
    this.boundInit = this.init.bind(this);
    this.wrapperDiv.addEventListener(this.startEvent, this.boundInit);

    var ImaOptions = {
      id: 'vid_player',
      adsManagerLoadedCallback: this.adsManagerLoadedCallback.bind(this)
    };
    this.player.ima(ImaOptions);

};

Ads.prototype.SAMPLE_AD_TAG = 'http://pubads.g.doubleclick.net/gampad/ads?' +
    'sz=640x480&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&' +
    'ad_rule=1&impl=s&gdfp_req=1&env=vp&output=xml_vmap1&' +
    'unviewed_position_start=1&' +
    'cust_params=sample_ar%3Dpremidpostpod%26deployment%3Dgmf-js&cmsid=496&' +
    'vid=short_onecue&correlator=';

Ads.prototype.init = function() {
    this.player.ima.initializeAdDisplayContainer();
    this.player.ima.setContentWithAdTag(null, this.SAMPLE_AD_TAG, false);
    this.player.ima.requestAds();
    this.wrapperDiv.removeEventListener(this.startEvent, this.boundInit);
};

Ads.prototype.adsManagerLoadedCallback = function() {
    var events = [
        google.ima.AdEvent.Type.ALL_ADS_COMPLETED,
        google.ima.AdEvent.Type.CLICK,
        google.ima.AdEvent.Type.COMPLETE,
        google.ima.AdEvent.Type.FIRST_QUARTILE,
        google.ima.AdEvent.Type.LOADED,
        google.ima.AdEvent.Type.MIDPOINT,
        google.ima.AdEvent.Type.PAUSED,
        google.ima.AdEvent.Type.RESUMED,
        google.ima.AdEvent.Type.STARTED,
        google.ima.AdEvent.Type.THIRD_QUARTILE
    ];

    for (var index = 0; index < events.length; index++) {
        this.player.ima.addEventListener(
            events[index],
            this.onAdEvent.bind(this));
    }

    setInterval(function() {
        console.log(this.player.currentTime());
    }.bind(this), 1000);

    this.player.on('adslog', this.onAdLog.bind(this));
};

Ads.prototype.onAdLog = function(data) {
    console.log('Ad log: ' + data.data.AdError);
};

Ads.prototype.onAdEvent = function(event) {
    var message = 'Ad event: ' + event.type;
    console.log(message);
};

new Ads();
currentTime_screen_shot
damjan25 commented 4 years ago
  1. This looks very similar to the advanced example and I can not see what could be missing, but looks like this guy managed to reproduce it somehow => https://groups.google.com/g/ima-sdk/c/iRd7wt8P9LE/m/bPpOYgbsAgAJ
  2. Do you think this could effect VTR tracking on ssp side ?
  3. If I will have time today I will try to make example code and upload it to github
  4. if you check google groups, they are saying that could be Chrome problem but it's a bit weird that it works if I change navigator.userAgent getter and and iPhone at the end of the string :thinking:
Kiro705 commented 4 years ago

I would not expect this to effect VTR tracking. Please let me know if you can share sample code to reproduce the issue.

Kiro705 commented 4 years ago

Hi @damjan25 ,

To confirm, the issue is currentTime is always 0 on iOS mobile web?

Just checking because the issue was originally raised for android.

damjan25 commented 4 years ago

@Kiro705 sorry my bad, I just saw on google groups that developer who also reproduced it added that this can happen on ios with playsinline, but now I tried it locally again and I double checked and we are using ios with playsinline and I could not reproduce it on IOS at all, but I still manage to reproduce it on android chrome(real device, in emulator it works). I will delete other comment.

Kiro705 commented 4 years ago

Hello @damjan25 ,

Not a problem. I think the best way to move forward would be for you to share example code to reproduce this issue. Once I can reproduce it, I can help debug the issue.

damjan25 commented 4 years ago

I just tried again with advanced example from github and I still see this bug. But since there is a way better solution for getting currentTime for the video ad I think you can close this issue.

 player.ima.addEventListener(google.ima.AdEvent.Type.AD_PROGRESS, (IMAEvent) => {
        let adProgressData = IMAEvent.getAdData();
        console.log( adProgressData.currentTime );
        console.log( adProgressData.duration );        
});