2

node.js サーバーでホストされている次の HTML でテストしています。

<!doctype html>
<html>
<head>
    <meta charset='utf-8'>
    <title>Audio Testing</title>
</head>
<body>
    <audio src='/public/tests/audioTest.mp3' controls autoplay loop></audio>
</body>
</html>

問題は、オーディオがページの読み込み時に 1 回しか再生されないことです (mp3 であるため、Chrome のみ)。

WebサーバーなしでHTMLファイルをロードするだけでローカルでこれをテストすると、オーディオが正常にループするため、これはnode.jsの問題であると思われます。また、テストした Apache サーバーでも期待どおりに動作します。さらに、Apache サーバーでホストされている mp3 ファイルにリンクすると、ノード サーバーによって提供される HTML で期待どおりに動作します。

base64としてエンコードされている場合、オーディオも正常にループします。

node.js のバージョン 0.8.14 を使用しています。ノードでホストされているコードのライブ デモは、ここからアクセスできます。

EDIT サーバーには、サーバーが要求された場合に常にファイルを提供する「public」という名前のディレクトリがあります。オーディオ ファイルと html ページはどちらも "public" ディレクトリにあります。

node.js サーバー コードは次のとおりです。

var http = require('http');
var fs = require('fs');
var mime = require('mime');//Third party library for looking up mime types
var handleRequest = function(req, res) {
  if (req.url === '/') {
    fs.createReadStream(__dirname+'/public/homePage.html').pipe(res);
    return;
  }
  else if (req.url === '/favicon.ico') {
    fs.createReadStream(__dirname+'/public/favicon.ico').pipe(res);
    return;
  }
  else if (req.url.substr(0, 7) === '/public') {
    var mim = mime.lookup(req.url);
    var ext = mime.extension(mim);
    console.log('mime '+mim+' ext '+ext);
    if (ext !== 'bin') {
        fs.exists(__dirname+'/'+req.url, function(exists) {
            if (exists) {
                    if (req.headers.range) {
        var filename = __dirname+req.url;
        fs.readFile(filename, 'binary', function(err, file) {
          var header = {};
          var range = req.headers.range; 
          var parts = range.replace(/bytes=/, "").split("-"); 
          var partialstart = parts[0]; 
          var partialend = parts[1]; 

          var total = file.length; 

          var start = parseInt(partialstart, 10); 
          var end = partialend ? parseInt(partialend, 10) : total-1;

          header["Content-Range"] = "bytes " + start + "-" + end + "/" + (total);
          header["Accept-Ranges"] = "bytes";
          header["Content-Length"]= (end-start)+1;
          //header['Transfer-Encoding'] = 'chunked';
          header["Connection"] = "close";

          res.writeHead(206, header); 
          res.write(file.slice(start, end)+'0', "binary");
          res.end();
          return;
        });
      }
      else {
        res.writeHead(200,{'Content-Type':mim});
        fs.createReadStream(__dirname+'/'+req.url).pipe(res);
        return;
      }
            else {res.end();}
        });
    }
    else {res.end();}
  }
  else {res.end();}
};
var server = http.createServer(handleRequest);
server.listen(8888);//Listening on port 8888
4

1 に答える 1

1

これは、Node.js サーバーが範囲要求に応答していないためだと思われます。

Chrome は、ファイル内の特定のバイト セットの範囲リクエストを送信しています。応答でこれらのバイトを取得せずにループできない理由はわかりませんが、それが唯一の違いです。

于 2013-06-02T04:41:08.943 に答える