I am trying to create an app that will allow somebody to record their video and audio feeds on the browser and play it back to themselves. While recording, I am streaming the video so they can see themselves on the screen.
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
streamRef.current = stream;
if (videoRef.current) {
videoRef.current.srcObject = stream;
}
The code snippet gets the video stream from the media device and adds that to a ref given to a video element.
<video
ref={videoRef}
autoPlay
playsInline
muted
/>
This set up works well on my local device, however, I have run into issue with the video properly loading in production - the app is built using Next.js and I host it on Vercel.
Instead of displaying the video feed there is simply a black screen, however, after the recording is complete I am still able to view the video and listen to the audio without issue - just the streaming of the video whilst recording that does not work as intended.
On production, I receive an error that the Cross-Origin-Embedder-Policy needs to be set to prevent the frame from being blocked.
However, I have already configured COEP and COOP in the next.config.js
file and can confirm that it is present in other requests in the application.
const nextConfig = {
async headers() {
return [
{
source: "/(.*)",
headers: [
{
key: "Cross-Origin-Opener-Policy",
value: "same-origin",
},
{
key: "Cross-Origin-Embedder-Policy",
value: "require-corp",
},
],
},
];
},
};
module.exports = nextConfig;
It feels like I'm missing something extremely fundamental and I have been completely unable to figure out what that is 😅. Any advice on this issue would be greatly appreciated, thank you !
The source code for where I set up the video feed can be found here.
A live working example can be found here, although the feature is behind an authentication wall and will require sign-up.
(1) Try with a middleware.ts
file on root of your project:
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const response = NextResponse.next();
response.headers.set('Cross-Origin-Opener-Policy', 'same-origin');
response.headers.set('Cross-Origin-Embedder-Policy', 'require-corp');
return response;
}
(2) Use .play()
to display camera feed inside the associated <video>
tag:
if (videoRef.current) {
videoRef.current.srcObject = stream;
videoRef.current.play(); //# to display the cameara feed
}