Skip to content

Commit d7edd42

Browse files
committed
coderabbit bits
1 parent 1f1fb45 commit d7edd42

File tree

14 files changed

+137
-314
lines changed

14 files changed

+137
-314
lines changed

.claude/settings.local.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@
5252
"Bash(RUST_LOG=info,cap_recording=debug ./target/release/examples/memory-leak-detector:*)",
5353
"Bash(git rm:*)",
5454
"Bash(./target/release/examples/decode-benchmark:*)",
55-
"Bash(RUST_LOG=warn ./target/release/examples/decode-benchmark:*)"
55+
"Bash(RUST_LOG=warn ./target/release/examples/decode-benchmark:*)",
56+
"Bash(git mv:*)",
57+
"Bash(xargs cat:*)"
5658
],
5759
"deny": [],
5860
"ask": []

apps/desktop/src-tauri/src/lib.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3225,15 +3225,15 @@ async fn wait_for_recording_ready(app: &AppHandle, path: &Path) -> Result<(), St
32253225
}
32263226
};
32273227

3228-
if let Some(studio_meta) = meta.studio_meta() {
3229-
if recording::needs_fragment_remux(path, studio_meta) {
3230-
info!("Recording needs remux (crash recovery), starting remux...");
3231-
let path = path.to_path_buf();
3232-
tokio::task::spawn_blocking(move || recording::remux_fragmented_recording(&path))
3233-
.await
3234-
.map_err(|e| format!("Remux task panicked: {e}"))??;
3235-
info!("Crash recovery remux completed");
3236-
}
3228+
if let Some(studio_meta) = meta.studio_meta()
3229+
&& recording::needs_fragment_remux(path, studio_meta)
3230+
{
3231+
info!("Recording needs remux (crash recovery), starting remux...");
3232+
let path = path.to_path_buf();
3233+
tokio::task::spawn_blocking(move || recording::remux_fragmented_recording(&path))
3234+
.await
3235+
.map_err(|e| format!("Remux task panicked: {e}"))??;
3236+
info!("Crash recovery remux completed");
32373237
}
32383238

32393239
Ok(())

apps/desktop/src/routes/editor/Editor.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
createSignal,
1515
Match,
1616
on,
17+
onCleanup,
1718
Show,
1819
Switch,
1920
} from "solid-js";
@@ -428,21 +429,29 @@ function Dialogs() {
428429
const [crop, setCrop] = createSignal(CROP_ZERO);
429430
const [aspect, setAspect] = createSignal<Ratio | null>(null);
430431

431-
const [frameDataUrl, setFrameDataUrl] = createSignal<
432+
const [frameBlobUrl, setFrameBlobUrl] = createSignal<
432433
string | null
433434
>(null);
434435

435436
const playerCanvas = document.getElementById(
436437
"canvas",
437438
) as HTMLCanvasElement | null;
438439
if (playerCanvas) {
439-
try {
440-
setFrameDataUrl(playerCanvas.toDataURL("image/png"));
441-
} catch {
442-
setFrameDataUrl(null);
443-
}
440+
playerCanvas.toBlob((blob) => {
441+
if (blob) {
442+
const url = URL.createObjectURL(blob);
443+
setFrameBlobUrl(url);
444+
}
445+
}, "image/png");
444446
}
445447

448+
onCleanup(() => {
449+
const url = frameBlobUrl();
450+
if (url) {
451+
URL.revokeObjectURL(url);
452+
}
453+
});
454+
446455
const initialBounds = {
447456
x: dialog().position.x,
448457
y: dialog().position.y,
@@ -607,7 +616,7 @@ function Dialogs() {
607616
class="shadow pointer-events-none max-h-[70vh]"
608617
alt="Current frame"
609618
src={
610-
frameDataUrl() ??
619+
frameBlobUrl() ??
611620
convertFileSrc(
612621
`${editorInstance.path}/screenshots/display.jpg`,
613622
)

apps/desktop/src/routes/editor/ExportPage.tsx

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ export const COMPRESSION_OPTIONS: Array<{
5656
{ label: "Potato", value: "Potato", bpp: 0.04 },
5757
];
5858

59-
const BPP_TO_COMPRESSION: Record<number, ExportCompression> = {
60-
0.3: "Minimal",
61-
0.15: "Social",
62-
0.08: "Web",
63-
0.04: "Potato",
59+
const BPP_TO_COMPRESSION: Record<string, ExportCompression> = {
60+
"0.3": "Minimal",
61+
"0.15": "Social",
62+
"0.08": "Web",
63+
"0.04": "Potato",
6464
};
6565

6666
const COMPRESSION_TO_BPP: Record<ExportCompression, number> = {
@@ -286,10 +286,10 @@ export function ExportPage() {
286286
createEffect(
287287
on(
288288
[
289-
() => _settings.format,
290-
() => _settings.fps,
291-
() => _settings.resolution.width,
292-
() => _settings.resolution.height,
289+
() => settings.format,
290+
() => settings.fps,
291+
() => settings.resolution.width,
292+
() => settings.resolution.height,
293293
compressionBpp,
294294
],
295295
() => {
@@ -918,11 +918,7 @@ export function ExportPage() {
918918
<div class="flex gap-2">
919919
<For
920920
each={
921-
settings.format === "Gif"
922-
? GIF_FPS_OPTIONS.filter((o) =>
923-
[10, 15, 20, 30].includes(o.value),
924-
)
925-
: FPS_OPTIONS
921+
settings.format === "Gif" ? GIF_FPS_OPTIONS : FPS_OPTIONS
926922
}
927923
>
928924
{(option) => (
@@ -1301,35 +1297,39 @@ export function ExportPage() {
13011297
exportState.type === "done"
13021298
}
13031299
>
1304-
<div class="relative">
1305-
<a
1306-
href={meta().sharing?.link}
1307-
target="_blank"
1308-
rel="noreferrer"
1309-
class="block"
1310-
>
1311-
<Button
1312-
onClick={() => {
1313-
setCopyPressed(true);
1314-
setTimeout(() => {
1315-
setCopyPressed(false);
1316-
}, 2000);
1317-
navigator.clipboard.writeText(
1318-
meta().sharing?.link!,
1319-
);
1320-
}}
1321-
variant="dark"
1322-
class="flex gap-2 justify-center items-center"
1323-
>
1324-
{!copyPressed() ? (
1325-
<IconCapCopy class="transition-colors duration-200 text-gray-1 size-4 group-hover:text-gray-12" />
1326-
) : (
1327-
<IconLucideCheck class="transition-colors duration-200 text-gray-1 size-4 svgpathanimation group-hover:text-gray-12" />
1328-
)}
1329-
<p>Open Link</p>
1330-
</Button>
1331-
</a>
1332-
</div>
1300+
<Show when={meta().sharing?.link}>
1301+
{(link) => (
1302+
<div class="flex gap-2">
1303+
<Button
1304+
onClick={() => {
1305+
setCopyPressed(true);
1306+
setTimeout(() => {
1307+
setCopyPressed(false);
1308+
}, 2000);
1309+
navigator.clipboard.writeText(link());
1310+
}}
1311+
variant="dark"
1312+
class="flex gap-2 justify-center items-center"
1313+
>
1314+
{!copyPressed() ? (
1315+
<IconCapCopy class="transition-colors duration-200 text-gray-1 size-4 group-hover:text-gray-12" />
1316+
) : (
1317+
<IconLucideCheck class="transition-colors duration-200 text-gray-1 size-4 svgpathanimation group-hover:text-gray-12" />
1318+
)}
1319+
<p>Copy Link</p>
1320+
</Button>
1321+
<a href={link()} target="_blank" rel="noreferrer">
1322+
<Button
1323+
variant="dark"
1324+
class="flex gap-2 justify-center items-center"
1325+
>
1326+
<IconCapLink class="transition-colors duration-200 text-gray-1 size-4 group-hover:text-gray-12" />
1327+
<p>Open Link</p>
1328+
</Button>
1329+
</a>
1330+
</div>
1331+
)}
1332+
</Show>
13331333
</Show>
13341334

13351335
<Show
File renamed without changes.

apps/desktop/src/routes/editor/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { createEffect, Suspense } from "solid-js";
55
import { generalSettingsStore } from "~/store";
66
import { commands } from "~/utils/tauri";
77
import { Editor } from "./Editor";
8-
import { EditorSkeleton } from "./EditorSkeleton";
8+
import { EditorSkeleton } from "./editor-skeleton";
99

1010
export default function () {
1111
const generalSettings = generalSettingsStore.createQuery();

crates/editor/examples/decode-benchmark.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,12 @@ impl BenchmarkResults {
124124
let min = self
125125
.random_access_times_ms
126126
.iter()
127-
.cloned()
127+
.copied()
128128
.fold(f64::INFINITY, f64::min);
129129
let max = self
130130
.random_access_times_ms
131131
.iter()
132-
.cloned()
132+
.copied()
133133
.fold(f64::NEG_INFINITY, f64::max);
134134
println!(" Samples: {}", self.random_access_times_ms.len());
135135
if self.random_access_failures > 0 {

crates/editor/src/playback.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,12 @@ impl Playback {
631631

632632
frame_number = frame_number.saturating_add(1);
633633
let _ = playback_position_tx.send(frame_number);
634-
let _ = audio_playhead_tx.send(frame_number as f64 / fps_f64);
634+
if audio_playhead_tx
635+
.send(frame_number as f64 / fps_f64)
636+
.is_err()
637+
{
638+
break 'playback;
639+
}
635640

636641
let expected_frame = self.start_frame_number
637642
+ (start.elapsed().as_secs_f64() * fps_f64).floor() as u32;
@@ -651,7 +656,12 @@ impl Playback {
651656
prefetch_buffer.retain(|p| p.frame_number >= frame_number);
652657
let _ = frame_request_tx.send(frame_number);
653658
let _ = playback_position_tx.send(frame_number);
654-
let _ = audio_playhead_tx.send(frame_number as f64 / fps_f64);
659+
if audio_playhead_tx
660+
.send(frame_number as f64 / fps_f64)
661+
.is_err()
662+
{
663+
break 'playback;
664+
}
655665
}
656666
}
657667
}

crates/recording/src/output_pipeline/core.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -553,12 +553,13 @@ fn spawn_video_encoder<TMutex: VideoMuxer<VideoFrame = TVideo::Frame>, TVideo: V
553553
let mut drained = 0u64;
554554
let mut skipped = 0u64;
555555

556+
let mut hit_limit = false;
556557
while let Some(frame) = video_rx.next().await {
557558
frame_count += 1;
558559

559560
if drain_start.elapsed() > drain_timeout || drained >= max_drain_frames {
560-
skipped += 1;
561-
continue;
561+
hit_limit = true;
562+
break;
562563
}
563564

564565
drained += 1;
@@ -581,11 +582,13 @@ fn spawn_video_encoder<TMutex: VideoMuxer<VideoFrame = TVideo::Frame>, TVideo: V
581582
}
582583
}
583584
}
584-
if drained > 0 || skipped > 0 {
585+
586+
if drained > 0 || skipped > 0 || hit_limit {
585587
info!(
586-
"mux-video drain complete: {} frames processed, {} skipped in {:?}",
588+
"mux-video drain complete: {} frames processed, {} errors (limit hit: {}) in {:?}",
587589
drained,
588590
skipped,
591+
hit_limit,
589592
drain_start.elapsed()
590593
);
591594
}

0 commit comments

Comments
 (0)