'Angular+Nodejs+S3 app videos doesnt work on iPhones

Works on: Windows PC, Ubuntu PC, MacOS Chrome

Does not work on: iPhone Chrome, iPhone Safari, MacOs Safari

Video just doesn't play there are no errors. Images are working on all platforms.

I am uploading raw videos to S3 with nodejs and multer, tried to use ffmpeg to encode videos to but didnt help.

public upload(file) {
    const fileStream = fs.createReadStream(file.path)
    let fileKey = `${file.filename}`

    const uploadParams = {
      Bucket: bucketName,
      Body: fileStream,
      Key: fileKey,
    }
    return s3.upload(uploadParams).promise()
}

Nodejs:

public async download(fileKey) {
    const downloadParams = {
      Key: fileKey,
      Bucket: bucketName,
    }
    try {
      const object = await s3.getObject(downloadParams).promise() // This throws error if image not found and catch get it
      return {readStream: s3.getObject(downloadParams).createReadStream(), object}
    } catch (err) {
      throw new NotFoundError()
    }
}

router.get('/file', async (req, res) => {
  const { key } = req.query
  const { readStream, object } = await Container.get(S3Service).download(key)
  if (readStream.httpCode) {
    res.json({ error: 'error' })
    return
  }
  if(key.split('.')[1] === 'mp4') {
    const range = req.headers.range
    const bytes = range.replace(/bytes=/, '').split('-')
    const start = parseInt(bytes[0], 10)
  
    const total = object.ContentLength
    const end = bytes[1] ? parseInt(bytes[1], 10) : total - 1
    const chunksize = end - start + 1
    res.status(206)
    res.set('Content-Type', object.ContentType)
    res.set('Content-Length', chunksize)
    res.set('Content-Disposition', 'inline')
    res.set('Accept-Ranges', 'bytes')
    res.set('Accept-Encoding', 'Identity')
    res.set('Content-Range', 'bytes ' + start + '-' + end + '/' + total)
    res.set('X-Playback-Session-Id', req.header('X-Playback-Session-Id'))
    res.set('Connection', 'keep-alive')
    res.set('Last-Modified', object.LastModified)
    res.set('ETag', object.ETag)
  } else {
    res.type('png')
  }
  readStream.pipe(res)
})

Angular:

<video playsinline muted autoplay controls="true" preload="metadata">
  <source [src]="message.files[0].fileUrl" type="video/mp4" />
  <source [src]="message.files[0].fileUrl" type="video/avi" />
  <source [src]="message.files[0].fileUrl" type="video/ogg" />
  <source [src]="message.files[0].fileUrl" type="video/webm" />
</video>


Solution 1:[1]

dev,
Seems browser capability issue. Try to run the website in chrome dev tools as iphone and try to do same with ie

Sometime all browser doesn’t support all feature. Majorly on mobile browser, we not have dev option see what is going wrong with dev tools

Regards,
Muhamed

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Muhamed Salih