#![cfg(feature = "rayon")]
use std::path::Path;
use image::DynamicImage;
use unbundle::{ExtractOptions, FrameRange, MediaFile};
const SAMPLE_VIDEO: &str = "tests/fixtures/sample_video.mp4";
fn skip_unless(path: &str) -> bool {
if !Path::new(path).exists() {
eprintln!("Skipping: fixture {path} not found");
return true;
}
false
}
#[test]
fn parallel_basic_consecutive() {
if skip_unless(SAMPLE_VIDEO) {
return;
}
let mut unbundler = MediaFile::open(SAMPLE_VIDEO).unwrap();
let config = ExtractOptions::new();
let frames = unbundler
.video()
.frames_parallel(FrameRange::Range(0, 9), &config)
.unwrap();
assert_eq!(frames.len(), 10);
for frame in &frames {
let frame: &DynamicImage = frame;
assert!(frame.width() > 0);
assert!(frame.height() > 0);
}
}
#[test]
fn parallel_with_large_gaps() {
if skip_unless(SAMPLE_VIDEO) {
return;
}
let mut unbundler = MediaFile::open(SAMPLE_VIDEO).unwrap();
let config = ExtractOptions::new();
let frames = unbundler
.video()
.frames_parallel(FrameRange::Specific(vec![0, 1, 50, 51, 100, 101]), &config)
.unwrap();
assert_eq!(frames.len(), 6, "should extract all 6 requested frames");
}
#[test]
fn parallel_matches_sequential() {
if skip_unless(SAMPLE_VIDEO) {
return;
}
let target = vec![10u64, 11, 12];
let mut unbundler = MediaFile::open(SAMPLE_VIDEO).unwrap();
let parallel = unbundler
.video()
.frames_parallel(FrameRange::Specific(target.clone()), &ExtractOptions::new())
.unwrap();
let mut unbundler2 = MediaFile::open(SAMPLE_VIDEO).unwrap();
let sequential = unbundler2
.video()
.frames(FrameRange::Specific(target))
.unwrap();
assert_eq!(parallel.len(), sequential.len());
let p_img = parallel[0].to_rgb8();
let s_img = sequential[0].to_rgb8();
assert_eq!(p_img.dimensions(), s_img.dimensions());
assert_eq!(
p_img.as_raw(),
s_img.as_raw(),
"parallel and sequential output should be pixel-identical",
);
}
#[test]
fn parallel_interval() {
if skip_unless(SAMPLE_VIDEO) {
return;
}
let mut unbundler = MediaFile::open(SAMPLE_VIDEO).unwrap();
let config = ExtractOptions::new();
let frames = unbundler
.video()
.frames_parallel(FrameRange::Interval(30), &config)
.unwrap();
assert!(
!frames.is_empty(),
"interval extraction should return at least one frame",
);
}
#[test]
fn parallel_from_open_url_source_input() {
if skip_unless(SAMPLE_VIDEO) {
return;
}
let mut unbundler = MediaFile::open_url(SAMPLE_VIDEO).unwrap();
let frames = unbundler
.video()
.frames_parallel(
FrameRange::Specific(vec![0, 15, 30]),
&ExtractOptions::new(),
)
.unwrap();
assert_eq!(frames.len(), 3);
for frame in &frames {
assert!(frame.width() > 0);
assert!(frame.height() > 0);
}
}