Compare commits

..

12 Commits
0.1.3 ... main

Author SHA1 Message Date
Bel LaPointe 6095fd69fc 0.1.6 release 2023-12-28 22:20:22 -05:00
Bel LaPointe 8f1c0876c5 for highlighted spans, add a fat green border 2023-12-28 22:19:59 -05:00
Bel LaPointe 6e2cf357f4 0.1.5 release 2023-12-28 22:17:36 -05:00
Bel LaPointe 4aede62dbb lint 2023-12-28 22:17:21 -05:00
Bel LaPointe c3d6cd1545 menu causes crashes so skip it 2023-12-28 22:16:16 -05:00
Bel LaPointe bf7d09dde0 0.1.4 release 2023-12-28 22:08:55 -05:00
Bel LaPointe d13266dd73 while processing, make the whole app look non-interactive 2023-12-28 22:08:29 -05:00
Bel LaPointe ccc4d7fbd2 dont make trivial splits 2023-12-28 21:58:49 -05:00
Bel LaPointe 48961fee2a pretty print timestamps 2023-12-28 21:57:05 -05:00
Bel LaPointe dfbdba81a6 reset statefuls on file change 2023-12-28 21:56:57 -05:00
Bel LaPointe a38e39b808 add cmd-q 2023-12-28 21:38:36 -05:00
Bel LaPointe 9e053c96d6 release 0.1.3 2023-12-28 21:33:42 -05:00
5 changed files with 52 additions and 13 deletions

View File

@ -207,12 +207,14 @@ impl Inspection {
for i in 0..unstuck_spans.len() {
let mut span = unstuck_spans[i];
for split in scene_splits.iter() {
if &span.start < split && split < &span.stop { // TODO buffer
if &(span.start + 5.0) < split && split < &(span.stop - 5.0) { // TODO const
result.push(ContentSpan{start: span.start, stop: *split});
span.start = *split;
}
}
result.push(span); // TODO assert nontrivial
if span.stop - span.start > 2.0 {
result.push(span);
}
}
result
}

2
src/Cargo.lock generated
View File

@ -1351,7 +1351,7 @@ dependencies = [
[[package]]
name = "home-video-blue-extractinator"
version = "0.1.0"
version = "0.1.6"
dependencies = [
"base64 0.21.5",
"dioxus",

View File

@ -1,6 +1,6 @@
[package]
name = "home-video-blue-extractinator"
version = "0.1.0"
version = "0.1.6"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -15,7 +15,7 @@ dioxus-desktop = "0.4.3"
[package.metadata.bundle]
name = "home-video-blue-extractinator"
identifier = "com.breel.home-video-blue-extractinator"
version = "0.1.0"
version = "0.1.6"
copyright = "Copyright (c) breel.dev 2023. All rights reserved."
long_description = """
Tool to turn long home movies into clips with less noise.

View File

@ -1,14 +1,16 @@
#![allow(non_snake_case)]
// import the prelude to get access to the `rsx!` macro and the `Scope` and `Element` types
use dioxus::prelude::*;
use dioxus::hooks::use_future;
use lib;
use base64::{engine::general_purpose, Engine as _};
use core::cmp::Ordering;
use std::str::FromStr;
fn main() {
dioxus_desktop::launch(App);
dioxus_desktop::launch_cfg(App, dioxus_desktop::Config::new()
.with_window(dioxus_desktop::WindowBuilder::new()
.with_title("home-video-blue-extractinator")
));
}
// define a component that renders a div with the text "Hello, world!"
@ -18,11 +20,19 @@ fn App(cx: Scope) -> Element {
let clipify_status = use_state(cx, || String::new());
let processing = use_state(cx, || false);
let analysis = use_state(cx, || Analysis::new());
let a_css = String::from_utf8_lossy(include_bytes!("./style.css"));
let processing_css = || {
match *processing.get() {
true => "body { background-color: lightgray !important; opacity: 0.75 !important; }".to_string(),
false => "".to_string(),
}
};
cx.render(rsx! {
header {
title { "home-video-blue-extractinator" }
style { "{a_css}" }
style { "{a_css} {processing_css()}" }
}
main {
rsx! {
@ -33,10 +43,13 @@ fn App(cx: Scope) -> Element {
r#type: "file",
disabled: *processing.get(),
onchange: |evt| {
to_owned![file];
if let Some(file_engine) = &evt.files {
for f in &file_engine.files() {
file.set(f.clone());
analyze_status.set(String::new());
clipify_status.set(String::new());
processing.set(false);
analysis.set(Analysis::new());
}
}
},
@ -109,7 +122,7 @@ fn App(cx: Scope) -> Element {
checked: a.has_content,
name: "{a.start}..{a.stop}",
}
"{a.start}..{a.stop}: "
"{a.pretty_range()}"
br {}
img { src: "data:image/png;base64, {a.screenshot}" }
}
@ -144,12 +157,33 @@ impl Analysis {
#[derive(Clone)]
struct Analyzed {
_start: f32,
_stop: f32,
start: String,
stop: String,
screenshot: String,
has_content: bool,
}
impl Analyzed {
fn pretty_range(&self) -> String {
format!("{} - {}", self.pretty_t(self._start), self.pretty_t(self._stop))
}
fn pretty_t(&self, t: f32) -> String {
if t < 60.0 {
return format!(":{:02}", t as i32);
} else if t < 60.0 * 60.0 {
return format!("{:02}:{:02}", (t / 60.0) as i32, (t % 60.0) as i32);
} else {
return format!("{:02}:{:02}:{:02}",
(t / 60.0 / 60.0) as i32,
(t / 60.0) as i32,
(t % 60.0) as i32);
}
}
}
async fn analyze(file: String) -> Analysis {
let content_spans = lib::video::inspect_async(&file).await;
if content_spans.is_err() {
@ -174,11 +208,13 @@ async fn analyze(file: String) -> Analysis {
let screenshot = |content_span: &lib::video::ContentSpan| -> Analyzed {
let ts = (content_span.start + content_span.stop) / 2.0;
Analyzed {
_start: content_span.start,
_stop: content_span.stop,
start: content_span.start.to_string(),
stop: content_span.stop.to_string(),
screenshot: match lib::video::screenshot_png(&file, ts) {
Ok(png) => general_purpose::STANDARD.encode(&png),
Err(_) => a_png.to_string(),
Err(_) => A_PNG.to_string(),
},
has_content: false,
}
@ -221,9 +257,9 @@ async fn clipify(file: String, content_spans: Vec<lib::video::ContentSpan>) -> S
}
let _ = opener::open(d.clone());
match statuses.len() {
_ => statuses.join(", "),
0 => d,
_ => statuses.join(", "),
}
}
const a_png: &str = r"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
const A_PNG: &str = r"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";

File diff suppressed because one or more lines are too long