音频无法播放(在iOS,Safari和Chrome上使用HowlerJs)

时间:2019-01-30 06:49:45

标签: javascript audio mobile-safari howler.js

我一直在尝试建立一个播放音频文件的站点,该音频文件远程存储(并且不公开显示)。 我一直在播放音频的方式是:

  1. 通过XMLHttpRequest从服务器获取音频
  2. 将此音频存储在blob中
  3. 使用Howler.js播放音频

我使用以下代码完成此操作:

//Get the audio file from the API 
var request = new XMLHttpRequest();
request.addEventListener("load", loadMusic);
request.responseType = "blob";
request.open("GET", root+"getmusic/"+path);
request.send();

//Function that catches the data, and plays the audio 
function loadMusic(data) {
    var objectUrl = window.URL.createObjectURL(data.currentTarget.response);
    var howler = new Howl({
         autoplay: true,
         src: [objectUrl],
         format: ["mp3"]
         });
    howler.play();
}

这在我的桌面浏览器Chrome,Safari和Firefox(音频播放)上正常工作。但是,当在iOS Safari或移动版本的Chrome中打开手机(iPhone 6s,iOS)上的页面时,音频无法播放,并且在开发控制台中也没有任何错误可以提供提示至于为什么。最让我困惑的是为什么它可以在我的桌面浏览器而不是移动环境中工作。

有什么办法可以解决这个问题?还是调试我应该遵循的路线?

一些其他信息:

  • 用户需要按下一个按钮来加载/启动音频,因此他们必须先与DOM交互。
  • 音频文件为mp3格式。

1 个答案:

答案 0 :(得分:0)

因此,我最终解决了以下问题:

  • 之所以无法在移动设备上播放音频,主要是因为我没有随数据发送正确的响应标头。
  • 我最终放弃了Howler.js,只是将blob用作音频元素来源,例如 $data = Storage::get("audio/".$path); header('Content-Transfer-Encoding: binary'); header('Content-Type: audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3'); header('Content-Length: ' . strlen($data)); header('Content-Disposition: attachment; filename="somefile.mp3"'); header('X-Pad: avoid browser bug'); header('Cache-Control: no-cache'); echo $data;

我正在使用的Laravel后端需要与音频文件(原始数据)一起发送以下标头,如下所示:

tab <- sort(rep(c('typeA','typeB'), 500))
group <- sort(rep(c('AA', 'BB', 'CC', 'DD'), 250))
subgroup <- sort(rep(LETTERS[seq(from = 1, to = 10)], 100))
year <- rep(seq(1996,1999), 250)
relValue <- rnorm(1000, 10, 5)
df <- data.frame(tab, group, subgroup, year, relValue, stringsAsFactors = FALSE)

dfBackup <- df

library(shiny)
library(plotly)
library(ggplot2)
library(dplyr)

ui <- fluidPage(
  sidebarPanel(
    #uiOutput("selected_tab_UI")
    selectInput(inputId = 'selected_tab', label = 'tab', choices = '') ,
    #uiOutput("selected_subgroup_UI")
    selectInput(inputId = 'selected_subgroup', label = 'subgroup', choices = ''),
    #uiOutput("selected_group_UI")
    hr(),
    conditionalPanel(
      condition = "input.selected_tab != 'typeA'",
      radioButtons(inputId = 'selected_group', label = 'group', choices = '')
    )
  ),
  mainPanel(
    plotlyOutput("graph")
  )
)

server <- function(input, output, session){

  observe({
    updateSelectInput(session,
                      'selected_tab',
                      choices = df$tab)
  })

  observe({
    updateSelectInput(
      session,
      'selected_subgroup',
      choices = df %>%
        filter(tab == input$selected_tab) %>%
        select(subgroup) %>%
        arrange(subgroup) %>%
        .[[1]]
    )
  })

   observe({
     if (input$selected_tab != 'typeA'){
     updateRadioButtons(session,
                        'selected_group',
                        choices = df %>%
                        filter(group == input$selected_group) %>%
                        select(group) %>%
                        .[[1]]
                        )
     }
  })

  plotdata <- reactive({df[df$subgroup == input$selected_subgroup,]}) #df$group == input$selected_group & 

  output$graph <- renderPlotly({
    plotdata() %>%
      plot_ly %>%
      ggplot()+
      geom_bar(mapping = aes(x = year, y = relValue), stat = 'identity', position = 'dodge', fill = '#6cb6ff')
  })
}

shinyApp(ui,server)