{"id":24554714,"url":"https://github.com/jwillikers/chapterz","last_synced_at":"2026-02-04T09:39:47.114Z","repository":{"id":272992928,"uuid":"918387341","full_name":"jwillikers/chapterz","owner":"jwillikers","description":"A script to help with audiobook creating chapters for MusicBrainz","archived":false,"fork":false,"pushed_at":"2025-07-19T15:46:13.000Z","size":80,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-20T07:39:38.102Z","etag":null,"topics":["audiobook","chapter","chapters","m4b","musicbrainz","nushell","tone"],"latest_commit_sha":null,"homepage":"","language":"Nushell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jwillikers.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.adoc","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-01-17T20:33:43.000Z","updated_at":"2025-07-19T15:46:16.000Z","dependencies_parsed_at":"2025-02-01T15:20:10.383Z","dependency_job_id":"faf219d0-2950-4675-a826-eedfa70bff7f","html_url":"https://github.com/jwillikers/chapterz","commit_stats":null,"previous_names":["jwillikers/chapterz"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jwillikers/chapterz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwillikers%2Fchapterz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwillikers%2Fchapterz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwillikers%2Fchapterz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwillikers%2Fchapterz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jwillikers","download_url":"https://codeload.github.com/jwillikers/chapterz/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwillikers%2Fchapterz/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266563915,"owners_count":23948689,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audiobook","chapter","chapters","m4b","musicbrainz","nushell","tone"],"created_at":"2025-01-23T03:33:09.775Z","updated_at":"2026-02-04T09:39:47.107Z","avatar_url":"https://github.com/jwillikers.png","language":"Nushell","readme":"= chapterz\nJordan Williams \u003cjordan@jwillikers.com\u003e\n:experimental:\n:icons: font\nifdef::env-github[]\n:tip-caption: :bulb:\n:note-caption: :information_source:\n:important-caption: :heavy_exclamation_mark:\n:caution-caption: :fire:\n:warning-caption: :warning:\nendif::[]\n:Asciidoctor_: https://asciidoctor.org/[Asciidoctor]\n:just: https://github.com/casey/just[just]\n:Linux: https://www.linuxfoundation.org/[Linux]\n:MusicBrainz: https://musicbrainz.org/[MusicBrainz]\n:Nix: https://nixos.org/[Nix]\n:nix-direnv: https://github.com/nix-community/nix-direnv[nix-direnv]\n:Nushell: https://www.nushell.sh/[Nushell]\n:tone: https://github.com/sandreas/tone[tone]\n\nA script to help with creating audiobook chapters for {MusicBrainz}.\n\n== Usage\n\nThe script can extract the chapter metadata from an M4B file using {tone}, from an Audible ASIN, or from a MusicBrainz Release ID and format it for import into MusicBrainz or in the `chapters.txt` format for tone.\nAn second script, `embed-chapterz.nu` can embed chapters in an M4B file given the source of the chapters.\nThe scripts only require {Nushell} and {tone}, both of which are cross-platform.\nFor Linux and macOS users, this repository contains a {Nix} package which will take care of the dependencies for you.\nHere are the steps for using the script.\n\n. If not using {Nix}, install {Nushell} and {tone}.\n\n. Clone this project's repository.\n+\n[,sh]\n----\ngit clone https://github.com/jwillikers/chapterz.git\n----\n\n. Change into the project directory.\n+\n[,sh]\n----\ncd chapterz\n----\n\n. If you're using {nix-direnv}, described in more detail in the \u003c\u003cDevelop\u003e\u003e section, simply run `direnv allow` to take care of the dependencies.\n\n. Now, the provided script can be run like so.\n+\n--\n[,sh]\n----\nnu chapterz.nu book.m4b\n----\n\nAlternatively, if you're using Nix but not using `nix-direnv`, you can run `nix build` and then execute the script in the resulting build output with `result/bin/chapterz.nu`.\n--\n\n. Now edit the output from the previous command as necessary and paste it in the _Add medium_ dialog in MusicBrainz.\n\n=== Embedding Chapters\n\nThe `embed-chapterz.nu` script can be used in the same manner as the `chapterz.nu` script.\nIt takes an M4B file as its first argument and either a MusicBrainz Release ID, an Audible ASIN, or the path to a `chapters.txt` file as its second argument.\nThe example to embed chapters for the file `Piranesi.m4b` from the MusicBrainz Release https://musicbrainz.org/release/9219a403-d530-4f4d-ab4a-19e4be647a0e[9219a403-d530-4f4d-ab4a-19e4be647a0e] would look as follows.\n\n[,sh]\n----\nnu embed-chapterz.nu Piranesi.m4b 9219a403-d530-4f4d-ab4a-19e4be647a0e\n----\n\n== A Little More Detail\n\nUnfortunately, MusicBrainz doesn't support down to the millisecond level in their editor yet.\nSee the issue https://tickets.metabrainz.org/browse/MBS-7130[MBS-7130].\nThis requires rounding the track lengths to the nearest second.\nWhen considering these track lengths as only track lengths, there's not much of a problem here.\nHowever, these track lengths can be used to determine the chapter offsets for chapters in an M4B file.\nThat's something that is very desirable for M4B's which may have chapter markings that are wrong or not even named at all.\nAcross multiple tracks, the rounding error in the track lengths can accumulate to the point where the resulting chapter offsets are no longer accurate.\nTo accommodate this, I take into account the cumulative rounding error and round in whichever direction minimizes the total error.\nThis should keep the chapter offsets generated from the track lengths within half a second of their true position.\n\n== Develop\n\nThe `nix develop` command can be used to enter or run commands in an environment with all of the necessary dependencies.\nFor convenience, direnv can be used to automatically load this environment when entering the project's directory.\nThe https://marketplace.visualstudio.com/items?itemName=mkhl.direnv[mkhl.direnv VSCode extension] integrates this environment in VSCode for development.\nNix also generates the configuration for https://pre-commit.com/[pre-commit], which automates formatting and various checks when committing changes.\nFollow the instructions here to set up your development environment using Nix.\n\n. Install an implementation of {Nix}, such as https://lix.systems[Lix] used here.\n+\n[,sh]\n----\ncurl -sSf -L https://install.lix.systems/lix | sh -s -- install\n----\n\n. Install direnv for your system according to the https://direnv.net/docs/installation.html[direnv installation instructions].\n+\n[,sh]\n----\nsudo rpm-ostree install direnv\nsudo systemctl reboot\n----\n\n. Integrate direnv with your shell by following the instructions on the https://direnv.net/docs/hook.html[direnv Setup page].\n\n. Permit the direnv configuration for the repository.\n+\n[,sh]\n----\ndirenv allow\n----\n\n== Similar Projects\n\n* https://github.com/kellnerd/cueshit[cueshit]\n* https://github.com/kellnerd/musicbrainz-scripts[musicbrainz-scripts]\n\n== Contributing\n\nContributions in the form of issues, feedback, and even pull requests are welcome.\nMake sure to adhere to the project's link:CODE_OF_CONDUCT.adoc[Code of Conduct].\n\n== Code of Conduct\n\nRefer to the project's link:CODE_OF_CONDUCT.adoc[Code of Conduct] for details.\n\n== License\n\nThis repository is licensed under the link:LICENSE[MIT license].\n\n© 2025 Jordan Williams\n\n== Authors\n\nmailto:{email}[{author}]\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwillikers%2Fchapterz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjwillikers%2Fchapterz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwillikers%2Fchapterz/lists"}