From a32785ce00b638e9079f0924fd9b00f98c077348 Mon Sep 17 00:00:00 2001 From: zyachel Date: Sat, 14 Jan 2023 16:36:20 +0530 Subject: [PATCH] fix: fix unseekable videos on webkit-based browsers this commit fixes videos not being able to fast-forward/rewind for lack of http headers and 206 status code fix https://github.com/zyachel/libremdb/issues/26 --- src/pages/api/media_proxy.ts | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/pages/api/media_proxy.ts b/src/pages/api/media_proxy.ts index 5d8e6e2..b3e4ef4 100644 --- a/src/pages/api/media_proxy.ts +++ b/src/pages/api/media_proxy.ts @@ -2,6 +2,22 @@ import { NextApiRequest, NextApiResponse } from 'next'; import redis from '../../utils/redis'; import axiosInstance from '../../utils/axiosInstance'; +const getCleanReqHeaders = (headers: NextApiRequest['headers']) => ({ + ...(headers.accept && { accept: headers.accept }), + ...(headers.range && { range: headers.range }), + ...(headers['accept-encoding'] && { + 'accept-encoding': headers['accept-encoding'] as string, + }), +}); + +const resHeadersArr = [ + 'content-range', + 'content-length', + 'content-type', + 'accept-ranges', +]; + +// checks if a url is pointing towards a video/image from imdb const regex = /^https:\/\/((m\.)?media-amazon\.com|imdb-video\.media-imdb\.com).*\.(jpg|jpeg|png|mp4|gif|webp).*$/; @@ -11,6 +27,7 @@ export default async function handler( ) { try { const mediaUrl = req.query.url as string | undefined; + const requestHeaders = getCleanReqHeaders(req.headers); // 1. returning if query is illegal if (!mediaUrl || !regex.test(mediaUrl)) @@ -23,9 +40,15 @@ export default async function handler( if (redis === null) { const mediaRes = await axiosInstance.get(mediaUrl, { responseType: 'stream', + headers: requestHeaders, }); - res.setHeader('Content-Type', mediaRes.headers['content-type']); + // chromium browsers want a 206 response with specific headers. so, we gotta pass them on. + res.statusCode = mediaRes.status; + resHeadersArr.forEach(key => { + const val = mediaRes.headers[key]; + if (val) res.setHeader(key, val); + }); mediaRes.data.pipe(res); return; } @@ -44,7 +67,7 @@ export default async function handler( responseType: 'arraybuffer', }); - const data = mediaRes.data; + const { data } = mediaRes; // saving in redis for 30 minutes await redis!.setex(mediaUrl, 30 * 60, Buffer.from(data));