karaoke-gen 0.75.16__py3-none-any.whl → 0.76.20__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.
Files changed (47) hide show
  1. karaoke_gen/audio_fetcher.py +984 -33
  2. karaoke_gen/audio_processor.py +4 -0
  3. karaoke_gen/instrumental_review/static/index.html +37 -14
  4. karaoke_gen/karaoke_finalise/karaoke_finalise.py +25 -1
  5. karaoke_gen/karaoke_gen.py +208 -39
  6. karaoke_gen/lyrics_processor.py +111 -31
  7. karaoke_gen/utils/__init__.py +26 -0
  8. karaoke_gen/utils/cli_args.py +15 -6
  9. karaoke_gen/utils/gen_cli.py +30 -5
  10. karaoke_gen/utils/remote_cli.py +301 -20
  11. {karaoke_gen-0.75.16.dist-info → karaoke_gen-0.76.20.dist-info}/METADATA +107 -5
  12. {karaoke_gen-0.75.16.dist-info → karaoke_gen-0.76.20.dist-info}/RECORD +47 -43
  13. lyrics_transcriber/core/controller.py +76 -2
  14. lyrics_transcriber/frontend/index.html +5 -1
  15. lyrics_transcriber/frontend/package-lock.json +4553 -0
  16. lyrics_transcriber/frontend/package.json +4 -1
  17. lyrics_transcriber/frontend/playwright.config.ts +69 -0
  18. lyrics_transcriber/frontend/public/nomad-karaoke-logo.svg +5 -0
  19. lyrics_transcriber/frontend/src/App.tsx +94 -63
  20. lyrics_transcriber/frontend/src/api.ts +25 -10
  21. lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx +55 -21
  22. lyrics_transcriber/frontend/src/components/AppHeader.tsx +65 -0
  23. lyrics_transcriber/frontend/src/components/CorrectedWordWithActions.tsx +5 -5
  24. lyrics_transcriber/frontend/src/components/DurationTimelineView.tsx +9 -9
  25. lyrics_transcriber/frontend/src/components/EditModal.tsx +1 -1
  26. lyrics_transcriber/frontend/src/components/EditWordList.tsx +1 -1
  27. lyrics_transcriber/frontend/src/components/Header.tsx +34 -48
  28. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx +22 -21
  29. lyrics_transcriber/frontend/src/components/ReferenceView.tsx +1 -1
  30. lyrics_transcriber/frontend/src/components/TranscriptionView.tsx +1 -1
  31. lyrics_transcriber/frontend/src/components/WordDivider.tsx +3 -3
  32. lyrics_transcriber/frontend/src/components/shared/components/Word.tsx +2 -2
  33. lyrics_transcriber/frontend/src/components/shared/constants.ts +15 -5
  34. lyrics_transcriber/frontend/src/main.tsx +1 -7
  35. lyrics_transcriber/frontend/src/theme.ts +337 -135
  36. lyrics_transcriber/frontend/vite.config.ts +5 -0
  37. lyrics_transcriber/frontend/web_assets/assets/{index-COYImAcx.js → index-BECn1o8Q.js} +38 -22
  38. lyrics_transcriber/frontend/web_assets/assets/{index-COYImAcx.js.map → index-BECn1o8Q.js.map} +1 -1
  39. lyrics_transcriber/frontend/web_assets/index.html +1 -1
  40. lyrics_transcriber/frontend/yarn.lock +1005 -1046
  41. lyrics_transcriber/output/countdown_processor.py +39 -0
  42. lyrics_transcriber/review/server.py +1 -1
  43. lyrics_transcriber/transcribers/audioshake.py +96 -7
  44. lyrics_transcriber/types.py +14 -12
  45. {karaoke_gen-0.75.16.dist-info → karaoke_gen-0.76.20.dist-info}/WHEEL +0 -0
  46. {karaoke_gen-0.75.16.dist-info → karaoke_gen-0.76.20.dist-info}/entry_points.txt +0 -0
  47. {karaoke_gen-0.75.16.dist-info → karaoke_gen-0.76.20.dist-info}/licenses/LICENSE +0 -0
@@ -34056,13 +34056,26 @@ function validateCorrectionData(data) {
34056
34056
  return CorrectionDataSchema.parse(data);
34057
34057
  }
34058
34058
  class LiveApiClient {
34059
- constructor(baseUrl) {
34059
+ constructor(baseUrl, reviewToken) {
34060
+ __publicField(this, "reviewToken");
34060
34061
  __publicField(this, "isUpdatingHandlers", false);
34061
34062
  this.baseUrl = baseUrl;
34062
34063
  this.baseUrl = baseUrl.replace(/\/$/, "");
34064
+ this.reviewToken = reviewToken;
34065
+ }
34066
+ /**
34067
+ * Build URL with reviewToken query parameter if available
34068
+ */
34069
+ buildUrl(path) {
34070
+ const url = `${this.baseUrl}${path}`;
34071
+ if (this.reviewToken) {
34072
+ const separator = url.includes("?") ? "&" : "?";
34073
+ return `${url}${separator}review_token=${encodeURIComponent(this.reviewToken)}`;
34074
+ }
34075
+ return url;
34063
34076
  }
34064
34077
  async getCorrectionData() {
34065
- const response = await fetch(`${this.baseUrl}/correction-data`);
34078
+ const response = await fetch(this.buildUrl("/correction-data"));
34066
34079
  if (!response.ok) {
34067
34080
  throw new Error(`API error: ${response.statusText}`);
34068
34081
  }
@@ -34079,7 +34092,7 @@ class LiveApiClient {
34079
34092
  corrections: data.corrections,
34080
34093
  corrected_segments: data.corrected_segments
34081
34094
  };
34082
- const response = await fetch(`${this.baseUrl}/complete`, {
34095
+ const response = await fetch(this.buildUrl("/complete"), {
34083
34096
  method: "POST",
34084
34097
  headers: {
34085
34098
  "Content-Type": "application/json"
@@ -34091,14 +34104,14 @@ class LiveApiClient {
34091
34104
  }
34092
34105
  }
34093
34106
  getAudioUrl(audioHash) {
34094
- return `${this.baseUrl}/audio/${audioHash}`;
34107
+ return this.buildUrl(`/audio/${audioHash}`);
34095
34108
  }
34096
34109
  async generatePreviewVideo(data) {
34097
34110
  const updatePayload = {
34098
34111
  corrections: data.corrections,
34099
34112
  corrected_segments: data.corrected_segments
34100
34113
  };
34101
- const response = await fetch(`${this.baseUrl}/preview-video`, {
34114
+ const response = await fetch(this.buildUrl("/preview-video"), {
34102
34115
  method: "POST",
34103
34116
  headers: {
34104
34117
  "Content-Type": "application/json"
@@ -34114,14 +34127,14 @@ class LiveApiClient {
34114
34127
  return await response.json();
34115
34128
  }
34116
34129
  getPreviewVideoUrl(previewHash) {
34117
- return `${this.baseUrl}/preview-video/${previewHash}`;
34130
+ return this.buildUrl(`/preview-video/${previewHash}`);
34118
34131
  }
34119
34132
  async updateHandlers(enabledHandlers) {
34120
34133
  console.log("API: Starting handler update...");
34121
34134
  this.isUpdatingHandlers = true;
34122
34135
  console.log("API: Set isUpdatingHandlers to", this.isUpdatingHandlers);
34123
34136
  try {
34124
- const response = await fetch(`${this.baseUrl}/handlers`, {
34137
+ const response = await fetch(this.buildUrl("/handlers"), {
34125
34138
  method: "POST",
34126
34139
  headers: {
34127
34140
  "Content-Type": "application/json"
@@ -34147,7 +34160,7 @@ class LiveApiClient {
34147
34160
  source,
34148
34161
  lyrics
34149
34162
  };
34150
- const response = await fetch(`${this.baseUrl}/add-lyrics`, {
34163
+ const response = await fetch(this.buildUrl("/add-lyrics"), {
34151
34164
  method: "POST",
34152
34165
  headers: {
34153
34166
  "Content-Type": "application/json"
@@ -34165,7 +34178,7 @@ class LiveApiClient {
34165
34178
  }
34166
34179
  async submitAnnotations(annotations) {
34167
34180
  for (const annotation of annotations) {
34168
- const response = await fetch(`${this.baseUrl}/v1/annotations`, {
34181
+ const response = await fetch(this.buildUrl("/v1/annotations"), {
34169
34182
  method: "POST",
34170
34183
  headers: {
34171
34184
  "Content-Type": "application/json"
@@ -34178,7 +34191,7 @@ class LiveApiClient {
34178
34191
  }
34179
34192
  }
34180
34193
  async getAnnotationStats() {
34181
- const response = await fetch(`${this.baseUrl}/v1/annotations/stats`);
34194
+ const response = await fetch(this.buildUrl("/v1/annotations/stats"));
34182
34195
  if (!response.ok) {
34183
34196
  throw new Error(`API error: ${response.statusText}`);
34184
34197
  }
@@ -38943,10 +38956,12 @@ const TimelineCanvas = reactExports.memo(function TimelineCanvas2({
38943
38956
  const deltaTime = time - dragStartRef.current.time;
38944
38957
  const updates = [];
38945
38958
  for (const [wordId, originalTimes] of dragOriginalTimesRef.current) {
38959
+ const newStartTime = Math.max(0, originalTimes.start + deltaTime);
38960
+ const newEndTime = Math.max(newStartTime + 0.05, originalTimes.end + deltaTime);
38946
38961
  updates.push({
38947
38962
  wordId,
38948
- newStartTime: Math.max(0, originalTimes.start + deltaTime),
38949
- newEndTime: Math.max(0.05, originalTimes.end + deltaTime)
38963
+ newStartTime,
38964
+ newEndTime
38950
38965
  });
38951
38966
  }
38952
38967
  if (updates.length > 0) {
@@ -39275,7 +39290,7 @@ const LyricsSynchronizer = reactExports.memo(function LyricsSynchronizer2({
39275
39290
  );
39276
39291
  const allWords = reactExports.useMemo(() => getAllWords(workingSegments), [workingSegments]);
39277
39292
  const audioDuration = reactExports.useMemo(() => {
39278
- if (window.getAudioDuration) {
39293
+ if (typeof window.getAudioDuration === "function") {
39279
39294
  const duration2 = window.getAudioDuration();
39280
39295
  return duration2 > 0 ? duration2 : 300;
39281
39296
  }
@@ -39347,7 +39362,7 @@ const LyricsSynchronizer = reactExports.memo(function LyricsSynchronizer2({
39347
39362
  const [isPlaying, setIsPlaying] = reactExports.useState(false);
39348
39363
  reactExports.useEffect(() => {
39349
39364
  const checkPlaying = () => {
39350
- setIsPlaying(window.isAudioPlaying || false);
39365
+ setIsPlaying(typeof window.isAudioPlaying === "boolean" ? window.isAudioPlaying : false);
39351
39366
  };
39352
39367
  checkPlaying();
39353
39368
  const interval = setInterval(checkPlaying, 100);
@@ -39359,7 +39374,7 @@ const LyricsSynchronizer = reactExports.memo(function LyricsSynchronizer2({
39359
39374
  }
39360
39375
  }, [onPlaySegment]);
39361
39376
  const handleStopAudio = reactExports.useCallback(() => {
39362
- if (window.toggleAudioPlayback && window.isAudioPlaying) {
39377
+ if (typeof window.toggleAudioPlayback === "function" && window.isAudioPlaying) {
39363
39378
  window.toggleAudioPlayback();
39364
39379
  }
39365
39380
  if (isManualSyncing) {
@@ -39616,7 +39631,7 @@ const LyricsSynchronizer = reactExports.memo(function LyricsSynchronizer2({
39616
39631
  if (onPlaySegment) {
39617
39632
  onPlaySegment(time);
39618
39633
  setTimeout(() => {
39619
- if (window.toggleAudioPlayback && window.isAudioPlaying) {
39634
+ if (typeof window.toggleAudioPlayback === "function" && window.isAudioPlaying) {
39620
39635
  window.toggleAudioPlayback();
39621
39636
  }
39622
39637
  }, 50);
@@ -42923,22 +42938,23 @@ function App() {
42923
42938
  const params = new URLSearchParams(window.location.search);
42924
42939
  const encodedApiUrl = params.get("baseApiUrl");
42925
42940
  const audioHashParam = params.get("audioHash");
42941
+ const reviewTokenParam = params.get("reviewToken");
42926
42942
  if (encodedApiUrl) {
42927
42943
  const baseApiUrl = decodeURIComponent(encodedApiUrl);
42928
- setApiClient(new LiveApiClient(baseApiUrl));
42944
+ setApiClient(new LiveApiClient(baseApiUrl, reviewTokenParam || void 0));
42929
42945
  setIsReadOnly(false);
42930
42946
  if (audioHashParam) {
42931
42947
  setAudioHash(audioHashParam);
42932
42948
  }
42933
- fetchData(baseApiUrl);
42949
+ fetchData(baseApiUrl, reviewTokenParam || void 0);
42934
42950
  } else {
42935
42951
  setApiClient(new FileOnlyClient());
42936
42952
  setIsReadOnly(true);
42937
42953
  }
42938
42954
  }, []);
42939
- const fetchData = async (baseUrl) => {
42955
+ const fetchData = async (baseUrl, reviewToken) => {
42940
42956
  try {
42941
- const client2 = new LiveApiClient(baseUrl);
42957
+ const client2 = new LiveApiClient(baseUrl, reviewToken);
42942
42958
  const data2 = await client2.getCorrectionData();
42943
42959
  setData(data2);
42944
42960
  } catch (err) {
@@ -43258,7 +43274,7 @@ const theme = createTheme({
43258
43274
  spacing: (factor) => `${0.6 * factor}rem`
43259
43275
  // Further reduced from 0.8 * factor
43260
43276
  });
43261
- const version = "0.82.0";
43277
+ const version = "0.83.0";
43262
43278
  const packageJson = {
43263
43279
  version
43264
43280
  };
@@ -43269,4 +43285,4 @@ ReactDOM$1.createRoot(document.getElementById("root")).render(
43269
43285
  /* @__PURE__ */ jsxRuntimeExports.jsx(App, {})
43270
43286
  ] })
43271
43287
  );
43272
- //# sourceMappingURL=index-COYImAcx.js.map
43288
+ //# sourceMappingURL=index-BECn1o8Q.js.map