lyrics-transcriber 0.12.9__tar.gz → 0.14.0__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.
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/PKG-INFO +16 -15
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/transcriber.py +25 -11
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/utils/cli.py +5 -3
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/pyproject.toml +16 -15
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/LICENSE +0 -0
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/README.md +0 -0
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/__init__.py +0 -0
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/llm_prompts/README.md +0 -0
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/llm_prompts/llm_prompt_lyrics_correction_andrew_handwritten_20231118.txt +0 -0
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/llm_prompts/llm_prompt_lyrics_correction_gpt_optimised_20231119.txt +0 -0
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/llm_prompts/llm_prompt_lyrics_matching_andrew_handwritten_20231118.txt +0 -0
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/llm_prompts/promptfooconfig.yaml +0 -0
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/llm_prompts/test_data/ABBA-UnderAttack-Genius.txt +0 -0
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/utils/__init__.py +0 -0
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/utils/ass.py +0 -0
- {lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/utils/subtitles.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: lyrics-transcriber
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.14.0
|
4
4
|
Summary: Automatically create synchronised lyrics files in ASS and MidiCo LRC formats with word-level timestamps, using Whisper and lyrics from Genius and Spotify
|
5
5
|
Home-page: https://github.com/karaokenerds/python-lyrics-transcriber
|
6
6
|
License: MIT
|
@@ -13,21 +13,22 @@ Classifier: Programming Language :: Python :: 3.9
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.10
|
14
14
|
Classifier: Programming Language :: Python :: 3.11
|
15
15
|
Classifier: Programming Language :: Python :: 3.12
|
16
|
-
Requires-Dist: Cython (>=0
|
17
|
-
Requires-Dist: dtw-python (>=1
|
18
|
-
Requires-Dist: llvmlite (>=0
|
19
|
-
Requires-Dist: lyricsgenius (>=3
|
20
|
-
Requires-Dist: numba (>=0.57
|
21
|
-
Requires-Dist: numpy (>=1
|
22
|
-
Requires-Dist: onnx (>=1
|
23
|
-
Requires-Dist: onnxruntime (>=1
|
16
|
+
Requires-Dist: Cython (>=0)
|
17
|
+
Requires-Dist: dtw-python (>=1)
|
18
|
+
Requires-Dist: llvmlite (>=0)
|
19
|
+
Requires-Dist: lyricsgenius (>=3)
|
20
|
+
Requires-Dist: numba (>=0.57)
|
21
|
+
Requires-Dist: numpy (>=1)
|
22
|
+
Requires-Dist: onnx (>=1)
|
23
|
+
Requires-Dist: onnxruntime (>=1)
|
24
24
|
Requires-Dist: openai (>=1,<2)
|
25
|
-
Requires-Dist: openai-whisper (
|
26
|
-
Requires-Dist: python-slugify (>=8
|
27
|
-
Requires-Dist: syrics (>=0
|
28
|
-
Requires-Dist: torch (
|
29
|
-
Requires-Dist: tqdm (>=4
|
30
|
-
Requires-Dist:
|
25
|
+
Requires-Dist: openai-whisper (>=20231117)
|
26
|
+
Requires-Dist: python-slugify (>=8)
|
27
|
+
Requires-Dist: syrics (>=0)
|
28
|
+
Requires-Dist: torch (>=1)
|
29
|
+
Requires-Dist: tqdm (>=4)
|
30
|
+
Requires-Dist: transformers (>=4)
|
31
|
+
Requires-Dist: whisper-timestamped (>=1)
|
31
32
|
Project-URL: Documentation, https://github.com/karaokenerds/python-lyrics-transcriber/blob/main/README.md
|
32
33
|
Project-URL: Repository, https://github.com/karaokenerds/python-lyrics-transcriber
|
33
34
|
Description-Content-Type: text/markdown
|
@@ -29,7 +29,7 @@ class LyricsTranscriber:
|
|
29
29
|
log_level=logging.DEBUG,
|
30
30
|
log_formatter=None,
|
31
31
|
transcription_model="medium",
|
32
|
-
llm_model="gpt-
|
32
|
+
llm_model="gpt-4o",
|
33
33
|
llm_prompt_matching="lyrics_transcriber/llm_prompts/llm_prompt_lyrics_matching_andrew_handwritten_20231118.txt",
|
34
34
|
llm_prompt_correction="lyrics_transcriber/llm_prompts/llm_prompt_lyrics_correction_andrew_handwritten_20231118.txt",
|
35
35
|
render_video=False,
|
@@ -66,7 +66,15 @@ class LyricsTranscriber:
|
|
66
66
|
self.llm_model = llm_model
|
67
67
|
self.llm_prompt_matching = llm_prompt_matching
|
68
68
|
self.llm_prompt_correction = llm_prompt_correction
|
69
|
+
|
69
70
|
self.openai_client = OpenAI()
|
71
|
+
|
72
|
+
# Uncomment for local models e.g. with ollama
|
73
|
+
# self.openai_client = OpenAI(
|
74
|
+
# base_url="http://localhost:11434/v1",
|
75
|
+
# api_key="ollama",
|
76
|
+
# )
|
77
|
+
|
70
78
|
self.openai_client.log = self.log_level
|
71
79
|
|
72
80
|
self.render_video = render_video
|
@@ -190,6 +198,9 @@ class LyricsTranscriber:
|
|
190
198
|
online_lyrics_text_key = f"{online_lyrics_source}_lyrics_text"
|
191
199
|
online_lyrics_filepath_key = f"{online_lyrics_source}_lyrics_filepath"
|
192
200
|
|
201
|
+
if online_lyrics_text_key not in self.outputs:
|
202
|
+
continue
|
203
|
+
|
193
204
|
data_input_str = (
|
194
205
|
f'Data input 1:\n{self.outputs["transcribed_lyrics_text"]}\nData input 2:\n{self.outputs[online_lyrics_text_key]}\n'
|
195
206
|
)
|
@@ -274,7 +285,7 @@ class LyricsTranscriber:
|
|
274
285
|
total_segments = len(self.outputs["transcription_data_dict"]["segments"])
|
275
286
|
self.logger.info(f"Beginning correction using LLM, total segments: {total_segments}")
|
276
287
|
|
277
|
-
with open(self.outputs["llm_transcript_filepath"], "a", buffering=1) as llm_transcript_file:
|
288
|
+
with open(self.outputs["llm_transcript_filepath"], "a", buffering=1, encoding="utf-8") as llm_transcript_file:
|
278
289
|
self.logger.debug(f"writing LLM chat instructions: {self.outputs['llm_transcript_filepath']}")
|
279
290
|
|
280
291
|
llm_transcript_header = f"--- SYSTEM instructions passed in for all segments ---:\n\n{system_prompt}\n"
|
@@ -370,7 +381,7 @@ class LyricsTranscriber:
|
|
370
381
|
self.logger.info(f'Successfully processed correction for all {len(corrected_lyrics_dict["segments"])} lyrics segments')
|
371
382
|
|
372
383
|
self.logger.debug(f"writing corrected lyrics data JSON filepath: {corrected_lyrics_data_json_cache_filepath}")
|
373
|
-
with open(corrected_lyrics_data_json_cache_filepath, "w") as corrected_lyrics_data_json_cache_file:
|
384
|
+
with open(corrected_lyrics_data_json_cache_filepath, "w", encoding="utf-8") as corrected_lyrics_data_json_cache_file:
|
374
385
|
corrected_lyrics_data_json_cache_file.write(json.dumps(corrected_lyrics_dict, indent=4))
|
375
386
|
|
376
387
|
self.outputs["corrected_lyrics_data_filepath"] = corrected_lyrics_data_json_cache_filepath
|
@@ -388,8 +399,11 @@ class LyricsTranscriber:
|
|
388
399
|
},
|
389
400
|
}
|
390
401
|
|
391
|
-
|
392
|
-
|
402
|
+
input_price = price_dollars_per_1000_tokens.get(self.llm_model, {"input": 0, "output": 0})["input"]
|
403
|
+
output_price = price_dollars_per_1000_tokens.get(self.llm_model, {"input": 0, "output": 0})["output"]
|
404
|
+
|
405
|
+
input_cost = input_price * (self.outputs["llm_token_usage"]["input"] / 1000)
|
406
|
+
output_cost = output_price * (self.outputs["llm_token_usage"]["output"] / 1000)
|
393
407
|
|
394
408
|
self.outputs["llm_costs_usd"]["input"] = round(input_cost, 3)
|
395
409
|
self.outputs["llm_costs_usd"]["output"] = round(output_cost, 3)
|
@@ -405,7 +419,7 @@ class LyricsTranscriber:
|
|
405
419
|
self.outputs["corrected_lyrics_text"] = ""
|
406
420
|
|
407
421
|
self.logger.debug(f"writing lyrics plain text to corrected_lyrics_text_filepath: {corrected_lyrics_text_filepath}")
|
408
|
-
with open(corrected_lyrics_text_filepath, "w") as f:
|
422
|
+
with open(corrected_lyrics_text_filepath, "w", encoding="utf-8") as f:
|
409
423
|
for corrected_segment in self.outputs["corrected_lyrics_data_dict"]["segments"]:
|
410
424
|
self.outputs["corrected_lyrics_text"] += corrected_segment["text"].strip() + "\n"
|
411
425
|
f.write(corrected_segment["text".strip()] + "\n")
|
@@ -452,7 +466,7 @@ class LyricsTranscriber:
|
|
452
466
|
self.logger.debug(
|
453
467
|
f"writing lyrics data JSON to spotify_lyrics_data_json_cache_filepath: {spotify_lyrics_data_json_cache_filepath}"
|
454
468
|
)
|
455
|
-
with open(spotify_lyrics_data_json_cache_filepath, "w") as f:
|
469
|
+
with open(spotify_lyrics_data_json_cache_filepath, "w", encoding="utf-8") as f:
|
456
470
|
f.write(spotify_lyrics_json)
|
457
471
|
except Exception as e:
|
458
472
|
self.logger.warn(f"caught exception while attempting to fetch from spotify: ", e)
|
@@ -472,7 +486,7 @@ class LyricsTranscriber:
|
|
472
486
|
self.outputs["spotify_lyrics_text"] = ""
|
473
487
|
|
474
488
|
self.logger.debug(f"writing lyrics plain text to spotify_lyrics_text_filepath: {spotify_lyrics_text_filepath}")
|
475
|
-
with open(spotify_lyrics_text_filepath, "w") as f:
|
489
|
+
with open(spotify_lyrics_text_filepath, "w", encoding="utf-8") as f:
|
476
490
|
for line in lines:
|
477
491
|
self.outputs["spotify_lyrics_text"] += line["words"].strip() + "\n"
|
478
492
|
f.write(line["words"].strip() + "\n")
|
@@ -504,7 +518,7 @@ class LyricsTranscriber:
|
|
504
518
|
lyrics = self.clean_genius_lyrics(song.lyrics)
|
505
519
|
|
506
520
|
self.logger.debug(f"writing clean lyrics to genius_lyrics_cache_filepath: {genius_lyrics_cache_filepath}")
|
507
|
-
with open(genius_lyrics_cache_filepath, "w") as f:
|
521
|
+
with open(genius_lyrics_cache_filepath, "w", encoding="utf-8") as f:
|
508
522
|
f.write(lyrics)
|
509
523
|
|
510
524
|
self.outputs["genius_lyrics_filepath"] = genius_lyrics_cache_filepath
|
@@ -558,7 +572,7 @@ class LyricsTranscriber:
|
|
558
572
|
|
559
573
|
lrc_filename = self.outputs["midico_lrc_filepath"]
|
560
574
|
self.logger.debug(f"writing midico formatted word timestamps to LRC file: {lrc_filename}")
|
561
|
-
with open(lrc_filename, "w") as f:
|
575
|
+
with open(lrc_filename, "w", encoding="utf-8") as f:
|
562
576
|
f.write("[re:MidiCo]\n")
|
563
577
|
for segment in self.outputs["corrected_lyrics_data_dict"]["segments"]:
|
564
578
|
for i, word in enumerate(segment["words"]):
|
@@ -752,7 +766,7 @@ class LyricsTranscriber:
|
|
752
766
|
self.outputs["transcribed_lyrics_text"] = ""
|
753
767
|
|
754
768
|
self.logger.debug(f"writing lyrics plain text to transcribed_lyrics_text_filepath: {transcribed_lyrics_text_filepath}")
|
755
|
-
with open(transcribed_lyrics_text_filepath, "w") as f:
|
769
|
+
with open(transcribed_lyrics_text_filepath, "w", encoding="utf-8") as f:
|
756
770
|
for segment in self.outputs["transcription_data_dict"]["segments"]:
|
757
771
|
self.outputs["transcribed_lyrics_text"] += segment["text"] + "\n"
|
758
772
|
f.write(segment["text"].strip() + "\n")
|
@@ -2,7 +2,6 @@
|
|
2
2
|
import argparse
|
3
3
|
import logging
|
4
4
|
import pkg_resources
|
5
|
-
from lyrics_transcriber import LyricsTranscriber
|
6
5
|
|
7
6
|
|
8
7
|
def main():
|
@@ -66,8 +65,8 @@ def main():
|
|
66
65
|
|
67
66
|
parser.add_argument(
|
68
67
|
"--llm_model",
|
69
|
-
default="gpt-
|
70
|
-
help="Optional: LLM model to use (currently only supports OpenAI chat completion models
|
68
|
+
default="gpt-4o",
|
69
|
+
help="Optional: LLM model to use (currently only supports OpenAI chat completion compatible models",
|
71
70
|
)
|
72
71
|
|
73
72
|
parser.add_argument(
|
@@ -110,6 +109,9 @@ def main():
|
|
110
109
|
|
111
110
|
logger.debug("Loading LyricsTranscriber class")
|
112
111
|
|
112
|
+
# Lazy load this class so help output is printed quickly rather than waiting for heavy libraries to load
|
113
|
+
from lyrics_transcriber import LyricsTranscriber
|
114
|
+
|
113
115
|
transcriber = LyricsTranscriber(
|
114
116
|
args.audio_filepath,
|
115
117
|
genius_api_token=args.genius_api_token,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "lyrics-transcriber"
|
3
|
-
version = "0.
|
3
|
+
version = "0.14.0"
|
4
4
|
description = "Automatically create synchronised lyrics files in ASS and MidiCo LRC formats with word-level timestamps, using Whisper and lyrics from Genius and Spotify"
|
5
5
|
authors = ["Andrew Beveridge <andrew@beveridge.uk>"]
|
6
6
|
license = "MIT"
|
@@ -13,21 +13,22 @@ documentation = "https://github.com/karaokenerds/python-lyrics-transcriber/blob/
|
|
13
13
|
|
14
14
|
[tool.poetry.dependencies]
|
15
15
|
python = ">=3.9"
|
16
|
-
Cython = "
|
17
|
-
dtw-python = "
|
18
|
-
llvmlite = "
|
19
|
-
numba = "
|
20
|
-
numpy = "
|
21
|
-
onnx = "
|
22
|
-
onnxruntime = "
|
23
|
-
torch = "
|
24
|
-
tqdm = "
|
25
|
-
lyricsgenius = "
|
26
|
-
python-slugify = "
|
27
|
-
syrics = "
|
16
|
+
Cython = ">=0"
|
17
|
+
dtw-python = ">=1"
|
18
|
+
llvmlite = ">=0"
|
19
|
+
numba = ">=0.57"
|
20
|
+
numpy = ">=1"
|
21
|
+
onnx = ">=1"
|
22
|
+
onnxruntime = ">=1"
|
23
|
+
torch = ">=1"
|
24
|
+
tqdm = ">=4"
|
25
|
+
lyricsgenius = ">=3"
|
26
|
+
python-slugify = ">=8"
|
27
|
+
syrics = ">=0"
|
28
28
|
openai = "^1"
|
29
|
-
openai-whisper = "20231117"
|
30
|
-
|
29
|
+
openai-whisper = ">=20231117"
|
30
|
+
transformers = ">=4"
|
31
|
+
whisper-timestamped = ">=1"
|
31
32
|
# Note: after adding openai-whisper and whisper-timestamped with poetry lock, I then removed all traces of triton
|
32
33
|
# from poetry.lock before running poetry install, as triton doesn't support macOS but isn't actually needed for whisper.
|
33
34
|
# This was the only way I was able to get a working cross-platform build published to PyPI.
|
File without changes
|
File without changes
|
File without changes
|
{lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/llm_prompts/README.md
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/utils/__init__.py
RENAMED
File without changes
|
File without changes
|
{lyrics_transcriber-0.12.9 → lyrics_transcriber-0.14.0}/lyrics_transcriber/utils/subtitles.py
RENAMED
File without changes
|