vidaio / scripts /clip_video.py
DavidHstar's picture
Update model files
f72237c verified
#!/usr/bin/env python3
"""
Video Clipping Script
This script clips a video file to exactly 19 seconds starting from the beginning.
Uses ffmpeg for efficient video processing.
"""
import os
import sys
import subprocess
from pathlib import Path
from typing import Optional, Tuple
import argparse
def _validate_video_file(file_path: str) -> bool:
"""
Validate that the input file exists and is a readable video file.
Args:
file_path: Path to the video file
Returns:
True if file is valid, False otherwise
"""
if not os.path.exists(file_path):
print(f"Error: File '{file_path}' does not exist.")
return False
if not os.path.isfile(file_path):
print(f"Error: '{file_path}' is not a file.")
return False
if not os.access(file_path, os.R_OK):
print(f"Error: File '{file_path}' is not readable.")
return False
return True
def _get_video_duration(file_path: str) -> Optional[float]:
"""
Get the duration of a video file using ffprobe.
Args:
file_path: Path to the video file
Returns:
Duration in seconds, or None if ffprobe fails
"""
try:
cmd = [
'ffprobe',
'-v', 'quiet',
'-show_entries', 'format=duration',
'-of', 'csv=p=0',
file_path
]
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
duration = float(result.stdout.strip())
return duration
except (subprocess.CalledProcessError, ValueError, FileNotFoundError) as e:
print(f"Error getting video duration: {e}")
return None
def _generate_output_filename(input_path: str) -> str:
"""
Generate output filename by adding '_19s' suffix before the extension.
Args:
input_path: Path to the input video file
Returns:
Output filename with '_19s' suffix
"""
input_path_obj = Path(input_path)
stem = input_path_obj.stem
suffix = input_path_obj.suffix
# Create output filename
output_filename = f"{stem}_19s{suffix}"
# If output would overwrite input, add timestamp
if output_filename == input_path_obj.name:
from datetime import datetime
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_filename = f"{stem}_19s_{timestamp}{suffix}"
return output_filename
def _clip_video(input_path: str, output_path: str, duration: int = 19) -> bool:
"""
Clip the video to the specified duration using ffmpeg.
Args:
input_path: Path to the input video file
output_path: Path for the output video file
duration: Duration to clip to in seconds (default: 19)
Returns:
True if clipping was successful, False otherwise
"""
try:
cmd = [
'ffmpeg',
'-i', input_path,
'-t', str(duration),
'-c', 'copy', # Copy streams without re-encoding for speed
'-avoid_negative_ts', 'make_zero',
'-y', # Overwrite output file if it exists
output_path
]
print(f"Cliping video to {duration} seconds...")
print(f"Input: {input_path}")
print(f"Output: {output_path}")
# Run ffmpeg command
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
print("Video clipping completed successfully!")
return True
except subprocess.CalledProcessError as e:
print(f"Error during video clipping: {e}")
if e.stderr:
print(f"FFmpeg error: {e.stderr}")
return False
except Exception as e:
print(f"Unexpected error: {e}")
return False
def clip_video_to_19s(video_path: str) -> bool:
"""
Main function to clip a video file to 19 seconds.
Args:
video_path: Path to the input video file
Returns:
True if clipping was successful, False otherwise
"""
# Validate input file
if not _validate_video_file(video_path):
return False
# Get original video duration
original_duration = _get_video_duration(video_path)
if original_duration is None:
return False
print(f"Original video duration: {original_duration:.2f} seconds")
# Check if video is already shorter than 19 seconds
if original_duration <= 19:
print(f"Video is already {original_duration:.2f} seconds long (≤ 19s). No clipping needed.")
return True
# Generate output filename
output_filename = _generate_output_filename(video_path)
output_path = os.path.join(os.path.dirname(video_path), output_filename)
# Perform video clipping
success = _clip_video(video_path, output_path, 19)
if success:
# Verify output file exists and get its duration
if os.path.exists(output_path):
output_duration = _get_video_duration(output_path)
if output_duration:
print(f"Output video duration: {output_duration:.2f} seconds")
print(f"Output saved to: {output_path}")
else:
print("Warning: Could not verify output video duration")
else:
print("Warning: Output file was not created")
return success
def main():
"""Main entry point for command line usage."""
parser = argparse.ArgumentParser(
description="Clip a video file to 19 seconds",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python clip_video.py video.mp4
python clip_video.py /path/to/video.mov
python clip_video.py "video with spaces.avi"
"""
)
parser.add_argument(
'video_path',
help='Path to the input video file'
)
#python clip_video.py --video_path /workspace/vidaio-subnet/2025-03-18 12-27-33.mov
args = parser.parse_args()
# Perform video clipping
success = clip_video_to_19s(args.video_path)
# Exit with appropriate code
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()