{"id":20240041,"url":"https://github.com/djdembeck/m4b-merge","last_synced_at":"2025-04-10T19:50:34.354Z","repository":{"id":38094150,"uuid":"317397134","full_name":"djdembeck/m4b-merge","owner":"djdembeck","description":"A Python-based CLI tool that standardizes audiobook files with clean metadata, cover art, and structured chapters, sourced from Audible. Essential for achieving organized and high-quality audiobook files.","archived":false,"fork":false,"pushed_at":"2025-04-09T22:26:01.000Z","size":391,"stargazers_count":62,"open_issues_count":12,"forks_count":10,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-09T23:27:13.415Z","etag":null,"topics":["audible","audiobooks","audnexus","cli","docker","m4a","m4b","metadata","mp3","pypi","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/djdembeck.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-12-01T02:00:08.000Z","updated_at":"2025-03-22T15:19:29.000Z","dependencies_parsed_at":"2023-10-10T14:43:52.754Z","dependency_job_id":"46173d75-f5c2-4cb8-95eb-62502661cf06","html_url":"https://github.com/djdembeck/m4b-merge","commit_stats":{"total_commits":334,"total_committers":5,"mean_commits":66.8,"dds":"0.29640718562874246","last_synced_commit":"b249eb470302d23c8de8c7becf27f8ef10e606d7"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djdembeck%2Fm4b-merge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djdembeck%2Fm4b-merge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djdembeck%2Fm4b-merge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djdembeck%2Fm4b-merge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/djdembeck","download_url":"https://codeload.github.com/djdembeck/m4b-merge/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248130899,"owners_count":21052816,"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","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":["audible","audiobooks","audnexus","cli","docker","m4a","m4b","metadata","mp3","pypi","python"],"created_at":"2024-11-14T08:42:47.612Z","updated_at":"2025-04-10T19:50:34.329Z","avatar_url":"https://github.com/djdembeck.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\r\n\u003ch1 align=\"center\"\u003em4b-merge\u003c/h1\u003e\r\n\r\n\u003cdiv align=\"center\"\u003e\r\n\r\n[![Status](https://img.shields.io/badge/status-active-success.svg)]()\r\n[![GitHub Issues](https://img.shields.io/github/issues/djdembeck/m4b-merge.svg)](https://github.com/djdembeck/m4b-merge/issues)\r\n[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/djdembeck/m4b-merge.svg)](https://github.com/djdembeck/m4b-merge/pulls)\r\n[![License](https://img.shields.io/github/license/djdembeck/m4b-merge)](https://github.com/djdembeck/m4b-merge/blob/develop/LICENSE)\r\n[![PyPI](https://img.shields.io/pypi/v/m4b-merge)](https://pypi.org/project/m4b-merge/)\r\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/m4b-merge?style=flat)\r\n[![Python package](https://github.com/djdembeck/m4b-merge/actions/workflows/build.yml/badge.svg)](https://github.com/djdembeck/m4b-merge/actions/workflows/build.yml)\r\n[![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/djdembeck/m4b-merge)](https://www.codefactor.io/repository/github/djdembeck/m4b-merge)\r\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/m4b-merge)](https://pypi.org/project/m4b-merge/)\r\n\r\n\u003c/div\u003e\r\n\r\n---\r\n\r\n\u003cp align=\"center\"\u003e A CLI tool which outputs consistently sorted, tagged, single m4b files regardless of the input.\r\n    \u003cbr\u003e \r\n\u003c/p\u003e\r\n\r\n## 📝 Table of Contents\r\n\r\n- [About](#about)\r\n- [Getting Started](#getting_started)\r\n- [Usage](#usage)\r\n- [Built Using](#built_using)\r\n- [Contributing](../CONTRIBUTING.md)\r\n- [Authors](#authors)\r\n- [Acknowledgments](#acknowledgement)\r\n\r\n## 🧐 About \u003ca name = \"about\"\u003e\u003c/a\u003e\r\n\r\nm4b-merge was originally part of [Bragi Books](https://github.com/djdembeck/bragibooks), but was split apart to allow savvy users to automate its usage in more advanced ways. Some of the things m4b-merge offers are:\r\n\r\n- Accepts single and multiple mp3, m4a and m4b files.\r\n- mp3s are converted to m4b. m4a/m4b files are edited/merged without conversion.\r\n- Matches existing bitrate and samplerate for target file conversions.\r\n- Final files moved to `/output/Author/Book/Book: Subtitle.m4b` format.\r\n- Moves finished files into `done` folder in `input` directory.\r\n\r\nMetadata provided by [audnexus](https://github.com/laxamentumtech/audnexus):\r\n\r\n- Title, authors, narrators, description, series, genres, release year - written as tags.\r\n- Chapter times/titles (only when input is m4b or a single mp3) - written as tags and `chapters.txt`.\r\n- High resolution (2000x2000 or greater) cover art - embedded into output file.\r\n\r\n## 🏁 Getting Started \u003ca name = \"getting_started\"\u003e\u003c/a\u003e\r\n\r\n### Prerequisites\r\n\r\nYou can either install this project via `pip` directly or run it prepackaged in Docker:\r\n- If installing directly on your system, you'll need to install m4b-tool and it's dependants from [the project's readme](https://github.com/sandreas/m4b-tool#installation)\r\n- If using Docker, all prerequisites are included in the image.\r\n\r\n### Installing\r\n\r\n#### For a `pip` installation\r\n\r\nSimply run\r\n\r\n```\r\npip install m4b-merge\r\n```\r\n\r\n#### For a Docker installation\r\n\r\nYou'll need to specify input/output volumes in the run command for easy use later:\r\n\r\n```\r\ndocker run --name=merge -v /path/to/input:/input -v /path/to/output:/output ghcr.io/djdembeck/m4b-merge:main\r\n```\r\n\r\nYou may also specify the user and group to run as with env variables:\r\n\r\n```\r\n-e UID=99 -e GID=100\r\n```\r\n\r\n## 🔧 Running the tests \u003ca name = \"tests\"\u003e\u003c/a\u003e\r\n\r\n- Run `pip install pytest`\r\n- To run all tests, run `pytest` from inside this project directory.\r\n- To run a single test, run `pytest tests/test_NAME.py`\r\n\r\n## 🎈 Usage \u003ca name=\"usage\"\u003e\u003c/a\u003e\r\n\r\n### Workflow\r\nThe process is simple\r\n1. Pass the file as input via `-i FILE.ext` or folder `-i DIR/`\r\n2. Enter the ASIN (found on audible.com) when prompted.\r\n3. Depending on necessary conversions, the process will take between 5 seconds and 5-10 minutes.\r\n\r\n### CLI usage\r\n```\r\nusage: m4b-merge [-h] [--api_url API_URL] [--completed_directory COMPLETED_DIRECTORY] -i INPUTS [INPUTS ...] [--log_level LOG_LEVEL]\r\n                 [--num_cpus NUM_CPUS] [-o OUTPUT]\r\n\r\nm4bmerge cli\r\n\r\noptional arguments:\r\n  -h, --help            show this help message and exit\r\n  --api_url API_URL     Audnexus mirror to use\r\n  --completed_directory COMPLETED_DIRECTORY\r\n                        Directory path to move original input files to\r\n  -i INPUTS [INPUTS ...], --inputs INPUTS [INPUTS ...]\r\n                        Input paths to process\r\n  --log_level LOG_LEVEL\r\n                        Set logging level\r\n  --num_cpus NUM_CPUS   Number of CPUs to use\r\n  -o OUTPUT, --output OUTPUT\r\n                        Output directory\r\n  -p PATH_FORMAT, --path_format PATH_FORMAT\r\n                        Structure of output path/naming.Supported terms: author, narrator, series_name, series_position, subtitle, title, year\r\n\r\n```\r\n\r\n#### When installed via `pip`, you can run inputs like so\r\n\r\n```\r\nm4b-merge -i /path/to/file.mp3\r\n```\r\n\r\nOr for multiple inputs\r\n\r\n```\r\nm4b-merge -i /path/to/file.mp3 /dir/ /path/to/other/file\r\n```\r\n\r\n#### On Docker, you can run inputs like so\r\n\r\n```\r\ndocker run -it merge m4b-merge -i /input/file.mp3\r\n```\r\n\r\nFor a folder of multiple audio files, simply pass the folder itself as an input, such as `-i /input/dir`\r\n\r\n## ⛏️ Built Using \u003ca name = \"built_using\"\u003e\u003c/a\u003e\r\n\r\n- [audnexus](https://github.com/laxamentumtech/audnexus) - API backend for metadata\r\n- [m4b-tool](https://github.com/sandreas/m4b-tool) - File merging and tagging\r\n\r\n## ✍️ Authors \u003ca name = \"authors\"\u003e\u003c/a\u003e\r\n\r\n- [@djdembeck](https://github.com/djdembeck) - Idea \u0026 Initial work\r\n\r\n## 🎉 Acknowledgements \u003ca name = \"acknowledgement\"\u003e\u003c/a\u003e\r\n\r\n- [sandreas](https://github.com/sandreas) for creating and maintaining [m4b-tool](https://github.com/sandreas/m4b-tool)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjdembeck%2Fm4b-merge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjdembeck%2Fm4b-merge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjdembeck%2Fm4b-merge/lists"}