Finish decode
This commit is contained in:
2 files changed
+107
-3
No files matched your search
+81
-2
@@ -1,5 +1,84 @@
|
|||||||
|
use image::ImageReader;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::process::Command;
|
||||||
|
use tempfile::TempDir;
|
||||||
|
|
||||||
pub fn decode(path: PathBuf) {
|
pub fn decode(video_path: PathBuf, output_path: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
println!("{}", path.display());
|
let temp_dir = TempDir::new()?;
|
||||||
|
let frames_dir = temp_dir.path();
|
||||||
|
|
||||||
|
let output_pattern = frames_dir.join("frame_%06d.png");
|
||||||
|
let output_pattern_str = output_pattern.to_str().ok_or("Invalid path")?;
|
||||||
|
|
||||||
|
let output = Command::new("ffmpeg")
|
||||||
|
.arg("-i")
|
||||||
|
.arg(&video_path)
|
||||||
|
.arg(output_pattern_str)
|
||||||
|
.output()?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
return Err(format!("ffmpeg failed: {}", stderr).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut data = Vec::new();
|
||||||
|
let mut bit_buffer: u8 = 0;
|
||||||
|
let mut bit_count = 0;
|
||||||
|
let mut found_blue = false;
|
||||||
|
|
||||||
|
let mut frame_files: Vec<_> = std::fs::read_dir(frames_dir)?
|
||||||
|
.filter_map(|e| {
|
||||||
|
e.ok().and_then(|entry| {
|
||||||
|
let name = entry.file_name();
|
||||||
|
let name_str = name.to_string_lossy();
|
||||||
|
if name_str.starts_with("frame_") && name_str.ends_with(".png") {
|
||||||
|
Some(entry.path())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
frame_files.sort();
|
||||||
|
|
||||||
|
for frame_path in frame_files {
|
||||||
|
let img = ImageReader::open(&frame_path)?.decode()?.to_rgb8();
|
||||||
|
|
||||||
|
for pixel in img.pixels() {
|
||||||
|
let r = pixel[0];
|
||||||
|
let g = pixel[1];
|
||||||
|
let b = pixel[2];
|
||||||
|
|
||||||
|
if b == 255 && r == 0 && g == 0 {
|
||||||
|
found_blue = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let bit = if g == 255 { 1 } else { 0 };
|
||||||
|
|
||||||
|
bit_buffer = (bit_buffer << 1) | bit;
|
||||||
|
bit_count += 1;
|
||||||
|
|
||||||
|
if bit_count == 8 {
|
||||||
|
data.push(bit_buffer);
|
||||||
|
bit_buffer = 0;
|
||||||
|
bit_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found_blue {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if bit_count > 0 {
|
||||||
|
bit_buffer <<= 8 - bit_count;
|
||||||
|
data.push(bit_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::fs::write(&output_path, data)?;
|
||||||
|
println!("Decoded file saved to: {}", output_path.display());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
+26
-1
@@ -1,4 +1,3 @@
|
|||||||
use gtk4::glib::spawn_future_local;
|
|
||||||
use gtk4::{Application, ApplicationWindow, Box, Button, Orientation};
|
use gtk4::{Application, ApplicationWindow, Box, Button, Orientation};
|
||||||
use gtk4::{Settings, prelude::*};
|
use gtk4::{Settings, prelude::*};
|
||||||
|
|
||||||
@@ -66,6 +65,32 @@ fn main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
decodebtn.connect_clicked({
|
||||||
|
let window = window.clone();
|
||||||
|
let decodebtn = decodebtn.clone();
|
||||||
|
move |_| {
|
||||||
|
decodebtn.set_sensitive(false);
|
||||||
|
let decodebtn = decodebtn.clone();
|
||||||
|
let window = window.clone();
|
||||||
|
get_user_selected_file(&window, move |file_path| {
|
||||||
|
if let Some(video_path) = file_path {
|
||||||
|
let decodebtn = decodebtn.clone();
|
||||||
|
|
||||||
|
let mut output_path = video_path.clone();
|
||||||
|
output_path.set_extension("decoded");
|
||||||
|
|
||||||
|
match decode(video_path, output_path) {
|
||||||
|
Ok(_) => println!("Decode completed successfully"),
|
||||||
|
Err(e) => eprintln!("Decode error: {}", e),
|
||||||
|
}
|
||||||
|
decodebtn.set_sensitive(true);
|
||||||
|
} else {
|
||||||
|
decodebtn.set_sensitive(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
vbox.append(&encodebtn);
|
vbox.append(&encodebtn);
|
||||||
vbox.append(&decodebtn);
|
vbox.append(&decodebtn);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user