【问题标题】:Issues with dynamically loaded, custom javascript/jQuery/HTML5 audio player动态加载的自定义 javascript/jQuery/HTML5 音频播放器的问题
【发布时间】:2015-06-09 18:05:37
【问题描述】:

问题

我创建了一个运行良好的 javascript/jQuery/HTML5 音频播放器,除了一些例外情况...

  1. 有时音频会加载,但不会开始播放,即使脚本中包含了 audio.play()
  2. 有时玩家会返回“Infinity:0NaN”的持续时间
  3. 有时音频不会一直加载,但播放器仍会播放(即 - 歌曲时长 90 秒,但只会加载、显示持续时间并播放大约 6 秒)

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

您可以在这里测试操作:http://goo.gl/Aw2OaY

一些细节

我通过将 mp3 的位置存储在“数据”属性中的 div 动态加载每个 mp3。单击时,脚本会加载位于我页面底部的单个 html5 音频播放器和新的 mp3。

这是加载器的表示:

<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;
    }
  }

});

【问题讨论】:

    标签: javascript jquery html audio


    【解决方案1】:

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

    “范围:字节=0-”

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

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

    【讨论】:

    • 抱歉忘记了 3,在大学等轨道中设置了内容范围:Content-Range:bytes 0-1326936/1326937 这是正确的吗?那是文件大小(以字节为单位)吗?这是正在读取的值,一切都基于此。
    • 感谢您的帮助。老实说,我不熟悉 Range 标头。我对使用 HTML5 音频元素比较陌生,而且我是 javascript 和 jQuery 的新手,但我已经设法做到了这一点。我在哪里可以获得有关 Range 标头和我的配置文件的更多信息?
    • 就“大学”而言,我相信 html5 音频元素正在收集以毫秒为单位的初始范围 - 音频的持续时间。但是,这个数字 1,326,937 绝对是音频文件的大小(以字节为单位)。
    • 是否有某些服务器信息可以通过 cPanel 转发给您?
    • 所以,我联系了我的虚拟主机,他们进行了一些调整(不包括我的域从 Varnish 服务器),这似乎已经纠正了问题 2 和 3。但是,我仍然有间歇性播放的问题。播放器仅在每隔一次加载时才开始播放。如果我省略了loadedmetadata 监听器,只是在load() 方法之后调用playAudio(),播放器每次都会工作。我最初写了loadedmetadata监听器来解决这些问题,但无济于事。我已经把它放在那里了。删除它是否可取?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多