2017-03-17 30 views
1

我在从我的nodejs服务器提供的Safari上加载mp4视频文件时出现问题。该问题在Chrome上不存在。无法在由nodejs服务器提供的Safari中播放mp4视频

为了说明问题,我有一个简单的html网页,它读取w3schools提供的mp4文件mov_bbb.mp4。然后我下载相同的文件并从我的nodejs服务器上提供它。

vid1(来自w3schools)在Chrome和Safari上均可正常加载。

vid2(来自我的nodejs服务器)在Chrome上加载正常,但在Safari上不加载。

这里是什么,我在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。在Safari还是同样的问题,但:

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/'); 

而且Chrome检查为HTTP标头:

enter image description here

回答

1

视频播放的问题与处理必须在服务器上实现的Content-Range范围标题有关。 Chrome和Safari发送不同的请求标头。在我的情况下,Chrome会将与范围一个请求:

bytes=0- 

而Safari浏览器发送多个请求:

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

欲了解更多信息,请参阅this thread以及该工作对我来说看到this answer特定代码。

+0

@stthoms ...我面临着同样的问题...没有在safari上工作...你找到了解决方案...如果可以的话,你可以分享它.. – dev9

1

首先,没有为提供文件服务使用readFile(),它会导致不必要的(潜在高)内存因为它将整个文件加载到内存中。改为使用fs.createReadStream(),然后将其改为response

其次,也是最重要的是,Content-Type未成功发送。另外,Content-Type在错误情况下是错误的,因为text/html数据是在响应中发送的,而不是视频/ mp4数据。

此外,任意路径不应该传递给文件系统调用,因为有人可能会通过恶意的路径(包括相对路径来获得文件系统根目录),并从文件系统中读取敏感信息(如私钥,密码等) 。

最后,如果你要一个Buffer写入响应,你不需要因为数据已经是Buffer表格指定的编码(如'utf-8')。

+0

Upvoting for nodejs建议,尽管问题仍然存在。 – sthomps

相关问题