Wrong mime type
I'm still trying to understand how all of this works. The issue is I record a video with MediaRecorder in the browser and submit it to my node server which uses multer (which uses busboy).
In chrome the content-type is: video/mp4;codecs=avc1,opus even when I specify video/mp4. In safari the content-type is video/mp4.
busboy returns the proper mimetype for safari but returns text/plain for chrome. The safari made video is saved properly and plays. The chrome made video does not play properly. I'm assuming it's corrupt or something.
I think that's an issue you'll have to dive into yourself because busboy can only give you what was given to it. It doesn't modify content types or anything like that. The most important thing to ensure is that you're giving busboy multipart/form-data data and not video data directly.
You are correct that the content-type is not modified. But isn't the content-type used to determine the mime type?
When I look through some of the code. I am comparing the safari run and the chrome run.
They both hit this code (in multipart.js):
if (header['content-type']) {
const conType = parseContentType(header['content-type'][0]);
if (conType) {
partType = `${conType.type}/${conType.subtype}`;
if (conType.params && typeof conType.params.charset === 'string')
partCharset = conType.params.charset.toLowerCase();
}
}
For safari header['content-type'][0] is equal to video/mp4
For chrome header['content-type'][0] is equal to video/mp4;codecs=avc1,opus
For safari conType is a proper object:
params = {}
subtype = 'mp4'
type = 'video'
For chrome conType is undefined.
I would imagine that is part of the problem.
Well, how nice, Chrome gives more, it is not missing or wrong.
This is a bug. It happens, because of the comma in the codecs parameter value. Having dived way too deep into RFCs and standards, it seems that comma-separated values for parameters are allowed. They are certainly for video/mp4 according to RFC6381.
For an easy repro head over to https://codepen.io/ChristianUlbrich/pen/zxvgKLz?editors=1111 (directly taken from source)
The problem is presumably in parseContentTypeParams, AI says:
It’s because the parser only allows unquoted “token” chars in parameter values. A comma , (ASCII 44) is not a token (TOKEN[44] === 0). The unquoted value stops at the comma (avc1), and the next char is not a semicolon ;, so the function treats it as malformed and returns undefined.
This looks plausible™ and hints at an incorrect, not rfc-compliant implementation of parameter values for media types. As the various "parsers" are hand-crafted loops, fixing this w/o affecting other stuff is not so trivial, well at least not for me. :)
I'd go either with a real (A)BNF parser and supplying the BNF rules for The Content-Type Header Field OR use a way more trivial, "direct" parser, that is much easier to read, than the current loop and magic token trickery.
They are certainly for
video/mp4according to RFC6381.
Notice how in the examples you linked to the values containing commas are only ever enclosed within quotes.
If you look at these rules more closely you'll notice that commas are only allowed inside a quoted value.