pub mod common;
use std::fs;
use std::env;
use std::process::Command;
use ffprobe::ffprobe;
use file_format::FileFormat;
use dash_mpd::fetch::DashDownloader;
use common::{check_file_size_approx, ffmpeg_approval, setup_logging};
#[tokio::test]
async fn test_decryption_webm_shaka_container() {
setup_logging();
let url = "https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine/dash.mpd";
let out = env::temp_dir().join("angel-shaka-container.webm");
if out.exists() {
let _ = fs::remove_file(&out);
}
DashDownloader::new(url)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("4d97930a3d7b55fa81d0028653f5e499"),
String::from("429ec76475e7a952d224d8ef867f12b6"))
.add_decryption_key(String::from("d21373c0b8ab5ba9954742bcdfb5f48b"),
String::from("150a6c7d7dee6a91b74dccfce5b31928"))
.add_decryption_key(String::from("6f1729072b4a5cd288c916e11846b89e"),
String::from("a84b4bd66901874556093454c075e2c6"))
.add_decryption_key(String::from("800aacaa522958ae888062b5695db6bf"),
String::from("775dbf7289c4cc5847becd571f536ff2"))
.add_decryption_key(String::from("67b30c86756f57c5a0a38a23ac8c9178"),
String::from("efa2878c2ccf6dd47ab349fcf90e6259"))
.with_muxer_preference("webm", "ffmpeg")
.with_decryptor_preference("shaka-container")
.download_to(&out).await
.unwrap();
check_file_size_approx(&out, 1_331_284);
let meta = ffprobe(&out).unwrap();
assert_eq!(meta.streams.len(), 2);
let audio = meta.streams.iter()
.find(|s| s.codec_type.eq(&Some(String::from("audio"))))
.expect("finding audio stream");
assert!(audio.codec_name.eq(&Some(String::from("vorbis"))) ||
audio.codec_name.eq(&Some(String::from("opus"))));
let video = meta.streams.iter()
.find(|s| s.codec_type.eq(&Some(String::from("video"))))
.expect("finding video stream");
assert_eq!(video.codec_name, Some(String::from("vp9")));
assert!(video.width.is_some());
let ffmpeg = Command::new("ffmpeg")
.env("LANG", "C")
.args(["-v", "error",
"-i", &out.to_string_lossy(),
"-f", "null", "-"])
.output()
.expect("spawning ffmpeg");
let msg = String::from_utf8_lossy(&ffmpeg.stderr);
if !msg.is_empty() {
eprintln!("FFMPEG stderr {msg}");
}
let _ = fs::remove_file(out);
}
#[tokio::test]
async fn test_decryption_wvcenc_shaka_container () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/spring_h265_v8/cenc/manifest_wvcenc.mpd";
let outpath = env::temp_dir().join("spring-shaka.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341237"),
String::from("12341234123412341234123412341237"))
.add_decryption_key(String::from("43215678123412341234123412341236"),
String::from("12341234123412341234123412341236"))
.with_decryptor_preference("shaka-container")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 33_746_341);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
assert!(ffmpeg_approval(&outpath));
let _ = fs::remove_file(outpath);
}
#[tokio::test]
async fn test_decryption_wvcenc_mp4box_container () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/spring_h265_v8/cenc/manifest_wvcenc.mpd";
let outpath = env::temp_dir().join("spring-mp4box-container.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341237"),
String::from("12341234123412341234123412341237"))
.add_decryption_key(String::from("43215678123412341234123412341236"),
String::from("12341234123412341234123412341236"))
.with_decryptor_preference("mp4box-container")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 33_746_341);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
assert!(ffmpeg_approval(&outpath));
let _ = fs::remove_file(outpath);
}
#[tokio::test]
async fn test_decryption_wvcbcs_mp4box_container () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/tears_of_steel_h265_v8/cbcs/manifest_wvcenc.mpd";
let outpath = env::temp_dir().join("tears-steel-wvcbcs-mp4box-container.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341237"),
String::from("12341234123412341234123412341237"))
.add_decryption_key(String::from("43215678123412341234123412341236"),
String::from("12341234123412341234123412341236"))
.with_decryptor_preference("mp4box-container")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 79_731_116);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
let _ = fs::remove_file(outpath);
}
#[tokio::test]
async fn test_decryption_prcenc_shaka_container () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/00_llama_h264_v8_8s/cenc/manifest_prcenc.mpd";
let outpath = env::temp_dir().join("llama-prcenc-shaka-container.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(3)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341236"),
String::from("12341234123412341234123412341236"))
.with_decryptor_preference("shaka-container")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 26_420_624);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
assert!(ffmpeg_approval(&outpath));
let _ = fs::remove_file(outpath);
}