在R Shiny界面中呈现YouTube链接

时间:2019-08-30 14:53:02

标签: r shiny hyperlink youtube

我正在开发一个Shiny应用程序,该应用程序将允许用户浏览音乐数据库,然后在一系列选项卡中查看选择结果,其中一个选项卡是数据表。该数据表中是一个包含YouTube链接的变量。

当用户单击特定的YT链接时,我希望该视频在 界面中播放。然后,用户可以在视频在后台播放时继续浏览Shiny应用程序,但是如果他们单击另一个YT链接,则将播放新视频。本质上,我试图在Shiny应用程序中创建响应式YouTube播放器。

我在这里创建了该应用程序的基本版本,其中包含一些虚拟数据。我已经能够使数据库中的URL信息成为可操作的链接,该链接会在新窗口中打开,但我希望它可以在YouTube渲染选项卡中打开/播放。我使用一个YouTube视频创建了该标签,并使用一个链接来演示我想要的内容-如果您切换回datatable标签,则该视频将在后台播放。

我无法做的是将用户操作(单击数据表中的链接)与YouTube渲染选项卡上发生的事情联系起来。

编辑:对于将我引向似乎是两个类似的问题/回答的方向,我深表感谢。我以前看过这两个问题,但都没有回答我的问题。我很抱歉,如果我在原始说明中不清楚,或者对相关问题的回答有误解,但是这种情况略有不同。

Embed instagram/youtube into Shiny R app中,解决方案涉及一个视频,如果单击可视化文件中的特定数据点,则该视频会播放。单击该示例中的另一个数据点不会触发备用视频(我将代码从www.anotherlink.com修改为YouTube链接,没有任何更改)。在另一个问题/解决方案embed iframe inside shiny app中,用户在边栏中进行选择,并通过该选择的内容来完成url。在我的实例中,链接将出现在主面板的输出中(如第一个示例中所示),但是用户将具有多个选项,因为输出是由侧面板中的选择所生成的数据框。在我的示例代码中,用户可以选择类型A或B的链接,这会更改返回的数据帧的内容,但是无论选择A还是B,他们仍然有两个链接可供选择。我的问题是这样的:

如果用户单击这两个链接之一(或四个,如果他们在侧边栏中选择了两种链接类型),那么如何编码YouTube渲染输出标签​​,以使视频链接单击被选择为视频标签的内容,此外,如果用户随后单击另一个链接,URL选择将如何做出反应。

似乎需要单击click =“ plot_click”的内容,但是我想问的是,如何在服务器端选择由该Click生成的输入(即URL)用户可通过侧面板中的选择创建的反应数据帧中的n个链接中的一个。对于上下文,我的数据框具有c 20k行,因此有20k You Tube链接,用户可以根据侧边栏中的许多参数从中选择。

希望现在可以更清楚地说明这一点,并且有人可以解决。谢谢。

library(shiny)
library(DT)
library(shinyWidgets)

#Create Data Frame
type <- c("A", "A", "B", "B")
link <- c("Link 1", "Link 2", "Link 3", "Link 4")
url <- c("https://www.youtube.com/watch_popup?v=-CPXRfwaHaM",
         "https://www.youtube.com/watch?v=YMpQFbe9Tho",
         "https://www.youtube.com/watch?v=N0mh-JlGxzY",
         "https://www.youtube.com/watch?v=osjA0b5ktKU")

data <- data.frame(type, link, url)

#Create Choices for Sidebar
types <- unique(data$type)

#Create URL links for Datatable
target_blank <- ' target="_blank"'
data$url <- paste0("<a ", target_blank, " href='",data$url,"'>", data$url,"</a>")

ui <- fluidPage(

    titlePanel("Data Table to External URL - Example"),

    sidebarLayout(
        sidebarPanel(
            pickerInput("type","Select Type", 
                        choices= types, 
                        options = list(`actions-box` = TRUE),
                        selected = type,
                        multiple = T)),

        # Main Panel
        mainPanel(
            tabsetPanel(type = "tabs", 
                        tabPanel("Table", DT::dataTableOutput(outputId = "table")),
                        tabPanel("You Tube Render", uiOutput("video"))
            ))
    )
)

server <- function(input, output) {

 data_sample <- reactive({
        req(input$type)
        data_sample <- data %>%
            filter(type %in% input$type)

    })

 output$table <- DT::renderDataTable({
     data_sample <- data_sample()
     DT::datatable(data = data_sample, 
                   options = list(pageLength = nrow(data_sample)),
                   colnames=c("Type", "Link Name", "URL"),
                   rownames = FALSE, escape = FALSE)
 })

 output$video <- renderUI({
     HTML(
         '<html>
        <body>
          <iframe id="existing-iframe"
              width="100%" height="360"
              src="https://www.youtube.com/watch_popup?v=-CPXRfwaHaM" ###This URL needs to change dynamically based on which link the user clicks in output$table
              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>'
     )
 })
}

shinyApp(ui = ui, server = server)

1 个答案:

答案 0 :(得分:0)

在这里查看文档,您可以获得使用输入绑定input$id_rows_selected选择的行。然后,我们可以过滤数据框并获取选中的链接。

library(shiny)
library(DT)
library(shinyWidgets)

#Create Data Frame
type <- c("A", "A", "B", "B")
link <- c("Link 1", "Link 2", "Link 3", "Link 4")
url <- c("https://www.youtube.com/watch_popup?v=-CPXRfwaHaM",
         "https://www.youtube.com/watch_popup?v=YMpQFbe9Tho",
         "https://www.youtube.com/watch_popup?v=N0mh-JlGxzY",
         "https://www.youtube.com/watch_popup?v=osjA0b5ktKU")

data <- data.frame(type, link, url)

#Create Choices for Sidebar
types <- unique(data$type)

#Create URL links for Datatable
target_blank <- ' target="_blank"'
data$url <- paste0("<a ", target_blank, " href='",data$url,"'>", data$url,"</a>")

ui <- fluidPage(
  titlePanel("Data Table to External URL - Example"),

  sidebarLayout(
    sidebarPanel(
      pickerInput("type","Select Type", 
                  choices= types, 
                  options = list(`actions-box` = TRUE),
                  selected = type,
                  multiple = T)),

    # Main Panel
    mainPanel(
      tabsetPanel(type = "tabs", 
                  tabPanel("Table", DT::dataTableOutput("table")),
                  tabPanel("You Tube Render", uiOutput("video"))
      ))
  )
)

server <- function(input, output) {

  data_sample <- reactive({
    req(input$type)
    data_sample <- data %>%
      filter(type %in% input$type)

  })

  output$table <- DT::renderDataTable({
    data_sample <- data_sample()
    DT::datatable(data = data_sample, 
                  options = list(pageLength = nrow(data_sample)),
                  colnames=c("Type", "Link Name", "URL"),
                  rownames = FALSE, escape = FALSE)
  })

  output$video <- renderUI({
    req(data_sample())

    selection = input$table_rows_selected
    urls = data_sample()$url
    url = if(length(selection) != 0) urls[selection[length(selection)]] else urls[1]

    url = gsub(".*href='(.*)'>.*$","\\1",url)

    HTML(paste0(
      '<html>
        <body>
          <iframe id="existing-iframe"
              width="100%" height="360"
              src="',url,'" ###This URL needs to change dynamically based on which link the user clicks in output$table
              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>'
    ))
  })
}

shinyApp(ui = ui, server = server)