`
huobengluantiao8
  • 浏览: 1029705 次
文章分类
社区版块
存档分类
最新评论

学习一个网页播放器

 
阅读更多
http://antimatter15.github.com/player/player.html

<!doctype html>
<html manifest="player.manifest">
  <head>
    <title>MP3 Player</title>
    <link rel="icon"  type="image/png" href="16.png">
    <style>
      body {
        background: #444;
        background-image: -webkit-gradient(
            linear,
            left top,
            right top,
            color-stop(0.8, rgb(133,133,133)),
            color-stop(1, rgb(68,68,68))
        );
        background-image: -moz-linear-gradient(
            left center,
            rgb(133,133,133) 80%,
            rgb(68,68,68) 100%
        );
        font-family: sans-serif;
        font-size: 14px;
        margin: 0;
        overflow-y: scroll;
      }
      #startup #prompt {
        width: 200px;
        background: #ddd;
        height: 20%;
        width: 30%;
        min-height: 180px;
        border-radius: 5px;
        z-index: 100;
        position: absolute;
        top: 35%;
        left: 35%;
      }
      
      #mask {
        position: absolute;
        opacity: 0.5;
        width: 100%;
        left: 0;
        top: 0;
        height: 100%;
        z-index: 4;
        background: #000;
      }
      
      #prompt input {
        margin-top: 15px;
        margin-left: 15px;
      }
      
      
      #search {
        width: 80%;
        position:fixed;
        top: 0;
        padding:0;
        margin:0;
      }
      
      
      #search input {
        width: 100%;
        height: 36px;
        font-size: 30px;
        border: none;
        padding-left: 5px;
        border-bottom: 1px solid #929292;
        outline: none;
        background: #929292;
        background-image: -webkit-gradient(
            linear,
            left top,
            left bottom,
            color-stop(0, rgb(255,255,255)),
            color-stop(1, rgb(221,221,221))
        );
        background-image: -moz-linear-gradient(
            center top,
            rgb(255,255,255) 0%,
            rgb(221,221,221) 100%
        );
        
      }
      audio {
        width: 100%;
        
      }
      
      #footer {
        position: fixed;
        bottom: -3px;
        width: 100%;
        background: #858585;
      }
      
      #songs {
        background: #ddd;
        width: 80%;
        padding-left: 5px;
      }
      
      #songs table {
        width: 100%;
      }
      
      #playlist {
        width: 20%;
        position: fixed;
        right: 0;
        color: white;
        top: 0;
      }
      
      #playlist table {
        width: 100%;
        margin: 5px;
        margin-left: 10px;
      }
      
      table tr:hover {
        background: #BBCEE9;
        border-radius: 5px;
      }
      
      table tr {
        -webkit-user-select: none;
        user-select: none;
        cursor: default;
        
      }
      table td {
        padding-top: 3px;
        padding-bottom: 3px;
        padding-right: 5px;
      }
      
      
      #playlist table tr.playing {
        /*background: #76AD8B;*/
        font-style: italic;
      }
      

      #playlist table tr.playing td {
        padding-left: 20px;
      }
      
      #listtools {
        position: fixed;
        bottom: 40px;
        right: 5px;
        color: #ddd;
      }
      #listtools a {
        color: white;
        text-decoration: none;
      }
      
      tr.hidden {
        display:none;
      }
      
    </style>
    <script src="id3v2.js"></script>
    <script>
      //beware! this code is pretty hacky and  ugly.
      /*
        This doesn't use jQuery or any js libraries, not because they aren't great
        in retrospect, I really think I should have used jQuery here.
        
        But yesterday when I started this, I was really offended by a chrome extension
        which was literally a one liner content script that had jquery as a dependency.
        
        That's just terrible.
        
        Anyway, this is more of a proof of concept and in a weird backwards way, I prefer
        to do my prototypes without jQuery.
      */
      function parseFile(file, callback){
        if(localStorage[file.fileName]) return callback(JSON.parse(localStorage[file.fileName]));
        ID3v2.parseFile(file,function(tags){
          //to not overflow localstorage
          localStorage[file.fileName] = JSON.stringify({
            Title: tags.Title,
            Artist: tags.Artist,
            Album: tags.Album,
            Genre: tags.Genre
          });
          callback(tags);
        })
      }
      
      function runSearch(query){
        console.log(query);
        var regex = new RegExp(query.trim().replace(/\s+/g, '.*'), 'ig');
        for(var i = $('songtable').getElementsByTagName('tr'), l = i.length; l--;){
          if(regex.test(i[l].innerHTML)){
            i[l].className = 'visible'
          }else{
            i[l].className = 'hidden';
          }
        }
      }
      
      function canPlay(type){
        var a = document.createElement('audio');
        return !!(a.canPlayType && a.canPlayType(type).replace(/no/, ''));
      }
      
      function $(id){return document.getElementById(id)}
      function getSongs(files){
        $("mask").style.display = 'none';
        $("startup").style.display = 'none';
        var queue = [];
        var mp3 = canPlay('audio/mpeg;'), ogg = canPlay('audio/ogg; codecs="vorbis"');
        for(var i = 0; i < files.length; i++){
          var file = files[i];
	  
	  var path = file.webkitRelativePath || file.mozFullPath || file.fileName;
          if (path.indexOf('.AppleDouble') != -1) {
		// Meta-data folder on Apple file systems, skip
		continue;
          }         
	  var size = file.size || file.fileSize || 4096;
	  if(size < 4095) { 
		// Most probably not a real MP3
		console.log(path);
		continue;
	  }
 
          if(file.fileName.indexOf('mp3') != -1){ //only does mp3 for now
            if(mp3){
              queue.push(file);
            }
          }
          if(file.fileName.indexOf('ogg') != -1  || file.fileName.indexOf('oga') != -1){
            if(ogg){
              queue.push(file);
            }
          }
        }
                                
        var process = function(){
          if(queue.length){
            
            var f = queue.shift();
            parseFile(f,function(tags){
              console.log(tags);
              var tr = document.createElement('tr');
              var t2 = guessSong(f.webkitRelativePath || f.mozFullPath || f.fileName); 
              //it should be innerText/contentText but its annoying.
              var td = document.createElement('td');
              td.innerHTML = tags.Title || t2.Title;
              tr.appendChild(td);
              
              var td = document.createElement('td');
              td.innerHTML = tags.Artist || t2.Artist;
              tr.appendChild(td);
              
              var td = document.createElement('td');
              td.innerHTML = tags.Album || t2.Album;
              tr.appendChild(td);
              
              var td = document.createElement('td');
              td.innerHTML = tags.Genre || "";
              tr.appendChild(td);
              tr.onclick = function(){
                var pl = document.createElement('tr');
                var st = document.createElement('td');
                st.innerHTML = tags.Title || t2.Title;
                pl.appendChild(st);
                $("playtable").appendChild(pl);
                pl.file = f;
                pl.className = 'visible';
                pl.onclick = function(e){
                  if(e && e.button == 1){
                    pl.parentNode.removeChild(pl);
                  }else{
                    var url;
                    if(window.createObjectURL){
                      url = window.createObjectURL(f)
                    }else if(window.createBlobURL){
                      url = window.createBlobURL(f)
                    }else if(window.URL && window.URL.createObjectURL){
                      url = window.URL.createObjectURL(f)
                    }else if(window.webkitURL && window.webkitURL.createObjectURL){
                      url = window.webkitURL.createObjectURL(f)
                    }
                    
                    $("player").src = url;
                    $("player").play();
                    for(var i = document.querySelectorAll('.playing'), l = i.length; l--;){
                      i[l].className = '';
                    }
                    pl.className += ' playing';
                    currentSong = pl;
                  }
                }
                if($("playtable").childNodes.length == 1) pl.onclick();
              }
              $('songtable').appendChild(tr);
              process();
            })
            var lq = queue.length;
            setTimeout(function(){
              if(queue.length == lq){
                process();
              }
            },300);
          }
        }
        process();
        
        console.log(files);
      }

      var currentSong = 0;

      function nextSong(){
        try{
          currentSong.nextSibling.onclick(); 
        }catch(e){
          currentSong = document.querySelector("#playtable tr");
          currentSong.onclick();
        }
      }
      
      function shuffle(){
        var pt = document.getElementById('playtable');
        //fisher yates shuffle. hopefully.
        for(var i = document.querySelectorAll("#playtable tr"), l = i.length;  l--;){
          var j = Math.floor(Math.random() * l);
          var jel = i[j], iel = i[l];
          var jref = jel.nextSibling, iref = iel.nextSibling;
          pt.insertBefore(jel, iref);
          pt.insertBefore(iel, jref);
        }
      }
      
      function empty(){
        var pt = document.getElementById('playtable');
        pt.innerHTML = '';
      }
      
      onload = function(){
        //with no dependencies, it should be fine to use this instead of ondomcontentloaded
        var a = document.createElement('audio');
        if(!a.canPlayType) $("support").innerHTML += "Your browser does not support HTML5 Audio<br>";
        if(!(a.canPlayType && a.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, ''))) 
          $("support").innerHTML += "Your browser does not support Ogg Vorbis Playback<br>";
        if(!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''))) 
          $("support").innerHTML += "Your browser does not support MP3 Playback<br>";
        var f = document.createElement('input');
        f.type = 'file';
        if(!('multiple' in f)) $("support").innerHTML += "Your browser does not support selecting multiple files<br>";
        if(!('webkitdirectory' in f)) $("support").innerHTML += "Your browser probably does not support selecting directories<br>";
        if(window.createObjectURL){}else if(window.createBlobURL){}else if(window.URL && window.URL.createObjectURL){
        }else if(window.webkitURL && window.webkitURL.createObjectURL){}else{
          $("support").innerHTML += "Your browser probably does not support Object URLs<br>";
        }
        
        document.querySelector('#search input').onkeydown = function(e){
          if(e.keyCode == 13){
            for(var i = document.querySelectorAll('#songtable tr.visible'), l = i.length; l--;){
              i[l].onclick();
            }
          }
        }
      }
    </script>
  </head>
  <body>
    <div id="mask"></div>
    <div id="startup">
      <div id="prompt">
        <center>
          <input type="file" webkitdirectory directory multiple mozdirectory onchange="getSongs(this.files)">
        </center>
        <p style="padding-left: 15px">
          This is <b>almost certainly</b> the first mp3 player of its kind. Right above you should see a file prompt, go and select your <b>music folder</b>. It will index songs on your hard drive, read ID3 tags, play songs and it works offline. <b>HTML5 is awesome.</b>
        </p>
        <p style="padding-left: 15px">
          By <a href="http://twitter.com/antimatter15">@antimatter15</a> <a href="http://antimatter15.com">http://antimatter15.com</a>
        </p>
      </div>
      <div id="support" style="position:absolute;z-index:99999;color:red;font-size:x-large"> <!-- insert cheap knockoff modernizer clone -->
      
      </div>
    </div>
    <div id="search">
      <input type="text" placeholder="filter library" spellcheck=off autocomplete=off oninput="runSearch(this.value)">
    </div>
    <div style="height: 37px"></div>
    <div id="playlist">
      <table id="playtable"></table>
    </div>
    <div id="listtools">
      <a href="javascript:shuffle()">Shuffle</a> / 
      <a href="javascript:empty()">Clear</a>
    </div>
    <div id="songs">
      <table id="songtable" cellspacing=0 cellpadding=0>
      </table>
    </div>
    

    <div style="height: 50px"></div>
    
    <div id="footer">
      <audio onended="nextSong()" controls id="player">
    </div>
  </body>
</html>


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics