Skip to content

Commit 5a3fbbc

Browse files
Merge pull request #1441 from CapSoftware/fragmented-mp4
feat: Add fragmented mp4 (.fMP4) for Studio Mode
2 parents cea939a + 36ee402 commit 5a3fbbc

File tree

51 files changed

+3533
-288
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+3533
-288
lines changed

.claude/settings.local.json

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,30 @@
77
"Bash(cargo check:*)",
88
"Bash(cargo fmt:*)",
99
"Bash(pnpm format:*)",
10-
"Bash(pnpm exec biome check:*)"
10+
"Bash(pnpm exec biome check:*)",
11+
"Bash(grep:*)",
12+
"Bash(cargo metadata:*)",
13+
"Bash(ffprobe:*)",
14+
"Bash(ls:*)",
15+
"Bash(find:*)",
16+
"Bash(cat:*)",
17+
"WebFetch(domain:raw.githubusercontent.com)",
18+
"WebFetch(domain:api.github.com)",
19+
"Bash(cargo doc:*)",
20+
"Bash(cargo clippy:*)",
21+
"Bash(python3:*)",
22+
"Bash(cargo run:*)",
23+
"WebSearch",
24+
"Bash(xargs ls:*)",
25+
"WebFetch(domain:ffmpeg.org)",
26+
"Bash(git log:*)",
27+
"Bash(tree:*)",
28+
"Bash(tail:*)",
29+
"Bash(pnpm typecheck:desktop:*)",
30+
"Bash(pnpm exec tsc:*)",
31+
"Bash(pnpm biome check:*)",
32+
"Bash(pnpm --dir apps/desktop exec tsc:*)",
33+
"Bash(xxd:*)"
1134
],
1235
"deny": [],
1336
"ask": []

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ specta = { version = "=2.0.0-rc.20", features = [
3030
"chrono"
3131
] }
3232
serde = { version = "1", features = ["derive"] }
33+
serde_json = "1"
3334

3435
nokhwa = { git = "https://github.com/CapSoftware/nokhwa", rev = "b9c8079e82e2", features = [
3536
"input-native",

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ fn start_whisperx_server(
10101010
std::thread::spawn(move || {
10111011
use std::io::BufRead;
10121012
let reader = std::io::BufReader::new(stderr);
1013-
for line in reader.lines().flatten() {
1013+
for line in reader.lines().map_while(Result::ok) {
10141014
if let Some(stripped) = line.strip_prefix("STDERR:") {
10151015
log::info!("[WhisperX] {}", stripped);
10161016
} else {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ pub struct GeneralSettingsStore {
124124
pub instant_mode_max_resolution: u32,
125125
#[serde(default)]
126126
pub default_project_name_template: Option<String>,
127+
#[serde(default)]
128+
pub crash_recovery_recording: bool,
127129
}
128130

129131
fn default_enable_native_camera_preview() -> bool {
@@ -190,6 +192,7 @@ impl Default for GeneralSettingsStore {
190192
delete_instant_recordings_after_upload: false,
191193
instant_mode_max_resolution: 1920,
192194
default_project_name_template: None,
195+
crash_recovery_recording: false,
193196
}
194197
}
195198
}

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

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ mod posthog;
2424
mod presets;
2525
mod recording;
2626
mod recording_settings;
27+
mod recovery;
2728
mod screenshot_editor;
2829
mod target_select_overlay;
2930
mod thumbnails;
@@ -2164,7 +2165,7 @@ async fn editor_delete_project(
21642165
#[specta::specta]
21652166
#[instrument(skip(app))]
21662167
async fn show_window(app: AppHandle, window: ShowCapWindow) -> Result<(), String> {
2167-
let _ = window.show(&app).await;
2168+
window.show(&app).await.map_err(|e| e.to_string())?;
21682169
Ok(())
21692170
}
21702171

@@ -2403,6 +2404,9 @@ pub async fn run(recording_logging_handle: LoggingHandle, logs_dir: PathBuf) {
24032404
target_select_overlay::focus_window,
24042405
editor_delete_project,
24052406
format_project_name,
2407+
recovery::find_incomplete_recordings,
2408+
recovery::recover_recording,
2409+
recovery::discard_incomplete_recording,
24062410
])
24072411
.events(tauri_specta::collect_events![
24082412
RecordingOptionsChanged,
@@ -2803,8 +2807,8 @@ pub async fn run(recording_logging_handle: LoggingHandle, logs_dir: PathBuf) {
28032807
tokio::spawn(EditorInstances::remove(window.clone()));
28042808

28052809
#[cfg(target_os = "windows")]
2806-
if CapWindowId::Settings.get(&app).is_none() {
2807-
reopen_main_window(&app);
2810+
if CapWindowId::Settings.get(app).is_none() {
2811+
reopen_main_window(app);
28082812
}
28092813
}
28102814
CapWindowId::ScreenshotEditor { id } => {
@@ -2815,8 +2819,8 @@ pub async fn run(recording_logging_handle: LoggingHandle, logs_dir: PathBuf) {
28152819
tokio::spawn(ScreenshotEditorInstances::remove(window.clone()));
28162820

28172821
#[cfg(target_os = "windows")]
2818-
if CapWindowId::Settings.get(&app).is_none() {
2819-
reopen_main_window(&app);
2822+
if CapWindowId::Settings.get(app).is_none() {
2823+
reopen_main_window(app);
28202824
}
28212825
}
28222826
CapWindowId::Settings => {
@@ -2834,8 +2838,8 @@ pub async fn run(recording_logging_handle: LoggingHandle, logs_dir: PathBuf) {
28342838
}
28352839

28362840
#[cfg(target_os = "windows")]
2837-
if !has_open_editor_window(&app) {
2838-
reopen_main_window(&app);
2841+
if !has_open_editor_window(app) {
2842+
reopen_main_window(app);
28392843
}
28402844

28412845
return;
@@ -3122,6 +3126,11 @@ async fn create_editor_instance_impl(
31223126
RenderFrameEvent::listen_any(&app, {
31233127
let preview_tx = instance.preview_tx.clone();
31243128
move |e| {
3129+
tracing::debug!(
3130+
frame = e.payload.frame_number,
3131+
fps = e.payload.fps,
3132+
"RenderFrameEvent received"
3133+
);
31253134
preview_tx.send_modify(|v| {
31263135
*v = Some((
31273136
e.payload.frame_number,

apps/desktop/src-tauri/src/platform/macos/delegates.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ pub fn setup<R: Runtime>(window: Window<R>, controls_inset: LogicalPosition<f64>
7575
use objc::runtime::{Object, Sel};
7676
use std::ffi::c_void;
7777

78-
let ns_win = window.ns_window().expect("Failed to create window handle");
78+
let Ok(ns_win) = window.ns_window() else {
79+
tracing::warn!("Failed to get window handle for delegate setup");
80+
return;
81+
};
7982

8083
// Do the initial positioning
8184
position_window_controls(UnsafeWindowHandle(ns_win), &controls_inset);

apps/desktop/src-tauri/src/platform/macos/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ pub use sc_shareable_content::*;
1818
pub fn set_window_level(window: tauri::Window, level: objc2_app_kit::NSWindowLevel) {
1919
let c_window = window.clone();
2020
_ = window.run_on_main_thread(move || unsafe {
21-
let ns_win = c_window
22-
.ns_window()
23-
.expect("Failed to get native window handle")
24-
as *const objc2_app_kit::NSWindow;
21+
let Ok(ns_win) = c_window.ns_window() else {
22+
return;
23+
};
24+
let ns_win = ns_win as *const objc2_app_kit::NSWindow;
2525
(*ns_win).setLevel(level);
2626
});
2727
}

0 commit comments

Comments
 (0)