2017-03-17 24 views
1

私のnodejsサーバから提供されているSafariでmp4ビデオファイルを読み込む際に問題があります。この問題はChromeには存在しません。nodejsサーバが提供するSafariでmp4ビデオを再生できません

問題を説明するために、私はw3schoolsから提供されたmp4ファイルmov_bbb.mp4を読み込む簡単なhtmlウェブページを持っています。私は同じファイルをダウンロードし、nodejsサーバーから提供します。

vid1(w3schoolsから提供)は、ChromeとSafariの両方でうまく読み込みます。

vid2(私のnodejsサーバーから提供されます)はSafariではなくChromeでは正常に読み込みます。ここで

は私がChromeで見るもののスクリーンショットです:

enter image description here

ここで私はSafariで見るもののスクリーンショットです:ここで

enter image description here

は私のhtmlです:

<!DOCTYPE html> 
<html> 
    <head> 
    <title>test</title> 
    </head> 
    <body> 
    <video id="vid1" controls preload="auto" src="https://www.w3schools.com/html/mov_bbb.mp4"></video> 
    <video id="vid2" controls preload="auto" src="http://localhost:8125/mov_bbb.mp4"></video> 
    </body> 
</html> 

ここに私のnodejsサーバです:

var http = require('http'); 
var fs = require('fs'); 
var path = require('path'); 

http.createServer(function (request, response) { 
    console.log('request starting...'); 

    var filePath = '.' + request.url; 
    if (filePath == './') 
     filePath = './index.html'; 

    var extname = path.extname(filePath); 
    var contentType = 'video/mp4'; 

    fs.readFile(filePath, function(error, content) { 
     if (error) { 
      if(error.code == 'ENOENT'){ 
       fs.readFile('./404.html', function(error, content) { 
        response.writeHead(200, { 'Content-Type': contentType }); 
        response.end(content, 'utf-8'); 
       }); 
      } 
      else { 
       response.writeHead(500); 
       response.end('Sorry, check with the site admin for error: '+error.code+' ..\n'); 
       response.end(); 
      } 
     } 
     else { 
      response.writeHead(200, { 
      }); 
      response.end(content, 'utf-8'); 
     } 
    }); 

}).listen(8125); 
console.log('Server running at http://127.0.0.1:8125/'); 

私は何か提案が大歓迎です。

更新:

改訂nodejsコード。しかしサファリでも同じ問題:

var http = require('http'); 
var fs = require('fs'); 

http.createServer(function (request, response) { 
    console.log('request starting...'); 

    var filePath = '.' + request.url; 
    if (filePath == './') { 
    var contentType = 'text/html'; 
    filePath = './index.html'; 
    } else { 
    var contentType = 'video/mp4'; 
    } 

    var rstream = fs.createReadStream(filePath); 
    rstream.on('error', function(error) { 
    response.writeHead(404); 
    response.end(); 
    }); 
    rstream.on('open', function() { 
    response.writeHead(200, { 
     'Content-Type': contentType, 
    }); 
    }); 
    rstream.pipe(response); 
}).listen(8125); 
console.log('Server running at http://127.0.0.1:8125/'); 

また、HTTPヘッダーのためのクロムインスペクタ:

enter image description here

答えて

1

ビデオの再生に関する問題は、サーバーに実装する必要があるContent-Rangeの範囲ヘッダーを処理することと関係しています。 ChromeとSafariは異なるリクエストヘッダーを送信します。Safariが複数の要求を送信一方

bytes=0- 

bytes=0-1 
bytes=0-1013150 
bytes=197534-1013150 

詳細についてはthis threadを参照してください、私はthis answerを見るために働いて、特定のコードのために私の場合はChromeは範囲を持つ単一の要求を送信します。

+0

@stthoms ...私は同じ問題に直面しています...サファリで作業していません...あなたは修正を見つけるか...もしそうなら、それを共有することができます.. – dev9

1

まず第一に、ファイルを提供するためreadFile()を使用していない、それが不要な(潜在的に高い)メモリを引き起こしそれはファイル全体をメモリにロードしているからです。 fs.createReadStream()を使用し、代わりにresponseにパイプしてください。

さらに重要なことに、Content-Typeが成功のケースで送信されていません。また、Content-Typeは、text/htmlデータがvideo/mp4データではなくレスポンスで送信されているため、エラーの場合は間違っています。

また、悪意のあるパス(ファイルシステムのルートに到達するための相対パスを含む)を渡したり、ファイルシステム(機密キー、パスワードなど)から機密情報を読み取る可能性があるため、任意のパスをファイルシステムコールに渡すべきではありません。 。

最後に、回答にBufferを書き込む場合は、データがすでにBuffer形式になっているため、エンコード(例:'utf-8')を指定する必要はありません。

+0

問題は残っていますが、nodejsの提案をアップしています。 – sthomps

関連する問題