2015-04-04 94 views
0

我创建了一个JavaScript/jQuery的/ HTML5的音频播放器,工作得非常好,节省一些异常的问题

...问题与动态加载,自定义JavaScript/jQuery的/ HTML5音频播放器

  1. 有时音频负荷,但不会进行播放,即使audio.play()被包含在脚本
  2. 有时候球员返回的时间“无限:0NaN”
  3. 有时音频不一路载入,但玩家无论如何弹奏(即 - 歌曲是90秒长,但只负载,显示持续时间,并播放像6秒)

我将不胜感激任何洞察力可以提供。提前致谢!

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

的一些细节

我动态加载通过在一个“数据”属性存储MP3的位置,一个div每个MP3。点击后,脚本会使用新的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

你(炒鸡蛋)音频文件返回206,并显示如下:

“Range:bytes = 0-”

单独加载时音频很好(200响应),但它不查找Range标头。为了启动loadedmetadata事件,范围标题需要完整。

您需要确保正在设置内容范围标题,无论音频来自何处,以使流正常工作。这将导致这两个问题。 如果你可以在你的服务器配置中提供一些细节,我可以给你一个更好的答案。

+0

对不起忘了3,在大学的轨道上设置了一个内容范围:Content-Range:bytes 0-1326936/1326937 这是正确的吗?那是以字节为单位的文件大小?这是正在读取的值,并且基于所有值。 – TechnicalChaos 2015-04-05 00:35:58

+0

感谢您的帮助。说实话,我不熟悉Range头文件。我对使用HTML5音频元素的工作相对比较陌生,而且我是javascript和jQuery的新手,但我已经设法实现了这一目标。我在哪里可以获得有关Range标题和我的配置文件的更多信息? – jkulakowski 2015-04-05 03:21:41

+0

就“大学”而言,我相信html5音频元素正在收集以毫秒为单位的初始范围 - 音频持续时间。但是,这个数字1,326,937肯定是以字节为单位的音频文件的大小。 – jkulakowski 2015-04-05 03:25:56