Compare commits
5 Commits
show
...
277c538f21
| Author | SHA1 | Date | |
|---|---|---|---|
| 277c538f21 | |||
| bb4adb1886 | |||
| 6c72834933 | |||
| 9d30844a1e | |||
| 5b0bb25177 |
@@ -0,0 +1,41 @@
|
|||||||
|
# Git
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Python cache
|
||||||
|
*.pyc
|
||||||
|
__pycache__/
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
*.egg-info/
|
||||||
|
.eggs/
|
||||||
|
|
||||||
|
# Virtual environments
|
||||||
|
.venv
|
||||||
|
venv/
|
||||||
|
env/
|
||||||
|
ENV/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# License (not needed for installation)
|
||||||
|
LICENSE
|
||||||
|
|
||||||
|
# Docker files (not needed in build context)
|
||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# Local test files
|
||||||
|
test_data/
|
||||||
|
*.mp3
|
||||||
|
*.flac
|
||||||
|
*.wav
|
||||||
|
*.txt
|
||||||
|
*.log
|
||||||
@@ -3,3 +3,4 @@ build/
|
|||||||
dist/
|
dist/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
test_data/
|
||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
FROM python:3.13-slim
|
||||||
|
|
||||||
|
# Install FFmpeg and dependencies required for gosu installation
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ffmpeg \
|
||||||
|
ca-certificates \
|
||||||
|
wget \
|
||||||
|
gnupg \
|
||||||
|
dirmngr \
|
||||||
|
gnupg-agent && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install gosu (lightweight tool for dropping privileges)
|
||||||
|
RUN set -eux; \
|
||||||
|
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
|
||||||
|
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.17/gosu-$dpkgArch"; \
|
||||||
|
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/1.17/gosu-$dpkgArch.asc"; \
|
||||||
|
export GNUPGHOME="$(mktemp -d)"; \
|
||||||
|
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
|
||||||
|
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
|
||||||
|
gpgconf --kill all; \
|
||||||
|
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
|
||||||
|
chmod +x /usr/local/bin/gosu; \
|
||||||
|
gosu --version
|
||||||
|
|
||||||
|
# Set Python environment variables
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||||
|
PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package metadata and source code
|
||||||
|
COPY setup.py pyproject.toml README.md ./
|
||||||
|
COPY audio_splitter/ ./audio_splitter/
|
||||||
|
|
||||||
|
# Install the package
|
||||||
|
RUN pip install --no-cache-dir .
|
||||||
|
|
||||||
|
# Create a non-root user with UID 1000
|
||||||
|
RUN addgroup --system --gid 1000 appgroup && \
|
||||||
|
adduser --system --uid 1000 --ingroup appgroup appuser
|
||||||
|
|
||||||
|
# Change ownership of /app to the container user (so it can write there if needed)
|
||||||
|
RUN chown -R appuser:appgroup /app
|
||||||
|
|
||||||
|
# Copy the entrypoint script
|
||||||
|
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||||
|
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||||
|
|
||||||
|
# Set the entrypoint
|
||||||
|
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
||||||
|
|
||||||
|
# Default command (shows help if no arguments provided)
|
||||||
|
CMD ["--help"]
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
[](https://www.python.org/downloads/)
|
[](https://www.python.org/downloads/)
|
||||||
[](https://ffmpeg.org/)
|
[](https://ffmpeg.org/)
|
||||||
[](https://opensource.org/license/gpl-3.0)
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||||
|
[](https://www.docker.com/)
|
||||||
|
|
||||||
**Split audio files into tracks using a flexible tracklist format.**
|
**Split audio files into tracks using a flexible tracklist format.**
|
||||||
|
|
||||||
@@ -20,6 +21,8 @@
|
|||||||
- **Character replacement** – Replace problematic filename characters with a custom character
|
- **Character replacement** – Replace problematic filename characters with a custom character
|
||||||
- **Dry‑run mode** – Preview parsed tracks without splitting
|
- **Dry‑run mode** – Preview parsed tracks without splitting
|
||||||
- **Skip existing files** – Avoid overwriting already‑extracted tracks
|
- **Skip existing files** – Avoid overwriting already‑extracted tracks
|
||||||
|
- **Delete original** – Optionally remove the input file after successful splitting
|
||||||
|
- **Docker image** – Run without installing dependencies; simple one‑line commands
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -43,8 +46,8 @@
|
|||||||
Clone the repository and install:
|
Clone the repository and install:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/yourusername/audio-splitter.git
|
git clone https://git.vmn.su/max/audio_splitter.git
|
||||||
cd audio-splitter
|
cd audio_splitter
|
||||||
pip install .
|
pip install .
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -54,15 +57,11 @@ Now the `audio_splitter` command is available globally:
|
|||||||
audio_splitter input.mp3 tracks.txt
|
audio_splitter input.mp3 tracks.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
Or run directly without installation:
|
> **Tip:** For development, install in editable mode: `pip install -e .`
|
||||||
|
|
||||||
```bash
|
|
||||||
python -m audio_splitter.main input.mp3 tracklist.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Quick Start
|
## 🚀 Quick Start
|
||||||
|
|
||||||
### 1. Prepare a tracklist file
|
### 1. Prepare a tracklist file
|
||||||
|
|
||||||
@@ -81,9 +80,6 @@ Create a `tracks.txt` file with one track per line:
|
|||||||
### 2. Run the splitter
|
### 2. Run the splitter
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# If not installed
|
|
||||||
python -m audio_splitter.main my_album.mp3 tracks.txt
|
|
||||||
# If installed
|
|
||||||
audio_splitter my_album.mp3 tracks.txt
|
audio_splitter my_album.mp3 tracks.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -147,6 +143,12 @@ Done!
|
|||||||
| `--tracklist-format FORMAT` | Custom tracklist format (default: `%ts %tn - %an`) |
|
| `--tracklist-format FORMAT` | Custom tracklist format (default: `%ts %tn - %an`) |
|
||||||
| `--skip-existing` | Skip extraction if output file already exists |
|
| `--skip-existing` | Skip extraction if output file already exists |
|
||||||
|
|
||||||
|
### Other Options
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
| ------------------- | --------------------------------------------------------- |
|
||||||
|
| `--delete-original` | Delete the original input file after successful splitting |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📝 Placeholders Reference
|
## 📝 Placeholders Reference
|
||||||
@@ -186,7 +188,7 @@ Done!
|
|||||||
If your tracklist uses `artist - title [time]`:
|
If your tracklist uses `artist - title [time]`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m audio_splitter.main input.flac tracks.txt \
|
audio_splitter input.flac tracks.txt \
|
||||||
--tracklist-format "%an - %tn [%ts]"
|
--tracklist-format "%an - %tn [%ts]"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -195,14 +197,14 @@ python -m audio_splitter.main input.flac tracks.txt \
|
|||||||
Name files as `01 - Artist - Song.mp3`:
|
Name files as `01 - Artist - Song.mp3`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m audio_splitter.main input.flac tracks.txt \
|
audio_splitter input.flac tracks.txt \
|
||||||
--output-template "%num - %an - %tn.%ext"
|
--output-template "%num - %an - %tn.%ext"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Override album and comment
|
### Override album and comment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m audio_splitter.main input.flac tracks.txt \
|
audio_splitter input.flac tracks.txt \
|
||||||
--album "Greatest Hits" \
|
--album "Greatest Hits" \
|
||||||
--comment "Live recording"
|
--comment "Live recording"
|
||||||
```
|
```
|
||||||
@@ -210,15 +212,21 @@ python -m audio_splitter.main input.flac tracks.txt \
|
|||||||
### Merge multiple comments from input file
|
### Merge multiple comments from input file
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m audio_splitter.main input.flac tracks.txt \
|
audio_splitter input.flac tracks.txt \
|
||||||
--merge-comments \
|
--merge-comments \
|
||||||
--comment-separator " | "
|
--comment-separator " | "
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Delete original file after splitting
|
||||||
|
|
||||||
|
```bash
|
||||||
|
audio_splitter input.flac tracks.txt --delete-original
|
||||||
|
```
|
||||||
|
|
||||||
### Dry‑run to preview parsing
|
### Dry‑run to preview parsing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m audio_splitter.main input.flac tracks.txt --dry-run
|
audio_splitter input.flac tracks.txt --dry-run
|
||||||
```
|
```
|
||||||
|
|
||||||
Output:
|
Output:
|
||||||
@@ -238,6 +246,69 @@ Dry‑run complete. No files were created.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 🐳 Docker
|
||||||
|
|
||||||
|
You can run `audio_splitter` in a Docker container without installing Python or FFmpeg on your host.
|
||||||
|
|
||||||
|
### Pull the Image (Optional)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker pull yourusername/audio_splitter:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build the Image Locally
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t audio_splitter .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
**You must mount your working directory to `/data` inside the container.**
|
||||||
|
The container will automatically adjust permissions so that you can read input files and write output files.
|
||||||
|
|
||||||
|
Simply provide the arguments as you would to the `audio_splitter` command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm -v $(pwd):/data audio_splitter /data/input.mp3 /data/tracks.txt [OPTIONS]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Examples
|
||||||
|
|
||||||
|
**Basic split:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm -v $(pwd):/data audio_splitter /data/input.mp3 /data/tracks.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
**With custom options:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm -v $(pwd):/data audio_splitter /data/input.mp3 /data/tracks.txt --album "Greatest Hits" --format mp3 --number-tracks
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dry‑run:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm -v $(pwd):/data audio_splitter /data/input.mp3 /data/tracks.txt --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
**Help:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm audio_splitter --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Output
|
||||||
|
|
||||||
|
All output files are written to the mounted directory on your host (under the default `input_splits/` subdirectory, or any custom `--output-dir` you specify).
|
||||||
|
|
||||||
|
### Permission Handling
|
||||||
|
|
||||||
|
The container automatically adjusts ownership of the mounted `/data` directory so that the container user can read and write files there. No `--user` or `:z` flags are required.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 📂 Project Structure
|
## 📂 Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -252,7 +323,10 @@ audio_splitter/
|
|||||||
├── metadata.py # Metadata selection and building
|
├── metadata.py # Metadata selection and building
|
||||||
├── formats.py # Container format decision and validation
|
├── formats.py # Container format decision and validation
|
||||||
├── core.py # Main orchestration logic
|
├── core.py # Main orchestration logic
|
||||||
└── main.py # Command‑line interface
|
├── main.py # Command‑line interface
|
||||||
|
├── docker-entrypoint.sh # Docker entrypoint script
|
||||||
|
├── Dockerfile # Docker image definition
|
||||||
|
└── README.md # This file
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -267,13 +341,13 @@ Contributions are welcome! Please follow these steps:
|
|||||||
4. Push to the branch (`git push origin feature/amazing-feature`)
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
||||||
5. Open a Pull Request
|
5. Open a Pull Request
|
||||||
|
|
||||||
For bug reports or feature requests, please [open an issue](https://github.com/yourusername/audio-splitter/issues).
|
For bug reports or feature requests, please [open an issue](https://git.vmn.su/max/audio_splitter/issues).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📄 License
|
## 📄 License
|
||||||
|
|
||||||
Distributed under the GPU GPL v3 or later. See [LICENSE](LICENSE) for more information.
|
Distributed under the GNU General Public License v3 (or later). See the [LICENSE](LICENSE) file for more details.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -281,10 +355,11 @@ Distributed under the GPU GPL v3 or later. See [LICENSE](LICENSE) for more infor
|
|||||||
|
|
||||||
- [FFmpeg](https://ffmpeg.org/) – the powerhouse behind audio processing
|
- [FFmpeg](https://ffmpeg.org/) – the powerhouse behind audio processing
|
||||||
- [Python](https://www.python.org/) – the language that makes it all possible
|
- [Python](https://www.python.org/) – the language that makes it all possible
|
||||||
|
- [gosu](https://github.com/tianon/gosu) – privilege dropping for Docker
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📬 Contact
|
## 📬 Contact
|
||||||
|
|
||||||
**Maintainer:** [Maxim Vershinin](https://git.vmn.su/max)
|
**Maintainer:** Maxim Vershinin
|
||||||
**Project Link:** [https://git.vmn.su/max/audio-splitter](https://git.vmn.su/max/audio-splitter)
|
**Project Link:** [https://git.vmn.su/max/audio_splitter](https://git.vmn.su/max/audio_splitter)
|
||||||
|
|||||||
Executable
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Check if we are running as root (default)
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
# If /data is a directory, change its ownership to the container user
|
||||||
|
if [ -d "/data" ]; then
|
||||||
|
echo "Setting ownership of /data to appuser:appgroup"
|
||||||
|
chown -R appuser:appgroup /data
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Drop privileges and run audio_splitter with the provided arguments
|
||||||
|
exec gosu appuser audio_splitter "$@"
|
||||||
|
else
|
||||||
|
# If not root, just run audio_splitter directly
|
||||||
|
# It's not supposed to be called
|
||||||
|
exec audio_splitter "$@"
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user