Overview

Given the following TCP stream:

# Request
GET / HTTP/1.1
Host: 192.168.1.100:8081
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:98.0) Gecko/20100101 Firefox/98.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
 
# Response
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: multipart/x-mixed-replace; boundary=BoundaryString
Date: Sat, 02 Apr 2022 20:31:18 GMT
 
2906
 
--BoundaryString
 
Content-type: image/jpeg
 
Content-Length: 10427

A clear HTTP exchange, breaking it down revealing the main purpose of this exchange:

  1. Content-Type: multipart/x-mixed-replace
    • The critical header. x-mixed-replace means the server will push multiple parts in a single HTTP connection, with each part replacing the previous one (like a slideshow or video feed).
  2. boundary=BoundaryString
    • Separates individual “frames” in the stream.
  3. Content-type: image/jpeg in the body part
    • Confirms each replacement segment is a JPEG image.
  4. Transfer-Encoding: chunked
    • Enables continuous streaming without closing the connection.

The client made a single HTTP request → The server responds with an infinite stream of JPEG images separated by --BoundaryString → Each image is displayed sequentially, replacing the previous one → The connection remains open indefinitely until closed by the client.

Converting raw into .mp4

The rest of the stream is not human-readable content, convert them to raw and save it as stream.mjpeg, which stands for Motion JPEG1.

Begin with converting stream.mjpeg to a sequence of jpeg files from the stream.

ffmpeg -i stream.mjpeg -q:v 2 output_%04d.jpg
  • -i stream.mjpeg - this specify the input
  • -q:v 2 - sets the quality of the image, the lower number means higher quality
  • output_%04d.jpg - sets the output format, they will be saved as output_0001.jpg, output_0002.jpg

This will result in a list of files in the current directory, now putting them together and form a video.

ffmpeg -framerate 10 -i output_%04d.jpg -c:v libx264 -pix_fmt yuv420p reconstructed.mp4
  • -framerate 10 - sets the playback speed to 10 frames per second. You can adjust this if the video plays too fast or too slow.
  • -i output_%04d.jpg — tells ffmpeg to use the extracted images as input, in numerical order.
  • -c:v libx264 — specifies the video codec (H.264) for good compatibility.
  • -pix_fmt yuv420p — ensures the video plays properly in most media players.
  • reconstructed.mp4 — is the name of the final video file.

Footnotes

  1. Motion-JPEG (MJPEG) is a video compression standard in which each frame of a video stream is compressed as JPEG image. H.264 or H.265 provide better compression rates compared to MJPEG. ↩