4

I am developing an Android app using Cordova and Ionic framework. I am playing a YouTube video with InAppBrowser using the code below:

window.open('https://www.youtube.com/embed/rAiw2SXPS-4', '_self');

But when I press the home button on the device while playing the video, the video is not paused. Due to this issue, my app is rejected after submitting to Google Play with the reason below:

Your submission has been rejected for enabling background playing of YouTube videos in violation of the YouTube API Terms of Service. If this submission was an update to an existing app, the version published prior to this update is still available in Google Play. Please modify your app and resubmit. Additional details have been sent to your account owner's email address.

I searched for a solution but have no luck. Can anybody help?

Pang
  • 9,564
  • 146
  • 81
  • 122
Anu
  • 93
  • 2
  • 9

3 Answers3

1

I was also struggling to find complete solution to pause(not stop) ongoing video(s) when device locks, but with no success. Eventually I found solution myself by combining several parts together.

Here is the directive that accomplishes YouTube player pause on device lock:

import { Directive, ElementRef, OnInit } from '@angular/core'
import { Platform } from 'ionic-angular'
import * as _ from 'lodash-es'

/* tslint:disable */
(function (apiInit) {
  let _registerYouTubeAPIIfNotAlready = function () {
    if (!window[ 'onYouTubeIframeAPIReady' ]) {
      window[ 'onYouTubeIframeAPIReady' ] = function () {
        apiInit.youTubeApiRegistered = true

        if ((typeof apiInit.callback !== "undefined") && _.isFunction(apiInit.callback)) {
          apiInit.callback()
        }
      }
    } else {
      console.error("trying to register YouTube API when it's already registered")
    }
  }

  apiInit.setupYouTubeApiOrDefault = function (callback) {
    if ((typeof callback === "undefined") || !_.isFunction(callback)) {
      _registerYouTubeAPIIfNotAlready()
      return
    }

    if(apiInit.youTubeApiRegistered){
      callback()
      return;
    }

    apiInit.callback = callback
    _registerYouTubeAPIIfNotAlready()
  }
}(window[ 'youTubeApiInit' ] = window[ 'youTubeApiInit' ] || {}))


@Directive({
  selector: "[preventYoutubePlayOnBackground]",
})
export class PreventYouTubePlayOnBackgroundDirective implements OnInit {
  public static youTubeIframeAPI = 'https://www.youtube.com/iframe_api'

  public static injectYouTubeIframeApi(): void {
    let youTubeCheckQuery = "script[src*='" + PreventYouTubePlayOnBackgroundDirective.youTubeIframeAPI + "']"

    if (!document.querySelector(youTubeCheckQuery)) {
      // from YouTube API documentation
      let tag = document.createElement('script')
      tag.src = PreventYouTubePlayOnBackgroundDirective.youTubeIframeAPI

      let firstScriptTag = document.getElementsByTagName('script')[ 0 ]
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag)
    }
  }

  public iframeId: string
  private youTubeIframeElm: any

  constructor(
    public elm: ElementRef,
    private platform: Platform,) {
    this.youTubeIframeElm = elm.nativeElement
    this.iframeId = this.youTubeIframeElm.getAttribute('id')
  }

  ngOnInit(): void {
    this.platform.ready().then(() => {
      PreventYouTubePlayOnBackgroundDirective.injectYouTubeIframeApi()

      window[ 'youTubeApiInit' ].setupYouTubeApiOrDefault(() => {
        this.setYouTubeApi()

        this.platform.pause.subscribe(() => {
          let player = new window[ 'YT' ].Player(this.iframeId) // TODO: add youtube API node module
          player.a.contentWindow.postMessage('{"event":"command","func":"' + 'pauseVideo' + '","args":""}', '*')
        })
      })
    })
  }

  private setYouTubeApi(): void {
    let url = new URL(this.youTubeIframeElm.src)

    if (!url.searchParams.get("enablejsapi")) { // enabling youTube js api to be able to create player
      let prefix = (this.youTubeIframeElm.src.indexOf("?") === -1) ? "?" : "&"
      this.youTubeIframeElm.src += prefix + "enablejsapi=true"
    }
  }
}

HTML for embedded YouTube player will be:

<iframe id="onboarding-video"
                  width="400"
                  height="300"
                  [src]="videoUrl"
                  frameborder="0"
                  allowfullscreen
                  preventYoutubePlayOnBackground
                  iframe-id="onboarding-video">
</iframe>

Note: above code is for ionic 2+, however for ionic 1 you can use:

 (function() {
    // same kind of logic here as written in above constructor body

    $ionicPlatform.on('pause', function(event) {
      // pausing player here
    });
 }())

Also you will need to create Angular 1 style directive instead of TypeScript one written above.

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
0

With $ionicPlatform you can use "on" method:

$ionicPlatform.on('pause', function(event) {
  // pause video here
});

It is based on Cordova pause event:

document.addEventListener("pause", onPause, false);

function onPause() {
    // Handle the pause event
}

See ionic documentation here and cordova documentation here.

Matteo Basso
  • 2,694
  • 2
  • 14
  • 21
  • Thank You. I tried this event to get the app's pause event. But how to pause the video through inappbrowser?! – Anu Jan 18 '16 at 08:35
  • I do a research and i find various solutions, but not all of these are good: - Open directly youtube app from cordova - Delete video DOM node and then put it again into cordova WebView (if it is an iframe) - If you can display your video in another way, i suggest you to see link below, I have never use this but it seems very interesting: [https://developers.google.com/youtube/iframe_api_reference](https://developers.google.com/youtube/iframe_api_reference) – Matteo Basso Jan 18 '16 at 18:57
  • @Anu are you able to solve this one? I am also facing same issue. – Roxx Aug 19 '17 at 17:53
0

You need to set shouldPauseOnSuspend=yes within the options when calling the open method for the inappbrowser. See the documentation here: https://github.com/apache/cordova-plugin-inappbrowser.

Something like this will work:

window.open('http://google.com','_blank', 'shouldPauseOnSuspend=yes');
Spencer Evison
  • 204
  • 3
  • 5