All articles
Guide

How to Convert M4B to MP3 (Whole File or Chapter by Chapter)

M4B is the audiobook format Apple uses, and it works great until your car stereo, MP3 player, or podcast app does not support it. This guide covers the proper way to convert M4B to MP3 using ffmpeg, including how to split the audiobook into individual MP3 files per chapter, something most guides just skip.

15 min read · Covers macOS, Windows, Linux

What is an M4B file?

M4B is an audiobook container format developed by Apple. Under the hood it is just an MPEG-4 file (same as M4A) with a couple of extras: chapters baked into the file and a bookmark that saves your place. The audio itself is typically AAC, which is actually a better codec than MP3 at equivalent bitrates, so converting to MP3 does involve a small quality trade-off.

That said, MP3 is universally supported. Older car stereos, basic MP3 players, and a lot of third-party apps do not handle M4B at all. Converting makes sense if you want to listen on a device that will not touch Apple's format.

A .m4b audiobook file shown in macOS Finder, with the file icon and file size visible
A .m4b file as it appears in Finder or File Explorer, with the file icon and size visible.

The easy way: convert in your browser

If you do not want to install anything or write a line of terminal commands, M4BConvert handles all of this in your browser. It runs ffmpeg locally via WebAssembly, so your file never leaves your machine, and it supports the full chapter-splitting workflow out of the box.

Convert M4B to MP3 without the terminal

Drop your file, pick your chapters, and download individual MP3s per chapter. All in the browser, no upload, no account. It's the same ffmpeg commands from this guide running locally on your machine.

Try M4BConvert free

If you're staying for the terminal walkthrough, read on.

Install ffmpeg

Everything in this guide runs through ffmpeg (and its companion tool ffprobe), so install that first. None of the commands below will work without it. It takes about two minutes on any platform.

macOS

1

Open Terminal and check if you already have Homebrew:

Terminal
brew --version

If that prints a version number, skip to step 3. If it says "command not found," continue to step 2.

2

Install Homebrew by pasting this one-liner into Terminal (it's the official installer from brew.sh):

Terminal
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

It'll ask for your Mac password partway through. Typing is normal, nothing will appear on screen. Let it finish, then close and reopen Terminal.

3

Install ffmpeg:

Terminal
brew install ffmpeg

Windows

Windows does not include ffmpeg, so you have to add it yourself. If you're on Windows 10 (2018 update or newer) or Windows 11, the fastest way is winget. If that does not work for you, use the manual method below. It works on every version of Windows.

Option 1: winget (fastest)

PowerShell or Command Prompt
winget install ffmpeg

Let it finish, then close and reopen your terminal window and skip down to "Verify it worked" below. If you get "winget is not recognized," your Windows install is too old for it. Use Option 2 instead.

Option 2: manual install (works on any Windows version)

1

Go to gyan.dev/ffmpeg/builds and, under "release builds," download ffmpeg-release-essentials.zip.

2

Right-click the downloaded zip and choose Extract All. Extract it somewhere permanent, like C:\ffmpeg. Not Downloads, and not anywhere you might delete later by accident. You should end up with a folder that looks like C:\ffmpeg\ffmpeg-7.1-essentials_build\bin, containing ffmpeg.exe and ffprobe.exe. That exact folder name will change with the version, so check what you actually got.

3

Add that bin folder to your PATH so Windows knows where to find it:

  • Press the Windows key, type environment variables, and open "Edit the system environment variables."
  • In the System Properties window, click the Environment Variables… button.
  • Under "System variables" (bottom half), select Path, then click Edit…
  • Click New and paste the full path to your bin folder, for example C:\ffmpeg\ffmpeg-7.1-essentials_build\bin
  • Click OK on all three open windows to save.
4

Close any Command Prompt or PowerShell windows you already had open, then open a new one.

The #1 thing people miss: a terminal window that was already open before you edited PATH will not see the change. If ffmpeg -version still fails after following every step, the fix is almost always to close that window and open a fresh one.

Linux

It's in your distro's package manager. Pick the matching command:

Terminal (Ubuntu / Debian)
sudo apt install ffmpeg
Terminal (Fedora)
sudo dnf install ffmpeg
Terminal (Arch)
sudo pacman -S ffmpeg

Verify it worked

Whichever method you used, confirm it from a fresh terminal window:

Terminal
ffmpeg -version

You should see a version string and a long line of build flags, not "command not found" or "not recognized."

Terminal showing the output of ffmpeg -version after a successful install, with the version string and build info visible
ffmpeg's version output after a successful install. That's your confirmation it's ready to use.

Check whether your file has chapters

Before you convert anything, find out whether your M4B actually has chapter markers, since that's what decides which option you'll use in the next section.

First, get the file's exact path instead of typing the filename

The single most common way this step "fails" has nothing to do with chapters. Typing just a filename, like audiobook.m4b, only works if your terminal happens to already be sitting in the exact same folder as the file, and it usually isn't, whether the file is in Downloads, on a USB drive, or somewhere custom. The fix that works no matter where the file lives is to copy the full path instead of typing any of it.

Windows

1

In File Explorer, find your .m4b file.

2

Right-click it and choose Copy as path. (On older Windows 10 builds, this option is hidden unless you hold Shift while right-clicking.)

3

That copies the complete path to your clipboard, already wrapped in quotes, for example "D:\Downloads\audiobook.m4b". You'll paste this directly into the command below.

macOS

1

Easiest option: open Terminal, then just drag the file from Finder straight into the Terminal window. Finder will type out the full, correctly escaped path for you automatically. Nothing to copy or remember.

2

If you'd rather copy it ahead of time: in Finder, right-click the file, hold Option, and the menu item changes to "Copy 'filename' as Pathname." Click it.

Linux

1

Easiest option: drag the file from your file manager (Nautilus, Dolphin, etc.) straight into your open terminal window. Most terminal emulators paste the full path for you automatically, same as on macOS.

2

If your file manager doesn't support that, navigate to the file's folder, copy the folder path from the address bar (Ctrl+L often reveals it as editable text), and type the filename onto the end yourself.

Windows right-click context menu on an .m4b file, with the Copy as path option highlighted
The Windows right-click menu, with "Copy as path" highlighted.

Now run the chapter check

Paste the path you just copied in place of the filename below, keeping the quotes (Windows already added them; on macOS/Linux, add your own if the path has spaces in it):

Terminal (inspect chapter data)
ffprobe -v quiet -print_format json -show_chapters "PASTE_YOUR_COPIED_PATH_HERE"

For example, a real Windows path would look like:

Terminal (example)
ffprobe -v quiet -print_format json -show_chapters "D:\Downloads\wonderful_wizard_oz_version_4_1501.m4b"

This prints JSON with a chapters array. Each entry has a title, a start_time, and an end_time in seconds. That's everything needed to slice the file later.

Still got {} back with nothing inside? That's not necessarily "no chapters." -v quiet also hides the error if ffprobe can't find the file at all, and an empty result looks identical to a real one at a glance. Double-check the path you pasted is exactly right (re-copy it using the steps above rather than re-typing it), or drop -v quiet for one run to see the actual error instead of a silent empty result.
Terminal showing ffprobe JSON output for an M4B file, listing chapter id, start_time, end_time, and title fields
ffprobe's JSON output for an M4B file, showing each chapter's id, start time, end time, and title.
Read the result, then jump ahead: if "chapters" lists entries, your file has chapter data, so use Option B in the next section to get one MP3 per chapter. If it's an empty array ([]), there's no chapter data to work with (common on audiobooks ripped from CDs or downloaded without metadata), so go straight to Option A for a single MP3 instead. Chapterization can't recover data that was never there.

Convert M4B to MP3

Two options, depending on what the previous step told you.

Same rule as the chapter check: use the path you copied earlier instead of typing a filename, especially if the file isn't in your terminal's current folder.

Option A: single MP3 file

Use this if your file has no chapters, or if you genuinely just want one file. Paste your copied path in place of PASTE_YOUR_COPIED_PATH_HERE:

Terminal
ffmpeg -i "PASTE_YOUR_COPIED_PATH_HERE" -q:a 0 output.mp3

For example:

Terminal (example)
ffmpeg -i "D:\Downloads\wonderful_wizard_oz_version_4_1501.m4b" -q:a 0 output.mp3

Here's what the flags mean:

  • -i "...": the input file, your copied path in quotes
  • -q:a 0: VBR quality setting, where 0 is the highest quality. Use -q:a 2 for a smaller file with barely noticeable difference, or -q:a 5 if size matters more than fidelity.
  • output.mp3: ffmpeg infers the MP3 format from the file extension. This one's fine to leave as a plain filename, it'll save into whatever folder your terminal is currently in.

This puts the entire audiobook into one MP3 file. If it's 12 hours long, you get one 12-hour MP3 with no chapter markers your player can jump between. If that's a problem, use Option B instead.

Terminal window showing the ffmpeg conversion command running, with progress output for duration, speed, and bitrate
ffmpeg running the conversion, with live progress for duration, speed, and bitrate.
Tip: Use -q:a 0 if you care about quality, -q:a 2 for everyday listening. The difference is hard to hear, but the file size difference (roughly 30%) can matter if you're loading an SD card.

Option B: one MP3 per chapter

ffmpeg has no built-in "split by chapters" flag, so the script below loops through the chapter list from ffprobe and calls ffmpeg once per chapter to cut and encode it as its own MP3. It uses Python 3, which is built into macOS and most Linux distros, and available via the Microsoft Store on Windows.

Here's the script. Don't worry if you've never written or run a Python file before, the walkthrough right after it covers saving and running with nothing more than what's already on your computer.

m4b-to-chapters.py
#!/usr/bin/env python3
# m4b-to-chapters.py
# Splits an M4B audiobook into individual MP3s, one per chapter.
# Requires: ffmpeg + ffprobe on your PATH
#
# Usage:
#   python3 m4b-to-chapters.py audiobook.m4b
#   python3 m4b-to-chapters.py audiobook.m4b --quality 2

import argparse, json, os, re, subprocess, sys
from pathlib import Path

def probe_chapters(path):
    result = subprocess.run(
        ["ffprobe", "-v", "quiet", "-print_format", "json",
         "-show_chapters", str(path)],
        capture_output=True, text=True
    )
    return json.loads(result.stdout).get("chapters", [])

def safe_name(title):
    return re.sub(r"[^\w\s-]", "", title).strip().replace(" ", "_")[:80]

def convert(m4b_path, quality=0):
    src      = Path(m4b_path)
    chapters = probe_chapters(src)

    if not chapters:
        print("No chapter markers found. Converting as a single file.")
        out = src.with_suffix(".mp3")
        subprocess.run(["ffmpeg", "-y", "-i", str(src),
                        "-q:a", str(quality), str(out)], check=True)
        return

    out_dir = src.parent / (src.stem + "_chapters")
    out_dir.mkdir(exist_ok=True)
    print(f"Found {len(chapters)} chapters → {out_dir}/\n")

    for ch in chapters:
        i     = int(ch["id"]) + 1
        title = ch["tags"].get("title", f"Chapter {i}")
        start = ch["start_time"]
        end   = ch["end_time"]
        fname = f"{i:02d}_{safe_name(title)}.mp3"
        out   = out_dir / fname

        subprocess.run([
            "ffmpeg", "-y",
            "-ss", start, "-to", end,
            "-i", str(src),
            "-q:a", str(quality),
            "-map_metadata", "-1",
            "-metadata", f"title={title}",
            "-metadata", f"track={i}",
            str(out)
        ], capture_output=True, check=True)
        print(f"  converted: {fname}")

    print(f"\nDone. {len(chapters)} MP3s saved to {out_dir}/")

if __name__ == "__main__":
    p = argparse.ArgumentParser(description="Split M4B into chapter MP3s")
    p.add_argument("input", help="Path to .m4b file")
    p.add_argument("--quality", type=int, default=0,
                   help="VBR quality: 0 (best) to 9 (smallest). Default: 0")
    args = p.parse_args()
    convert(args.input, args.quality)

Save the script as a .py file

No need for VS Code or any code editor here. Any plain text editor will do, including whatever's already built into your computer. The only thing to watch for is two small traps: Notepad on Windows quietly tacks on a .txt extension unless you stop it, and TextEdit on Mac saves rich text by default, which will corrupt the script without you noticing. Both are a non issue once you know they're there.

Windows (Notepad)

1

Click Copy on the code block above to grab the whole script.

2

Open Notepad. Press the Windows key and type "notepad," it's already on your computer, nothing to install.

3

Paste the script with Ctrl+V.

4

Go to File, then Save As.

5

Find the "Save as type" dropdown near the bottom of the dialog and change it from "Text Documents (*.txt)" to "All Files (*.*)". Easy to skip past, but it matters: without it, Notepad saves the file as m4b-to-chapters.py.txt and Python won't touch it.

6

Type m4b-to-chapters.py into the File name field, pick a folder you'll remember, and click Save.

macOS (TextEdit)

1

Copy the script, then open TextEdit. It's built in, search for it with Spotlight if you don't have it pinned anywhere.

2

Before you paste, or any time before you save, go to Format, then Make Plain Text (or just press Shift+Cmd+T). TextEdit opens in Rich Text mode by default, and that adds formatting you can't see but that's enough to break a Python script.

3

Paste the script, go to File, then Save, name it m4b-to-chapters.py, and save it somewhere you'll remember. If TextEdit asks whether to keep ".py" or use ".txt," keep ".py."

Linux (any text editor)

A GUI editor like GNOME Text Editor, gedit, or Kate saves plain text by default, so just open one, paste the script, and save it as m4b-to-chapters.py. No traps to worry about here. If you'd rather stay in the terminal:

Terminal
nano m4b-to-chapters.py

Paste the script in (usually right-click and Paste, or Ctrl+Shift+V), then press Ctrl+O to save and Ctrl+X to exit.

Getting "can't open file" or "no such file" when you try to run it? You probably ended up with m4b-to-chapters.py.txt instead of m4b-to-chapters.py. On Windows, turn on "File name extensions" under File Explorer's View tab to see what you're actually working with. On macOS, the extension shows in Finder by default unless someone's hidden it. Either way, just rename the file and drop the trailing .txt.

Run it

1

Open Terminal (macOS/Linux) or Command Prompt / PowerShell (Windows).

2

Get the script's full path the same way you got your audiobook's path earlier (right-click and Copy as path on Windows, drag it into the terminal on macOS/Linux). There's no way to guess where you saved it, so don't rely on typing just m4b-to-chapters.py, the same "wrong folder" problem from before applies here too.

Then run it with both paths, script first, audiobook second:

Terminal
python3 "PASTE_SCRIPT_PATH_HERE" "PASTE_AUDIOBOOK_PATH_HERE"

For example:

Terminal (example)
python3 "C:\Users\ASUS\Desktop\m4b-to-chapters.py" "D:\Downloads\wonderful_wizard_oz_version_4_1501.m4b"

If the script happens to be in the same folder your terminal already opened in, the plain filename works fine on its own too, but pasting the full path is what works every time, regardless of where you saved it.

On Windows, seeing a message about installing from the Microsoft Store? That's not Python talking, it's a placeholder Windows ships called an App execution alias, and it intercepts python3 before the real thing ever gets a chance to run. If you don't have Python yet, go ahead and let it install from the Store. If you already installed Python from python.org, that installer registers the command as py instead, so swap it in: py "PASTE_SCRIPT_PATH_HERE" "PASTE_AUDIOBOOK_PATH_HERE". To get rid of the placeholder for good, go to Settings, then Apps, then Advanced app settings, then App execution aliases, and turn off the Python entries there.
3

The script creates a new folder named <your-file-name>_chapters/ right next to the audiobook itself, not next to the script. So for the example above, look in D:\Downloads\wonderful_wizard_oz_version_4_1501_chapters\. Inside, you'll find numbered MP3 files, one per chapter, with the chapter titles as filenames.

Quality flag: Add --quality 2 for a noticeably smaller file that still sounds good at normal listening speeds. --quality 0 (the default) targets roughly 245 kbps VBR, which is more than enough for speech.
Terminal showing the chapterization script running: a line reporting how many chapters were found, a line for each chapter as it's converted, then a Done message
The chapterization script running. It reports how many chapters it found, lists each one as it's converted, then confirms when it's done.
Finder or Explorer list view showing the resulting chapters folder, with numbered MP3 files like 01_Chapter_One.mp3
The resulting folder of chapter MP3s, numbered in order with each chapter's title in the filename.

Load the folder onto your device and any MP3 player will see them as separate tracks in order. Most car stereos and dedicated MP3 players handle a folder of sequentially named files exactly like chapters.

Troubleshooting

ffprobe returns {} with no chapters, but I know the file has them

This is almost always a file-not-found error hiding behind -v quiet, not actually missing chapter data. ffprobe suppresses the "no such file or directory" message along with everything else when that flag is set, so it looks identical to a real empty result. Confirm the file is actually where you think it is (dir *.m4b on Windows, ls *.m4b on macOS/Linux), or just use the full path, e.g. "D:\Downloads\audiobook.m4b" if your Downloads folder lives on a different drive. Dropping -v quiet for one test run will show you the real error instead of a silent {}.

The output MP3 has no chapters / just plays as one track

That's expected from Option A (single file). Use Option B above, or M4BConvert, to get individual MP3s per chapter.

The script says "No chapter markers found"

Some M4B files genuinely have no chapter table, especially ones converted from audiobook CDs or ripped from DRM-free downloads without chapter data. Run ffprobe -v quiet -print_format json -show_chapters yourfile.m4b to confirm. If the chapters array is empty, the file has no chapter data and the script will convert the whole thing to a single MP3 automatically.

Poor audio quality in the output

Make sure you're using -q:a 0 or at most -q:a 2. Higher numbers mean lower quality. Also, the source M4B is usually encoded at 64 kbps (common for speech audiobooks), so there's a ceiling to how good the output can sound regardless of the encoder settings. Converting at 64 kbps AAC input, you won't get CD-quality MP3 out; you'll get a clean re-encode of whatever was there to begin with.

Conversion is very slow on a large file

Option A should be fast (often faster than real-time on modern hardware). Option B calls ffmpeg once per chapter, which adds some overhead, but should still be quick. If it's crawling, check that ffmpeg isn't also transcoding video; use ffprobe yourfile.m4b to confirm it's audio-only.

Windows says to install Python from the Microsoft Store

That message comes from a Windows placeholder called an App execution alias, not from Python itself, and it shows up the moment you type python3 if Python isn't registered under that exact name. If you don't have Python yet, installing from the Store works fine. If you installed it from python.org instead, that installer registers the command as py, so use py m4b-to-chapters.py "your path here" instead of python3. You can also turn the placeholder off entirely at Settings, then Apps, then Advanced app settings, then App execution aliases.

Python says "ModuleNotFoundError" or the script won't run on Windows

The script only uses standard library modules, so there's nothing to pip install. Make sure you have Python 3.6 or later, and try py in place of python3 if that's what your install responds to (see the entry above). If you're on macOS or Linux, python3 should already work out of the box.

"ffmpeg is not recognized" even after installing on Windows

This almost always means PATH was updated but your terminal window is still the old one. Close every open Command Prompt / PowerShell window and open a fresh one. PATH changes only apply to new windows. If it's still not found after that, double check the exact folder path you added in the install step actually contains ffmpeg.exe.


Convert M4B to MP3 in your browser

M4BConvert is a free, browser-based M4B converter with a built-in chapter editor. Drop your file, preview chapters, rename or reorder them if you want, and export as individual MP3s. Nothing is uploaded; all processing runs locally with ffmpeg.wasm.

Try M4BConvert free