mirror of
https://github.com/pandorafuture/wx-cli.git
synced 2026-08-29 04:00:55 +00:00
141 lines
4.1 KiB
Rust
141 lines
4.1 KiB
Rust
use wx_media::MediaError;
|
|
|
|
#[cfg(feature = "audio")]
|
|
fn silent_pcm_frame() -> Vec<u8> {
|
|
vec![0_u8; 24_000 / 1_000 * 40 * 2]
|
|
}
|
|
|
|
#[cfg(feature = "audio")]
|
|
fn sample_silk() -> Vec<u8> {
|
|
silk_rs::encode_silk(silent_pcm_frame(), 24_000, 24_000, true).unwrap()
|
|
}
|
|
|
|
#[cfg(feature = "audio")]
|
|
fn long_sample_silk() -> Vec<u8> {
|
|
silk_rs::encode_silk(
|
|
vec![0_u8; silent_pcm_frame().len() * 250],
|
|
24_000,
|
|
24_000,
|
|
true,
|
|
)
|
|
.unwrap()
|
|
}
|
|
|
|
#[cfg(feature = "audio")]
|
|
#[test]
|
|
fn audio_transcode_ogg_returns_ogg_when_ffmpeg_is_available() {
|
|
if !wx_media::ffmpeg_available() {
|
|
return;
|
|
}
|
|
|
|
let result = wx_media::transcode_silk_to_ogg_opus(&sample_silk()).unwrap();
|
|
assert_eq!(result.ext, "ogg");
|
|
assert_eq!(result.mime, "audio/ogg");
|
|
assert!(result.transcoded);
|
|
assert!(!result.data.is_empty());
|
|
}
|
|
|
|
#[cfg(feature = "audio")]
|
|
#[test]
|
|
fn audio_transcode_ogg_errors_when_ffmpeg_is_missing() {
|
|
if wx_media::ffmpeg_available() {
|
|
return;
|
|
}
|
|
|
|
let result = wx_media::transcode_silk_to_ogg_opus(&sample_silk());
|
|
assert!(matches!(result, Err(MediaError::FfmpegNotFound)));
|
|
}
|
|
|
|
#[cfg(feature = "audio")]
|
|
#[test]
|
|
fn audio_transcode_mp3_keeps_existing_compatibility() {
|
|
let result = wx_media::transcode_silk_to_mp3(&sample_silk()).unwrap();
|
|
if wx_media::ffmpeg_available() {
|
|
assert_eq!(result.ext, "mp3");
|
|
assert_eq!(result.mime, "audio/mpeg");
|
|
assert!(result.transcoded);
|
|
assert!(!result.data.is_empty());
|
|
} else {
|
|
assert_eq!(result.ext, "silk");
|
|
assert_eq!(result.mime, "audio/x-silk");
|
|
assert!(!result.transcoded);
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "audio")]
|
|
#[test]
|
|
fn audio_transcode_mp3_handles_long_audio_without_hanging() {
|
|
if !wx_media::ffmpeg_available() {
|
|
return;
|
|
}
|
|
|
|
let output = run_long_audio_child(std::time::Duration::from_secs(5));
|
|
assert!(
|
|
output.status.success(),
|
|
"child failed: stdout={}\nstderr={}",
|
|
String::from_utf8_lossy(&output.stdout),
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
assert!(String::from_utf8_lossy(&output.stdout).contains("long-audio-ok"));
|
|
}
|
|
|
|
#[cfg(feature = "audio")]
|
|
#[test]
|
|
fn audio_transcode_long_audio_child_mode() {
|
|
if std::env::var_os("WECHAT_MEDIA_LONG_AUDIO_CHILD").is_none() {
|
|
return;
|
|
}
|
|
|
|
let result = wx_media::transcode_silk_to_mp3(&long_sample_silk()).unwrap();
|
|
assert_eq!(result.ext, "mp3");
|
|
assert_eq!(result.mime, "audio/mpeg");
|
|
assert!(result.transcoded);
|
|
assert!(!result.data.is_empty());
|
|
println!("long-audio-ok {}", result.data.len());
|
|
}
|
|
|
|
#[cfg(feature = "audio")]
|
|
fn run_long_audio_child(timeout: std::time::Duration) -> std::process::Output {
|
|
let current_exe = std::env::current_exe().unwrap();
|
|
let mut child = std::process::Command::new(current_exe)
|
|
.arg("--exact")
|
|
.arg("audio_transcode_long_audio_child_mode")
|
|
.arg("--nocapture")
|
|
.arg("--test-threads=1")
|
|
.env("WECHAT_MEDIA_LONG_AUDIO_CHILD", "1")
|
|
.stdout(std::process::Stdio::piped())
|
|
.stderr(std::process::Stdio::piped())
|
|
.spawn()
|
|
.unwrap();
|
|
|
|
let start = std::time::Instant::now();
|
|
loop {
|
|
if child.try_wait().unwrap().is_some() {
|
|
return child.wait_with_output().unwrap();
|
|
}
|
|
|
|
if start.elapsed() >= timeout {
|
|
let _ = child.kill();
|
|
let output = child.wait_with_output().unwrap();
|
|
panic!(
|
|
"child timed out after {:?}: stdout={}\nstderr={}",
|
|
timeout,
|
|
String::from_utf8_lossy(&output.stdout),
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
}
|
|
|
|
std::thread::sleep(std::time::Duration::from_millis(25));
|
|
}
|
|
}
|
|
|
|
#[cfg(not(feature = "audio"))]
|
|
#[test]
|
|
fn audio_transcode_feature_disabled_returns_error() {
|
|
let result = wx_media::transcode_silk_to_mp3(b"ignored");
|
|
assert!(matches!(result, Err(MediaError::AudioFeatureDisabled)));
|
|
|
|
let result = wx_media::transcode_silk_to_ogg_opus(b"ignored");
|
|
assert!(matches!(result, Err(MediaError::AudioFeatureDisabled)));
|
|
}
|