PierfrancescoSoffritti / android-youtube-player

YouTube Player library for Android and Chromecast, stable and customizable.
https://pierfrancescosoffritti.github.io/android-youtube-player/
MIT License
3.4k stars 759 forks source link

Detecting Advertisements #287

Open MatanKoby opened 5 years ago

MatanKoby commented 5 years ago

What way is there to detect an advertisement? I noticed "onApiChange()" is called for advertisements, but I haven't managed to reproduce it enough times in order to count on it, also, it is sometimes called when there are no advertisements at all.

How can one detect that an ad is currently/started playing, instead of a video? (For reference, the Android Youtube SDK has an "onAdStarted()" call)

PierfrancescoSoffritti commented 5 years ago

Hi, unfortunately at the moment the YouTube IFrame API doesn't expose any API for ads events. Therefore there is no way (without using some hacks) to detect when an ad starts playing.

MatanKoby commented 5 years ago

Well, that's unfortunate. Thanks for the quick response and I hope this issue is solved soon.

nicktz9 commented 5 years ago

Hello PierfrancescoSoffritti, The youtube advertisement seems to be disabled. Is there any way to play advertisements? Thanks!

PierfrancescoSoffritti commented 5 years ago

Hi, that's controlled by the IFrame API and it's not configurable.

Serkali-sudo commented 2 years ago

You can detect ads like this (you can call this function inside sendPlayerStateChange function in js) :

    var adDetect = true;
    var detectAdCallbackId;

    function detectAd() {
        if (detectAdCallbackId) clearInterval(detectAdCallbackId);

        const playerIframe = document.querySelector("iframe");

        if (adDetect && playerIframe) {
            detectAdCallbackId = setInterval(() => {
                if (!playerIframe) {
                    console.log('adDetect : playerIframe is returned null');
                    return;
                }

                const frameDoc = playerIframe.contentDocument;

                if (!frameDoc) {
                    console.log('adDetect : frameDoc is returned null');
                    return;
                }

                const adsContainer = frameDoc.querySelector('.video-ads');

                if (!adsContainer || adsContainer.childElementCount == 0) {
                    console.log('adDetect adsContainer null or child is empty return');
                    return;
                }
                const adsVideo = adsContainer.querySelector("video");
                if (adsVideo) {
                    //Ad Detected
                    console.log('case 1 : Ad is showing right now!');
                    //To send ad event to java go to YouTubePlayerBridge class and add 'sendAdDetected' as 
                   //JavascriptInterface  method
                    YouTubePlayerBridge.sendAdDetected();
                    if (detectAdCallbackId) clearInterval(detectAdCallbackId);
                } else {
                    const isAdShowing = frameDoc.getElementsByClassName('ad-showing').length != 0;

                    if (!isAdShowing) {
                        console.log('case 2 : ad is not showing');
                        return;
                    }

                    const mainVideo = frameDoc.querySelector('.html5-main-video');

                    if (!mainVideo) {
                        console.log('case 2 : main video does not exist');
                        return;
                    }

                    //Ad Detected
                    console.log('case 2 : Ad is showing right now!');
                    //To send ad event to java go to YouTubePlayerBridge class and add 'sendAdDetected' as 
                   //JavascriptInterface  method
                    YouTubePlayerBridge.sendAdDetected();

                    if (detectAdCallbackId) clearInterval(detectAdCallbackId);
                }

            }, 100);
        }
    }
hijacker4163 commented 1 year ago

Hi, does this method still work?

Because my client can always the ad, but I can't retest (very annoying)

If available. I add [detectAd()] to this side case [YT.PlayerState.PLAYING:]?

Serkali-sudo commented 1 year ago

Yes it still works but it sounds like you want to block ads not just detecting them.

IFrame player ads are weird they are not exactly like youtube video ads. The videos that contains ad always shows the ad which can be frustrating.

You can use this code to block ads. Call this function from sendPlayerStateChange in ayp_youtube_player.html#L65 (Blocking ads may violate Youtube Terms so if you are planning to publish your app on google play store it might be rejected)

var adBlockCallbackId; 
function startAdBlock() {
            if (adBlockCallbackId) clearInterval(adBlockCallbackId);

            const playerIFrame = document.querySelector("iframe");

            if (playerIFrame) {
                adBlockCallbackId = setInterval(() => {
                    const frameDoc = playerIFrame.contentDocument;

                    if (!frameDoc) {
                        return;
                    }

                    const adsContainer = frameDoc.querySelector('.video-ads');

                    if (!adsContainer || adsContainer.childElementCount == 0) {
                        return;
                    }

                    const adsVideo = adsContainer.querySelector("video");

                    if (adsVideo) {
                        adsVideo.muted = true;
                        adsVideo.style.display = 'none';
                        adsVideo.currentTime = adsVideo.duration - 0.15;
                        adsVideo.muted = false;
                        adsVideo.style.display = '';
                    } else {

                        const isAdShowing = frameDoc.getElementsByClassName('ad-showing').length != 0;

                        if (!isAdShowing) {
                            return;
                        }

                        const mainVideo = frameDoc.querySelector('.html5-main-video');

                        if (!mainVideo) {
                            return;
                        }
                        mainVideo.muted = true;
                        mainVideo.currentTime = mainVideo.duration - 0.15;
                        mainVideo.muted = false;
                    }

                }, 100);
            }
        }
amanTHEBreaker commented 5 months ago

any one preventing the ads in Android?