动态加载的自定义javascript/jQuery/HTML5音频播放器的问题

Issues with dynamically loaded, custom javascript/jQuery/HTML5 audio player

本文关键字:音频 播放器 问题 HTML5 jQuery 自定义 javascript 动态 加载      更新时间:2023-09-26

问题

我已经创建了一个javascript/jQuery/HTML5音频播放器,它运行得很好,除了一些例外。。。

  1. 有时加载音频,但不会开始播放,即使脚本中包含audio.play()
  2. 有时玩家会返回"无限:0NaN"的持续时间
  3. 有时音频不会一直加载,但播放器无论如何都会播放(即,一首歌有90秒长,但只加载、显示持续时间并播放大约6秒)

如果能提供任何见解,我将不胜感激。提前感谢!

您可以在此处测试操作:http://goo.gl/Aw2OaY

一些细节

我通过一个div动态加载每个mp3,该div将mp3的位置存储在"data"属性中。点击后,脚本会加载位于我页面底部的一个带有新mp3的html5音频播放器。

以下是加载器的表示:

<div class="song-link" data="/song-url.mp3"><p class="song-title"> My Song</p></div>

玩家

<!-- audioPlayer.js -->
<audio id="music">
  <source id="mp3Source" src="" type="audio/mpeg" />
</audio>
<div id="audioPlayerWrap">
  <div id="currentSong"></div>
  <div id="audioplayer">
    <button id="pButton" class="play"></button>
    <div id="timeline">
      <div id="playhead"></div>
    </div>
    <div id="time"></div>
    <div id="exitPlayer">X</div>
  </div>
</div>

脚本

jQuery(document).ready(function() {
  //
  // Store elements
  //
  var audioPlayerWrap = document.getElementById('audioPlayerWrap');
  var audio = jQuery('audio');
  var music = document.getElementById('music');
  var mp3Source = jQuery('#mp3Source');
  var pButton = document.getElementById('pButton');
  var timeline = jQuery('#timeline');
  var playhead = document.getElementById('playhead');
  var songLink = jQuery('.song-link');
  var currentSong = jQuery('#currentSong');
  var exitPlayer = jQuery('#exitPlayer');
  //
  // Event Listeners  
  //  
  // Play audio on songLink click
  songLink.click(function() {
    // Get song URL from data attribute
    var songURL = jQuery(this).attr('data');
    // Set song URL as audio player source
    mp3Source.attr('src', songURL);
    // Get song name
    var songName = jQuery(this).text();
    // Set current song text
    currentSong.text('Now playing: ' + '"' + songName + '"');
    // Load music
    music.load();
    //Load meta data and play
    music.addEventListener("loadedmetadata", function(event) {
       var duration = music.duration;
       // Play music
       playAudio();
    });
    // Bind song time to timeline
    jQuery('#music').bind('timeupdate', updateTime);
    // Bind song end to time
    jQuery('#music').bind('ended', songEnded);
    // Show audio player
    audioPlayerWrap.style.opacity = 1;
  });
  // Add play/pause function pButton click
  pButton.addEventListener('click', function() {
    playAudio();
  });
  // Make Timeline clickable
  timeline.click(function(e) {
    // Store click position X and timeline width in px
    var offsetLeft = jQuery(this).parent().offset().left;
    var positionX = (e.pageX - offsetLeft) - 40;  // 40 makes up for width of playhead
    var timelineWidth = timeline.width();
    // Update audio position
    var songDuration = Math.floor(music.duration);
    var clickPercentage = positionX / timelineWidth;
    var clickInSeconds = clickPercentage * songDuration;
    music.currentTime = clickInSeconds;
  });
  // Close audio player on click
  exitPlayer.click(function() {
    audioPlayerWrap.style.opacity = 0;
    // Remove audio player once it's invisible
    setTimeout(function() {
      audioPlayerWrap.style.display = 'none';
    }, 500);
    music.pause();
    // remove pause, add play
    pButton.className = "";
    pButton.className = "play";
  });
  //
  // Functions
  //
  //Play/Pause function
  function playAudio() {
    // start music
    if (music.paused) {
      music.play();
      // remove play, add pause
      pButton.className = "";
      pButton.className = "pause";
      audioPlayerWrap.style.display = 'block';  // Make sure player can be seen
    } else { // pause music
      music.pause();
      // remove pause, add play
      pButton.className = "";
      pButton.className = "play";
    }
  }
  // time function
  var updateTime = function() { 
    // Timeline width
    timeline.css({'width': '100%'});
    var playheadPosition = Math.floor((this.currentTime / this.duration) * 100);
    playhead.style.marginLeft = playheadPosition + '%';
    // Update timer
    time.innerHTML =  readableDuration(Math.floor(this.currentTime)) + ' / ' + readableDuration(Math.floor(this.duration));
  }
  // Convert time to readable format
  function readableDuration(seconds) {
    sec = Math.floor( seconds );    
    min = Math.floor( sec / 60 );
    min = min >= 10 ? min : '0' + min;    
    sec = Math.floor( sec % 60 );
    sec = sec >= 10 ? sec : '0' + sec;    
    return min + ':' + sec;
  }
  // song end function
  var songEnded = function() {
    if (music.currentTime >= music.duration) {
      music.pause();
      // remove pause, add play
      pButton.className = "";
      pButton.className = "play";
      music.currentTime = 0;
    }
  }
});

您的(炒鸡蛋)音频文件返回206并显示以下内容:

"范围:字节=0-"

独立加载时音频很好(200响应),但不查找Range标头。要激发已加载的元数据事件,需要完成范围标头。

您需要确保在提供音频的任何位置都设置了内容范围标头,以便流能够工作。这将导致这两个问题。如果你能提供一些服务器配置的细节,我可以给你一个更好的答案。