> ## Content Index
> Fetch the complete content index at: https://blog.addpipe.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Dealing With Huge MediaRecorder Chunks
- URL: https://blog.addpipe.com/dealing-with-huge-mediarecorder-slices/
- Published: 2024-09-30T09:07:02.000Z
- Updated: 2026-05-21T08:06:02.000Z
- Author: Octavian
- Tags: Technology, MediaStream Recording API, #Import 2026-05-22 13:18

A more technical blog post.

We've been monitoring the size of the chunks made available through MediaRecorder's `ondataavailable` function for a while. For example, with a [timeslice](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/start#timeslice) of 200ms, these chunks should contain data amounting to roughly 1/5th of a second, so they shouldn't be too large. Indeed, most chunks are small (approximately 75KB for 200ms of 1080p H.264 video through Chrome), but we constantly saw larger chunks, some as large as 50MB, from vanilla browsers (Chrome on Windows, etc.).

Now, your app's reaction to such large slices might vary. They might go unnoticed, or you might get a 413 (Request Entity Too Large) error from Nginx which has a default value for **`client_max_body_size`** of 1 megabyte (MB). 

We push these chunks to our ingestion servers through [socket.io](https://socket.io) and, by default, the maximum amount of data it allows in a websocket message is 1MB or 1000000 bytes (the setting is called [maxHttpBufferSize](https://socket.io/docs/v4/server-options/#maxhttpbuffersize)). Because the larger chunks were above our limit they were rejected. This pushed our desktop recording client into an infinite loop:

1. the chunks were rejected server side by [socket.io](https://socket.io/)
2. socket.io closed the websocket connection,
3. our desktop recording client attempted to re-connect
4. the new connection went through
5. the large chunk was still in the local buffer marked as unsent
6. large chunk is picked up to be sent through the active websocket connection only to be rejected again

Several questions arose:

1. what causes it?
2. can we fix it?
3. is there valuable data in the chunk?

To find out, we've updated our [MediaRecorder demo](https://addpipe.com/media-recorder-api-demo/) to display the size in bytes of each chunk, the `onmute`, `onunmute`, and `onended` events, the recording `timecode`, and began testing.

Eventually, we were able to generate large and very large chunks in 3 ways, detailed below. There might be other ways.

### 1) Pause and resume camera access on Safari on macOS/iOS

Safari, across macOS and iOS, has easily accessible UI elements that allow users to *pause* and *resume* access to the "Camera and Microphone". Using these UI elements results in `track.onmute` and `track.onunmute` being called on both the audio and video tracks but also results in a few larger chunks showing up through `ondataavailabe` immediately after resuming/umuting (as if having to empty a local buffer). `ondataavailabe` is called with 0 data while the devices are paused. 

With this method, I could easily generate chunks 15x, the size of a normal chunk. A quick inspection with `ffprobe -show_frames video.mp4` reveals a continuous stream of audio frames for the *paused* period but no video frames.

This is a bug as the final recording ~~does not have and~~ should not have any (audio) data for the period of time during which camera and mic access has been paused. We've opened a [WebKit bug report](https://bugs.webkit.org/show%5Fbug.cgi?id=279432) about it which contains a bit more details.

We've tested with Safari 17.6 on macOS Sonoma 14.6.1 and Safari on iOS 17.6.1.

![A Safari 17.6 browser window with orange arrows pointing to the two pause camera and microphone options available in it's UI.](https://blog.addpipe.com/content/images/2024/09/pause-options-in-Safari-17.6-on-macOS.jpg)

The two pause camera and microphone options on Safari 17.6 on macOS. A similar option exists in Safari on iOS.

### 2) Sleeping the computer while recording with Chrome on macOS/Windows

If, while recording, the computer you're on enters sleep mode (we've either closed the lid or used the *Sleep* option in the OS menus), then wakes up, when you eventually stop the recording, you'll get two new `ondataavailable` calls with one of them containing a very big chunk. 

There's a few issues with this scenario:

1. on wake up `ondataavailable` is not fired anymore (it is on Chrome on Android, see below)
2. the scenario can't be totally accurately reproduced across different machines; there's variations.

Clearly a buggy scenario. We've [reported the bug]( https://issues.chromium.org/issues/367915809) in the Chromium issue tracker including a detailed log for when we managed to create a 23MB chunk.

Recording content, as extracted with `ffprobe -show_frames` differs between variations.

![The Activity Monitor on macOS with the Preventing Sleep column visible and Chrome preventing sleep.](https://blog.addpipe.com/content/images/2024/09/Google-Chrome-preventing-sleep-on-macOs-when-camera-and-microphone-are-acessed-1.png)

Camera access in the browser prevents macOS from **automatically* going to sleep

### 3) Locking the screen with Chrome on Android

If you record on Chrome on Android and lock the phone, the recording switches from audio+video to audio only while the video track mutes. When you unlock the phone, the video track unmutes, and there's a big chunk made available through `ondataavailabe` (probably containing all the audio data captured while the phone was locked). I was able to generate a 15MB chunk by recording 20 minutes with the phone locked.

The final recording has three sections: (1) video + audio (2) audio only while the screen was locked and (3) video + audio. The recording plays back correctly.

This also happens if you receive a phone call or switch apps while recording, 

This behavior does not feel buggy in any way so these big chunks are here to stay. We'll have to find a workaround!

We've tested with a [Google Pixel 4a](https://www.gsmarena.com/google%5Fpixel%5F4a-10123.php) and Chrome 128 on Android 13.

### Solutions

Even if someone immediately fixes the Chrome and Safari bugs above, we still need a way to account for the large slices created by Chrome on Android (scenario 3 above).

Increasing the [maxHttpBufferSize](https://socket.io/docs/v4/server-options/#maxhttpbuffersize) value seems like the immediate solution, but it doesn't feel like a *true fix*, more like we're pushing the threshold past which we have a problem.

Eventually, we ended up splitting the bigger chunks into smaller ones locally, in the browser, using [Blob.slice()](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice). This workaround is here to stay. A [new desktop recording client build](https://changelog.addpipe.com/fixed-issue-with-big-recording-chunks-300339) containing this fix was rolled out recently.

Another solution - which we have not explored - could involve actively calling [MediaRecorder.requestData()](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/requestData).

### Conclusion 

The size and duration of a recording slice received through `ondataavailable` can vary a lot.