lyrics-transcriber 0.34.2__py3-none-any.whl → 0.35.0__py3-none-any.whl
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/core/controller.py +10 -1
- lyrics_transcriber/correction/corrector.py +4 -3
- lyrics_transcriber/frontend/dist/assets/index-CQCER5Fo.js +181 -0
- lyrics_transcriber/frontend/dist/index.html +1 -1
- lyrics_transcriber/frontend/src/App.tsx +6 -2
- lyrics_transcriber/frontend/src/api.ts +9 -0
- lyrics_transcriber/frontend/src/components/AudioPlayer.tsx +155 -0
- lyrics_transcriber/frontend/src/components/CorrectionMetrics.tsx +1 -1
- lyrics_transcriber/frontend/src/components/DetailsModal.tsx +23 -191
- lyrics_transcriber/frontend/src/components/EditModal.tsx +407 -0
- lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +255 -221
- lyrics_transcriber/frontend/src/components/ModeSelector.tsx +39 -0
- lyrics_transcriber/frontend/src/components/ReferenceView.tsx +35 -264
- lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx +232 -0
- lyrics_transcriber/frontend/src/components/SegmentDetailsModal.tsx +64 -0
- lyrics_transcriber/frontend/src/components/TimelineEditor.tsx +315 -0
- lyrics_transcriber/frontend/src/components/TranscriptionView.tsx +116 -138
- lyrics_transcriber/frontend/src/components/WordEditControls.tsx +116 -0
- lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx +243 -0
- lyrics_transcriber/frontend/src/components/shared/components/SourceSelector.tsx +28 -0
- lyrics_transcriber/frontend/src/components/shared/components/Word.tsx +52 -0
- lyrics_transcriber/frontend/src/components/{constants.ts → shared/constants.ts} +1 -0
- lyrics_transcriber/frontend/src/components/shared/hooks/useWordClick.ts +137 -0
- lyrics_transcriber/frontend/src/components/{styles.ts → shared/styles.ts} +1 -1
- lyrics_transcriber/frontend/src/components/shared/types.ts +99 -0
- lyrics_transcriber/frontend/src/components/shared/utils/newlineCalculator.ts +37 -0
- lyrics_transcriber/frontend/src/components/shared/utils/referenceLineCalculator.ts +76 -0
- lyrics_transcriber/frontend/src/types.ts +2 -43
- lyrics_transcriber/frontend/tsconfig.tsbuildinfo +1 -1
- lyrics_transcriber/lyrics/spotify.py +11 -0
- lyrics_transcriber/output/generator.py +28 -11
- lyrics_transcriber/review/server.py +38 -12
- {lyrics_transcriber-0.34.2.dist-info → lyrics_transcriber-0.35.0.dist-info}/METADATA +1 -1
- {lyrics_transcriber-0.34.2.dist-info → lyrics_transcriber-0.35.0.dist-info}/RECORD +37 -24
- lyrics_transcriber/frontend/dist/assets/index-DqFgiUni.js +0 -245
- lyrics_transcriber/frontend/src/components/DebugPanel.tsx +0 -311
- {lyrics_transcriber-0.34.2.dist-info → lyrics_transcriber-0.35.0.dist-info}/LICENSE +0 -0
- {lyrics_transcriber-0.34.2.dist-info → lyrics_transcriber-0.35.0.dist-info}/WHEEL +0 -0
- {lyrics_transcriber-0.34.2.dist-info → lyrics_transcriber-0.35.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
import { LyricsData, LyricsSegment } from '../../../types'
|
2
|
+
|
3
|
+
export function calculateNewlineIndices(
|
4
|
+
corrected_segments: LyricsSegment[],
|
5
|
+
anchors: LyricsData['anchor_sequences'],
|
6
|
+
currentSource: 'genius' | 'spotify'
|
7
|
+
): Set<number> {
|
8
|
+
return new Set(
|
9
|
+
corrected_segments.slice(0, -1).map((segment, segmentIndex) => {
|
10
|
+
const segmentText = segment.text.trim()
|
11
|
+
const segmentWords = segmentText.split(/\s+/)
|
12
|
+
const segmentStartWord = corrected_segments
|
13
|
+
.slice(0, segmentIndex)
|
14
|
+
.reduce((acc, s) => acc + s.text.trim().split(/\s+/).length, 0)
|
15
|
+
const lastWordPosition = segmentStartWord + segmentWords.length - 1
|
16
|
+
|
17
|
+
const matchingAnchor = anchors.find(a => {
|
18
|
+
const start = a.transcription_position
|
19
|
+
const end = start + a.length - 1
|
20
|
+
return lastWordPosition >= start && lastWordPosition <= end
|
21
|
+
})
|
22
|
+
|
23
|
+
if (matchingAnchor?.reference_positions[currentSource] !== undefined) {
|
24
|
+
const anchorWords = matchingAnchor.words
|
25
|
+
const wordIndex = anchorWords.findIndex(w =>
|
26
|
+
w.toLowerCase() === segmentWords[segmentWords.length - 1].toLowerCase()
|
27
|
+
)
|
28
|
+
|
29
|
+
if (wordIndex !== -1) {
|
30
|
+
return matchingAnchor.reference_positions[currentSource] + wordIndex
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
return null
|
35
|
+
}).filter((pos): pos is number => pos !== null && pos >= 0)
|
36
|
+
)
|
37
|
+
}
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import { LyricsData, LyricsSegment } from '../../../types'
|
2
|
+
import { LinePosition } from '../types'
|
3
|
+
|
4
|
+
export function calculateReferenceLinePositions(
|
5
|
+
corrected_segments: LyricsSegment[],
|
6
|
+
anchors: LyricsData['anchor_sequences'],
|
7
|
+
currentSource: 'genius' | 'spotify'
|
8
|
+
): { linePositions: LinePosition[] } {
|
9
|
+
const linePositions: LinePosition[] = []
|
10
|
+
let currentReferencePosition = 0
|
11
|
+
|
12
|
+
// First, find all anchor sequences that cover entire lines
|
13
|
+
const fullLineAnchors = anchors.map(anchor => {
|
14
|
+
const referencePos = anchor.reference_positions[currentSource]
|
15
|
+
if (referencePos === undefined) return null
|
16
|
+
|
17
|
+
return {
|
18
|
+
referenceStart: referencePos,
|
19
|
+
referenceLength: anchor.length,
|
20
|
+
transcriptionLine: corrected_segments.findIndex((segment, segmentIndex) => {
|
21
|
+
const words = segment.words
|
22
|
+
if (!words.length) return false
|
23
|
+
|
24
|
+
// Calculate the absolute position of the first and last words in this segment
|
25
|
+
let absolutePosition = 0
|
26
|
+
for (let i = 0; i < segmentIndex; i++) {
|
27
|
+
absolutePosition += corrected_segments[i].words.length
|
28
|
+
}
|
29
|
+
|
30
|
+
const firstWordPosition = absolutePosition
|
31
|
+
const lastWordPosition = absolutePosition + words.length - 1
|
32
|
+
|
33
|
+
return firstWordPosition >= anchor.transcription_position &&
|
34
|
+
lastWordPosition < anchor.transcription_position + anchor.length
|
35
|
+
})
|
36
|
+
}
|
37
|
+
}).filter((a): a is NonNullable<typeof a> => a !== null)
|
38
|
+
|
39
|
+
// Sort by reference position to process in order
|
40
|
+
fullLineAnchors.sort((a, b) => a.referenceStart - b.referenceStart)
|
41
|
+
|
42
|
+
// Add line positions with padding
|
43
|
+
let currentLine = 0
|
44
|
+
fullLineAnchors.forEach(anchor => {
|
45
|
+
// Add empty lines if needed to match transcription line number
|
46
|
+
while (currentLine < anchor.transcriptionLine) {
|
47
|
+
linePositions.push({
|
48
|
+
position: currentReferencePosition,
|
49
|
+
lineNumber: currentLine,
|
50
|
+
isEmpty: false
|
51
|
+
})
|
52
|
+
currentReferencePosition += 1
|
53
|
+
currentLine++
|
54
|
+
}
|
55
|
+
|
56
|
+
// Add the actual line position
|
57
|
+
linePositions.push({
|
58
|
+
position: anchor.referenceStart,
|
59
|
+
lineNumber: currentLine
|
60
|
+
})
|
61
|
+
currentLine++
|
62
|
+
})
|
63
|
+
|
64
|
+
// Add any remaining lines after the last anchor
|
65
|
+
while (currentLine < corrected_segments.length) {
|
66
|
+
linePositions.push({
|
67
|
+
position: currentReferencePosition,
|
68
|
+
lineNumber: currentLine,
|
69
|
+
isEmpty: false
|
70
|
+
})
|
71
|
+
currentReferencePosition += 1
|
72
|
+
currentLine++
|
73
|
+
}
|
74
|
+
|
75
|
+
return { linePositions }
|
76
|
+
}
|
@@ -89,7 +89,7 @@ export interface CorrectionData {
|
|
89
89
|
reference_texts: Record<string, string>
|
90
90
|
anchor_sequences: AnchorSequence[]
|
91
91
|
gap_sequences: GapSequence[]
|
92
|
-
resized_segments
|
92
|
+
resized_segments?: LyricsSegment[]
|
93
93
|
corrected_text: string
|
94
94
|
corrections_made: number
|
95
95
|
confidence: number
|
@@ -114,45 +114,4 @@ export interface HighlightInfo {
|
|
114
114
|
type: 'single' | 'gap' | 'anchor'
|
115
115
|
}
|
116
116
|
|
117
|
-
export
|
118
|
-
segment: string
|
119
|
-
lastWord: string
|
120
|
-
normalizedLastWord: string
|
121
|
-
overlappingAnchors: Array<{
|
122
|
-
text: string
|
123
|
-
range: [number, number]
|
124
|
-
words: string[]
|
125
|
-
hasMatchingWord: boolean
|
126
|
-
}>
|
127
|
-
matchingGap: {
|
128
|
-
text: string
|
129
|
-
position: number
|
130
|
-
length: number
|
131
|
-
corrections: Array<{
|
132
|
-
word: string
|
133
|
-
referencePosition: number | undefined
|
134
|
-
}>
|
135
|
-
followingAnchor: {
|
136
|
-
text: string
|
137
|
-
position: number | undefined
|
138
|
-
} | null
|
139
|
-
} | null
|
140
|
-
highlightDebug?: Array<{
|
141
|
-
wordIndex: number
|
142
|
-
refPos: number | undefined
|
143
|
-
highlightPos: number | undefined
|
144
|
-
anchorLength: number
|
145
|
-
isInRange: boolean
|
146
|
-
}>
|
147
|
-
wordPositionDebug?: {
|
148
|
-
anchorWords: string[]
|
149
|
-
wordIndex: number
|
150
|
-
referencePosition: number
|
151
|
-
finalPosition: number
|
152
|
-
normalizedWords: {
|
153
|
-
anchor: string
|
154
|
-
segment: string
|
155
|
-
}
|
156
|
-
}
|
157
|
-
debugLog?: string[]
|
158
|
-
}
|
117
|
+
export type InteractionMode = 'highlight' | 'details' | 'edit'
|
@@ -1 +1 @@
|
|
1
|
-
{"root":["./src/app.tsx","./src/api.ts","./src/main.tsx","./src/types.ts","./src/vite-env.d.ts","./src/components/
|
1
|
+
{"root":["./src/app.tsx","./src/api.ts","./src/main.tsx","./src/types.ts","./src/vite-env.d.ts","./src/components/audioplayer.tsx","./src/components/correctionmetrics.tsx","./src/components/detailsmodal.tsx","./src/components/editmodal.tsx","./src/components/fileupload.tsx","./src/components/lyricsanalyzer.tsx","./src/components/modeselector.tsx","./src/components/referenceview.tsx","./src/components/reviewchangesmodal.tsx","./src/components/segmentdetailsmodal.tsx","./src/components/timelineeditor.tsx","./src/components/transcriptionview.tsx","./src/components/wordeditcontrols.tsx","./src/components/shared/constants.ts","./src/components/shared/styles.ts","./src/components/shared/types.ts","./src/components/shared/components/highlightedtext.tsx","./src/components/shared/components/sourceselector.tsx","./src/components/shared/components/word.tsx","./src/components/shared/hooks/usewordclick.ts","./src/components/shared/utils/newlinecalculator.ts","./src/components/shared/utils/referencelinecalculator.ts"],"version":"5.6.3"}
|
@@ -51,6 +51,10 @@ class SpotifyProvider(BaseLyricsProvider):
|
|
51
51
|
if not line.get("words"):
|
52
52
|
continue
|
53
53
|
|
54
|
+
# Skip lines that are just musical notes
|
55
|
+
if not self._clean_lyrics(line["words"]):
|
56
|
+
continue
|
57
|
+
|
54
58
|
segment = LyricsSegment(
|
55
59
|
text=line["words"],
|
56
60
|
words=[], # TODO: Could potentially split words if needed
|
@@ -80,3 +84,10 @@ class SpotifyProvider(BaseLyricsProvider):
|
|
80
84
|
)
|
81
85
|
|
82
86
|
return LyricsData(source="spotify", lyrics="\n".join(segment.text for segment in segments), segments=segments, metadata=metadata)
|
87
|
+
|
88
|
+
def _clean_lyrics(self, lyrics: str) -> str:
|
89
|
+
"""Clean and process lyrics from Spotify to remove unwanted content."""
|
90
|
+
# Remove lines that contain only musical note symbols
|
91
|
+
if lyrics.strip() == "♪":
|
92
|
+
return ""
|
93
|
+
return lyrics
|
@@ -154,17 +154,34 @@ class OutputGenerator:
|
|
154
154
|
|
155
155
|
def _get_video_params(self, resolution: str) -> tuple:
|
156
156
|
"""Get video parameters: (width, height), font_size, line_height based on video resolution config."""
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
157
|
+
# Get resolution dimensions
|
158
|
+
resolution_map = {
|
159
|
+
"4k": (3840, 2160),
|
160
|
+
"1080p": (1920, 1080),
|
161
|
+
"720p": (1280, 720),
|
162
|
+
"360p": (640, 360),
|
163
|
+
}
|
164
|
+
|
165
|
+
if resolution not in resolution_map:
|
166
|
+
raise ValueError("Invalid video_resolution value. Must be one of: 4k, 1080p, 720p, 360p")
|
167
|
+
|
168
|
+
resolution_dims = resolution_map[resolution]
|
169
|
+
|
170
|
+
# Default font sizes for each resolution
|
171
|
+
default_font_sizes = {
|
172
|
+
"4k": 250,
|
173
|
+
"1080p": 120,
|
174
|
+
"720p": 100,
|
175
|
+
"360p": 40,
|
176
|
+
}
|
177
|
+
|
178
|
+
# Get font size from styles if available, otherwise use default
|
179
|
+
font_size = self.config.styles.get("karaoke", {}).get("font_size", default_font_sizes[resolution])
|
180
|
+
|
181
|
+
# Line height matches font size for all except 360p
|
182
|
+
line_height = 50 if resolution == "360p" else font_size
|
183
|
+
|
184
|
+
return resolution_dims, font_size, line_height
|
168
185
|
|
169
186
|
def write_corrections_data(self, correction_result: CorrectionResult, output_prefix: str) -> str:
|
170
187
|
"""Write corrections data to JSON file."""
|
@@ -9,6 +9,8 @@ import os
|
|
9
9
|
import atexit
|
10
10
|
import urllib.parse
|
11
11
|
from fastapi.staticfiles import StaticFiles
|
12
|
+
from fastapi.responses import FileResponse
|
13
|
+
from pathlib import Path
|
12
14
|
|
13
15
|
logger = logging.getLogger(__name__)
|
14
16
|
|
@@ -27,22 +29,23 @@ app.add_middleware(
|
|
27
29
|
current_review: Optional[CorrectionResult] = None
|
28
30
|
review_completed = False
|
29
31
|
vite_process: Optional[subprocess.Popen] = None
|
32
|
+
audio_filepath: Optional[str] = None # Add this new global variable
|
30
33
|
|
31
34
|
|
32
35
|
def start_vite_server():
|
33
36
|
"""Get path to the built frontend assets."""
|
34
37
|
global vite_process # We'll keep this for backwards compatibility
|
35
|
-
|
38
|
+
|
36
39
|
# Get the path to the built frontend assets
|
37
40
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
38
41
|
frontend_dir = os.path.abspath(os.path.join(current_dir, "../frontend/dist"))
|
39
|
-
|
42
|
+
|
40
43
|
if not os.path.exists(frontend_dir):
|
41
44
|
raise FileNotFoundError(f"Frontend assets not found at {frontend_dir}. Ensure the package was built correctly.")
|
42
|
-
|
45
|
+
|
43
46
|
# Mount the static files
|
44
47
|
app.mount("/", StaticFiles(directory=frontend_dir, html=True), name="frontend")
|
45
|
-
|
48
|
+
|
46
49
|
logger.info(f"Mounted frontend assets from {frontend_dir}")
|
47
50
|
return None # No process to return since we're serving static files
|
48
51
|
|
@@ -86,6 +89,20 @@ async def complete_review(updated_data: Dict[str, Any] = Body(...)):
|
|
86
89
|
return {"status": "error", "message": str(e)}
|
87
90
|
|
88
91
|
|
92
|
+
@app.get("/api/audio")
|
93
|
+
async def get_audio():
|
94
|
+
"""Stream the audio file for playback in the browser."""
|
95
|
+
if not audio_filepath or not os.path.exists(audio_filepath):
|
96
|
+
logger.error(f"Audio file not found at {audio_filepath}")
|
97
|
+
return {"error": "Audio file not found"}
|
98
|
+
|
99
|
+
return FileResponse(
|
100
|
+
audio_filepath,
|
101
|
+
media_type="audio/mpeg",
|
102
|
+
headers={"Accept-Ranges": "bytes", "Content-Disposition": f"attachment; filename={Path(audio_filepath).name}"},
|
103
|
+
)
|
104
|
+
|
105
|
+
|
89
106
|
def start_review_server(correction_result: CorrectionResult) -> CorrectionResult:
|
90
107
|
"""
|
91
108
|
Start the review server and wait for completion.
|
@@ -99,35 +116,44 @@ def start_review_server(correction_result: CorrectionResult) -> CorrectionResult
|
|
99
116
|
import uvicorn
|
100
117
|
import webbrowser
|
101
118
|
from threading import Thread
|
119
|
+
import signal
|
120
|
+
import sys
|
102
121
|
|
103
|
-
global current_review, review_completed
|
122
|
+
global current_review, review_completed, audio_filepath # Add audio_filepath to globals
|
104
123
|
current_review = correction_result
|
105
124
|
review_completed = False
|
106
125
|
|
126
|
+
# Get the audio filepath from the correction result's metadata if available
|
127
|
+
audio_filepath = correction_result.metadata.get("audio_filepath") if correction_result.metadata else None
|
128
|
+
|
107
129
|
logger.info("Starting review server...")
|
108
130
|
|
109
131
|
# Start Vite dev server (now just mounts static files)
|
110
132
|
start_vite_server()
|
111
133
|
logger.info("Frontend assets mounted")
|
112
134
|
|
135
|
+
# Create a custom server config
|
136
|
+
config = uvicorn.Config(app, host="127.0.0.1", port=8000, log_level="info")
|
137
|
+
server = uvicorn.Server(config)
|
138
|
+
|
113
139
|
# Start FastAPI server in a separate thread
|
114
|
-
server_thread = Thread(target=
|
140
|
+
server_thread = Thread(target=server.run, daemon=True)
|
115
141
|
server_thread.start()
|
116
142
|
logger.info("Server thread started")
|
117
143
|
|
118
|
-
# Open browser
|
144
|
+
# Open browser - Updated to use port 8000 instead of 5173
|
119
145
|
base_api_url = "http://localhost:8000/api"
|
120
146
|
encoded_api_url = urllib.parse.quote(base_api_url, safe="")
|
121
|
-
webbrowser.open(f"http://localhost:
|
147
|
+
webbrowser.open(f"http://localhost:8000?baseApiUrl={encoded_api_url}")
|
122
148
|
logger.info("Opened browser for review")
|
123
149
|
|
124
150
|
# Wait for review to complete
|
125
151
|
start_time = time.time()
|
126
152
|
while not review_completed:
|
127
153
|
time.sleep(0.1)
|
128
|
-
# if time.time() - start_time > 600: # 10 minute timeout
|
129
|
-
# logger.error("Review timed out after 10 minutes")
|
130
|
-
# raise TimeoutError("Review did not complete within the expected time frame.")
|
131
154
|
|
132
|
-
logger.info("Review completed,
|
155
|
+
logger.info("Review completed, shutting down server...")
|
156
|
+
server.should_exit = True
|
157
|
+
server_thread.join(timeout=5) # Wait up to 5 seconds for server to shut down
|
158
|
+
|
133
159
|
return current_review
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: lyrics-transcriber
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.35.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
|
License: MIT
|
6
6
|
Author: Andrew Beveridge
|
@@ -3,9 +3,9 @@ lyrics_transcriber/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
3
3
|
lyrics_transcriber/cli/cli_main.py,sha256=TFB7CwzgLuwPfoV7ggPPe5dh4WKNcWRoZkCu_WWUcLQ,9818
|
4
4
|
lyrics_transcriber/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
lyrics_transcriber/core/config.py,sha256=y6MsAL0gFz7zRErtRRF81Z0vFOrySIrCw2aKDHExBz8,1160
|
6
|
-
lyrics_transcriber/core/controller.py,sha256=
|
6
|
+
lyrics_transcriber/core/controller.py,sha256=iLDbMcn1BD1bTBiT9JDTBlLXs-2Frex-I_CKig3gdqk,17844
|
7
7
|
lyrics_transcriber/correction/anchor_sequence.py,sha256=YpKyY24Va5i4JgzP9ssqlOIkaYu060KaldiehbfgTdk,22200
|
8
|
-
lyrics_transcriber/correction/corrector.py,sha256=
|
8
|
+
lyrics_transcriber/correction/corrector.py,sha256=RVANu99cX-fmgr70C5aKZKjNOnu8o8NyJVqQ1wRGUqo,13342
|
9
9
|
lyrics_transcriber/correction/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
lyrics_transcriber/correction/handlers/base.py,sha256=Vanmp6ykP5cdejuJ5ttzjP0Wl4JgKBL-mHbo9EFaeVc,1009
|
11
11
|
lyrics_transcriber/correction/handlers/extend_anchor.py,sha256=9rBrZPmc4grMSnCL2ilkcBsWHc05s6RBL9GDyNAplJk,3821
|
@@ -21,38 +21,51 @@ lyrics_transcriber/correction/phrase_analyzer.py,sha256=dtO_2LjxnPdHJM7De40mYIdH
|
|
21
21
|
lyrics_transcriber/correction/text_utils.py,sha256=VkOqgZHa9wEqLJdVNi4-KLFojQ6d4lWOGl_Y_vknenU,808
|
22
22
|
lyrics_transcriber/frontend/.gitignore,sha256=lgGIPiVpFVUNSZl9oNQLelLOWUzpF7sikLW8xmsrrqI,248
|
23
23
|
lyrics_transcriber/frontend/README.md,sha256=-D6CAfKTT7Y0V3EjlZ2fMy7fyctFQ4x2TJ9vx6xtccM,1607
|
24
|
-
lyrics_transcriber/frontend/dist/assets/index-
|
25
|
-
lyrics_transcriber/frontend/dist/index.html,sha256=
|
24
|
+
lyrics_transcriber/frontend/dist/assets/index-CQCER5Fo.js,sha256=cNVRhdGBCEh8WhvstqPAV2f1W34hR8qNSzUJ-NvJ0aw,424046
|
25
|
+
lyrics_transcriber/frontend/dist/index.html,sha256=aicpama1D98ChWrPgrngwqBFhH03Mnx33SWB8jacE9I,400
|
26
26
|
lyrics_transcriber/frontend/dist/vite.svg,sha256=SnSK_UQ5GLsWWRyDTEAdrjPoeGGrXbrQgRw6O0qSFPs,1497
|
27
27
|
lyrics_transcriber/frontend/eslint.config.js,sha256=3ADH23ANA4NNBKFy6nCVk65e8bx1DrVd_FIaYNnhuqA,734
|
28
28
|
lyrics_transcriber/frontend/index.html,sha256=KfqJVONzpUyPIwV73nZRiCWlwLnFWeB3z0vzxDPNudU,376
|
29
29
|
lyrics_transcriber/frontend/package-lock.json,sha256=-VEaxgVZhB6rbaxiZPy3_qGsMuVlSYxZZg-K3mvhS4A,149189
|
30
30
|
lyrics_transcriber/frontend/package.json,sha256=7WBOIcjE3T8bg9GpJWziPYyhTe724AFnHJOtJi-XCpY,1006
|
31
31
|
lyrics_transcriber/frontend/public/vite.svg,sha256=SnSK_UQ5GLsWWRyDTEAdrjPoeGGrXbrQgRw6O0qSFPs,1497
|
32
|
-
lyrics_transcriber/frontend/src/App.tsx,sha256=
|
33
|
-
lyrics_transcriber/frontend/src/api.ts,sha256=
|
34
|
-
lyrics_transcriber/frontend/src/components/
|
35
|
-
lyrics_transcriber/frontend/src/components/
|
36
|
-
lyrics_transcriber/frontend/src/components/DetailsModal.tsx,sha256=
|
32
|
+
lyrics_transcriber/frontend/src/App.tsx,sha256=yUsB9SZvOar0PKBMzmgfbJHv6fJW2mXdBExUZYgSaWY,6035
|
33
|
+
lyrics_transcriber/frontend/src/api.ts,sha256=ORzQqlEKkFYrc78qFbOCNsSP6zW_vN2PFT_IiEwiiao,2089
|
34
|
+
lyrics_transcriber/frontend/src/components/AudioPlayer.tsx,sha256=v_UBNwIBoll20z7-_yItibIhucpDPaJg6ePZF2Q62d4,4343
|
35
|
+
lyrics_transcriber/frontend/src/components/CorrectionMetrics.tsx,sha256=Bp8h_x7dOq9lo2lDwj9f6Zf_lE04b6L2169YPUCKup0,5342
|
36
|
+
lyrics_transcriber/frontend/src/components/DetailsModal.tsx,sha256=bQmrsneXiMD7ecEAbV_bD8_ZDQaxyV7KGpP5j999k1I,3917
|
37
|
+
lyrics_transcriber/frontend/src/components/EditModal.tsx,sha256=m15ahAgWfLqz2q9qyAiFQfNCv3bNH1d2dZbPNE9sJWE,14941
|
37
38
|
lyrics_transcriber/frontend/src/components/FileUpload.tsx,sha256=Q_Y2YvlVGJvucdoDBbbI2pzymycWAprrc7vtSEGuIHs,2375
|
38
|
-
lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx,sha256=
|
39
|
-
lyrics_transcriber/frontend/src/components/
|
40
|
-
lyrics_transcriber/frontend/src/components/
|
41
|
-
lyrics_transcriber/frontend/src/components/
|
42
|
-
lyrics_transcriber/frontend/src/components/
|
39
|
+
lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx,sha256=mXZhfK5Us7HLv0jspT9Z5l9P0L2EfyPf3kAN0VmVxus,19173
|
40
|
+
lyrics_transcriber/frontend/src/components/ModeSelector.tsx,sha256=bHtjmj5DQx2CwkdL5A4fgLP3XEifu-QecPsMZVdMTmU,1422
|
41
|
+
lyrics_transcriber/frontend/src/components/ReferenceView.tsx,sha256=VgeGhDlcO1bqKSU8gBH_d3MBO2_Z50J_kh7iG8QACoM,1941
|
42
|
+
lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx,sha256=LokjuN0ukt6ao_ClWX3PCeQlV19V2hvEAWF0SPHzG3M,8974
|
43
|
+
lyrics_transcriber/frontend/src/components/SegmentDetailsModal.tsx,sha256=6ME02FkFwCgDAxW49yW260N4vbr80eAJ332Ex811GOo,1643
|
44
|
+
lyrics_transcriber/frontend/src/components/TimelineEditor.tsx,sha256=FABlfssDFKubdFmeEAv4VbvxnxugdlG8jswAUXOqfRQ,11025
|
45
|
+
lyrics_transcriber/frontend/src/components/TranscriptionView.tsx,sha256=Zw909OCLJbUCpEOD5N2ts0nLz1oC9nXJhizdGmw8qHk,5486
|
46
|
+
lyrics_transcriber/frontend/src/components/WordEditControls.tsx,sha256=5mMztxoYhHwn6cUhLBcBis7fA21h03tlt-U3-9yytO0,3369
|
47
|
+
lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx,sha256=hqdJI5zL2JuJgHSQ1IsrDwR_4oZQU4TIGR7PXkGTDKk,10713
|
48
|
+
lyrics_transcriber/frontend/src/components/shared/components/SourceSelector.tsx,sha256=f4PZ-XEhGvp4rZAaST_AhkZRDlVkWipYtM0_2ZhSN3c,842
|
49
|
+
lyrics_transcriber/frontend/src/components/shared/components/Word.tsx,sha256=xed50sPTI4edKp5fwz9vLyBqTNOU4MbhTe-NEApS3JI,1324
|
50
|
+
lyrics_transcriber/frontend/src/components/shared/constants.ts,sha256=25q1qjCwzV-hR72wSb_rJSe4dVuQ0l-piLMoZSpynGQ,488
|
51
|
+
lyrics_transcriber/frontend/src/components/shared/hooks/useWordClick.ts,sha256=pgaAC_rhzGS1ppXzmcQ9IH9PSZPcQo1lJJqOJ9OqWjM,5447
|
52
|
+
lyrics_transcriber/frontend/src/components/shared/styles.ts,sha256=J1jCSuRqpk1mOFYAqJudhxeozH-q1bi-dsOibLukBJU,411
|
53
|
+
lyrics_transcriber/frontend/src/components/shared/types.ts,sha256=AeNIhKUZu9sHhOClDUaBgo1myixLjpkikbuky29UCw4,2928
|
54
|
+
lyrics_transcriber/frontend/src/components/shared/utils/newlineCalculator.ts,sha256=vhOP-VS7H_NIK3JSpN_yPjy6qcJqZoA6eDWopOCWB2c,1530
|
55
|
+
lyrics_transcriber/frontend/src/components/shared/utils/referenceLineCalculator.ts,sha256=vzXdLDlQ1hKWfco1RB6aLztbjBg1BXL6gend34qXKd4,2753
|
43
56
|
lyrics_transcriber/frontend/src/main.tsx,sha256=gKJOIr1laz68BhgxWz0JXb1LNacA2oxfbypxW_B1USo,139
|
44
|
-
lyrics_transcriber/frontend/src/types.ts,sha256=
|
57
|
+
lyrics_transcriber/frontend/src/types.ts,sha256=yv4A8AamI9VPXGqNi7rH6vdUZdDiUhTJsO2016e4u8s,2840
|
45
58
|
lyrics_transcriber/frontend/src/vite-env.d.ts,sha256=ZZlpNvuwQpFfe3SiAPzd5-QQ8ypmmxq5WXz6pLD63bU,38
|
46
59
|
lyrics_transcriber/frontend/tsconfig.app.json,sha256=7aUBVcaBqEtmtfQXsbwsgBxSUng06xzQi5t4QCgWQ3E,665
|
47
60
|
lyrics_transcriber/frontend/tsconfig.json,sha256=AOS5v1AsNPL3wGc8bt58Ybh8HHpbYrlK91q0KIzaSgs,627
|
48
61
|
lyrics_transcriber/frontend/tsconfig.node.json,sha256=oMBhK5xufBrVE7SkbADRxA3pxm8_L9m5YwtCOZSafsc,536
|
49
|
-
lyrics_transcriber/frontend/tsconfig.tsbuildinfo,sha256=
|
62
|
+
lyrics_transcriber/frontend/tsconfig.tsbuildinfo,sha256=NR-Uu3EJ34W4mGOQJT-Vkp_XHVwJxSxh6kIPWCAdH4w,1038
|
50
63
|
lyrics_transcriber/frontend/vite.config.d.ts,sha256=S5bdGf0pSdKM6A6RNBKwAm3EIeW_bDHYfHtesRtXU7Q,76
|
51
64
|
lyrics_transcriber/frontend/vite.config.js,sha256=rJsgKgeHdZ3lUbab4NaNcxVsiUmmtTQee4iPweN5Ktc,165
|
52
65
|
lyrics_transcriber/frontend/vite.config.ts,sha256=TTbbNSKnst0Q4JNuEAQ3PH7mXxD3zXkgzXZBBFnBWkU,161
|
53
66
|
lyrics_transcriber/lyrics/base_lyrics_provider.py,sha256=l61XJCvazt7wb6_vIQ23N8x9Otane8Pac5nvnBVCig8,6563
|
54
67
|
lyrics_transcriber/lyrics/genius.py,sha256=x8dNOygrDRZgwK0v2qK6F6wmqGEIiXe_Edgx-IkNWHA,5003
|
55
|
-
lyrics_transcriber/lyrics/spotify.py,sha256=
|
68
|
+
lyrics_transcriber/lyrics/spotify.py,sha256=8Abxc7B_1eGPOCHDJ-zVAdhWRvz0nls9LipD7L4fhV8,4004
|
56
69
|
lyrics_transcriber/output/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
57
70
|
lyrics_transcriber/output/ass/__init__.py,sha256=EYQ45gI7_-vclVgzISL0ML8VgxCdB0odqEyPyiPCIw0,578
|
58
71
|
lyrics_transcriber/output/ass/ass.py,sha256=xHId7Rv5gqmdQ7ZrWQSy46JX7vZcB_BzpZC800DwQk8,74315
|
@@ -96,22 +109,22 @@ lyrics_transcriber/output/fonts/Zurich_Cn_BT_Bold.ttf,sha256=WNG5LOQ-uGUF_WWT5aQ
|
|
96
109
|
lyrics_transcriber/output/fonts/arial.ttf,sha256=NcDzVZ2NtWnjbDEJW4pg1EFkPZX1kTneQOI_ragZuDM,275572
|
97
110
|
lyrics_transcriber/output/fonts/georgia.ttf,sha256=fQuyDGMrtZ6BoIhfVzvSFz9x9zIE3pBY_raM4DIicHI,142964
|
98
111
|
lyrics_transcriber/output/fonts/verdana.ttf,sha256=lu0UlJyktzks_yNbnEHVXBJTgqu-DA08K53WaJfK4Ms,139640
|
99
|
-
lyrics_transcriber/output/generator.py,sha256=
|
112
|
+
lyrics_transcriber/output/generator.py,sha256=TzgYjppsGKev5Fg-q7JtjTAiTkuKOBE8Ssaf6ZoAwQA,8294
|
100
113
|
lyrics_transcriber/output/lyrics_file.py,sha256=_KQyQjCOMIwQdQ0115uEAUIjQWTRmShkSfQuINPKxaw,3741
|
101
114
|
lyrics_transcriber/output/plain_text.py,sha256=3mYKq0BLYz1rGBD6ROjG2dn6BPuzbn5dxIQbWZVi4ao,3689
|
102
115
|
lyrics_transcriber/output/segment_resizer.py,sha256=b553FCdcjYAl9T1IA5K6ya0pcn1-irD5spmxSc26wnI,17143
|
103
116
|
lyrics_transcriber/output/subtitles.py,sha256=BQy7N_2zdBBWEiHL0NWFz3ZgAerWqQvTLALgxxK3Etk,16920
|
104
117
|
lyrics_transcriber/output/video.py,sha256=kYGeEMYtoJvrGnMuyNpuSmu2DTskGDXBNlrv6ddvC8I,8485
|
105
118
|
lyrics_transcriber/review/__init__.py,sha256=_3Eqw-uXZhOZwo6_sHZLhP9vxAVkLF9EBXduUvPdLjQ,57
|
106
|
-
lyrics_transcriber/review/server.py,sha256=
|
119
|
+
lyrics_transcriber/review/server.py,sha256=0WVcB5FaQWi8DeX-QgHZM-3ZIVr4LHiYNysWwKVBGw8,5494
|
107
120
|
lyrics_transcriber/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
108
121
|
lyrics_transcriber/storage/dropbox.py,sha256=Dyam1ULTkoxD1X5trkZ5dGp5XhBGCn998moC8IS9-68,9804
|
109
122
|
lyrics_transcriber/transcribers/audioshake.py,sha256=QzKGimVa6BovlvYFj35CbGpaGePI_DApAJGEBR_JQLc,8709
|
110
123
|
lyrics_transcriber/transcribers/base_transcriber.py,sha256=yPzUWPTCGmzE97H5Rz6g61e-qEGL77ZzUoiBOmswhts,5973
|
111
124
|
lyrics_transcriber/transcribers/whisper.py,sha256=P0kas2_oX16MO1-Qy7U5gl5KQN-RuUIJZz7LsEFLUiE,12906
|
112
125
|
lyrics_transcriber/types.py,sha256=xGf3hkTRcGZTTAjMVIev2i2DOU6co0QGpW8NxvaBQAA,16759
|
113
|
-
lyrics_transcriber-0.
|
114
|
-
lyrics_transcriber-0.
|
115
|
-
lyrics_transcriber-0.
|
116
|
-
lyrics_transcriber-0.
|
117
|
-
lyrics_transcriber-0.
|
126
|
+
lyrics_transcriber-0.35.0.dist-info/LICENSE,sha256=BiPihPDxhxIPEx6yAxVfAljD5Bhm_XG2teCbPEj_m0Y,1069
|
127
|
+
lyrics_transcriber-0.35.0.dist-info/METADATA,sha256=I23-5rG95JB0m7Ew5hLebDRGZGhkw71q0dXNeXMQ_AE,5856
|
128
|
+
lyrics_transcriber-0.35.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
129
|
+
lyrics_transcriber-0.35.0.dist-info/entry_points.txt,sha256=ChnmR13YoalGnC3sHW0TppX5FbhEXntYIha24tVQJ1M,104
|
130
|
+
lyrics_transcriber-0.35.0.dist-info/RECORD,,
|