【问题标题】:Render YouTube links within R Shiny interface在 R Shiny 界面中渲染 YouTube 链接
【发布时间】:2020-01-03 20:15:07
【问题描述】:

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

当用户点击特定的 YT 链接时,我希望该视频能够在 Shiny 界面中播放。当视频在后台播放时,用户可以继续探索 Shiny 应用程序,但如果他们随后单击另一个 YT 链接,则会播放新视频。本质上,我正在尝试在 Shiny 应用程序中创建响应式 YouTube 播放器。

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

我无法将用户操作(点击数据表中的链接)与 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" 的内容,但我想我要问的是如何在服务器端选择由该点击生成的输入(即 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)

【问题讨论】:

标签: r shiny hyperlink youtube


【解决方案1】:

查看此处的文档,您可以获取使用输入绑定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)

【讨论】:

    猜你喜欢
    • 2020-08-20
    • 2019-03-07
    • 2020-11-08
    • 2020-04-26
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-14
    相关资源
    最近更新 更多