获取嵌入在有光泽的应用程序中的YouTube视频的当前时间

时间:2019-07-03 13:59:41

标签: javascript shiny youtube-api

我试图在单击按钮时将嵌入式YouTube视频的当前时间存储在一个闪亮的应用程序中。最终,我希望能够将这些时间数据带回到我的R环境中,但是现在,我只是在努力使用闪亮的YouTube API。

通过查看YouTube API和this问题,我知道您可以获得嵌入式YouTube视频的当前时间。但是,当我将该视频包装到Shiny界面中时,该视频具有 shiny-html-output Shiny-bound-output 类,而且我似乎找不到与YouTube视频相对应的底层元素由api控制。

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs()

  ,titlePanel("Hello Shiny!")

  ,sidebarLayout(

    sidebarPanel(
      actionButton("button", "Capture Video Time")
    ),

    mainPanel(
      uiOutput("video")
    )
  )
)

server <- function(input, output) {

  output$video <- renderUI({
    HTML('<iframe width="560" height="315" src="https://www.youtube.com/embed/FR4QIeZaPeM" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>')
  })

  observeEvent(input$button, {
    runjs(
      "ytplayer = document.getElementById('video');
      var time = ytplayer.getCurrentTime();
      alert(time);"
    )
  })
}

shinyApp(ui = ui, server = server)

我期望的是,当我单击Shiny应用程序中的按钮时,应该弹出一个窗口,显示YouTube视频的当前时间,但是什么也没发生。因此,我最大的需要是直接在runjs()函数中获取该javascript代码(如果此处不适合runjs(),则可以使用其他代码),以便实际上可以找到视频播放器的时间。如果您对如何将当前时间值带回我的R环境有任何见识,也将不胜感激,但是一旦我正确地做到这一点,我可能就能弄清楚这一点。提前非常感谢!

1 个答案:

答案 0 :(得分:0)

我自己弄清楚了。问题是我没有正确设置YouTube iframe API。一旦实现,其余的代码就会按我预期的那样工作。供参考here是YouTube iframe API的文档。

我的工作代码如下:

library(shiny)
library(shinyjs)

ui = shinyUI(fluidPage(
  useShinyjs(),
  headerPanel("New Application"),
  sidebarPanel(
    actionButton("getTime","Get Video Time")
  )
  ,mainPanel(
    uiOutput("video")
  )
))

server = function(input, output) {

  output$video <- renderUI({
    HTML(
      '<html>
        <body>
          <iframe id="existing-iframe"
              width="640" height="360"
              src="https://www.youtube.com/embed/fmuUQCB3pAE?enablejsapi=1"
              frameborder="0"
          ></iframe>

          <script type="text/javascript">
            var tag = document.createElement(\'script\');
            tag.src = \'https://www.youtube.com/iframe_api\';
            var firstScriptTag = document.getElementsByTagName(\'script\')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

            var player;
            function onYouTubeIframeAPIReady() {
              player = new YT.Player(\'existing-iframe\');
            }
          </script>
        </body>
      </html>'
    )
  })

  observeEvent(input$getTime,{
    runjs("alert(player.getCurrentTime())")
  })
}

shinyApp(ui = ui, server = server)

请注意,主要区别在于从第18行开始的HTML()包装器内部。我以相同的方式设置了iframe,但在URL中使用了id="existing-iframe"enablejsapi=1。然后,我需要使用<script>标签,该标签下面有我需要的所有JavaScript代码,以使应用程序识别出我正在使用YouTube iframe api。我还清理了第44行的runjs()包装器中的代码。