2016-05-04 2 views
2

У меня возникла проблема с потоковым видео с моим приложением iOS из URL-адреса PFFile, загруженного в мою базу данных. Я использовал Heroku и AWS, и у меня все еще есть одна и та же проблема. Он работал нормально, когда файлы размещались на старом сервере синтаксического анализа.Cant stream video (PFFile) от сервера синтаксического анализа

PFFile url отлично работает, когда я открываю его в браузере Chrome, но не в сафари и в приложении iOS.

следующее звено видео: http://shuuapp.herokuapp.com/parse/files/wnQeou0L4klDelSEtMOX6SxXRVKu1f3sKl6vg349/24092609eadcc049f711aafbd59c1a18_movie.mp4

Его точно такой же вопрос, как вопрос упоминается в ссылке ниже:

iOS - Can't stream video from Parse Backend

+0

Вы решили проблему? кажется, что синтаксический анализ сервера mp4 не работает. Было бы здорово, если бы вы могли ответить на ваш вопрос, если вы его разрешили. – Tobio

ответ

0

разбора сервер не кажется, поддерживать поддержку потоковой передачи в Safari/iOS, а решение - разрешить использование с помощью экспресс & GridStore следующим образом:

синтаксического анализа-сервера Пример \ node_modules \ синтаксического анализа-сервер \ Lib \ Маршрутизаторы \ FilesRouter

{ 
key: 'getHandler', 
value: function getHandler(req, res, content) { 
var config = new _Config2.default(req.params.appId); 
var filesController = config.filesController; 
var filename = req.params.filename; 
var video = '.mp4' 
var lastFourCharacters = video.substr(video.length - 4); 
if (lastFourCharacters == '.mp4') { 

    filesController.handleVideoStream(req, res, filename).then(function (data) { 

    }).catch(function (err) { 
     console.log('404FilesRouter'); 
     res.status(404); 
     res.set('Content-Type', 'text/plain'); 
     res.end('File not found.'); 
    }); 
}else{ 
filesController.getFileData(config, filename).then(function (data) { 
    res.status(200); 
    res.end(data); 
}).catch(function (err) { 
    res.status(404); 
    res.set('Content-Type', 'text/plain'); 
    res.end('File not found.'); 
    }); 
} 
} 
} , ... 

синтаксического анализа-сервера Пример \ node_modules \ синтаксического анализа-сервер \ Lib \ Контроллеры \ FilesController

_createClass(FilesController, [{ 
key: 'getFileData', 
value: function getFileData(config, filename) { 
return this.adapter.getFileData(filename); 
} 
},{ 
key: 'handleVideoStream', 
value: function handleVideoStream(req, res, filename) { 
return this.adapter.handleVideoStream(req, res, filename); 
} 
}, ... 

разбор сервер пример \ node_modules \ разбор сервер \ Lib \ Переходники \ Files \ GridStoreAdapter

... , { 
    key: 'handleVideoStream', 
    value: function handleVideoStream(req, res, filename) { 
    return this._connect().then(function (database) { 
    return _mongodb.GridStore.exist(database, filename).then(function () { 
    var gridStore = new _mongodb.GridStore(database, filename, 'r'); 
    gridStore.open(function(err, GridFile) { 
     if(!GridFile) { 
      res.send(404,'Not Found'); 
      return; 
     } 
     console.log('filename'); 
     StreamGridFile(GridFile, req, res); 
     }); 
     }); 
     }) 
     } 
     }, ... 

Дно адаптер GridStore

function StreamGridFile(GridFile, req, res) { 
var buffer_size = 1024 * 1024;//1024Kb 

if (req.get('Range') != null) { //was: if(req.headers['range']) 
    // Range request, partialle stream the file 
    console.log('Range Request'); 
    var parts = req.get('Range').replace(/bytes=/, "").split("-"); 
    var partialstart = parts[0]; 
    var partialend = parts[1]; 
    var start = partialstart ? parseInt(partialstart, 10) : 0; 
    var end = partialend ? parseInt(partialend, 10) : GridFile.length - 1; 
    var chunksize = (end - start) + 1; 

    if(chunksize == 1){ 
    start = 0; 
    partialend = false; 
    } 

    if(!partialend){ 
    if(((GridFile.length-1) - start) < (buffer_size)){ 
     end = GridFile.length - 1; 
    }else{ 
     end = start + (buffer_size); 
    } 
     chunksize = (end - start) + 1; 
    } 

    if(start == 0 && end == 2){ 
     chunksize = 1; 
    } 

res.writeHead(206, { 
     'Cache-Control': 'no-cache', 
    'Content-Range': 'bytes ' + start + '-' + end + '/' + GridFile.length, 
    'Accept-Ranges': 'bytes', 
    'Content-Length': chunksize, 
    'Content-Type': 'video/mp4', 
    }); 

    GridFile.seek(start, function() { 
    // get GridFile stream 

      var stream = GridFile.stream(true); 
      var ended = false; 
      var bufferIdx = 0; 
      var bufferAvail = 0; 
      var range = (end - start) + 1; 
      var totalbyteswanted = (end - start) + 1; 
      var totalbyteswritten = 0; 
      // write to response 
      stream.on('data', function (buff) { 
      bufferAvail += buff.length; 
      //Ok check if we have enough to cover our range 
      if(bufferAvail < range) { 
      //Not enough bytes to satisfy our full range 
       if(bufferAvail > 0) 
       { 
       //Write full buffer 
        res.write(buff); 
        totalbyteswritten += buff.length; 
        range -= buff.length; 
        bufferIdx += buff.length; 
        bufferAvail -= buff.length; 
       } 
      } 
      else{ 

      //Enough bytes to satisfy our full range! 
       if(bufferAvail > 0) { 
        var buffer = buff.slice(0,range); 
        res.write(buffer); 
        totalbyteswritten += buffer.length; 
        bufferIdx += range; 
        bufferAvail -= range; 
       } 
      } 

      if(totalbyteswritten >= totalbyteswanted) { 
      // totalbytes = 0; 
       GridFile.close(); 
       res.end(); 
       this.destroy(); 
      } 
      }); 
     }); 

    }else{ 

// res.end(GridFile); 
     // stream back whole file 
     res.header('Cache-Control', 'no-cache'); 
     res.header('Connection', 'keep-alive'); 
     res.header("Accept-Ranges", "bytes"); 
     res.header('Content-Type', 'video/mp4'); 
     res.header('Content-Length', GridFile.length); 
     var stream = GridFile.stream(true).pipe(res); 
    } 
    }; 

P.S оригинальный ответ дается @Bragegs здесь - https://github.com/ParsePlatform/parse-server/issues/1440#issuecomment-212815625.

Смежные вопросы