ffmpegx 0.1.5

Rust bindings for FFmpeg, providing common features such as frame sequence decoding and PCM data encoding/decoding.
Documentation
use super::core::Ffmpeg;
impl Ffmpeg {
    /// Get keyframe timestamps from a video file
    ///
    /// Extracts the timestamps of all keyframes (I-frames) from the video
    /// using ffprobe. Falls back to packet-based analysis if frame-based
    /// analysis fails.
    ///
    /// # Arguments
    /// * `file_path` - Path to the video file
    ///
    /// # Returns
    /// * `Ok(Vec<f64>)` - List of keyframe timestamps in seconds
    /// * `Err(String)` - Error message if extraction fails
    pub fn get_keyframes(&self, file_path: &str) -> Result<Vec<f64>, String> {
        if !std::path::Path::new(file_path).exists() {
            return Err(format!("File not found: {}", file_path));
        }
        let output = std::process::Command::new("ffprobe")
            .args(["-v", "error", "-select_streams", "v:0", "-show_entries", "frame=key_frame,pts_time", "-of", "csv=p=0", file_path])
            .output()
            .map_err(|e| format!("ffprobe failed: {}", e))?;
        if !output.status.success() {
            let stderr = String::from_utf8_lossy(&output.stderr);
            return Err(format!("ffprobe error: {}", stderr));
        }
        let output_str = String::from_utf8_lossy(&output.stdout);
        let mut timestamps = Vec::new();
        for line in output_str.lines() {
            let parts: Vec<&str> = line.split(',').collect();
            if parts.len() >= 2 {
                let key_frame = parts[0].trim();
                let pts_time = parts[1].trim();
                if key_frame == "1" {
                    if let Ok(time) = pts_time.parse::<f64>() {
                        timestamps.push(time);
                    }
                }
            }
        }
        if timestamps.is_empty() {
            return self.get_keyframe_timestamps_from_packets(file_path);
        }
        if timestamps.len() > 0 {}
        Ok(timestamps)
    }
    /// Get keyframe timestamps from packet analysis
    ///
    /// Alternative method to extract keyframe timestamps by analyzing
    /// packet flags instead of frame data. Used as fallback when
    /// the primary frame-based method fails.
    ///
    /// # Arguments
    /// * `file_path` - Path to the video file
    ///
    /// # Returns
    /// * `Ok(Vec<f64>)` - List of keyframe timestamps in seconds
    /// * `Err(String)` - Error message if extraction fails
    fn get_keyframe_timestamps_from_packets(&self, file_path: &str) -> Result<Vec<f64>, String> {
        let output = std::process::Command::new("ffprobe")
            .args(["-v", "error", "-select_streams", "v:0", "-show_entries", "packet=flags,pts_time", "-of", "csv=p=0", file_path])
            .output()
            .map_err(|e| format!("ffprobe failed: {}", e))?;
        let output_str = String::from_utf8_lossy(&output.stdout);
        let mut timestamps = Vec::new();
        for line in output_str.lines() {
            let parts: Vec<&str> = line.split(',').collect();
            if parts.len() >= 2 {
                let flags = parts[0].trim();
                let pts_time = parts[1].trim();
                if flags.contains('K') {
                    if let Ok(time) = pts_time.parse::<f64>() {
                        timestamps.push(time);
                    }
                }
            }
        }
        if timestamps.len() > 0 {}
        Ok(timestamps)
    }
}