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

时间:2015-04-04 23:55:42

标签: javascript jquery html5 audio

问题

我创建了一个非常好用的javascript / jQuery / HTML5音频播放器,除了少数例外......

  1. 有时音频会加载但不会开始播放,即使剧本中包含了audio.play()
  2. 有时玩家会返回“Infinity:0NaN”
  3. 的持续时间
  4. 有时音频不会一直加载,但播放器无论如何都会播放(即 - 一首歌是90秒长,但只加载,显示持续时间,并播放6秒钟)
  5. 我非常感谢能够提供的任何见解。提前谢谢!

    您可以在此处测试操作: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;
        }
      }
    
    });
    

1 个答案:

答案 0 :(得分:1)

您的(Scrambled-eggs)音频文件返回206并显示以下内容:

&#34;范围:字节= 0-&#34;

独立加载时音频很好(200响应),但它不会查找Range标头。要触发loadedmetadata事件,需要完成范围标头。

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