【问题标题】:Use YouTube Iframe API with Nativescript?将 YouTube Iframe API 与 Nativescript 一起使用?
【发布时间】:2019-06-28 23:09:44
【问题描述】:

更新:从下面@Manoj 的代码和其他一些来源,我现在能够将 youtube 播放器加载到基于 Youtube iframe api 的 webview 中。但问题仍然是:如何让我的应用程序识别视频本身何时开始播放? (视频加载后,以及任何广告播放后)。

关键代码被“困”在webview中。

有一个 nativescript-webview 接口插件,旨在让您从 webview 获取信息。如果这是这里所需要的,那么在视频本身开始播放时注册该插件的正确代码是什么?

该插件的 repo 中的示例似乎非常具体,并且与我在这里想到的不同。


原问题:

我有一个使用 iOS 和 Angular 的 Nativescript 应用程序。我想在应用程序中播放 youtube 视频,并且我希望能够控制播放。所以我想做一些事情,比如以编程方式自动播放它并在视频实际播放时注册。

我该怎么做?

更多详情:

有一个 nativescript-youtubeplayer 插件,但我不能在这里使用它,因为它需要一个 api 密钥和其他一些原因。

我可以将基本 iframe 嵌入到 WebView 中,代码如下:

<WebView (loaded)="onWebViewLoaded($event)" requiresUserActionForMediaPlayback="false" [src]="urlSource"></WebView>

在ts中:

 public urlSource= '<iframe src="https://www.youtube.com/embed/ZwO3PG-c5Cs?playsinline=1&autoplay=1&fs=0&controls=1&enablejsapi=1"></iframe>'

这会加载视频。但它没有正常的 youtube 控件(比如视频上没有大的暂停按钮)——也许它被 webview 覆盖了。更重要的是,它不会自动播放,而且它没有给我一种以编程方式访问 iframe 信息的方法——例如,我不知道何时视频实际播放与暂停时的对比。

Youtube Iframe Player API 就是为此目的而设计的,但是如何将它与 Nativescript 一起使用呢?它似乎需要以我以前从未见过 Nativescript 的方式进行 dom 操作。

例如,基本代码是:

var player;
function onYouTubeIframeAPIReady() {
  player = new YT.Player('player', {
    height: '390',
    width: '640',
    videoId: 'M7lc1UVf-VE',
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    }
  });
}

但是,不出所料,这会引发错误,例如“找不到名称 YT”。

那么,我如何使用 iframe 在 Nativescript 中嵌入 youtube 视频并像我有一个 Web 应用程序一样控制它?

【问题讨论】:

  • 你发现了吗?
  • 请参阅下面发布的我的答案。我能够让它主要与那里的代码一起工作。我说“主要是”是因为那是不久前的事了,在将其投入生产之前我转向了其他项目(我记得,它基本上是功能性的)。也可能有比我提供的代码更好的与 web 视图交互的方式——但这应该足以让人们开始。
  • 在我根据您的代码进行更改之前 - 您还记得自动播放是否在那里工作吗?因为这是我的主要问题......
  • 我不能肯定地说,因为那是不久前,但我记得自动播放是通过将 autoplay 参数设置为 true 来工作的。

标签: nativescript


【解决方案1】:

您可以在 WebView 中使用 YouTubeIframeAPI,创建一个单独的本地 html 文件来保存脚本。

<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<body>
    <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
    <div id="player"></div>

    <script>
        // 2. This code loads the IFrame Player API code asynchronously.
      var tag = document.createElement('script');

      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

      // 3. This function creates an <iframe> (and YouTube player)
      //    after the API code downloads.
      var player;
      function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
          width: '100%',
          videoId: 'M7lc1UVf-VE',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }

      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        event.target.playVideo();
      }

      // 5. The API calls this function when the player's state changes.
      //    The function indicates that when playing a video (state=1),
      //    the player should play for six seconds and then stop.
      var done = false;
      function onPlayerStateChange(event) {
        if (event.data == YT.PlayerState.PLAYING && !done) {
          setTimeout(stopVideo, 6000);
          done = true;
        }
      }
      function stopVideo() {
        player.stopVideo();
      }
    </script>
</body>

</html>

Playground Sample

注意:您甚至可以在查询字符串中传递 videoId 或任何其他参数,然后在 html 文件中解析和使用相同的参数。

【讨论】:

  • 在您的操场上,它仍然没有自动播放视频,也没有注册状态更改(似乎没有调用 onPlayerReady 和 onPlayerStateChange)
  • 播放器本身似乎与 youtube 的默认设置有些不同。例如,如果您点击 youtube 视频,它们通常会在中间显示一个大的暂停按钮。这不会发生在这里。这对我来说很好,但我想确保 Youtube 不会有问题。
  • 我想我已经很接近了——只是不确定我在这里的 cmets 中注意到了什么。 (仅供参考,反对票不是来自我)
  • 我不确定你的问题可能是什么,我的代码工作得很好。仅供参考,我刚刚在forum 上分享了相同的解决方案。不介意投反对票,我现在看到至少 10 个来自我的不同线程的随机投反对票,好像有人在生我的气?
  • JavaScript 在{N} WebView 中默认启用,不知道您为什么必须明确启用它。如果您希望播放器与应用程序的其他部分进行交互,我建议使用nativescript-youtubeplayer 插件。如果您更喜欢从 WebView 与您的应用代码交互,那么 nativescript-webview-interface 插件应该会有所帮助。
【解决方案2】:

我已经有一段时间没有看这个了,但我认为跟进以显示在我的案例中主要工作的原因会有所帮助。希望这里有一些代码可以帮助其他人。

对我来说,关键的见解是将基本的 youtube 代码(他们给你的 here)放入 TS 组件中的一个变量中:

所以,首先,我的 TS 组件像这样放入 Youtube 代码:

exportClass YoutubeComponent implements OnInit {
        public youtubeVideoId = [ID OF VIDEO I WANT TO PLAY]
        public youtubeCode = 
          `
           <!DOCTYPE html>
          <html>
          <body>
             <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
               <iframe id="player"
                width="90%" height="375"
                src="https://www.youtube.com/embed/` + this.youtubeVideoId + `?enablejsapi=1&playsinline=1&autoplay=1&fs=0&controls=1" 
            frameborder="0"
                 ></iframe>
           <script>
           /**
           * WebViewInterface class to handle communication between webView and Android/iOS.
          */
         var NSWebViewinterface = (function () {
               function NSWebViewinterface() {
         
          [PUT IN THE REST OF THE WHOLE YOUTUBE CODE IN THIS VARIABLE]
             ...   
        `

然后在html中:

<WebView row="0" src="{{youtubeCode}}" #webView></WebView> 

然后与webview交互,在同上的TS组件中:

 @ViewChild('webView') webView: ElementRef;

  onWebViewLoaded(args) {
     let webView: WebView = this.webView.nativeElement;
     this.oWebViewInterface = new WebViewInterface(webView); 
     this.nextFunction()
   }

  nextFunction {
     this.oWebViewInterface.on('onPlayerStateChange, (data) =>{
       if (data.state === 5){ //video cued
         console.log('video is cued up')
       }
    })
  }
 

【讨论】:

  • 现在对此进行了测试...自动播放不起作用...:/ YouTube的规则一直在变化...现在通过iframe自动播放仅在与mute结合使用时才有效。 .
猜你喜欢
  • 2016-07-27
  • 1970-01-01
  • 1970-01-01
  • 2018-06-29
  • 1970-01-01
  • 2021-08-04
  • 2021-12-14
  • 2014-01-14
  • 1970-01-01
相关资源
最近更新 更多