Skip to content

Commit

Permalink
Merge branch 'CapSoftware:main' into next-windows
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsEeleeya authored Dec 18, 2024
2 parents 0bc925b + 2985489 commit 3f12dcd
Show file tree
Hide file tree
Showing 17 changed files with 158 additions and 106 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/desktop/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "desktop"
version = "0.3.9"
version = "0.3.10"
description = "Beautiful screen recordings, owned by you."
authors = ["you"]
edition = "2021"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ export default function FeedbackTab() {
Help us improve Cap by submitting feedback or reporting bugs. We'll get
right on it.
</p>
<form class="space-y-4" onSubmit={() => sendFeedback(feedback())}>
<form
class="space-y-4"
onSubmit={(e) => {
e.preventDefault();
sendFeedback(feedback());
}}
>
<fieldset disabled={submission.pending}>
<div>
<textarea
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ function Inner(props: { initialStore: HotkeysStore | null }) {
if (
!(
(data.code >= "KeyA" && data.code <= "KeyZ") ||
(data.code >= "Key0" && data.code <= "Key9") ||
data.code.startsWith("F")
)
)
Expand Down
22 changes: 0 additions & 22 deletions apps/desktop/src/routes/editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,28 +119,6 @@ function Inner() {
)
);

const togglePlayback = async () => {
try {
if (playing()) {
await commands.stopPlayback(videoId);
setPlaying(false);
} else {
await commands.startPlayback(videoId);
setPlaying(true);
}
} catch (error) {
console.error("Error toggling playback:", error);
setPlaying(false);
}
};

createEventListener(document, "keydown", async (e: KeyboardEvent) => {
if (e.code === "Space" && e.target === document.body) {
e.preventDefault();
await togglePlayback();
}
});

return (
<div class="w-screen h-screen flex flex-col">
<Header />
Expand Down
49 changes: 13 additions & 36 deletions apps/desktop/src/routes/editor/Timeline.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import "~/styles/timeline.css";
import { createElementBounds } from "@solid-primitives/bounds";
import {
Accessor,
ComponentProps,
For,
Show,
Expand All @@ -12,24 +11,20 @@ import {
} from "solid-js";
import { createEventListenerMap } from "@solid-primitives/event-listener";
import { cx } from "cva";
import { createStore, produce } from "solid-js/store";
import { produce } from "solid-js/store";
import { mergeRefs } from "@solid-primitives/refs";
import { createContextProvider } from "@solid-primitives/context";
import { createMemo } from "solid-js";

import { commands, TimelineSegment } from "~/utils/tauri";
import { useEditorContext } from "./context";
import {
TimelineContextProvider,
TrackContextProvider,
useEditorContext,
useTimelineContext,
useTrackContext,
} from "./context";
import { formatTime } from "./utils";

const [TimelineContextProvider, useTimelineContext] = createContextProvider(
(props: { duration: number }) => {
return {
duration: () => props.duration,
};
},
null!
);

export function Timeline() {
const {
project,
Expand Down Expand Up @@ -181,7 +176,6 @@ export function Timeline() {
"timeline",
"segments",
produce((segments) => {
console.log({ splitTime });
segments.splice(i() + 1, 0, {
start: splitTime,
end: segment.end,
Expand Down Expand Up @@ -319,7 +313,11 @@ export function Timeline() {
i(),
"end",
Math.max(
Math.min(newEnd, segment.start + maxDuration),
Math.min(
newEnd,
maxSegmentDuration,
availableTimelineDuration
),
segment.start + 1
)
);
Expand Down Expand Up @@ -421,7 +419,6 @@ export function Timeline() {
},
},
});
console.log(zoomSegments);
})
);
});
Expand Down Expand Up @@ -630,26 +627,6 @@ export function Timeline() {
);
}

const [TrackContextProvider, useTrackContext] = createContextProvider(
(props: {
ref: Accessor<Element | undefined>;
isFreeForm: Accessor<boolean>;
}) => {
const [trackState, setTrackState] = createStore({
draggingHandle: false,
});
const bounds = createElementBounds(() => props.ref());

return {
trackBounds: bounds,
isFreeForm: () => props.isFreeForm(),
trackState,
setTrackState,
};
},
null!
);

function TrackRoot(props: ComponentProps<"div"> & { isFreeForm: boolean }) {
const [ref, setRef] = createSignal<HTMLDivElement>();

Expand Down
30 changes: 29 additions & 1 deletion apps/desktop/src/routes/editor/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { trackStore } from "@solid-primitives/deep";
import { createEventListener } from "@solid-primitives/event-listener";
import { createUndoHistory } from "@solid-primitives/history";
import { debounce } from "@solid-primitives/scheduled";
import { createEffect, createSignal, on } from "solid-js";
import { Accessor, createEffect, createSignal, on } from "solid-js";
import { createStore, reconcile, unwrap } from "solid-js/store";

import type { PresetsStore } from "../../store";
Expand All @@ -15,6 +15,7 @@ import {
} from "~/utils/tauri";
import { useEditorInstanceContext } from "./editorInstanceContext";
import { DEFAULT_PROJECT_CONFIG } from "./projectConfig";
import { createElementBounds } from "@solid-primitives/bounds";

export type CurrentDialog =
| { type: "createPreset" }
Expand Down Expand Up @@ -148,3 +149,30 @@ type Static<T = unknown> =
[K in number | string]: T;
}
| T[];

export const [TimelineContextProvider, useTimelineContext] =
createContextProvider((props: { duration: number }) => {
return {
duration: () => props.duration,
};
}, null!);

export const [TrackContextProvider, useTrackContext] = createContextProvider(
(props: {
ref: Accessor<Element | undefined>;
isFreeForm: Accessor<boolean>;
}) => {
const [trackState, setTrackState] = createStore({
draggingHandle: false,
});
const bounds = createElementBounds(() => props.ref());

return {
trackBounds: bounds,
isFreeForm: () => props.isFreeForm(),
trackState,
setTrackState,
};
},
null!
);
10 changes: 10 additions & 0 deletions apps/web/content/changelog/30.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: More bug fixes
app: Cap Desktop
publishedAt: "2024-12-18"
version: 0.3.10
image:
---

- Fixes exporting cropped videos
- Fixes camera mirroring
9 changes: 4 additions & 5 deletions crates/editor/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,24 +76,23 @@ impl Renderer {
let frame_tx = self.frame_tx.clone();

frame_task = Some(tokio::spawn(async move {
let now = Instant::now();
let (frame, stride) = produce_frame(
let frame = produce_frame(
&render_constants,
&screen_frame,
&camera_frame,
cap_rendering::Background::from(background),
&uniforms,
time, // Pass the actual time value
time,
)
.await
.unwrap();

frame_tx
.try_send(WSFrame {
data: frame,
data: frame.data,
width: uniforms.output_size.0,
height: uniforms.output_size.1,
stride,
stride: frame.padded_bytes_per_row,
})
.ok();
finished.send(()).ok();
Expand Down
56 changes: 41 additions & 15 deletions crates/export/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use cap_media::{
};
use cap_project::{ProjectConfiguration, RecordingMeta};
use cap_rendering::{
ProjectUniforms, RecordingSegmentDecoders, RenderSegment, RenderVideoConstants,
ProjectUniforms, RecordingSegmentDecoders, RenderSegment, RenderVideoConstants, RenderedFrame,
SegmentVideoPaths,
};
use futures::FutureExt;
Expand Down Expand Up @@ -111,7 +111,7 @@ where
buffer: AudioFrameBuffer,
}

let (tx_image_data, mut rx_image_data) = tokio::sync::mpsc::channel::<Vec<u8>>(4);
let (tx_image_data, mut rx_image_data) = tokio::sync::mpsc::channel::<RenderedFrame>(4);

let (frame_tx, frame_rx) = std::sync::mpsc::sync_channel::<MP4Input>(4);

Expand Down Expand Up @@ -225,7 +225,11 @@ where
self.output_size.1,
30,
)
.wrap_frame(&frame, 0);
.wrap_frame(
&frame.data,
0,
frame.padded_bytes_per_row as usize,
);
video_frame.set_pts(Some(frame_count as i64));

frame_tx
Expand All @@ -239,16 +243,14 @@ where
}

// Save the first frame as a screenshot and thumbnail
if let Some(frame_data) = first_frame {
let width = self.output_size.0;
let height = self.output_size.1;
if let Some(frame) = first_frame {
let rgba_img: ImageBuffer<Rgba<u8>, Vec<u8>> =
ImageBuffer::from_raw(width, height, frame_data)
ImageBuffer::from_raw(frame.width, frame.height, frame.data)
.expect("Failed to create image from frame data");

// Convert RGBA to RGB
let rgb_img: ImageBuffer<image::Rgb<u8>, Vec<u8>> =
ImageBuffer::from_fn(width, height, |x, y| {
ImageBuffer::from_fn(frame.width, frame.height, |x, y| {
let rgba = rgba_img.get_pixel(x, y);
image::Rgb([rgba[0], rgba[1], rgba[2]])
});
Expand Down Expand Up @@ -306,7 +308,7 @@ where
pipe_tx: tokio::sync::mpsc::Sender<Vec<u8>>,
}

let (tx_image_data, mut rx_image_data) = tokio::sync::mpsc::channel::<Vec<u8>>(4);
let (tx_image_data, mut rx_image_data) = tokio::sync::mpsc::channel::<RenderedFrame>(4);

let ffmpeg_handle = tokio::spawn({
let project = self.project.clone();
Expand All @@ -325,6 +327,17 @@ where
let pipe_path = cap_utils::create_channel_named_pipe(
rx,
audio_dir.path().join("audio.pipe"),
{
let mut done = false;
move |value| {
if done {
None
} else {
done = true;
Some(&value)
}
}
},
);

ffmpeg.add_input(cap_ffmpeg_cli::FFmpegRawAudioInput {
Expand All @@ -348,11 +361,26 @@ where
};

let video_tx = {
let (tx, rx) = tokio::sync::mpsc::channel::<Vec<u8>>(30);
let (tx, rx) = tokio::sync::mpsc::channel::<RenderedFrame>(30);

let pipe_path = cap_utils::create_channel_named_pipe(
rx,
video_dir.path().join("video.pipe"),
{
let mut i = 0;

move |frame| {
if i < frame.data.len() as u32 {
let value =
&frame.data[i as usize..(i + frame.width * 4) as usize];

i += frame.padded_bytes_per_row;
Some(value)
} else {
None
}
}
},
);

ffmpeg.add_input(cap_ffmpeg_cli::FFmpegRawVideoInput {
Expand Down Expand Up @@ -442,16 +470,14 @@ where
ffmpeg_process.stop().await;

// Save the first frame as a screenshot and thumbnail
if let Some(frame_data) = first_frame {
let width = self.output_size.0;
let height = self.output_size.1;
if let Some(frame) = first_frame {
let rgba_img: ImageBuffer<Rgba<u8>, Vec<u8>> =
ImageBuffer::from_raw(width, height, frame_data)
ImageBuffer::from_raw(frame.width, frame.height, frame.data)
.expect("Failed to create image from frame data");

// Convert RGBA to RGB
let rgb_img: ImageBuffer<image::Rgb<u8>, Vec<u8>> =
ImageBuffer::from_fn(width, height, |x, y| {
ImageBuffer::from_fn(frame.width, frame.height, |x, y| {
let rgba = rgba_img.get_pixel(x, y);
image::Rgb([rgba[0], rgba[1], rgba[2]])
});
Expand Down
4 changes: 2 additions & 2 deletions crates/flags/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub struct Flags {
pub const FLAGS: Flags = Flags {
record_mouse: false, // cfg!(debug_assertions),
split: false, // cfg!(debug_assertions),
pause_resume: false, // cfg!(debug_assertions),
zoom: false, // false, // false, // cfg!(debug_assertions),
pause_resume: cfg!(debug_assertions),
zoom: false, // cfg!(debug_assertions),
custom_s3: true,
};
Loading

0 comments on commit 3f12dcd

Please sign in to comment.