How to send a webcam feed to a server

In today's digital age, webcams have become integral to our lives. They are used in various applications ranging from video conferencing to computer vision. We will explore capturing a webcam feed using a React application and sending it to a server. We will use React and Node.js to create a seamless and efficient solution.

We will create a system that can capture the webcam feed of a user, encode it in an appropriate format, and send it to a server for further processing or storage. The server should be able to receive the webcam feed and perform actions such as image recognition, real-time video streaming, or storing the images in a database.

Capturing webcam feed with React

First, we will implement the client-side code to capture the webcam feed. We will utilize the react-webcam package, which provides an easy-to-use interface for accessing the user's webcam. We will capture a screenshot and send it to the server for further processing or storage. The captured image will be displayed on the screen once it is successfully sent to the server. Let's look at an example of this with React.

import React, { useRef, useState } from 'react';
import Webcam from 'react-webcam';
import axios from 'axios';

function WebcamCapture () {
  const webcamRef = useRef(null);
  const [imgSrc, setImgSrc] = useState("");

  async function capture () {
    const imageSrc = webcamRef.current.getScreenshot();

    try {
      await axios.post('/upload', { image: imageSrc });
      console.log('Image sent to server.');
      setImgSrc(imageSrc);
    } catch (error) {
      console.error('Error sending image to server:', error);
    }
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
      <h1>Webcam Data to Server</h1>
      <div style={{ margin: 'auto' }}>
        <Webcam audio={false} ref={webcamRef} screenshotFormat="image/jpeg" />
      </div>
      <div style={{ margin: 'auto' }}>
        <button
          style={{
            marginTop: '10px',
            fontSize: '20px',
            backgroundColor: '#423fff',
            cursor: 'pointer',
            borderRadius: "10px",
            color: "white",
            padding: "10px"
          }}
          onClick={capture}
        >
          Capture
        </button>
      </div>

      {
        imgSrc !== "" &&
        <div style={{ marginTop: '20px' }}>
          <h2>Captured Image</h2>
          <img src={imgSrc} alt="Captured" style={{ marginTop: '10px' }} />
        </div>
      }
    </div>
  );
};

export default WebcamCapture;
Client side

Code explanation:

  • Line 5: We define a component called WebcamCapture that will capture the webcam feed and send it to the server.

  • Line 6: We create a variable webcamRef using the useRef hook that will allow us to reference the webcam component.

  • Line 7: We use the useState hook to create a state variable to store the captured image URL.

  • Lines 9–19: The capture function is defined as an asynchronous function. When called, it captures the screenshot from the webcam using the getScreenshot method from webcamRef.current. It then sends a POST request to the server at the /upload endpoint, with the captured image as the payload.

    • If the request is successful, the image URL is set in the state variable imgSrc.

    • If there's an error, it is logged into the console.

  • Lines 21–53: The component is rendered on the screen. It includes a heading, a Webcam component from react-webcam, and a button to capture a screenshot. If an image is captured, it is displayed on the screen.

Sending webcam feed to the server

With the webcam feed captured, we need to send it to the server for further processing or storage. We will set up an Express server that listens for POST requests to the /upload endpoint and finally save the received image. Let's look at what the server will look like.

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require("cors");
const fs = require('fs');

// Set maximum payload size limit
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ limit: '10mb', extended: true }));

app.use(bodyParser.json());

app.use(cors());

app.post('/upload', (req, res) => {
  const image = req.body.image;
  const imageName = `frame_${Date.now()}.jpg`;
  const imagePath = `/webcam_server/server/images/${imageName}`;
  const imageBuffer = Buffer.from(image.replace(/^data:image\/\w+;base64,/, ''), 'base64');
  
  fs.writeFile(imagePath, imageBuffer, (err) => {
    if (err) {
      console.error('Error saving image:', err);
      res.status(500).send('Error saving image');
    } else {
      console.log('Image saved:', imageName);
      res.sendStatus(200);
    }
  });
});

app.listen(8080, () => {
  console.log('Server is running on port 8080');
});
Server side

Code explanation:

  • Lines 8–9: We set the maximum payload size limit for incoming requests using the express.json and express.urlencoded middleware. This ensures that we can handle larger payload sizes without encountering errors.

  • Lines 15–30: We define a route to handle POST requests to the /upload endpoint. When a request is made to this endpoint, we will extract the image data from the request body.

  • Line 17: We generate a unique image name using the current timestamp.

  • Line 18: We specify the path where the image will be saved on the server.

  • Lines 21–29: We use the fs.writeFile method to save the image to the specified path.

    • If there is an error while saving the image, we send a 500 response status.

    • If the image is saved successfully, we send a 200 response status.

  • Lines 32–34: We start the server and listen on port 8080.

Code example

Now, let's look at the complete working example where we have a button that, when clicked, will capture an image using the webcam and send that image to the server. The server will store images and display the logs in the console.

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require("cors");
const fs = require('fs');

// Set maximum payload size limit
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ limit: '10mb', extended: true }));


app.use(bodyParser.json());

app.use(cors());

app.post('/upload', (req, res) => {
  const image = req.body.image;
  const imageName = `frame_${Date.now()}.jpg`;
  const imagePath = `/webcam_server/server/images/${imageName}`;
  const imageBuffer = Buffer.from(image.replace(/^data:image\/\w+;base64,/, ''), 'base64');
  
  fs.writeFile(imagePath, imageBuffer, (err) => {
    if (err) {
      console.error('Error saving image:', err);
      res.status(500).send('Error saving image');
    } else {
      console.log('Image saved:', imageName);
      res.sendStatus(200);
    }
  });
});

app.listen(8080, () => {
  console.log('Server is running on port 8080');
});
Sending webcam feed from client to server

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved