繁体   English   中英

HTML5音频元素-某些Android浏览器未正确报告音轨长度

[英]HTML5 Audio element - Track length misreported by some Android browsers

我正在使用HTML5 <audio>元素开发音频播放器,并试图解决跨浏览器的一些问题。

此播放器配置为在单击其他音轨的链接时在音轨之间切换。 在内部,它会暂停<audio>元素,将其currentTime设置为0 (如HTML5音频中所述,Android 4.0.4设备Native Browser中不会多次播放 ),然后在创建新的<audio>元素之前将其从DOM中删除。指定的新源轨道。 在元素上调用play()方法以加载曲目并开始播放。

在桌面浏览器,iPhone和iPad上,这可以正常工作。 它还可以在同事的三星Galaxy S3 Mini上使用。 但是,在另一部测试电话(全尺寸三星Galaxy S3)上,后续曲目的播放失败-该曲目甚至无法播放,并且在播放栏中显示为已完成。 在我的Motorola Xoom平板电脑上使用的普通Android 4.1.2浏览器中也是如此。

页面加载上指定的第一个曲目始终可以正常运行。

在JavaScript代码中添加了一些调试语句之后,特别是timeupdate回调函数,我发现在回放失败的情况下,当timeupdate升高的两个实例中, <audio>元素的duration值为1 通常情况下,持续时间为3-4分钟,从350到刚好超过1000 这解释了为什么回放栏立即显示新加载的曲目已完成回放。

我认为后续的曲目无法正确加载; 即使先前已将其加载并缓存在手机上,也肯定必须能够正确加载它。 所有曲目均为MP3,可以在各自的浏览器中播放。

我在这里想念什么? 您知道问题是什么以及如何使其正常工作吗?

非常感谢。

更多信息:我已经将其他事件连接到<audio>元素以跟踪可能发生的情况:

  • progress (有关缓冲范围的报告)
  • loadedmetadata
  • canplay
  • error

在桌面上(其中,该正常工作),则事件如下: timeupdate (与NaN的持续时间), progress X3(0缓冲范围), loadedmetadatacanplaytimeupdate与121.172368持续时间, progress与1米缓冲范围[0,11.507715] ,随后随着轨道继续播放,将发生一系列时间timeupdateprogress事件。 iPhone具有类似的事件序列。

在Samsung S3上,我收到以下事件:持续时间为1的timeupdate ,其后是progress (0缓冲范围), loadedmetadatacanplay和最后一个持续时间仍为1的timeupdate

该页面对于解释事件和数据结构非常有用: http : //www.sitepoint.com/essential-audio-and-video-events-for-html5/

好了,我终于解决了:

  • 首先,我更新了音频实现,以在切换音轨时重用相同的<audio>元素,确保在更改src等之前暂停音频。这可能会或不会产生任何积极影响,尽管这是一种方法请确保我们没有太多的<audio>元素可能在内存中浮动,特别是如果某个未知的电话一次只能处理一个实例的话。
  • 在切换音轨之前,我添加了保护子句以停止任何当前正在播放的音频,并确保如果没有加载音频,则无论是pause()还是设置currentTime都不会导致错误:

     if (audioPlayerElement.readyState > 0) { audioPlayerElement.pause(); audioPlayerElement.currentTime = 0; } 
  • 由于后续曲目会自动播放,因此需要修正语句的顺序。

轨道持续时间的错误报告是使用<audio>元素的方式中存在较大问题的征兆。 以前,我已按如下方式初始化音频播放器:

  1. 创建<audio>元素/将src设置为MP3轨道的新URL
  2. <audio>元素上调用load()
  3. 绑定时间timeupdateended事件
  4. 由于这是自动播放,因此将autoplay属性添加到<audio>元素
  5. 由于这是自动播放,因此在<audio>元素上称为play()

(在上面的步骤1和步骤2之间执行了用于调试跟踪的loadedmetadatacanplayprogress事件的绑定。)

我发现此序列的问题是:

  • 如果设置了autoplay属性,则调用play()是多余的。
  • 添加autoplay属性应该在调用load()之前进行,因为一旦缓冲了足够的数据, load()自动开始播放曲目。

因此,有效的最后步骤是:

  1. <audio>元素的src属性设置为MP3轨道的新URL
  2. 绑定时间timeupdateended事件
  3. 由于这是自动播放,因此将autoplay属性添加到<audio>元素
  4. <audio>元素上调用load()

仅当单击播放/暂停按钮或从轨迹栏上的特定位置开始播放时, play()函数才适用。

最后,值得注意的是,在iOS设备和某些Android设备(取决于浏览器)上,如果播放器初始化为在页面加载时开始播放,则会忽略自动播放。 在此类设备上,仅当执行可以追溯到click事件(或类似事件)时,自动播放才会起作用。 在更新视觉效果以指示“正在播放”状态时,请记住这一点canplay事件处理程序似乎是执行此操作的好地方。

我将完全回答您的问题,因为它对我也很有用-如果您有更好的解决方案,请告诉我:)

我将保留每种声音所需的所有元数据的哈希值。 该哈希可能只是服务器的json响应-例如:

app.sounds.metadata = {
    "enter the sandman": {
        "artist": "Metaliica",
        "album": "Metallica.",
        "description": "Lorem ipsum dolor sit amet."
        "genre": "metal",
        "duration": 19920,
        "playcount": 312
    },
    "piano man": {
        "artist": "Billy Joel",
        "album": "You're my home",
        "description": "Lorem ipsum dolor sit amet."
        "genre": "Soft rock",
        "duration": 16200,
        "playcount": 135,

    }
}

我的音频元素将被声明为:

<audio data-sound="piano man">
    <source src="piano_man.ogg" type="audio/ogg">
    <source src="piano_man.mp3" type="audio/mpeg">
</audio>

现在,当我使用声音时,我可以使用:
var html5offset = 1000

var meta = app.sounds.metadata[sound.getAttribute("data-sound")];
var soundduration = meta.duration || sound.duration*html5offset;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM