【问题标题】:Preloading HTML5 Audio in Mobile Safari在 Mobile Safari 中预加载 HTML5 音频
【发布时间】:2011-05-04 05:42:46
【问题描述】:

我在预加载 HTML5 音频内容然后使用缓存中的内容而不是每次尝试重播音频时都尝试重新下载音频时遇到问题。

http://cs.sandbox.millennialmedia.com/~tkirchner/rich/K/kungFuPanda2_tj/

这种体验假设是当有人点击横幅时,它会弹出一个带有加载栏的广告。加载栏正在加载动画所需的所有图像。与此同时,音频也通过 DOM 中已经存在的音频标签加载(这很好)。加载完所有图像后,加载栏消失,用户可以继续。屏幕底部有 4 个按钮可供他们单击。单击其中一个播放音频文件,图像会播放与音频同步的翻书式动画。

音频标签:

<audio id="mmviperTrack" src='tigress.mp3'></audio>
<audio id="mmmantisTrack" src='viper.mp3'></audio>
<audio id="mmtigressTrack" src='kungfu3.mp3'></audio>
<audio id="mmcraneTrack" src='crane.wav'></audio>

播放按钮事件监听器:

button.addEventListener('click',function(){
    if ( f.playing ) return false;
    f.playing = true;
    button.audio.play();
},false);

button.audio.addEventListener('playing', function(){
    animate();
}, false);

问题是,在 javascript 中,每次我单击 play() 时,它都会重新加载音频文件然后播放它。我似乎无法让它在开始时加载一次音频并关闭存储在内存中的内容,而不是每次单击按钮时都尝试重新加载音频。

我尝试过使用 preload 和 autobuffer 属性,但移动 safari 似乎忽略了这些属性,因为无论我如何设置它们,行为总是相同的。我已经尝试过使用源标签和不同的文件格式......什么都没有。

有什么想法吗?

【问题讨论】:

  • HTTP 缓存标头,也许? must-revalidate 或过去过期?
  • 我可以在 javascript 中为我的音频和图像资源设置它吗?此广告将在其他人的网站上投放
  • IBM 有一篇很棒的文章解释了 iOs 处理音频的局限性:ibm.com/developerworks/library/wa-ioshtml5。基本上据我了解,iO 一次只能有一个音频通道。当您更改音频时,它会从内存中丢失其他音频,因此切换会导致重新加载。您拥有一个音轨的解决方案绕过了这个限制。
  • 酷!谢谢你分享。很有道理。

标签: javascript html html5-audio html5-animation


【解决方案1】:

好的,所以解决方案有点像 hack、作弊、变通方法,随便你怎么称呼它。

我注意到,如果我在刚刚播放的音频文件上点击播放按钮,它不会自行重新加载。可能是因为我在播放完音频后暂停了音频,但我对此不是 100% 确定的。无论如何,我所做的是将所有 4 个音频文件合并为一个大音频文件(耶 Audacity~!)。然后,每次我点击其中一个播放按钮时,我都会将音频对象的 currentTime 属性设置为该轨道的起点,然后播放轨道直到它到达终点,然后再次暂停。任务完成!开始时加载一次,每次播放都不会再次加载。

我对必须合并所有不同音轨的想法并不疯狂,但是嘿,它确实有效。

哦,还有。为了让音轨加载并触发“canplaythrough”事件,我将此函数附加到用户点击事件:

var track;
function addHTMLAudio() {
    track = document.createElement('audio');
    track.id = 'mm_audio'
    track.autoplay = false;
    track.preload = false;
    track.addEventListener('canplaythrough',function(){
        track.removeEventListener('canplaythrough');
        audioLoaded = true;
    },false);       
    document.getElementById('body').appendChild(track);
    track.src = f.trackURL;
    track.play();
    setTimeout(function(){ track.pause();  },1);
}

playButton.addEventListener('click',function(e){
    if ( playStatus > 0 ) return;
    playStatus = 1;

    var myId = e.target.parentNode.id;
    var myClip = findClip( myId );

    myClip.state = 'active';        
    track.currentTime = myClip.tIndex.start;

    track.play();
    runAnimation(myClip);       
},false);

【讨论】:

  • 这还能用吗?或者最后一个已知的 iOS 版本是正确的?
  • 我在 iOS 4.2 上实现了这个解决方案。我相信它也应该适用于 4.3。
  • 如果您能看看这个问题,看看您是否可以发表评论,我将不胜感激:stackoverflow.com/questions/7862391/… — 干杯!
  • 我很乐意。抱歉回复慢,我没有收到此评论的通知
猜你喜欢
  • 1970-01-01
  • 2012-08-08
  • 1970-01-01
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多