video playback test

This commit is contained in:
2024-07-08 14:34:57 +02:00
parent 99f7fa2a28
commit 91051a82be
8 changed files with 364 additions and 8 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
/target /target
*.png *.png
*.webm

202
Cargo.lock generated
View File

@@ -80,8 +80,10 @@ dependencies = [
"clap", "clap",
"clearscreen", "clearscreen",
"colored", "colored",
"ffmpeg-next",
"image", "image",
"nokhwa", "nokhwa",
"video-rs",
] ]
[[package]] [[package]]
@@ -90,7 +92,7 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [ dependencies = [
"hermit-abi", "hermit-abi 0.1.19",
"libc", "libc",
"winapi", "winapi",
] ]
@@ -124,6 +126,26 @@ dependencies = [
"which 4.4.2", "which 4.4.2",
] ]
[[package]]
name = "bindgen"
version = "0.69.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
dependencies = [
"bitflags 2.6.0",
"cexpr",
"clang-sys",
"itertools",
"lazy_static",
"lazycell",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn",
]
[[package]] [[package]]
name = "bit_field" name = "bit_field"
version = "0.10.2" version = "0.10.2"
@@ -512,6 +534,31 @@ dependencies = [
"simd-adler32", "simd-adler32",
] ]
[[package]]
name = "ffmpeg-next"
version = "7.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfce5242643c8a57b5a44b7e933ccbde85f9508d1379e578e97eee4a9d4334b"
dependencies = [
"bitflags 2.6.0",
"ffmpeg-sys-next",
"libc",
]
[[package]]
name = "ffmpeg-sys-next"
version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "972a460dd8e901b737ce0482bf71a837e1751e3dd7c8f8b0a4ead808e7f174a5"
dependencies = [
"bindgen 0.69.4",
"cc",
"libc",
"num_cpus",
"pkg-config",
"vcpkg",
]
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.30" version = "1.0.30"
@@ -565,6 +612,15 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.30" version = "0.3.30"
@@ -631,6 +687,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hermit-abi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]] [[package]]
name = "home" name = "home"
version = "0.5.9" version = "0.5.9"
@@ -640,6 +702,16 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "idna"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]] [[package]]
name = "image" name = "image"
version = "0.24.9" version = "0.24.9"
@@ -664,6 +736,15 @@ version = "1.70.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
[[package]]
name = "itertools"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
dependencies = [
"either",
]
[[package]] [[package]]
name = "jobserver" name = "jobserver"
version = "0.1.31" version = "0.1.31"
@@ -930,6 +1011,16 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi 0.3.9",
"libc",
]
[[package]] [[package]]
name = "objc" name = "objc"
version = "0.2.7" version = "0.2.7"
@@ -967,6 +1058,12 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "percent-encoding"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]] [[package]]
name = "phf" name = "phf"
version = "0.11.2" version = "0.11.2"
@@ -1025,6 +1122,18 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "pin-project-lite"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "pkg-config"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]] [[package]]
name = "png" name = "png"
version = "0.17.13" version = "0.17.13"
@@ -1278,12 +1387,84 @@ dependencies = [
"weezl", "weezl",
] ]
[[package]]
name = "tinyvec"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6b6a2fb3a985e99cebfaefa9faa3024743da73304ca1c683a36429613d3d22"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tracing"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
]
[[package]]
name = "unicode-bidi"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.12" version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
dependencies = [
"tinyvec",
]
[[package]]
name = "url"
version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]] [[package]]
name = "utf8parse" name = "utf8parse"
version = "0.2.2" version = "0.2.2"
@@ -1307,7 +1488,24 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6779878362b9bacadc7893eac76abe69612e8837ef746573c4a5239daf11990b" checksum = "6779878362b9bacadc7893eac76abe69612e8837ef746573c4a5239daf11990b"
dependencies = [ dependencies = [
"bindgen", "bindgen 0.65.1",
]
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "video-rs"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5d8155306a18fbe217e0d019018311fd4e82bcfe9ceff39638244dffcb0e411"
dependencies = [
"ffmpeg-next",
"tracing",
"url",
] ]
[[package]] [[package]]

View File

@@ -8,5 +8,7 @@ atty = "0.2.14"
clap = { version = "4.5.8", features = ["derive"] } clap = { version = "4.5.8", features = ["derive"] }
clearscreen = "3.0.0" clearscreen = "3.0.0"
colored = "2.1.0" colored = "2.1.0"
ffmpeg-next = "7.0.2"
image = "0.24.9" image = "0.24.9"
nokhwa = { path = "/home/mike/Software/nokhwa", version = "0.10.4", features = ["input-native"] } nokhwa = { path = "../../Software/nokhwa", version = "0.10.4", features = ["input-native"] }
video-rs = "0.8.1"

View File

@@ -3,3 +3,4 @@ pub mod image;
pub mod ascii; pub mod ascii;
pub mod gen_handler; pub mod gen_handler;
pub mod cam_handler; pub mod cam_handler;
pub mod vid_handler;

View File

@@ -72,4 +72,33 @@ pub enum Subcommands {
#[arg(long, default_value_t = String::from(""))] #[arg(long, default_value_t = String::from(""))]
lightmap: String, lightmap: String,
}, },
Vid {
#[arg(long, default_value_t = false)]
invert: bool,
#[arg(long, default_value_t = false)]
colorful: bool,
#[arg(long, default_value_t = 80)]
width: usize,
#[arg(long, default_value_t = 25)]
height: usize,
#[arg(long, default_value_t = 2)]
pixel: usize,
#[arg(long, default_value_t = false)]
noresize: bool,
#[arg(long, default_value_t = false)]
matrix: bool,
#[arg(long, default_value_t = false)]
nofill: bool,
#[arg(long, default_value_t = String::from(""))]
lightmap: String,
},
} }

View File

@@ -6,7 +6,7 @@ use nokhwa::{
Camera, Camera,
}; };
pub fn video( pub fn camera(
invert: bool, invert: bool,
colorful: bool, colorful: bool,
width: usize, width: usize,

110
src/libs/vid_handler.rs Normal file
View File

@@ -0,0 +1,110 @@
use std::time::Duration;
use crate::libs;
use image::{DynamicImage, ImageBuffer};
use ffmpeg_next::format::{input, Pixel};
use ffmpeg_next::media::Type;
use ffmpeg_next::software::scaling::{context::Context, flag::Flags};
use ffmpeg_next::util::frame::video::Video;
pub fn video(
invert: bool,
colorful: bool,
width: usize,
height: usize,
pixel: usize,
noresize: bool,
matrix: bool,
nofill: bool,
lightmap: String,
) {
ffmpeg_next::init().unwrap();
if let Ok(mut ictx) = input("bad_apple.webm") {
let input = ictx
.streams()
.best(Type::Video)
.ok_or(ffmpeg_next::Error::StreamNotFound)
.unwrap();
let video_stream_index = input.index();
let context_decoder =
ffmpeg_next::codec::context::Context::from_parameters(input.parameters()).unwrap();
let mut decoder = context_decoder.decoder().video().unwrap();
let mut scaler = Context::get(
decoder.format(),
decoder.width(),
decoder.height(),
Pixel::RGB24,
decoder.width(),
decoder.height(),
Flags::BILINEAR,
)
.unwrap();
let frame_rate = input.avg_frame_rate();
let frame_duration = Duration::from_secs_f64(frame_rate.denominator() as f64 / frame_rate.numerator() as f64);
let mut frame_index = 0;
let mut receive_and_process_decoded_frames =
|decoder: &mut ffmpeg_next::decoder::Video| -> Result<(), ffmpeg_next::Error> {
let mut decoded = Video::empty();
while decoder.receive_frame(&mut decoded).is_ok() {
let start = std::time::Instant::now();
let mut rgb_frame = Video::empty();
scaler.run(&decoded, &mut rgb_frame)?;
let vwidth = rgb_frame.width();
let vheight = rgb_frame.height();
let data = rgb_frame.data(0);
let buf = ImageBuffer::from_raw(vwidth, vheight, data.to_vec()).unwrap();
let mut img = DynamicImage::ImageRgb8(buf);
if !noresize && !nofill {
img = libs::image::resize_image(&img, width, height);
eprintln!("Image resized");
libs::image::print_size(&img);
}
if !noresize && nofill {
img = libs::image::resize_image_no_fill(&img, width, height);
eprintln!("Image resized exact");
libs::image::print_size(&img);
}
let ascii_img =
libs::ascii::to_ascii(&img, &lightmap, pixel, invert, colorful, matrix);
eprintln!("ASCII image created");
clearscreen::clear().expect("Failed to clear screen");
print!("{ascii_img}");
frame_index += 1;
let elapsed = start.elapsed();
if elapsed < frame_duration {
std::thread::sleep(frame_duration - elapsed);
}
}
Ok(())
};
for (stream, packet) in ictx.packets() {
if stream.index() == video_stream_index {
decoder.send_packet(&packet).unwrap();
receive_and_process_decoded_frames(&mut decoder).unwrap();
}
}
decoder.send_eof().unwrap();
receive_and_process_decoded_frames(&mut decoder).unwrap();
}
}

View File

@@ -37,12 +37,27 @@ fn main() {
nofill, nofill,
lightmap, lightmap,
}) => { }) => {
libs::cam_handler::video( libs::cam_handler::camera(
invert, colorful, width, height, pixel, noresize, matrix, nofill, lightmap,
);
}
Some(libs::args::Subcommands::Vid {
invert,
colorful,
width,
height,
pixel,
noresize,
matrix,
nofill,
lightmap,
}) => {
libs::vid_handler::video(
invert, colorful, width, height, pixel, noresize, matrix, nofill, lightmap, invert, colorful, width, height, pixel, noresize, matrix, nofill, lightmap,
); );
} }
None => { None => {
eprintln!("No subcommand provided. Available subcommands: `gen`, `cam`"); eprintln!("No subcommand provided. Available subcommands: `gen`, `cam`, and `vid`");
std::process::exit(1); std::process::exit(1);
} }
} }