music-recognition-tool 1.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- music_recognition_tool-1.2.1/.gitignore +38 -0
- music_recognition_tool-1.2.1/LICENSE +21 -0
- music_recognition_tool-1.2.1/PKG-INFO +275 -0
- music_recognition_tool-1.2.1/README.md +236 -0
- music_recognition_tool-1.2.1/pyproject.toml +63 -0
- music_recognition_tool-1.2.1/src/music_recognition/__init__.py +24 -0
- music_recognition_tool-1.2.1/src/music_recognition/analyzer.py +71 -0
- music_recognition_tool-1.2.1/src/music_recognition/cache.py +80 -0
- music_recognition_tool-1.2.1/src/music_recognition/cli.py +412 -0
- music_recognition_tool-1.2.1/src/music_recognition/core.py +664 -0
- music_recognition_tool-1.2.1/src/music_recognition/models.py +32 -0
- music_recognition_tool-1.2.1/src/music_recognition/watcher.py +83 -0
- music_recognition_tool-1.2.1/tests/__init__.py +1 -0
- music_recognition_tool-1.2.1/tests/test_core.py +355 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Byte-compiled
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
|
|
7
|
+
# Distribution
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
*.egg-info/
|
|
11
|
+
.eggs/
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.venv/
|
|
15
|
+
venv/
|
|
16
|
+
ENV/
|
|
17
|
+
|
|
18
|
+
# Testing
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.coverage
|
|
21
|
+
htmlcov/
|
|
22
|
+
.tox/
|
|
23
|
+
|
|
24
|
+
# IDE
|
|
25
|
+
.idea/
|
|
26
|
+
.vscode/
|
|
27
|
+
*.swp
|
|
28
|
+
|
|
29
|
+
# OS
|
|
30
|
+
.DS_Store
|
|
31
|
+
Thumbs.db
|
|
32
|
+
|
|
33
|
+
# Project
|
|
34
|
+
*.mp3
|
|
35
|
+
*.wav
|
|
36
|
+
*.flac
|
|
37
|
+
output/
|
|
38
|
+
reports/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 formeo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: music-recognition-tool
|
|
3
|
+
Version: 1.2.1
|
|
4
|
+
Summary: Identify music files using Shazam, write ID3 tags, rename and organize
|
|
5
|
+
Project-URL: Homepage, https://github.com/formeo/music_recognition
|
|
6
|
+
Project-URL: Repository, https://github.com/formeo/music_recognition
|
|
7
|
+
Project-URL: Issues, https://github.com/formeo/music_recognition/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/formeo/music_recognition/blob/main/CHANGELOG.md
|
|
9
|
+
Author-email: Roman Gordienko <grlformeo@gmail.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: id3,mp3,music,recognition,shazam,tags
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
23
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Requires-Dist: mutagen>=1.47.0
|
|
26
|
+
Requires-Dist: pydub>=0.25.1
|
|
27
|
+
Requires-Dist: shazamio>=0.7.0
|
|
28
|
+
Provides-Extra: analyze
|
|
29
|
+
Requires-Dist: librosa>=0.10.0; extra == 'analyze'
|
|
30
|
+
Requires-Dist: numpy>=1.24.0; extra == 'analyze'
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
36
|
+
Provides-Extra: watch
|
|
37
|
+
Requires-Dist: watchdog>=4.0.0; extra == 'watch'
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# ๐ต Music Recognition
|
|
41
|
+
|
|
42
|
+
[](LICENSE)
|
|
43
|
+
[](https://www.python.org/downloads/)
|
|
44
|
+
[](https://pypi.org/project/music-recognition/)
|
|
45
|
+
[](https://github.com/formeo/music_recognition/actions)
|
|
46
|
+

|
|
47
|
+

|
|
48
|
+
|
|
49
|
+
**Bulk music identification and tagging tool** โ bring order to your chaotic music collection.
|
|
50
|
+
|
|
51
|
+
Automatically identify unknown music files using Shazam, write ID3 tags, rename files, and organize into Artist/Album folders.
|
|
52
|
+
|
|
53
|
+
## โจ Features
|
|
54
|
+
|
|
55
|
+
- ๐ **Identify tracks** via Shazam API
|
|
56
|
+
- ๐ **Write ID3 tags** โ title, artist, album, year, genre
|
|
57
|
+
- ๐ **Rename files** โ customizable templates like `{artist} - {title}.mp3`
|
|
58
|
+
- ๐๏ธ **Organize** โ automatic Artist/Album folder structure
|
|
59
|
+
- โก **Async processing** โ concurrent requests with rate limiting
|
|
60
|
+
- ๐ **Format conversion** โ WAV, FLAC, M4A, OGG โ MP3
|
|
61
|
+
- ๐ **Export reports** โ JSON/CSV for processed files
|
|
62
|
+
- ๐ก๏ธ **Safe** โ dry-run mode to preview changes
|
|
63
|
+
|
|
64
|
+
## ๐ Quick Start
|
|
65
|
+
|
|
66
|
+
### Installation
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# From source
|
|
70
|
+
git clone https://github.com/formeo/music_recognition.git
|
|
71
|
+
cd music_recognition
|
|
72
|
+
pip install -e .
|
|
73
|
+
|
|
74
|
+
# Or install dependencies only
|
|
75
|
+
pip install -r requirements.txt
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Requirements
|
|
79
|
+
|
|
80
|
+
- Python 3.9+
|
|
81
|
+
- FFmpeg (for audio conversion)
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Ubuntu/Debian
|
|
85
|
+
sudo apt install ffmpeg
|
|
86
|
+
|
|
87
|
+
# macOS
|
|
88
|
+
brew install ffmpeg
|
|
89
|
+
|
|
90
|
+
# Windows
|
|
91
|
+
winget install ffmpeg
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Basic Usage
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Recognize and tag all files in a directory
|
|
98
|
+
music-recognize /path/to/music
|
|
99
|
+
|
|
100
|
+
# Also rename files to "Artist - Title.mp3"
|
|
101
|
+
music-recognize /path/to/music --rename
|
|
102
|
+
|
|
103
|
+
# Organize into Artist/Album folders
|
|
104
|
+
music-recognize /path/to/music --organize --output /sorted
|
|
105
|
+
|
|
106
|
+
# Preview changes without modifying files
|
|
107
|
+
music-recognize /path/to/music --rename --dry-run
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## ๐ Usage Examples
|
|
111
|
+
|
|
112
|
+
### Command Line
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Process single file
|
|
116
|
+
music-recognize song.mp3
|
|
117
|
+
|
|
118
|
+
# Process directory with custom template
|
|
119
|
+
music-recognize /music --rename --template "{artist}/{album}/{title}.mp3"
|
|
120
|
+
|
|
121
|
+
# Export results to JSON
|
|
122
|
+
music-recognize /music --output report.json
|
|
123
|
+
|
|
124
|
+
# Force re-recognition of already tagged files
|
|
125
|
+
music-recognize /music --force --overwrite
|
|
126
|
+
|
|
127
|
+
# Quiet mode (minimal output)
|
|
128
|
+
music-recognize /music -q
|
|
129
|
+
|
|
130
|
+
# Verbose mode (detailed logging)
|
|
131
|
+
music-recognize /music -v
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Python API
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
import asyncio
|
|
138
|
+
from music_recognition import MusicRecognizer, recognize_and_tag
|
|
139
|
+
|
|
140
|
+
# Simple one-liner
|
|
141
|
+
asyncio.run(recognize_and_tag("/music", rename=True))
|
|
142
|
+
|
|
143
|
+
# Full control
|
|
144
|
+
async def process_collection():
|
|
145
|
+
recognizer = MusicRecognizer(
|
|
146
|
+
max_concurrent=5,
|
|
147
|
+
delay_between_requests=0.5,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
stats = await recognizer.process_directory(
|
|
151
|
+
source_dir="/music",
|
|
152
|
+
output_dir="/sorted",
|
|
153
|
+
write_tags=True,
|
|
154
|
+
rename=True,
|
|
155
|
+
rename_template="{artist} - {title}.mp3",
|
|
156
|
+
organize=True,
|
|
157
|
+
skip_recognized=True,
|
|
158
|
+
dry_run=False,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
print(f"Recognized: {stats.recognized}/{stats.processed}")
|
|
162
|
+
print(f"Success rate: {stats.success_rate:.1f}%")
|
|
163
|
+
|
|
164
|
+
asyncio.run(process_collection())
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## โ๏ธ CLI Options
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
usage: music-recognize [-h] [-o PATH] [--rename] [--template TPL] [--organize]
|
|
171
|
+
[--overwrite] [-f] [-c N] [--delay SEC] [-n] [-v] [-q]
|
|
172
|
+
path
|
|
173
|
+
|
|
174
|
+
Arguments:
|
|
175
|
+
path File or directory to process
|
|
176
|
+
|
|
177
|
+
Options:
|
|
178
|
+
-o, --output PATH Output directory or report file (.json/.csv)
|
|
179
|
+
--rename Rename files based on metadata
|
|
180
|
+
--template TPL Filename template (default: "{artist} - {title}.mp3")
|
|
181
|
+
--organize Organize files into Artist/Album folders
|
|
182
|
+
--overwrite Overwrite existing ID3 tags
|
|
183
|
+
-f, --force Process files even if they have valid tags
|
|
184
|
+
-c, --concurrent N Max concurrent requests (default: 5)
|
|
185
|
+
--delay SEC Delay between requests (default: 0.5)
|
|
186
|
+
-n, --dry-run Preview changes without modifying files
|
|
187
|
+
-v, --verbose Verbose output
|
|
188
|
+
-q, --quiet Minimal output
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Template Placeholders
|
|
192
|
+
|
|
193
|
+
| Placeholder | Description | Example |
|
|
194
|
+
|-------------|-------------|---------|
|
|
195
|
+
| `{artist}` | Artist name | Queen |
|
|
196
|
+
| `{title}` | Track title | Bohemian Rhapsody |
|
|
197
|
+
| `{album}` | Album name | A Night at the Opera |
|
|
198
|
+
| `{year}` | Release year | 1975 |
|
|
199
|
+
| `{genre}` | Genre | Rock |
|
|
200
|
+
| `{track}` | Track number | 01 |
|
|
201
|
+
|
|
202
|
+
## ๐ Output Example
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
206
|
+
โ ๐ต Music Recognition v1.0.0 โ
|
|
207
|
+
โ Identify โข Tag โข Rename โข Organize โ
|
|
208
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
209
|
+
|
|
210
|
+
Processing: /music/old_collection
|
|
211
|
+
Actions: tag, rename
|
|
212
|
+
|
|
213
|
+
[150/150] 100.0% โ Unknown Track.mp3
|
|
214
|
+
|
|
215
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
216
|
+
SUMMARY
|
|
217
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
218
|
+
Total files: 150
|
|
219
|
+
Processed: 150
|
|
220
|
+
Recognized: 142
|
|
221
|
+
Failed: 5
|
|
222
|
+
Skipped: 3
|
|
223
|
+
Success rate: 94.7%
|
|
224
|
+
Duration: 125.3s
|
|
225
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## ๐ฏ Use Cases
|
|
229
|
+
|
|
230
|
+
- **Digital hoarders**: 50GB folder of `Track01.mp3` from 2005
|
|
231
|
+
- **DJs**: Tracks from old mixtapes without metadata
|
|
232
|
+
- **Media server admins**: Plex/Jellyfin shows "Unknown Artist"
|
|
233
|
+
- **Music collectors**: Vinyl rips without proper tags
|
|
234
|
+
|
|
235
|
+
## ๐ง Supported Formats
|
|
236
|
+
|
|
237
|
+
| Format | Read | Convert to MP3 |
|
|
238
|
+
|--------|------|----------------|
|
|
239
|
+
| MP3 | โ
| โ |
|
|
240
|
+
| WAV | โ
| โ
|
|
|
241
|
+
| FLAC | โ
| โ
|
|
|
242
|
+
| M4A | โ
| โ
|
|
|
243
|
+
| OGG | โ
| โ
|
|
|
244
|
+
| OPUS | โ
| โ
|
|
|
245
|
+
|
|
246
|
+
## ๐งช Development
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# Install with dev dependencies
|
|
250
|
+
pip install -e ".[dev]"
|
|
251
|
+
|
|
252
|
+
# Run tests
|
|
253
|
+
pytest -v
|
|
254
|
+
|
|
255
|
+
# Run tests with coverage
|
|
256
|
+
pytest --cov=music_recognition --cov-report=html
|
|
257
|
+
|
|
258
|
+
# Format code
|
|
259
|
+
black src/
|
|
260
|
+
isort src/
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## ๐ License
|
|
264
|
+
|
|
265
|
+
MIT License โ use freely.
|
|
266
|
+
|
|
267
|
+
## ๐ Credits
|
|
268
|
+
|
|
269
|
+
- [ShazamIO](https://github.com/dotX12/ShazamIO) โ Python Shazam API wrapper
|
|
270
|
+
- [Mutagen](https://github.com/quodlibet/mutagen) โ Audio metadata library
|
|
271
|
+
- [PyDub](https://github.com/jiaaro/pydub) โ Audio format conversion
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
**Like this project?** Give it a โญ on [GitHub](https://github.com/formeo/music_recognition)!
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# ๐ต Music Recognition
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
[](https://www.python.org/downloads/)
|
|
5
|
+
[](https://pypi.org/project/music-recognition/)
|
|
6
|
+
[](https://github.com/formeo/music_recognition/actions)
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
**Bulk music identification and tagging tool** โ bring order to your chaotic music collection.
|
|
11
|
+
|
|
12
|
+
Automatically identify unknown music files using Shazam, write ID3 tags, rename files, and organize into Artist/Album folders.
|
|
13
|
+
|
|
14
|
+
## โจ Features
|
|
15
|
+
|
|
16
|
+
- ๐ **Identify tracks** via Shazam API
|
|
17
|
+
- ๐ **Write ID3 tags** โ title, artist, album, year, genre
|
|
18
|
+
- ๐ **Rename files** โ customizable templates like `{artist} - {title}.mp3`
|
|
19
|
+
- ๐๏ธ **Organize** โ automatic Artist/Album folder structure
|
|
20
|
+
- โก **Async processing** โ concurrent requests with rate limiting
|
|
21
|
+
- ๐ **Format conversion** โ WAV, FLAC, M4A, OGG โ MP3
|
|
22
|
+
- ๐ **Export reports** โ JSON/CSV for processed files
|
|
23
|
+
- ๐ก๏ธ **Safe** โ dry-run mode to preview changes
|
|
24
|
+
|
|
25
|
+
## ๐ Quick Start
|
|
26
|
+
|
|
27
|
+
### Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# From source
|
|
31
|
+
git clone https://github.com/formeo/music_recognition.git
|
|
32
|
+
cd music_recognition
|
|
33
|
+
pip install -e .
|
|
34
|
+
|
|
35
|
+
# Or install dependencies only
|
|
36
|
+
pip install -r requirements.txt
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Requirements
|
|
40
|
+
|
|
41
|
+
- Python 3.9+
|
|
42
|
+
- FFmpeg (for audio conversion)
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Ubuntu/Debian
|
|
46
|
+
sudo apt install ffmpeg
|
|
47
|
+
|
|
48
|
+
# macOS
|
|
49
|
+
brew install ffmpeg
|
|
50
|
+
|
|
51
|
+
# Windows
|
|
52
|
+
winget install ffmpeg
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Basic Usage
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Recognize and tag all files in a directory
|
|
59
|
+
music-recognize /path/to/music
|
|
60
|
+
|
|
61
|
+
# Also rename files to "Artist - Title.mp3"
|
|
62
|
+
music-recognize /path/to/music --rename
|
|
63
|
+
|
|
64
|
+
# Organize into Artist/Album folders
|
|
65
|
+
music-recognize /path/to/music --organize --output /sorted
|
|
66
|
+
|
|
67
|
+
# Preview changes without modifying files
|
|
68
|
+
music-recognize /path/to/music --rename --dry-run
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## ๐ Usage Examples
|
|
72
|
+
|
|
73
|
+
### Command Line
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Process single file
|
|
77
|
+
music-recognize song.mp3
|
|
78
|
+
|
|
79
|
+
# Process directory with custom template
|
|
80
|
+
music-recognize /music --rename --template "{artist}/{album}/{title}.mp3"
|
|
81
|
+
|
|
82
|
+
# Export results to JSON
|
|
83
|
+
music-recognize /music --output report.json
|
|
84
|
+
|
|
85
|
+
# Force re-recognition of already tagged files
|
|
86
|
+
music-recognize /music --force --overwrite
|
|
87
|
+
|
|
88
|
+
# Quiet mode (minimal output)
|
|
89
|
+
music-recognize /music -q
|
|
90
|
+
|
|
91
|
+
# Verbose mode (detailed logging)
|
|
92
|
+
music-recognize /music -v
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Python API
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
import asyncio
|
|
99
|
+
from music_recognition import MusicRecognizer, recognize_and_tag
|
|
100
|
+
|
|
101
|
+
# Simple one-liner
|
|
102
|
+
asyncio.run(recognize_and_tag("/music", rename=True))
|
|
103
|
+
|
|
104
|
+
# Full control
|
|
105
|
+
async def process_collection():
|
|
106
|
+
recognizer = MusicRecognizer(
|
|
107
|
+
max_concurrent=5,
|
|
108
|
+
delay_between_requests=0.5,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
stats = await recognizer.process_directory(
|
|
112
|
+
source_dir="/music",
|
|
113
|
+
output_dir="/sorted",
|
|
114
|
+
write_tags=True,
|
|
115
|
+
rename=True,
|
|
116
|
+
rename_template="{artist} - {title}.mp3",
|
|
117
|
+
organize=True,
|
|
118
|
+
skip_recognized=True,
|
|
119
|
+
dry_run=False,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
print(f"Recognized: {stats.recognized}/{stats.processed}")
|
|
123
|
+
print(f"Success rate: {stats.success_rate:.1f}%")
|
|
124
|
+
|
|
125
|
+
asyncio.run(process_collection())
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## โ๏ธ CLI Options
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
usage: music-recognize [-h] [-o PATH] [--rename] [--template TPL] [--organize]
|
|
132
|
+
[--overwrite] [-f] [-c N] [--delay SEC] [-n] [-v] [-q]
|
|
133
|
+
path
|
|
134
|
+
|
|
135
|
+
Arguments:
|
|
136
|
+
path File or directory to process
|
|
137
|
+
|
|
138
|
+
Options:
|
|
139
|
+
-o, --output PATH Output directory or report file (.json/.csv)
|
|
140
|
+
--rename Rename files based on metadata
|
|
141
|
+
--template TPL Filename template (default: "{artist} - {title}.mp3")
|
|
142
|
+
--organize Organize files into Artist/Album folders
|
|
143
|
+
--overwrite Overwrite existing ID3 tags
|
|
144
|
+
-f, --force Process files even if they have valid tags
|
|
145
|
+
-c, --concurrent N Max concurrent requests (default: 5)
|
|
146
|
+
--delay SEC Delay between requests (default: 0.5)
|
|
147
|
+
-n, --dry-run Preview changes without modifying files
|
|
148
|
+
-v, --verbose Verbose output
|
|
149
|
+
-q, --quiet Minimal output
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Template Placeholders
|
|
153
|
+
|
|
154
|
+
| Placeholder | Description | Example |
|
|
155
|
+
|-------------|-------------|---------|
|
|
156
|
+
| `{artist}` | Artist name | Queen |
|
|
157
|
+
| `{title}` | Track title | Bohemian Rhapsody |
|
|
158
|
+
| `{album}` | Album name | A Night at the Opera |
|
|
159
|
+
| `{year}` | Release year | 1975 |
|
|
160
|
+
| `{genre}` | Genre | Rock |
|
|
161
|
+
| `{track}` | Track number | 01 |
|
|
162
|
+
|
|
163
|
+
## ๐ Output Example
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
167
|
+
โ ๐ต Music Recognition v1.0.0 โ
|
|
168
|
+
โ Identify โข Tag โข Rename โข Organize โ
|
|
169
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
170
|
+
|
|
171
|
+
Processing: /music/old_collection
|
|
172
|
+
Actions: tag, rename
|
|
173
|
+
|
|
174
|
+
[150/150] 100.0% โ Unknown Track.mp3
|
|
175
|
+
|
|
176
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
177
|
+
SUMMARY
|
|
178
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
179
|
+
Total files: 150
|
|
180
|
+
Processed: 150
|
|
181
|
+
Recognized: 142
|
|
182
|
+
Failed: 5
|
|
183
|
+
Skipped: 3
|
|
184
|
+
Success rate: 94.7%
|
|
185
|
+
Duration: 125.3s
|
|
186
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## ๐ฏ Use Cases
|
|
190
|
+
|
|
191
|
+
- **Digital hoarders**: 50GB folder of `Track01.mp3` from 2005
|
|
192
|
+
- **DJs**: Tracks from old mixtapes without metadata
|
|
193
|
+
- **Media server admins**: Plex/Jellyfin shows "Unknown Artist"
|
|
194
|
+
- **Music collectors**: Vinyl rips without proper tags
|
|
195
|
+
|
|
196
|
+
## ๐ง Supported Formats
|
|
197
|
+
|
|
198
|
+
| Format | Read | Convert to MP3 |
|
|
199
|
+
|--------|------|----------------|
|
|
200
|
+
| MP3 | โ
| โ |
|
|
201
|
+
| WAV | โ
| โ
|
|
|
202
|
+
| FLAC | โ
| โ
|
|
|
203
|
+
| M4A | โ
| โ
|
|
|
204
|
+
| OGG | โ
| โ
|
|
|
205
|
+
| OPUS | โ
| โ
|
|
|
206
|
+
|
|
207
|
+
## ๐งช Development
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
# Install with dev dependencies
|
|
211
|
+
pip install -e ".[dev]"
|
|
212
|
+
|
|
213
|
+
# Run tests
|
|
214
|
+
pytest -v
|
|
215
|
+
|
|
216
|
+
# Run tests with coverage
|
|
217
|
+
pytest --cov=music_recognition --cov-report=html
|
|
218
|
+
|
|
219
|
+
# Format code
|
|
220
|
+
black src/
|
|
221
|
+
isort src/
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## ๐ License
|
|
225
|
+
|
|
226
|
+
MIT License โ use freely.
|
|
227
|
+
|
|
228
|
+
## ๐ Credits
|
|
229
|
+
|
|
230
|
+
- [ShazamIO](https://github.com/dotX12/ShazamIO) โ Python Shazam API wrapper
|
|
231
|
+
- [Mutagen](https://github.com/quodlibet/mutagen) โ Audio metadata library
|
|
232
|
+
- [PyDub](https://github.com/jiaaro/pydub) โ Audio format conversion
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
**Like this project?** Give it a โญ on [GitHub](https://github.com/formeo/music_recognition)!
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "music-recognition-tool"
|
|
7
|
+
version = "1.2.1"
|
|
8
|
+
description = "Identify music files using Shazam, write ID3 tags, rename and organize"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Roman Gordienko", email = "grlformeo@gmail.com" }
|
|
13
|
+
]
|
|
14
|
+
keywords = ["music", "recognition", "shazam", "id3", "mp3", "tags"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: End Users/Desktop",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Topic :: Multimedia :: Sound/Audio",
|
|
26
|
+
"Topic :: Multimedia :: Sound/Audio :: Analysis",
|
|
27
|
+
]
|
|
28
|
+
requires-python = ">=3.10"
|
|
29
|
+
dependencies = [
|
|
30
|
+
"shazamio>=0.7.0",
|
|
31
|
+
"mutagen>=1.47.0",
|
|
32
|
+
"pydub>=0.25.1",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
watch = ["watchdog>=4.0.0"]
|
|
37
|
+
analyze = ["librosa>=0.10.0", "numpy>=1.24.0"]
|
|
38
|
+
dev = [
|
|
39
|
+
"pytest>=7.0.0",
|
|
40
|
+
"pytest-asyncio>=0.21.0",
|
|
41
|
+
"ruff>=0.1.0",
|
|
42
|
+
"mypy>=1.0.0",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[project.scripts]
|
|
46
|
+
music-recognize = "music_recognition.cli:main"
|
|
47
|
+
|
|
48
|
+
[project.urls]
|
|
49
|
+
Homepage = "https://github.com/formeo/music_recognition"
|
|
50
|
+
Repository = "https://github.com/formeo/music_recognition"
|
|
51
|
+
Issues = "https://github.com/formeo/music_recognition/issues"
|
|
52
|
+
Changelog = "https://github.com/formeo/music_recognition/blob/main/CHANGELOG.md"
|
|
53
|
+
|
|
54
|
+
[tool.hatch.build.targets.wheel]
|
|
55
|
+
packages = ["src/music_recognition"]
|
|
56
|
+
|
|
57
|
+
[tool.hatch.build.targets.sdist]
|
|
58
|
+
include = [
|
|
59
|
+
"/src",
|
|
60
|
+
"/tests",
|
|
61
|
+
"/README.md",
|
|
62
|
+
"/LICENSE",
|
|
63
|
+
]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# src/music_recognition/__init__.py
|
|
2
|
+
"""Music Recognition - Identify, tag, rename and organize music files."""
|
|
3
|
+
|
|
4
|
+
__version__ = "1.1.0"
|
|
5
|
+
__author__ = "formeo"
|
|
6
|
+
|
|
7
|
+
from .core import (
|
|
8
|
+
MusicRecognizer,
|
|
9
|
+
TrackInfo,
|
|
10
|
+
ProcessingResult,
|
|
11
|
+
ProcessingStats,
|
|
12
|
+
recognize_and_tag,
|
|
13
|
+
setup_logging,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"MusicRecognizer",
|
|
18
|
+
"TrackInfo",
|
|
19
|
+
"ProcessingResult",
|
|
20
|
+
"ProcessingStats",
|
|
21
|
+
"recognize_and_tag",
|
|
22
|
+
"setup_logging",
|
|
23
|
+
"__version__",
|
|
24
|
+
]
|