Home / IOS Development / Unable to get video playback to work in iOS via HTTP: iOSProgramming

Unable to get video playback to work in iOS via HTTP: iOSProgramming



I create an app with React Native on iOS and Android, and the app supports video playback from a mongoDB gridFS server through node. At first I thought there might be a strange error with responding native, but I can not even play the videos via URL through safari either. I can play them on Android and desktop, and with a little tweaking of the headers on the server side, I was able to get videos that were played flawlessly with scrubbing on safari for Mac as well. But I * can * not for the rest of my life figure out why video playback does not work on iOS. I only get the play button with a slash through it on safari and a bug in the responsive native player I use in my app.

This is my code on the server side of Node:

var ObjectId = require('mongodb').ObjectID;
var MongoClient = require('mongodb').MongoClient;
var Server = require('mongodb').Server;
const mongo = require('mongodb');
const mime = require('mime-types');
const filesDatabaseLoc = 'mongodb://path:path@localhost:36200/files?authSource=files';

function streamGridFile(req, res, file, bucket, dbConnection) {

  if (!file) {
    res.sendStatus(404);
    return;
  }

  if (req.headers['range']) {
    // stream back only the parts specified
    var parts = req.headers['range'].replace(/bytes=/, "").split("-");
    var partialstart = parts[0];
    var partialend = parts[1];

    var start = parseInt(partialstart, 10);
    var end = partialend ? parseInt(partialend, 10) : file.length - 1;
    var chunksize = (end - start) + 1;

    let fileParts = file.filename.split('.');

    let contentType = 'video/mp4';
    let ext = fileParts[1];
    if (ext) {
        contentType = mime.lookup(ext);
    }

    res.writeHead(206, {
      'Content-Range': 'bytes ' + start + '-' + end + '/' + file.length,
      'Accept-Ranges': 'bytes',
      'Content-Length': chunksize,
      'Content-Type': contentType,
    });

    let stream = bucket.openDownloadStream(file.id, {
      start: start,
      end: end + 1
    });

    stream.on('data', (chunk) => {
      res.write(chunk);
    });

    stream.on('error', (err) => {
      res.sendStatus(404);
    });

    stream.on('end', () => {
      res.end();
      dbConnection.close();
    });
  } else {

    // stream back whole file

    let fileParts = file.filename.split('.');

    let contentType = 'video/mp4';
    let ext = fileParts[1];
    if (ext) {
        contentType = mime.lookup(ext);
    }

    res.writeHead(206, {
      'Content-Length': file.length,
      'Content-Type': contentType,
    });

    let stream = bucket.openDownloadStream(file.id, );

    stream.on('data', (chunk) => {
      res.write(chunk);
    });

    stream.on('error', (err) => {
      res.sendStatus(404);
    });

    stream.on('end', () => {
      res.end();
      dbConnection.close();
    });
  }
}

module.exports = async function(req, res, filename) {

  MongoClient.connect(filesDatabaseLoc, {
    useUnifiedTopology: true
  }, async function(err, db) {

    if (err) {
      res.status(500).send('Database Error');
      return;
    }

    var dbo = db.db('files');
    let bucket = new mongo.GridFSBucket(dbo);
    let files = await bucket.find({
      id: ObjectId(filename.split('.')[0])
    }).toArray();

    streamGridFile(req, res, files[0], bucket, db);
  });
}

Something to do with the headlines I send maybe? I can not figure this out. Any help would be greatly appreciated.


Source link