如何在Javascript中预加载声音?

如何在Javascript中预加载声音?,javascript,audio,preload,Javascript,Audio,Preload,得益于onload功能,我可以轻松地预加载图像。但它不适用于音频。Chrome、Safari、Firefox等浏览器不支持音频标签中的onload功能 如何在不使用JS库和不使用或创建HTML标记的情况下在Javascript中预加载声音?根据您的目标浏览器,在音频标记上设置属性可能就足够了。//在Chrome、FF、IE6上测试 //Tested on Chrome, FF, IE6 function LoadSound(filename) { var xmlhttp; if

得益于
onload
功能,我可以轻松地预加载图像。但它不适用于音频。Chrome、Safari、Firefox等浏览器不支持音频标签中的
onload
功能


如何在不使用JS库和不使用或创建HTML标记的情况下在Javascript中预加载声音?

根据您的目标浏览器,在
音频
标记上设置属性可能就足够了。

//在Chrome、FF、IE6上测试
//Tested on Chrome, FF, IE6

function LoadSound(filename) {
    var xmlhttp;
    if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else { // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            document.getElementById("load-sound").innerHTML = '<embed src="' + filename + '" controller="1" autoplay="0" autostart="0" />';
        }
    }
    xmlhttp.open("GET", filename, true);
    xmlhttp.send();
}
函数LoadSound(文件名){ var-xmlhttp; if(window.XMLHttpRequest){//IE7+、Firefox、Chrome、Opera、Safari的代码 xmlhttp=新的XMLHttpRequest(); }else{//IE6、IE5的代码 xmlhttp=新的ActiveXObject(“Microsoft.xmlhttp”); } xmlhttp.onreadystatechange=函数(){ if(xmlhttp.readyState==4&&xmlhttp.status==200){ document.getElementById(“加载声音”).innerHTML=''; } } open(“GET”,文件名,true); xmlhttp.send(); }
参考


Remy提出了一个iOS解决方案,它利用了精灵的概念:


不确定它是否直接解决了预加载问题,但它的优点是您只需要加载一个音频文件(我想这也是一个缺点)

您是否尝试对该文件发出ajax请求?在它完全加载之前,您不会显示/使用它


例如(您不必使用jQuery)。

您的问题是音频对象不支持“加载”事件

相反,有一个名为“canplaythrough”的事件,这并不意味着它已完全加载,但加载的足够多,以当前下载速率,它将在曲目有足够时间播放时完成

所以不是

audio.onload = isAppLoaded;
试一试

或者更好……)


我尝试了tylermwashburn接受的答案,但在Chrome中不起作用。所以我继续创建了这个,它从jQuery中受益。它还嗅探ogg和mp3支持。默认设置为ogg,因为一些专家说192KBS的ogg文件与320KBS的MP3一样好,因此您可以在所需的音频下载上节省40%。但是,IE9需要mp3:

// Audio preloader

$(window).ready(function(){
  var audio_preload = 0;
  function launchApp(launch){
    audio_preload++;
    if ( audio_preload == 3 || launch == 1) {  // set 3 to # of your files
      start();  // set this function to your start function
    }
  }
  var support = {};
  function audioSupport() {
    var a = document.createElement('audio');
    var ogg = !!(a.canPlayType && a.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, ''));
    if (ogg) return 'ogg';
    var mp3 = !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
    if (mp3) return 'mp3';
    else return 0;
  }
  support.audio = audioSupport();
  function loadAudio(url, vol){
    var audio = new Audio();
    audio.src = url;
    audio.preload = "auto";
    audio.volume = vol;
    $(audio).on("loadeddata", launchApp);  // jQuery checking
    return audio;
  }
  if (support.audio === 'ogg') {
    var snd1 = loadAudio("sounds/sound1.ogg", 1);  // ie) the 1 is 100% volume
    var snd2 = loadAudio("sounds/sound2.ogg", 0.3);  // ie) the 0.3 is 30%
    var snd3 = loadAudio("sounds/sound3.ogg", 0.05);
        // add more sounds here
  } else if (support.audio === 'mp3') { 
    var snd1 = loadAudio("sounds/sound1.mp3", 1);
    var snd2 = loadAudio("sounds/sound2.mp3", 0.3);
    var snd3 = loadAudio("sounds/sound3.mp3", 0.05);
        // add more sounds here
  } else {
    launchApp(1);  // launch app without audio
  }

// this is your first function you want to start after audio is preloaded:
  function start(){
     if (support.audio) snd1.play();  // this is how you play sounds
  }

});
此外: 这是一个mp3到ogg的转换器: 也可以使用VLC媒体播放器进行转换。
右键单击mp3文件(在Windows中)并转到文件详细信息,检查mp3比特率。为新的“ogg”文件选择新比特率时,请尝试降低40%。转换器可能会抛出错误,因此请继续增大大小,直到接受为止。当然,测试听起来质量令人满意。还有(这也适用于我)如果您使用VLC Media player测试音频曲目,请确保将音量设置为100%或更低,否则您会听到音频降级,并可能会错误地认为这是压缩的结果。

我知道的唯一方法是使用
参考声音,使其不可见并禁用自动播放。但是如果你不想添加HTML,我不知道还有什么好推荐的编辑:我知道你不想要一个库,但这一个可能值得检查(10K大小):谢谢Brad,但是SoundManager使用Flash!我认为最好的选择是第二个链接中给出的解决方案。但它使用JQuery。难道没有一种自然的方式吗让我知道。好的,我试试这个代码!虽然我认为这将是难以管理的声音像图像。为什么谷歌、Mozilla、微软没有像对待图像那样实施预加载?我尝试了你的解决方案,但它对我不起作用,因为我必须创建嵌入标签。我只需要使用JS。谢谢你的努力ASeptik!是的,如果没有选择,我想我会使用这个解决方案。我不想用JQery。谢谢,爸爸,但它没用!谢谢Tylermwashburn!你终于找到解决办法了!这对我有用!非常感谢!:-)@曼努埃尔·伊格纳西奥·洛佩斯·昆特罗:我想这只适用于
HTML5
,无论如何,如果你想通过这种方式,阅读这篇文章可能会帮助你@tylermwashburn为什么addEventListener更好?@tylermwashburn这篇文章和onload有什么区别?这能在iOS上运行吗?很好的解决方案,但由于完全愚蠢的预测,连接速度慢会有问题。非常有用,谢谢!至于音频转换,我实际上对Audacity非常满意(相对而言,因为它是一个免费工具)。提供批处理,并且(理论上)比在线工具快得多,因为它是本地程序。另外,iOS不支持OGG
audio.addEventListener('canplaythrough', isAppLoaded, false);
// Audio preloader

$(window).ready(function(){
  var audio_preload = 0;
  function launchApp(launch){
    audio_preload++;
    if ( audio_preload == 3 || launch == 1) {  // set 3 to # of your files
      start();  // set this function to your start function
    }
  }
  var support = {};
  function audioSupport() {
    var a = document.createElement('audio');
    var ogg = !!(a.canPlayType && a.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, ''));
    if (ogg) return 'ogg';
    var mp3 = !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
    if (mp3) return 'mp3';
    else return 0;
  }
  support.audio = audioSupport();
  function loadAudio(url, vol){
    var audio = new Audio();
    audio.src = url;
    audio.preload = "auto";
    audio.volume = vol;
    $(audio).on("loadeddata", launchApp);  // jQuery checking
    return audio;
  }
  if (support.audio === 'ogg') {
    var snd1 = loadAudio("sounds/sound1.ogg", 1);  // ie) the 1 is 100% volume
    var snd2 = loadAudio("sounds/sound2.ogg", 0.3);  // ie) the 0.3 is 30%
    var snd3 = loadAudio("sounds/sound3.ogg", 0.05);
        // add more sounds here
  } else if (support.audio === 'mp3') { 
    var snd1 = loadAudio("sounds/sound1.mp3", 1);
    var snd2 = loadAudio("sounds/sound2.mp3", 0.3);
    var snd3 = loadAudio("sounds/sound3.mp3", 0.05);
        // add more sounds here
  } else {
    launchApp(1);  // launch app without audio
  }

// this is your first function you want to start after audio is preloaded:
  function start(){
     if (support.audio) snd1.play();  // this is how you play sounds
  }

});