在队列中预加载mp3文件以避免在队列中播放下一个文件时出现任何延迟

时间:2017-02-05 07:38:56

标签: javascript jquery

我正在编写一个脚本,我正在播放多个mp3并且每个文件都在队列中。播放下一个.mp3文件有一点延迟,因为缓冲/加载文件需要时间。

如何缓冲下一个队列的.mp3文件,以便所有文件顺利运行而不会有任何延迟。



.play-btn {
  background-image: url("https://cdn0.iconfinder.com/data/icons/cosmo-player/40/button_play_1-64.png");
  float: none;
  font-size: 0 !important;
  height: 50px;
  margin: 15px auto;
  padding: 5px 10px;
  text-align: center;
  width: 50px;
}
body{float:right; direction:rtl;}
span{padding:5px 10px; direction:rtl; text-align:right;
  margin:5px 1px;
font-size:20px}
.qplaying {
  background: #f00 none repeat scroll 0 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
         <audio id="myAudio" >
	        <source src="" type="audio/mpeg">
        </audio>

       
         <div class="play-btn-wrapper">
            <select class="customSurah form-control ddCountry styled-select" id="surah" name="surah" onchange="getData($('#surah option:selected').val())"><option value="1">Al-Faatiha</option><option value="2">Al-Baqara</option><option value="3">Aal-i-Imraan</option><option value="4">An-Nisaa</option><option value="5">Al-Maaida</option><option value="6">Al-An'aam</option><option value="7">Al-A'raaf</option><option value="8">Al-Anfaal</option><option value="9">At-Tawba</option><option value="10">Yunus</option><option value="11">Hud</option><option value="12">Yusuf</option><option value="13">Ar-Ra'd</option><option value="14">Ibrahim</option><option value="15">Al-Hijr</option><option value="16">An-Nahl</option><option value="17">Al-Israa</option><option value="18">Al-Kahf</option><option value="19">Maryam</option><option value="20">Taa-Haa</option><option value="21">Al-Anbiyaa</option><option value="22">Al-Hajj</option><option value="23">Al-Muminoon</option><option value="24">An-Noor</option><option value="25">Al-Furqaan</option><option value="26">Ash-Shu'araa</option><option value="27">An-Naml</option><option value="28">Al-Qasas</option><option value="29">Al-Ankaboot</option><option value="30">Ar-Room</option><option value="31">Luqman</option><option value="32">As-Sajda</option><option value="33">Al-Ahzaab</option><option value="34">Saba</option><option value="35">Faatir</option><option value="36">Yaseen</option><option value="37">As-Saaffaat</option><option value="38">Saad</option><option value="39">Az-Zumar</option><option value="40">Al-Ghaafir</option><option value="41">Fussilat</option><option value="42">Ash-Shura</option><option value="43">Az-Zukhruf</option><option value="44">Ad-Dukhaan</option><option value="45">Al-Jaathiya</option><option value="46">Al-Ahqaf</option><option value="47">Muhammad</option><option value="48">Al-Fath</option><option value="49">Al-Hujuraat</option><option value="50">Qaaf</option><option value="51">Adh-Dhaariyat</option><option value="52">At-Tur</option><option value="53">An-Najm</option><option value="54">Al-Qamar</option><option value="55">Ar-Rahmaan</option><option value="56">Al-Waaqia</option><option value="57">Al-Hadid</option><option value="58">Al-Mujaadila</option><option value="59">Al-Hashr</option><option value="60">Al-Mumtahana</option><option value="61">As-Saff</option><option value="62">Al-Jumu'a</option><option value="63">Al-Munaafiqoon</option><option value="64">At-Taghaabun</option><option value="65">At-Talaaq</option><option value="66">At-Tahrim</option><option value="67">Al-Mulk</option><option value="68">Al-Qalam</option><option value="69">Al-Haaqqa</option><option value="70">Al-Ma'aarij</option><option value="71">Nooh</option><option value="72">Al-Jinn</option><option value="73">Al-Muzzammil</option><option value="74">Al-Muddaththir</option><option value="75">Al-Qiyaama</option><option value="76">Al-Insaan</option><option value="77">Al-Mursalaat</option><option value="78">An-Naba</option><option value="79">An-Naazi'aat</option><option value="80">Abasa</option><option value="81">At-Takwir</option><option value="82">Al-Infitaar</option><option value="83">Al-Mutaffifin</option><option value="84">Al-Inshiqaaq</option><option value="85">Al-Burooj</option><option value="86">At-Taariq</option><option value="87">Al-A'laa</option><option value="88">Al-Ghaashiya</option><option value="89">Al-Fajr</option><option value="90">Al-Balad</option><option value="91">Ash-Shams</option><option value="92">Al-Lail</option><option value="93">Ad-Dhuhaa</option><option value="94">Ash-Sharh</option><option value="95">At-Tin</option><option value="96">Al-Alaq</option><option value="97">Al-Qadr</option><option value="98">Al-Bayyina</option><option value="99">Az-Zalzala</option><option value="100">Al-Aadiyaat</option><option value="101">Al-Qaari'a</option><option value="102">At-Takaathur</option><option value="103">Al-Asr</option><option value="104">Al-Humaza</option><option value="105">Al-Fil</option><option value="106">Quraish</option><option value="107">Al-Maa'un</option><option value="108">Al-Kawthar</option><option value="109">Al-Kaafiroon</option><option value="110">An-Nasr</option><option value="111">Al-Masad</option><option value="112">Al-Ikhlaas</option><option value="113">Al-Falaq</option><option value="114">An-Naas</option></select>
             <div class="play-btn"></div>
        </div>

        <div id="surah-wrapper"></div>
&#13;
args
&#13;
&#13;
&#13;

这是我想要实现的实际脚本:我希望在小提琴中提到的脚本的上下文中解决。

http://codepen.io/anon/pen/pRKreo

2 个答案:

答案 0 :(得分:7)

你走了。我遇到的最大挑战是handling the value of this within the handler。将<audio>元素设置为preload="none"。我的脚本会在您播放下一首歌之前加载下一首歌曲,并在第一首歌曲完成后自动播放下一首歌曲。

如果您担心Global Scope,请将其放入IIFE。享受!

var files = document.getElementsByTagName('audio');
var songs = [];
var index = 0;

var Song = function(element) {

this.index = index;
this.playing = function(event) {
	try {
		files[this.index].preload = "auto";
	}
	catch (e) {

	}
};
this.ended = function(event) {
	try {
		files[this.index].play();
	}
	catch (e) {

	}
};
element.addEventListener('playing', this.playing.bind(this), false);
element.addEventListener('ended', this.ended.bind(this), false); // Trick
};

for (var len = files.length, i = 0; i < len; ++i) {
index++;
songs.push(new Song(files[i]));
}
ul{
  list-style: none;
}
<!DOCTYPE html>
<html lang="en">
    <meta name="description" content="HTML5 Media Auto Player Skeleton" />
    <title>HTML5 Media Auto Player Skeleton</title>
    <style>

    </style>
</head>

<body>
        
    <main>
<ul>
	<li class="album">
		<h3 class="album-title">HTML5 Media Player w Auto Next</h3>
	</li>
	<li>
		<audio controls="controls" class="full-width" preload="metadata">
			<source src="//rack.international/samples/AttritionDantesKitchenwWHellmixSAMPLE.mp3" type="audio/mpeg">
			<source src="//rack.international/samples/AttritionDantesKitchenwWHellmixSAMPLE.ogg" type="audio/ogg">
			Your browser does not support the audio element.
		</audio>
	</li>
	<li>
		<audio controls="controls" class="full-width" preload="metadata">
			<source src="//rack.international/samples/AttritionDantesKitchenRascalKlonermxSAMPLE3.mp3" type="audio/mpeg">
			<source src="//rack.international/samples/AttritionDantesKitchenRascalKlonermxSAMPLE3.ogg" type="audio/ogg">
			Your browser does not support the audio element.
		</audio>		
	</li>
	<li>
		<audio controls="controls" class="full-width" preload="metadata">
			<source src="//rack.international/samples/crankRingtone.mp3" type="audio/mpeg">
			<source src="//rack.international/samples/crankRingtone.ogg" type="audio/ogg">
			Your browser does not support the audio element.
		</audio>		
	</li>
        
</body>

</html>

答案 1 :(得分:5)

您可以先使用Promise.all()Array.prototype.map()Audio()构造函数,canplaythrough事件来加载所有音频;然后使用Array.prototype.reduce()Promise构造函数在ended事件中按顺序播放音频。

&#13;
&#13;
var audioAddress = [
  "http://download.quranicaudio.com/verses/Sudais/mp3/003001.mp3",
  "http://download.quranicaudio.com/verses/Sudais/mp3/003002.mp3",
  "http://download.quranicaudio.com/verses/Sudais/mp3/003003.mp3",
  "http://download.quranicaudio.com/verses/Sudais/mp3/003004.mp3",
  "http://download.quranicaudio.com/verses/Sudais/mp3/003005.mp3",
  "http://download.quranicaudio.com/verses/Sudais/mp3/003006.mp3"
];

$("button").click(function() {
  Promise.all(audioAddress.map(function(url) {
    return new Promise(function(resolve) {
      var audio = new Audio(url);
      audio.oncanplay = function() {
        resolve(audio);
      }
    })
  }))
  .then(function(data) {
    data.reduce(function(promise, a, index) {
      return promise.then(function() {
        return new Promise(function(resolve) {        
          a.onended = resolve;
          a.play();
          $("p > span").removeClass("playing");
          $("p > span:nth-child(" + (index + 1) + ")")
          .addClass("playing");
        })
      })
    }, Promise.resolve())
  })
});
&#13;
#myAudio {
  display: none;
}
span {
  margin: 0px 10px;
}
.playing {
  background: yellow;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">  
</script>
<button>Play Audio</button>
<p>
  <span>Verse 1</span>
  <span>Verse 2</span>
  <span>Verse 3</span>
  <span>Verse 4</span>
  <span>Verse 5</span>
  <span>Verse 6</span>
</p>
&#13;
&#13;
&#13;

您还可以将音轨序列混合创建为单曲Is it possible to mix multiple audio files on top of each other preferably with javascript并使用AudioContext.linearRampToValueAtTime Web audio api, stop sound gracefully