pub mod common;
use std::fs;
use std::env;
use std::process::Command;
use std::time::Duration;
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_content_protection_parsing() {
use dash_mpd::{parse, MPD};
setup_logging();
fn known_cp_name(name: &str) -> bool {
let known = &["cenc", "MSPR 2.0", "Widevine", "ClearKey1.0"];
known.contains(&name)
}
fn known_cp_scheme(scheme: &str) -> bool {
let known = &["urn:mpeg:dash:mp4protection:2011",
"urn:mpeg:dash:sea:2012",
"urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95",
"urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",
"urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e",
"urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4",
"urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"];
known.contains(&scheme)
}
async fn check_cp(mpd_url: &str) {
println!("Checking MPD URL {mpd_url}");
let client = reqwest::Client::builder()
.timeout(Duration::new(30, 0))
.gzip(true)
.build()
.expect("creating HTTP client");
let xml = client.get(mpd_url)
.header("Accept", "application/dash+xml,video/vnd.mpeg.dash.mpd")
.send().await
.expect("requesting MPD content")
.text().await
.expect("fetching MPD content");
let mpd: MPD = parse(&xml)
.expect("parsing MPD");
for p in mpd.periods {
for adap in p.adaptations.iter() {
for cp in adap.ContentProtection.iter() {
if let Some(v) = &cp.value {
assert!(known_cp_name(v));
}
assert!(known_cp_scheme(&cp.schemeIdUri));
}
}
}
}
check_cp("https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p.mpd").await;
}
#[tokio::test]
async fn test_decryption_webm_shaka() {
setup_logging();
let url = "https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine/dash.mpd";
let out = env::temp_dir().join("angel.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")
.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);
}
#[ignore]
#[tokio::test]
async fn test_decryption_cra () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://devs.origin.cdn.cra.cz/dashmultikey/manifest.mpd";
let outpath = env::temp_dir().join("cra.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("75bf33ac08440c81d623019c87fe1360"),
String::from("bacd0a82f91a44d9315e6269dd769e0f"))
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 28_926_446);
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_mp4decrypt () {
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-mp4decrypt.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"))
.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_shaka () {
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")
.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 () {
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.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")
.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_mp4decrypt () {
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-mp4decrypt.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"))
.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_wvcbcs_shaka () {
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-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")
.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_wvcbcs_mp4box () {
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.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")
.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_mp4decrypt () {
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-mp4decrypt.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"))
.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);
}
#[tokio::test]
async fn test_decryption_prcenc_shaka () {
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.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")
.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);
}
#[tokio::test]
async fn test_decryption_prcenc_mp4box () {
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-mp4box.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("mp4box")
.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);
}
#[tokio::test]
async fn test_decryption_marlincenc_mp4decrypt () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/agent327_h264_v8/cenc/manifest_mlcenc.mpd";
let outpath = env::temp_dir().join("llama-marlin-cenc-mp4decrypt.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 14_357_917);
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_marlincenc_shaka () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/agent327_h264_v8/cenc/manifest_mlcenc.mpd";
let outpath = env::temp_dir().join("llama-marlin-cenc-shaka.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.with_decryptor_preference("shaka")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 14_357_917);
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_marlincenc_mp4box () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/agent327_h264_v8/cenc/manifest_mlcenc.mpd";
let outpath = env::temp_dir().join("llama-marlin-cenc-mp4box.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.with_decryptor_preference("mp4box")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 14_357_917);
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_marlincbcs_mp4decrypt () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/agent327_h264_v8/cbcs/manifest_mlcenc.mpd";
let outpath = env::temp_dir().join("llama-marlin-cbcs.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 14_357_925);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
let _ = fs::remove_file(outpath);
}
#[tokio::test]
async fn test_decryption_marlincbcs_shaka () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/agent327_h264_v8/cbcs/manifest_mlcenc.mpd";
let outpath = env::temp_dir().join("llama-marlin-cbcs-shaka.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.with_decryptor_preference("shaka")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 14_357_925);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
let _ = fs::remove_file(outpath);
}
#[tokio::test]
async fn test_decryption_marlincbcs_mp4box () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/agent327_h264_v8/cbcs/manifest_mlcenc.mpd";
let outpath = env::temp_dir().join("llama-marlin-cbcs-mp4box.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.with_decryptor_preference("mp4box")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 14_357_925);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
let _ = fs::remove_file(&outpath);
}
#[tokio::test]
async fn test_decryption_mlcenc_shaka () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/agent327_h264_v8/cenc/manifest_mlcenc.mpd";
let outpath = env::temp_dir().join("llama-mlcenc-shaka.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.with_decryptor_preference("shaka")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 14_357_917);
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_mlcbcs_shaka () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/agent327_h264_v8/cbcs/manifest_mlcenc.mpd";
let outpath = env::temp_dir().join("llama-mlcbcs-shaka.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.with_decryptor_preference("shaka")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 14_357_925);
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_mlcbcs_mp4box () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://refapp.hbbtv.org/videos/agent327_h264_v8/cbcs/manifest_mlcenc.mpd";
let outpath = env::temp_dir().join("llama-mlcbcs-mp4box.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.with_decryptor_preference("mp4box")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 14_357_925);
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_axinom_cmaf_h265_multikey () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://media.axprod.net/TestVectors/H265/protected_cmaf_1080p_h265_multikey/manifest.mpd";
let outpath = env::temp_dir().join("axinom-h264-multikey.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("53dc3eaa5164410a8f4ee15113b43040"),
String::from("620045a34e839061ee2e9b7798fdf89b"))
.add_decryption_key(String::from("9dbace9e41034c5296aa63227dc5f773"),
String::from("a776f83276a107a3c322f9dbd6d4f48c"))
.add_decryption_key(String::from("a76f0ca68e7d40d08a37906f3e24dde2"),
String::from("2a99b42f08005ab4b57af20f4da3cc05"))
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 48_233_447);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
assert!(ffmpeg_approval(&outpath));
}
#[tokio::test]
async fn test_decryption_axinom_cbcs_shaka () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://media.axprod.net/TestVectors/v9-MultiFormat/Encrypted_Cbcs/Manifest_1080p.mpd";
let outpath = env::temp_dir().join("axinom-cbcs-shaka.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("f8c80c25690f47368132430e5c6994ce"),
String::from("7bc99cb1dd0623cd0b5065056a57a1dd"))
.with_decryptor_preference("shaka")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 41_614_809);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
assert!(ffmpeg_approval(&outpath));
}
#[tokio::test]
async fn test_decryption_axinom_cbcs_mp4box () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "https://media.axprod.net/TestVectors/v9-MultiFormat/Encrypted_Cbcs/Manifest_1080p.mpd";
let outpath = env::temp_dir().join("axinom-cbcs-mp4box.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("f8c80c25690f47368132430e5c6994ce"),
String::from("7bc99cb1dd0623cd0b5065056a57a1dd"))
.with_decryptor_preference("mp4box")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 41_614_809);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
assert!(ffmpeg_approval(&outpath));
}
#[tokio::test]
async fn test_decryption_axinom_widevine_shaka () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "http://media.axprod.net/TestVectors/v6.1-MultiDRM/Manifest_1080p.mpd";
let outpath = env::temp_dir().join("axinom-widevine-shaka.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("6e5a1d26275747d78046eaa5d1d34b5a"),
String::from("197f26f572c864d2338b3ae5d114ea9c"))
.with_decryptor_preference("shaka")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 47_396_046);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
assert!(ffmpeg_approval(&outpath));
}
#[tokio::test]
async fn test_decryption_axinom_widevine_mp4box () {
setup_logging();
if env::var("CI").is_ok() {
return;
}
let mpd = "http://media.axprod.net/TestVectors/v6.1-MultiDRM/Manifest_1080p.mpd";
let outpath = env::temp_dir().join("axinom-widevine-mp4box.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("6e5a1d26275747d78046eaa5d1d34b5a"),
String::from("197f26f572c864d2338b3ae5d114ea9c"))
.with_decryptor_preference("mp4box")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 47_396_046);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
assert!(ffmpeg_approval(&outpath));
}
#[ignore]
#[tokio::test]
async fn test_decryption_oldsmall () {
setup_logging();
let mpd = "https://m.dtv.fi/dash/dasherh264/drm/manifest_clearkey.mpd";
let outpath = env::temp_dir().join("caminandes.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 6_975_147);
assert!(ffmpeg_approval(&outpath));
}
#[tokio::test]
async fn test_decryption_small () {
setup_logging();
let mpd = "https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine/dash.mpd";
let outpath = env::temp_dir().join("angel.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.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")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 1_316_391);
assert!(ffmpeg_approval(&outpath));
}
#[tokio::test]
async fn test_decryption_unencrypted_mp4decrypt () {
setup_logging();
let mpd = "http://dash.edgesuite.net/envivio/dashpr/clear/Manifest.mpd";
let outpath = env::temp_dir().join("unencrypted-mp4decrypt.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.with_decryptor_preference("mp4decrypt")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 12_975_377);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
assert!(ffmpeg_approval(&outpath));
}
#[ignore]
#[tokio::test]
async fn test_decryption_unencrypted_shaka () {
setup_logging();
let mpd = "http://dash.edgesuite.net/envivio/dashpr/clear/Manifest.mpd";
let outpath = env::temp_dir().join("unencrypted-shaka.mp4");
if outpath.exists() {
let _ = fs::remove_file(&outpath);
}
DashDownloader::new(mpd)
.worst_quality()
.verbosity(2)
.sandbox(true)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.with_decryptor_preference("shaka")
.download_to(&outpath).await
.unwrap();
check_file_size_approx(&outpath, 12_975_377);
let format = FileFormat::from_file(&outpath).unwrap();
assert_eq!(format, FileFormat::Mpeg4Part14Video);
assert!(ffmpeg_approval(&outpath));
let _ = fs::remove_file(outpath);
}
#[tokio::test]
#[should_panic(expected = "unknown decryption application")]
async fn test_decryption_invalid_decryptor () {
let mpd = "http://dash.edgesuite.net/envivio/dashpr/clear/Manifest.mpd";
let outpath = env::temp_dir().join("failing.mp4");
DashDownloader::new(mpd)
.add_decryption_key(String::from("43215678123412341234123412341234"),
String::from("12341234123412341234123412341234"))
.with_decryptor_preference("unknown")
.download_to(&outpath).await
.unwrap();
}
#[tokio::test]
#[should_panic(expected = "Decrypting")]
async fn test_decryption_invalid_key_mp4decrypt () {
let mpd = "http://dash.edgesuite.net/envivio/dashpr/clear/Manifest.mpd";
let outpath = env::temp_dir().join("failing.mp4");
DashDownloader::new(mpd)
.add_decryption_key(String::from("66"),
String::from("99"))
.with_decryptor_preference("mp4decrypt")
.download_to(&outpath).await
.unwrap();
}
#[tokio::test]
#[should_panic(expected = "Decrypting")]
async fn test_decryption_invalid_key_shaka () {
let mpd = "http://dash.edgesuite.net/envivio/dashpr/clear/Manifest.mpd";
let outpath = env::temp_dir().join("failing.mp4");
DashDownloader::new(mpd)
.add_decryption_key(String::from("66"),
String::from("99"))
.with_decryptor_preference("shaka")
.download_to(&outpath).await
.unwrap();
}