#!/usr/bin/env python3
import subprocess
import os
import sys
from datetime import datetime
import time
# Configuration
REOLINK_USER = "admin"
REOLINK_PASS = "Scootercam02"
REOLINK_IP = "192.168.1.211"
REOLINK_PORT = "554" # Standard RTSP port
FTP_USER = "ftp_user@scootercam.net"
FTP_PASS = "password"
FTP_HOST = "11.222.33.444"
# Directories
TEMP_DIR = "/tmp"
OUTPUT_DIR = "/var/www/html/mp"
def log(message):
"""Simple logging function"""
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f"[{timestamp}] {message}")
def check_connectivity():
"""Check if camera is reachable"""
log("Checking camera connectivity...")
try:
result = subprocess.run(['ping', '-c', '1', '-W', '2', REOLINK_IP],
capture_output=True, timeout=5)
if result.returncode == 0:
log("Camera is reachable")
return True
else:
log("ERROR: Camera is not reachable")
return False
except subprocess.TimeoutExpired:
log("ERROR: Ping timeout")
return False
except Exception as e:
log(f"ERROR: Connectivity check failed: {e}")
return False
def capture_video():
"""Capture 10 seconds of video from Reolink camera"""
timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
temp_filename = f"{TEMP_DIR}/reolink_capture_{timestamp}.mp4"
final_filename = f"{OUTPUT_DIR}/live_{timestamp}.mp4"
# RTSP URL for Reolink camera
rtsp_url = f"rtsp://{REOLINK_USER}:{REOLINK_PASS}@{REOLINK_IP}:{REOLINK_PORT}/h264Preview_01_main"
log("Starting 10-second video capture...")
# ffmpeg command to capture 10 seconds of video with audio
ffmpeg_cmd = [
'ffmpeg',
'-i', rtsp_url,
'-t', '10', # 10 seconds duration
'-c:v', 'libx264',
'-preset', 'fast',
'-crf', '23',
'-c:a', 'aac',
'-b:a', '128k',
'-vf', 'scale=1280x720:flags=lanczos',
'-movflags', '+faststart',
'-y', # Overwrite output file
temp_filename
]
try:
# Run ffmpeg with timeout
result = subprocess.run(ffmpeg_cmd, capture_output=True, text=True, timeout=30)
if result.returncode == 0:
log("Video capture completed successfully")
# Check if file was created and has reasonable size
if os.path.exists(temp_filename):
file_size = os.path.getsize(temp_filename)
if file_size > 100000: # At least 100KB
log(f"Video file created: {os.path.basename(temp_filename)} ({file_size} bytes)")
# Move to final location
os.makedirs(OUTPUT_DIR, exist_ok=True)
os.rename(temp_filename, final_filename)
return final_filename
else:
log(f"ERROR: Video file too small ({file_size} bytes)")
if os.path.exists(temp_filename):
os.remove(temp_filename)
return None
else:
log("ERROR: Video file was not created")
return None
else:
log(f"ERROR: ffmpeg failed with return code {result.returncode}")
log(f"ffmpeg stderr: {result.stderr}")
return None
except subprocess.TimeoutExpired:
log("ERROR: Video capture timed out")
return None
except Exception as e:
log(f"ERROR: Video capture failed: {e}")
return None
def upload_video(video_file):
"""Upload video to FTP server"""
if not video_file or not os.path.exists(video_file):
log("ERROR: No video file to upload")
return False
video_name = os.path.basename(video_file)
log(f"Uploading {video_name} to FTP server...")
curl_cmd = [
'curl',
'-T', video_file,
f'ftp://{FTP_HOST}/live/', # Back to /live/ directory
'--user', f'{FTP_USER}:{FTP_PASS}',
'--connect-timeout', '30',
'--max-time', '300' # 5 minute timeout for upload
]
try:
result = subprocess.run(curl_cmd, capture_output=True, text=True, timeout=360)
if result.returncode == 0:
log(f"Upload successful: {video_name}")
return True
else:
log(f"ERROR: Upload failed with return code {result.returncode}")
if result.stderr:
log(f"curl stderr: {result.stderr}")
return False
except subprocess.TimeoutExpired:
log("ERROR: Upload timed out")
return False
except Exception as e:
log(f"ERROR: Upload failed: {e}")
return False
def cleanup_old_files():
"""Clean up old temporary and video files"""
try:
# Remove temp files older than 1 hour (more targeted search)
temp_pattern = f"{TEMP_DIR}/reolink_capture_*.mp4"
subprocess.run(['find', TEMP_DIR, '-maxdepth', '1', '-name', 'reolink_capture_*.mp4',
'-mtime', '+0.04', '-delete'], timeout=10)
# Remove old live videos older than 7 days
subprocess.run(['find', OUTPUT_DIR, '-name', 'live_*.mp4',
'-mtime', '+7', '-delete'], timeout=10)
log("Cleanup completed")
except Exception as e:
log(f"Cleanup failed: {e}")
def main():
"""Main execution function"""
log("=== Starting on-demand Reolink video capture ===")
# Check dependencies
dependencies = ['ffmpeg', 'curl', 'ping']
for dep in dependencies:
try:
subprocess.run(['which', dep], check=True, capture_output=True)
except subprocess.CalledProcessError:
log(f"ERROR: Required dependency '{dep}' not found")
sys.exit(1)
# Check camera connectivity
if not check_connectivity():
sys.exit(1)
# Capture video
video_file = capture_video()
if video_file:
# Upload video
if upload_video(video_file):
log("Process completed successfully")
else:
log("Process completed with upload errors")
else:
log("Process failed during video capture")
sys.exit(1)
# Clean up old files
cleanup_old_files()
log("=== On-demand capture completed ===")
if __name__ == "__main__":
main()