Skip to content

Commit e0f7168

Browse files
committed
[*] update normally
1 parent 192e335 commit e0f7168

File tree

6 files changed

+45
-39
lines changed

6 files changed

+45
-39
lines changed

lib/recorder/examples/recording_5s_demo.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
5959
thread::spawn(move || {
6060
if let Some(rx) = frame_receiver_user {
6161
while let Ok(frame) = rx.recv() {
62-
log::debug!(
63-
"frame_receiver_user frame len: {} bytes",
64-
frame.frame.cb_data.data.pixel_data.len()
65-
);
62+
if let Some(frame) = frame.frame {
63+
log::debug!(
64+
"frame_receiver_user frame len: {} bytes",
65+
frame.cb_data.data.pixel_data.len()
66+
);
67+
}
6668
}
6769
log::debug!("exit frame_receiver_user");
6870
} else {

lib/recorder/src/mp4_ffmpeg.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ pub fn is_ffmpeg_installed() -> bool {
3030
ffmpeg_sidecar::command::ffmpeg_is_installed()
3131
}
3232

33-
// FFmpeg command examples for reference:
34-
// ffmpeg -r 30 -i video.h264 -i audio.wav -c:v libx264 -c:a aac -r 30 -pix_fmt yuv420p -shortest output.mp4
35-
// ffmpeg -r 30 -i video.h264 -i audio.wav -i speaker.wav -filter_complex [1:a][2:a]amix=inputs=2:duration=shortest[aout] -c:v libx264 -c:a aac -r 30 -pix_fmt yuv420p -map 0:v -map [aout] -shortest output.mp4
36-
3733
/// Combine H.264 video and WAV audio tracks into MP4 using FFmpeg.
3834
///
3935
/// This function uses FFmpeg to combine separate H.264 video and WAV audio files
@@ -85,6 +81,17 @@ pub fn is_ffmpeg_installed() -> bool {
8581
/// Err(e) => eprintln!("Error: {}", e),
8682
/// }
8783
/// ```
84+
//ffmpeg \
85+
// -i /home/blue/Code/rust/wayshot/target/2025-10-14_13:09:43.h264 \
86+
// -i /home/blue/Code/rust/wayshot/target/2025-10-14_13:09:43.input.wav \
87+
// -i /home/blue/Code/rust/wayshot/target/2025-10-14_13:09:43.speaker.wav \
88+
// -filter_complex "[1:a][2:a]amix=inputs=2:duration=shortest[aout]" \
89+
// -c:v copy \
90+
// -c:a aac \
91+
// -b:a 128k \
92+
// -map 0:v \
93+
// -map "[aout]" \
94+
// -y /home/blue/Code/rust/wayshot/target/2025-10-14_13:09:43.tmp.mp4
8895
pub fn combine_tracks(
8996
config: CombineTracksConfig,
9097
mut progress_cb: impl FnMut(f32),
@@ -99,8 +106,7 @@ pub fn combine_tracks(
99106
let mut total_duration = None;
100107
let mut cmd = FfmpegCommand::new();
101108

102-
cmd.args(&["-r", &config.fps.to_u32().to_string()])
103-
.input(config.h264_path.display().to_string());
109+
cmd.input(config.h264_path.display().to_string());
104110

105111
if let Some(ref wav_path) = config.input_wav_path {
106112
if !wav_path.exists() {
@@ -129,25 +135,17 @@ pub fn combine_tracks(
129135
]);
130136
}
131137

132-
cmd.args(&["-c:v", "libx264"]);
138+
cmd.args(&["-c:v", "copy"]);
133139

134140
if config.input_wav_path.is_some() || config.speaker_wav_path.is_some() {
135-
cmd.args(&["-c:a", "aac"]);
141+
cmd.args(&["-c:a", "aac", "-b:a", "128k"]);
136142
}
137143

138-
cmd.args(&[
139-
"-r",
140-
&config.fps.to_u32().to_string(),
141-
"-pix_fmt",
142-
"yuv420p",
143-
]);
144-
145144
if config.input_wav_path.is_some() && config.speaker_wav_path.is_some() {
146145
cmd.args(&["-map", "0:v", "-map", "[aout]"]);
147146
}
148147

149148
let mut child_process = cmd
150-
.args(&["-shortest"])
151149
.output(config.output_path.display().to_string())
152150
.overwrite()
153151
.print_command()

lib/recorder/src/recorder.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use spin_sleep::SpinSleeper;
1212
use std::{
1313
collections::HashMap,
1414
fs,
15+
path::PathBuf,
1516
sync::{
1617
Arc, Mutex,
1718
atomic::{AtomicBool, AtomicU64, Ordering},
@@ -29,8 +30,8 @@ const INPUT_AUDIO_EXTENSION: &str = "input.wav";
2930
const SPEAKER_AUDIO_EXTENSION: &str = "speaker.wav";
3031
const TMP_OUTPUT_VIDEO_EXTENSION: &str = "tmp.mp4";
3132

32-
const USER_CHANNEL_SIZE: usize = 8;
33-
const RESIZE_WORKER_CHANNEL_SIZE: usize = 32;
33+
const USER_CHANNEL_SIZE: usize = 64;
34+
const RESIZE_WORKER_CHANNEL_SIZE: usize = 64;
3435
const ENCODER_WORKER_CHANNEL_SIZE: usize = 128;
3536

3637
static CAPTURE_MEAN_TIME: Lazy<Mutex<Option<Duration>>> = Lazy::new(|| Mutex::new(None));
@@ -202,6 +203,10 @@ impl RecordingSession {
202203
}
203204
}
204205

206+
pub fn output_path(&self) -> PathBuf {
207+
self.config.output_path.clone()
208+
}
209+
205210
/// Start the recording session.
206211
///
207212
/// This method begins the actual recording process by spawning multiple threads
@@ -713,17 +718,16 @@ impl RecordingSession {
713718
}
714719
}
715720

716-
{
721+
log::debug!("{}", {
717722
let mut s = String::default();
718723
for (index, sender) in resize_senders.iter().enumerate() {
719724
s.push_str(&format!(
720725
"send[{index}] remained: {}. ",
721726
sender.capacity().unwrap_or_default() - sender.len()
722727
));
723728
}
724-
725-
log::debug!("{s}");
726-
}
729+
s
730+
});
727731

728732
let sender = resize_senders
729733
.iter()

wayshot/src/logic/recorder.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use crate::{
1515
use anyhow::{Result, bail};
1616
use once_cell::sync::Lazy;
1717
use recorder::{
18-
AudioRecorder, FPS, ProgressState, RecorderConfig, RecordingSession, Resolution,
19-
SpeakerRecorder, StreamingAudioRecorder, bounded,
18+
AudioRecorder, FPS, RecorderConfig, RecordingSession, Resolution, SpeakerRecorder,
19+
StreamingAudioRecorder, bounded,
2020
};
2121
use slint::{
2222
ComponentHandle, Model, SharedPixelBuffer, SharedString, ToSharedString, VecModel, Weak,
@@ -566,7 +566,9 @@ fn inner_start_recording(ui_weak: Weak<AppWindow>) -> Result<()> {
566566
});
567567

568568
let ui_weak_clone = ui_weak.clone();
569-
let state = session.wait(move |v| {
569+
let final_video_path = session.output_path();
570+
571+
session.wait(move |v| {
570572
log::debug!("combine tracks progress: {}%", (v * 100.0) as u32);
571573
_ = ui_weak_clone.upgrade_in_event_loop(move |ui| {
572574
global_store!(ui).set_record_status(UIRecordStatus::Mergeing);
@@ -576,13 +578,10 @@ fn inner_start_recording(ui_weak: Weak<AppWindow>) -> Result<()> {
576578

577579
_ = ui_weak.upgrade_in_event_loop(move |ui| {
578580
global_store!(ui).set_record_status(UIRecordStatus::Stopped);
579-
match state {
580-
ProgressState::Finished => {
581-
global_store!(ui).set_merge_tracks_status(UIMergeTrackStatus::Finished);
582-
}
583-
ProgressState::Stopped => {
584-
global_store!(ui).set_merge_tracks_status(UIMergeTrackStatus::None);
585-
}
581+
582+
if global_store!(ui).get_merge_tracks_status() != UIMergeTrackStatus::Cancelled {
583+
global_store!(ui).set_merge_tracks_status(UIMergeTrackStatus::Finished);
584+
global_store!(ui).set_final_video_path(final_video_path.display().to_shared_string());
586585
}
587586
});
588587

@@ -611,6 +610,7 @@ fn stop_merge_tracks(ui: &AppWindow) {
611610
}
612611

613612
global_store!(ui).set_record_status(UIRecordStatus::Stopped);
613+
global_store!(ui).set_merge_tracks_status(UIMergeTrackStatus::Cancelled);
614614
}
615615

616616
pub fn picker_directory(ui: Weak<AppWindow>, title: &str, filename: &str) -> Option<PathBuf> {

wayshot/ui/panel/desktop/home.slint

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -428,13 +428,13 @@ component Banners inherits VerticalLayout {
428428
}
429429
}
430430

431-
if Store.merge-tracks-status != MergeTrackStatus.None: Banner {
431+
if Store.merge-tracks-status == MergeTrackStatus.Finished || Store.merge-tracks-status == MergeTrackStatus.Failed: Banner {
432432
background: Store.merge-tracks-status == MergeTrackStatus.Finished ? Theme.success-color : Theme.warning-color;
433433

434434
HorizontalLayout {
435435
Label {
436436
color: Theme.light-text-color;
437-
text: Store.merge-tracks-status == MergeTrackStatus.Finished ? Logic.tr("Merging tracks successfully") : Logic.tr("Merging tracks failed");
437+
text: Store.merge-tracks-status == MergeTrackStatus.Finished ? (Logic.tr("Merging tracks successfully!") + " " + Logic.tr("Output file") + ": " + Store.final-video-path) : Logic.tr("Merging tracks failed");
438438
font-weight: Theme.bold-font-weight;
439439
}
440440
}
@@ -450,7 +450,7 @@ export component Home inherits VerticalLayout {
450450
spacing: Theme.spacing;
451451

452452
private property <length> banner-height;
453-
private property <bool> is-show-banners: !Store.ffmpeg-is-installed || Store.merge-tracks-status != MergeTrackStatus.None;
453+
private property <bool> is-show-banners: !Store.ffmpeg-is-installed || Store.merge-tracks-status == MergeTrackStatus.Finished || Store.merge-tracks-status == MergeTrackStatus.Failed;
454454

455455
if is-show-banners: Banners {
456456
init => {

wayshot/ui/store.slint

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export enum MergeTrackStatus {
119119
None,
120120
Finished,
121121
Failed,
122+
Cancelled,
122123
}
123124

124125
//////////////////////////////// Logic Struct End ////////////////////////////////
@@ -159,6 +160,7 @@ export global Store {
159160
in-out property <bool> ffmpeg-is-installed;
160161
in-out property <float> merge-tracks-progress;
161162
in-out property <MergeTrackStatus> merge-tracks-status: MergeTrackStatus.None;
163+
in-out property <string> final-video-path;
162164
in-out property <image> preview-image: @image-url("./images/png/wechat-pay.png");
163165
in-out property <int> input-audio-db: -60;
164166
in-out property <int> speaker-audio-db: -60;

0 commit comments

Comments
 (0)