Skip to main content

Audio joiner

Put several audio files end to end in the order you choose, with an optional crossfade at each seam. MP3 or WAV out, encoded by ffmpeg compiled to WebAssembly inside this tab.

Your audio stays in this tab. Only the ffmpeg WebAssembly core is fetched, once, from the jsDelivr CDN — no audio bytes are sent anywhere.

Joining audio sounds trivial until the files disagree. Two MP3s recorded at different sample rates, or one stereo and one mono, cannot simply be glued together: a naive concatenation produces a file that plays at the wrong speed or drops a channel after the seam. This page therefore decodes every input first, normalises it to one sample format, and then joins — which also makes crossfades possible, because you can only blend two signals once they are signals rather than compressed streams. Add your files, drag them into the order you want, choose how much overlap you want at each seam, and export one MP3 or WAV. The engine is ffmpeg compiled to WebAssembly, running in this tab.

Key facts about Audio joiner

Key facts about Audio joiner
How the join is madeffmpeg's concat filter over decoded audio, not the stream-copying concat demuxer — so mismatched inputs join correctly instead of playing at the wrong speed
Format normalisationEvery input is resampled to the output sample rate and channel layout before joining, via an aformat filter per input
Crossfade0 to 10 seconds, in half-second steps, applied at every seam with a triangular curve (acrossfade c1=tri:c2=tri)
Crossfade arithmeticEach seam overlaps, so N clips with a D-second crossfade produce a result (N−1) × D shorter than the sum of the parts — the estimate updates as you drag the slider
Crossfade limitA crossfade must be shorter than the shortest clip; the tool refuses rather than producing a mangled seam
Input formatsMP3, WAV, M4A, AAC, OGG, Opus, FLAC, WMA and AIFF — anything the wasm ffmpeg build decodes
Output formatsMP3 (libmp3lame, 128–320 kbps) or WAV (16-bit PCM). Joining always re-encodes, because the audio is decoded to join it
OrderTop to bottom in the list; drag a row or use the up and down arrows
Per-job limitsUp to 20 files and 150 MB of input in total — the single-threaded wasm engine holds every input in memory at once
Per-file limit200 MB, the same ceiling as the rest of the client-side audio tools
Engine downloadThe first run fetches the ~32 MB ffmpeg WebAssembly core from the jsDelivr CDN; the browser caches it for every later run and every other audio tool here
Not includedOverlapping tracks on separate layers (that is mixing, not joining), per-clip volume automation, and metadata carry-over from the inputs

What happens to your file

Your audio files are written into the WebAssembly filesystem inside this tab, processed by ffmpeg compiled to WebAssembly, and read back as bytes that become a Blob and a local object URL for playback and download. No audio is uploaded: there is no endpoint, no queue and no server-side ffmpeg anywhere in this. One thing does leave the browser, and it is worth naming exactly: the first time you use any ffmpeg-powered tool here, the page downloads the ffmpeg core — ffmpeg-core.js and ffmpeg-core.wasm, about 32 MB — from cdn.jsdelivr.net. That request carries no audio and no file names; it is a fetch for two static library files, which the browser then caches. After that the tool works with the network off. Nothing is stored between sessions.

About this tool

  1. 1

    Add the files

    Drop them in or browse. Each row shows the name, the length read from the file, and its size. Up to 20 files and 150 MB per job.

  2. 2

    Put them in order

    Drag a row to move it, or use the arrows. The join follows the list from top to bottom, and the estimated output length is shown above it.

  3. 3

    Choose the output format

    MP3 for anything that will be shared or uploaded; WAV when the result goes into another editor and you want no further lossy encoding.

  4. 4

    Set sample rate and channels

    44.1 kHz stereo suits music, 44.1 kHz mono suits voice and halves the file. Every input is converted to whatever you pick here.

  5. 5

    Decide on a crossfade

    Leave it at Off for chapters, interviews or anything where the seam should be exact. One to three seconds is the usual range for music. The tool blocks a crossfade longer than your shortest clip.

  6. 6

    Join and check the seams

    The progress bar tracks ffmpeg. When it finishes, play the result in the page and listen at each join before downloading.

Specs & compatibility
Engine@ffmpeg/ffmpeg 0.12 with the single-threaded @ffmpeg/core 0.12.10 build (no SharedArrayBuffer, so no COOP/COEP headers are needed)
Filter graphaformat per input, then either concat=n=N:v=0:a=1 for a butt join or a chain of acrossfade filters for a crossfaded one
Output sample rate22.05 kHz, 44.1 kHz or 48 kHz — every input is resampled to it
Output channelsStereo or mono; a mono input joined into a stereo output is duplicated across both channels
MP3 bitrate128, 192, 256 or 320 kbps constant bitrate
SpeedSingle-threaded WebAssembly runs perhaps 2–5× slower than native ffmpeg — a 10-minute join takes a few minutes on a laptop
CancellationThe Cancel button terminates the worker outright, which is the only way to interrupt a running ffmpeg exec
Browser supportAny browser with WebAssembly — Chrome, Edge, Firefox and Safari, desktop and mobile. Mobile Safari has less memory, so keep jobs small there
  • Joining MP3s always re-encodes here, so keep the output bitrate at or above the highest input bitrate to avoid stacking a second round of loss.
  • For voice — podcast segments, audiobook chapters — mono at 128 kbps is half the file and indistinguishable from stereo.
  • A crossfade needs something to fade into. Clips that already end in silence sound better butt-joined, with the silence trimmed first.
  • If a file's length shows as --:-- the browser could not decode its header; ffmpeg may still read it, but check that seam carefully in the result.
  • The 150 MB job limit is about memory, not policy — the single-threaded engine holds every input at once. Join in two passes for a longer set.
  • The first run is slow because of the 32 MB engine download. The second run on the same browser starts immediately.
  • Join up to 20 MP3, WAV, M4A, AAC, OGG, Opus or FLAC files
  • Drag-to-reorder list with per-file length and size
  • Optional 0–10 second crossfade at every seam
  • MP3 (128–320 kbps) or 16-bit WAV output
  • Sample-rate and channel normalisation across mismatched inputs
  • Live progress, cancellation, and in-page playback of the result
  • Stitching recorded podcast segments into one episode, with a short crossfade between them.
  • Merging audiobook chapters into a single file for a player that has no playlist.
  • Building a continuous DJ-style set from separate tracks with a two-second blend at each change.
  • Joining voice memos recorded in pieces into one recording to send on.
  • Concatenating sound effects or stingers into a single asset for a game or video edit.
  • Turning a lecture recorded across several files into one track for offline listening.
Yes, and here that is the deliberate choice. There is a lossless way to join MP3s — copying the compressed frames end to end — but it only works when every file shares a sample rate, channel count and encoder configuration, and it leaves a small gap at each seam from the encoder's padding. Since files people join rarely match, this page decodes everything first, normalises it, and re-encodes once. That is also what makes crossfades possible. To limit the cost, set the output bitrate at or above the highest input bitrate.
It overlaps each pair of clips by the number of seconds you choose and fades one out while the other fades in, using a triangular curve. That is why the total length shrinks: with five clips and a two-second crossfade, four seams overlap, so the result is eight seconds shorter than the sum of the parts. The estimate above the list updates as you move the slider. A crossfade must be shorter than the shortest clip in the set — otherwise a whole clip would vanish inside one fade — and the tool refuses that instead of producing a mess.
No. The audio is written into the WebAssembly filesystem in this browser tab, processed there, and read back into a Blob. There is no upload endpoint for this tool. The one thing fetched over the network is the ffmpeg WebAssembly core itself — two static files, roughly 32 MB, from the jsDelivr CDN — on the first run in a browser. That request contains no audio and no file names, and afterwards the core is cached, so subsequent joins work offline.
Two reasons stack up. The first run has to download the ~32 MB ffmpeg core before any processing starts, and the engine is the single-threaded build, which runs roughly two to five times slower than native ffmpeg. Single-threaded is a deliberate choice: the multithreaded build needs SharedArrayBuffer, which needs COOP and COEP response headers, which would break embeds and cross-origin fetches across the whole site. Later joins skip the download, so they start immediately.
A joiner puts files one after another in time — clip one, then clip two — so the output is as long as all of them together. A mixer plays them at the same time on separate layers, so the output is as long as the longest one and you hear both at once. Use this page for episodes, chapters and sets; use the mixer for background music under a voiceover.
Yes, that is the normal case and the reason for the filter-graph approach. Each input is decoded and passed through a format filter that converts it to the output sample rate and channel layout you selected before any joining happens. A 128 kbps mono MP3 at 22.05 kHz and a 320 kbps stereo file at 48 kHz will join cleanly into one 44.1 kHz stereo track. What cannot be rescued is a file the engine cannot decode at all — that fails loudly rather than being skipped.
View all

Part of Audio tools that run in your browser

Updated

We use anonymous analytics to improve ToolChamp. No personal data is stored or sold. Privacy Policy