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.