Fix video rotation
This commit is contained in:
@@ -140,7 +140,9 @@ async fn is_h264_encoded(video_path: &str) -> bool {
|
|||||||
|
|
||||||
/// Check if a video has rotation metadata
|
/// Check if a video has rotation metadata
|
||||||
/// Returns the rotation angle in degrees (0, 90, 180, 270) or 0 if none detected
|
/// Returns the rotation angle in degrees (0, 90, 180, 270) or 0 if none detected
|
||||||
|
/// Checks both legacy stream tags and modern display matrix side data
|
||||||
async fn get_video_rotation(video_path: &str) -> i32 {
|
async fn get_video_rotation(video_path: &str) -> i32 {
|
||||||
|
// Check legacy rotate stream tag (older videos)
|
||||||
let output = tokio::process::Command::new("ffprobe")
|
let output = tokio::process::Command::new("ffprobe")
|
||||||
.arg("-v")
|
.arg("-v")
|
||||||
.arg("error")
|
.arg("error")
|
||||||
@@ -154,18 +156,52 @@ async fn get_video_rotation(video_path: &str) -> i32 {
|
|||||||
.output()
|
.output()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match output {
|
if let Ok(output) = output {
|
||||||
Ok(output) if output.status.success() => {
|
if output.status.success() {
|
||||||
let rotation_str = String::from_utf8_lossy(&output.stdout);
|
let rotation_str = String::from_utf8_lossy(&output.stdout);
|
||||||
let rotation_str = rotation_str.trim();
|
let rotation_str = rotation_str.trim();
|
||||||
if rotation_str.is_empty() {
|
if !rotation_str.is_empty() {
|
||||||
0
|
if let Ok(rotation) = rotation_str.parse::<i32>() {
|
||||||
} else {
|
if rotation != 0 {
|
||||||
rotation_str.parse::<i32>().unwrap_or(0)
|
debug!("Detected rotation {}° from stream tag for {}", rotation, video_path);
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => 0,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check display matrix side data (modern videos, e.g. iPhone)
|
||||||
|
let output = tokio::process::Command::new("ffprobe")
|
||||||
|
.arg("-v")
|
||||||
|
.arg("error")
|
||||||
|
.arg("-select_streams")
|
||||||
|
.arg("v:0")
|
||||||
|
.arg("-show_entries")
|
||||||
|
.arg("side_data=rotation")
|
||||||
|
.arg("-of")
|
||||||
|
.arg("default=noprint_wrappers=1:nokey=1")
|
||||||
|
.arg(video_path)
|
||||||
|
.output()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
if let Ok(output) = output {
|
||||||
|
if output.status.success() {
|
||||||
|
let rotation_str = String::from_utf8_lossy(&output.stdout);
|
||||||
|
let rotation_str = rotation_str.trim();
|
||||||
|
if !rotation_str.is_empty() {
|
||||||
|
if let Ok(rotation) = rotation_str.parse::<f64>() {
|
||||||
|
let rotation = rotation.abs() as i32;
|
||||||
|
if rotation != 0 {
|
||||||
|
debug!("Detected rotation {}° from display matrix for {}", rotation, video_path);
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VideoPlaylistManager {
|
pub struct VideoPlaylistManager {
|
||||||
|
|||||||
Reference in New Issue
Block a user