0

I'm trying to stream a video from a minio bucket (very similar to S3) through my app's Node server to a browser (tried Firefox 89 and Chrome 91). The problem is the video seems to load successfully but when I click the play button the video plays for half a second before immediately pausing and showing a spinner. The video element also fires an end event even though the player shows like 10 seconds left in the video playback.

Here's the endpoint responsible for streaming the video from Minio to the browser (using koa and koa-router):

export const videoRouter = new Router()
  .get('/video/:videoFileName', async (context) => {
    await assertLoggedIn(context);

    context.body = fileStore
      .getObject({
        Bucket: UPLOAD_BUCKET,
        Key: `videos/${context.params.videoFileName}`,
      })
      .createReadStream();

    context.response.status = 200;
  }));

And here's how I'm rendering the video on the front-end (react app):

<video controls width="305px">
  <source src={`/api/video/${videoKey}.mp4`} type="video/mp4" />
  <source src={`/api/video/${videoKey}.ogg`} type="video/ogg" />
  <source src={`/api/video/${videoKey}.webm`} type="video/webm" />
  Sorry, your browser doesn't support embedded videos.
</video>

Also here's how the fileStore object is created using the official AWS SDK for Node:

export const fileStore = new S3({
  region: S3_REGION,
  endpoint: MINIO_URL,
  s3ForcePathStyle: true,
  signatureVersion: 'v4',
  credentials: {
    accessKeyId: S3_ACCESS_KEY_ID,
    secretAccessKey: S3_SECRET_ACCESS_KEY,
  },
});

Some more notes:

  • The video thumbnail displays and the video plays for a split second before pausing, so I'm fairly confident this isn't an API path or S3 key mismatch between my client/server/minio.
  • I tried checking the network tab in Firefox, but it says "no headers", "no response", "no request", "no timing" which is frustratingly unhelpful.
  • The Node server logs the request with a 200 status.
  • After waiting several minutes I saw net::ERR_INCOMPLETE_CHUNKED_ENCODING in the chrome console which lead me to this question. I did recently install Bitdefender on this computer (required on company computers). I'm currently trying to figure out how to kill it, but it appears they didn't include a "disable" or "close" feature.
  • I'm connecting directly to the Node server (no Apache/Nginx reverse-proxy because I'm running locally for development).
SimpleJ
  • 13,812
  • 13
  • 53
  • 93

1 Answers1

0

The issue ended up being the koa-range middleware breaks video streaming. It either needs to be removed or moved to only effect routes that don't stream videos.

See: https://github.com/koajs/koa-range/issues/20

Edit: There is now a fork of koa-range available with bug fixes (including a fix for this bug): https://www.npmjs.com/package/@masx200/koa-range

SimpleJ
  • 13,812
  • 13
  • 53
  • 93