I am currently using FFmpeg.wasm. It is a great tool, but I have not found a way to do this with plain JavaScript because the audio and video have different codecs sometimes. I made a function to merge videos and return a Uint8Array, which can be used in a blob.
<script src='https://unpkg.com/@ffmpeg/ffmpeg@0.9.6/dist/ffmpeg.min.js'></script>
async function mergeVideo(video, audio) {
let { createFFmpeg, fetchFile } = FFmpeg;
let ffmpeg = createFFmpeg();
await ffmpeg.load();
ffmpeg.FS('writeFile', 'video.mp4', await fetchFile(video));
ffmpeg.FS('writeFile', 'audio.mp4', await fetchFile(audio));
await ffmpeg.run('-i', 'video.mp4', '-i', 'audio.mp4', '-c', 'copy', 'output.mp4');
let data = await ffmpeg.FS('readFile', 'output.mp4');
return new Uint8Array(data.buffer);
};