init
This commit is contained in:
293
check_files.py
Normal file
293
check_files.py
Normal file
@@ -0,0 +1,293 @@
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
import logging
|
||||
from datetime import datetime
|
||||
import sys
|
||||
|
||||
# ANSI color codes
|
||||
class Colors:
|
||||
GREEN = '\033[92m'
|
||||
RED = '\033[91m'
|
||||
YELLOW = '\033[93m'
|
||||
ENDC = '\033[0m'
|
||||
|
||||
# Set up logging
|
||||
log_dir = "logs"
|
||||
os.makedirs(log_dir, exist_ok=True)
|
||||
log_file = os.path.join(log_dir, f"check_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log")
|
||||
logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
def write_debug_info(message):
|
||||
with open("debug_output.txt", "a", encoding='utf-8') as f:
|
||||
f.write(f"{message}\n")
|
||||
|
||||
def get_file_info(file_path):
|
||||
try:
|
||||
cmd = [
|
||||
'ffprobe',
|
||||
'-v', 'error',
|
||||
'-show_entries', 'format=duration,size:stream=codec_name,codec_type,width,height,r_frame_rate,channels,channel_layout',
|
||||
'-of', 'json',
|
||||
str(file_path)
|
||||
]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
return None, f"ffprobe failed: {result.stderr}"
|
||||
info = json.loads(result.stdout)
|
||||
if 'format' not in info:
|
||||
return None, "No format information in ffprobe output"
|
||||
return info, None
|
||||
except Exception as e:
|
||||
return None, f"Error running ffprobe: {str(e)}"
|
||||
|
||||
def format_file_size(size_bytes):
|
||||
size_mb = size_bytes / (1024 * 1024)
|
||||
if size_mb >= 1024: # If size is 1GB or larger
|
||||
size_gb = size_mb / 1024
|
||||
return f"{size_gb:.2f} GB"
|
||||
return f"{size_mb:.2f} MB"
|
||||
|
||||
def check_file(input_path, output_path):
|
||||
try:
|
||||
input_info, input_error = get_file_info(input_path)
|
||||
if input_error:
|
||||
return f"Input file error: {input_error}"
|
||||
|
||||
output_info, output_error = get_file_info(output_path)
|
||||
if output_error:
|
||||
return f"Output file error: {output_error}"
|
||||
|
||||
# Check if output file exists
|
||||
if not os.path.exists(output_path):
|
||||
return f"Missing output file: {output_path}"
|
||||
|
||||
# Check duration difference
|
||||
input_duration = float(input_info['format']['duration'])
|
||||
output_duration = float(output_info['format']['duration'])
|
||||
duration_diff = abs(input_duration - output_duration)
|
||||
|
||||
if duration_diff > 0.1: # More than 0.1 seconds difference
|
||||
return f"Duration mismatch: Input={input_duration:.2f}s, Output={output_duration:.2f}s, Diff={duration_diff:.2f}s"
|
||||
|
||||
# Check video streams
|
||||
input_video = next((s for s in input_info['streams'] if s['codec_type'] == 'video'), None)
|
||||
output_video = next((s for s in output_info['streams'] if s['codec_type'] == 'video'), None)
|
||||
|
||||
if not input_video or not output_video:
|
||||
return "Missing video stream in input or output"
|
||||
|
||||
# Check video resolution
|
||||
if input_video['width'] != output_video['width'] or input_video['height'] != output_video['height']:
|
||||
return f"Resolution mismatch: Input={input_video['width']}x{input_video['height']}, Output={output_video['width']}x{output_video['height']}"
|
||||
|
||||
# Check audio streams
|
||||
input_audio = [s for s in input_info['streams'] if s['codec_type'] == 'audio']
|
||||
output_audio = [s for s in output_info['streams'] if s['codec_type'] == 'audio']
|
||||
|
||||
if len(input_audio) != len(output_audio):
|
||||
return f"Audio stream count mismatch: Input={len(input_audio)}, Output={len(output_audio)}"
|
||||
|
||||
# Check audio channels
|
||||
for i, (in_audio, out_audio) in enumerate(zip(input_audio, output_audio)):
|
||||
if in_audio['channels'] != out_audio['channels']:
|
||||
return f"Audio channel mismatch in stream {i}: Input={in_audio['channels']}, Output={out_audio['channels']}"
|
||||
|
||||
# Check file size
|
||||
input_size = int(input_info['format']['size'])
|
||||
output_size = int(output_info['format']['size'])
|
||||
|
||||
if output_size < input_size * 0.1: # Output less than 10% of input size
|
||||
return f"{Colors.YELLOW}Suspiciously small output: Input={format_file_size(input_size)}, Output={format_file_size(output_size)}{Colors.ENDC}"
|
||||
|
||||
return None # No issues found
|
||||
|
||||
except Exception as e:
|
||||
return f"Error checking file: {str(e)}"
|
||||
|
||||
def main():
|
||||
# Clear previous debug output
|
||||
with open("debug_output.txt", "w", encoding='utf-8') as f:
|
||||
f.write("=== Debug Output ===\n")
|
||||
|
||||
input_dir = "input"
|
||||
output_dir = "output"
|
||||
|
||||
# Initialize issue counters
|
||||
issue_counts = {
|
||||
"Missing from output": 0,
|
||||
"Missing from input": 0,
|
||||
"Duration mismatch": 0,
|
||||
"Missing video stream": 0,
|
||||
"Resolution mismatch": 0,
|
||||
"Audio stream count mismatch": 0,
|
||||
"Audio channel mismatch": 0,
|
||||
"Suspiciously small output": 0,
|
||||
"Other errors": 0
|
||||
}
|
||||
|
||||
write_debug_info(f"\nChecking directories at {datetime.now()}")
|
||||
write_debug_info(f"Input dir: {input_dir}")
|
||||
write_debug_info(f"Output dir: {output_dir}")
|
||||
|
||||
# Check if directories exist
|
||||
write_debug_info(f"\nDirectory existence check:")
|
||||
write_debug_info(f"Input directory exists: {os.path.exists(input_dir)}")
|
||||
write_debug_info(f"Output directory exists: {os.path.exists(output_dir)}")
|
||||
|
||||
# Try to list contents using different methods
|
||||
write_debug_info("\nTrying 'dir' command:")
|
||||
try:
|
||||
result = subprocess.run(['dir', input_dir], capture_output=True, text=True)
|
||||
write_debug_info("Input directory contents (dir command):")
|
||||
write_debug_info(result.stdout)
|
||||
except Exception as e:
|
||||
write_debug_info(f"Error with dir command: {str(e)}")
|
||||
|
||||
write_debug_info("\nTrying os.listdir():")
|
||||
try:
|
||||
write_debug_info("Input directory contents (os.listdir):")
|
||||
for item in os.listdir(input_dir):
|
||||
full_path = os.path.join(input_dir, item)
|
||||
write_debug_info(f" {item} - Exists: {os.path.exists(full_path)} - Is file: {os.path.isfile(full_path)}")
|
||||
except Exception as e:
|
||||
write_debug_info(f"Error with os.listdir: {str(e)}")
|
||||
|
||||
write_debug_info("\nTrying Path.iterdir():")
|
||||
try:
|
||||
write_debug_info("Input directory contents (Path.iterdir):")
|
||||
for item in Path(input_dir).iterdir():
|
||||
write_debug_info(f" {item.name} - Exists: {item.exists()} - Is file: {item.is_file()}")
|
||||
except Exception as e:
|
||||
write_debug_info(f"Error with Path.iterdir: {str(e)}")
|
||||
|
||||
print("\nDebug information has been written to debug_output.txt")
|
||||
print("Please check that file to see what's actually in the directories")
|
||||
|
||||
# Continue with the rest of the script...
|
||||
print("\nChecking files for inconsistencies...")
|
||||
logging.info("Starting file check")
|
||||
|
||||
# First verify the directories exist
|
||||
print("\nVerifying directories:")
|
||||
print(f"Input directory exists: {os.path.isdir(input_dir)}")
|
||||
print(f"Output directory exists: {os.path.isdir(output_dir)}")
|
||||
|
||||
if not os.path.isdir(input_dir) or not os.path.isdir(output_dir):
|
||||
print("Error: One or both directories do not exist!")
|
||||
return
|
||||
|
||||
issues_found = []
|
||||
|
||||
# Get list of files that exist in both directories, verifying each file exists
|
||||
input_files = set()
|
||||
for f in os.listdir(input_dir):
|
||||
if f.endswith(('.mp4', '.DVR.mp4')):
|
||||
full_path = os.path.join(input_dir, f)
|
||||
if os.path.isfile(full_path):
|
||||
input_files.add(f)
|
||||
write_debug_info(f"Found real file in input: {f}")
|
||||
else:
|
||||
write_debug_info(f"Found non-existent file in input: {f}")
|
||||
|
||||
output_files = set()
|
||||
for f in os.listdir(output_dir):
|
||||
if f.endswith(('.mp4', '.DVR.mp4')):
|
||||
full_path = os.path.join(output_dir, f)
|
||||
if os.path.isfile(full_path):
|
||||
output_files.add(f)
|
||||
write_debug_info(f"Found real file in output: {f}")
|
||||
else:
|
||||
write_debug_info(f"Found non-existent file in output: {f}")
|
||||
|
||||
# Debug: Print and log what files were found
|
||||
logging.info("Files found in input directory:")
|
||||
for f in sorted(input_files):
|
||||
logging.info(f" {f}")
|
||||
|
||||
logging.info("Files found in output directory:")
|
||||
for f in sorted(output_files):
|
||||
logging.info(f" {f}")
|
||||
|
||||
# Report missing files
|
||||
missing_in_output = input_files - output_files
|
||||
missing_in_input = output_files - input_files
|
||||
|
||||
if missing_in_output:
|
||||
print(f"\n{Colors.YELLOW}Files missing from output directory:{Colors.ENDC}")
|
||||
for f in sorted(missing_in_output):
|
||||
print(f" {f}")
|
||||
logging.warning(f"File missing from output: {f}")
|
||||
issues_found.append((f, "Missing from output"))
|
||||
issue_counts["Missing from output"] += 1
|
||||
|
||||
if missing_in_input:
|
||||
print(f"\n{Colors.YELLOW}Files missing from input directory:{Colors.ENDC}")
|
||||
for f in sorted(missing_in_input):
|
||||
print(f" {f}")
|
||||
logging.warning(f"File missing from input: {f}")
|
||||
issues_found.append((f, "Missing from input"))
|
||||
issue_counts["Missing from input"] += 1
|
||||
|
||||
files_to_check = input_files.intersection(output_files)
|
||||
logging.info(f"Number of matching files found: {len(files_to_check)}")
|
||||
|
||||
if not files_to_check:
|
||||
msg = "No matching files found in both input and output directories"
|
||||
print(f"\n{Colors.YELLOW}{msg}{Colors.ENDC}")
|
||||
logging.warning(msg)
|
||||
return
|
||||
|
||||
for input_file in sorted(files_to_check):
|
||||
input_path = os.path.join(input_dir, input_file)
|
||||
output_path = os.path.join(output_dir, input_file)
|
||||
|
||||
print(f"\nChecking: {input_file}")
|
||||
logging.info(f"Checking file: {input_file}")
|
||||
|
||||
issue = check_file(input_path, output_path)
|
||||
if issue:
|
||||
issues_found.append((input_file, issue))
|
||||
print(f"{Colors.RED}ISSUE FOUND: {issue}{Colors.ENDC}")
|
||||
logging.warning(f"Issue with {input_file}: {issue}")
|
||||
|
||||
# Count the type of issue
|
||||
if "Duration mismatch" in issue:
|
||||
issue_counts["Duration mismatch"] += 1
|
||||
elif "Missing video stream" in issue:
|
||||
issue_counts["Missing video stream"] += 1
|
||||
elif "Resolution mismatch" in issue:
|
||||
issue_counts["Resolution mismatch"] += 1
|
||||
elif "Audio stream count mismatch" in issue:
|
||||
issue_counts["Audio stream count mismatch"] += 1
|
||||
elif "Audio channel mismatch" in issue:
|
||||
issue_counts["Audio channel mismatch"] += 1
|
||||
elif "Suspiciously small output" in issue:
|
||||
issue_counts["Suspiciously small output"] += 1
|
||||
else:
|
||||
issue_counts["Other errors"] += 1
|
||||
else:
|
||||
print(f"{Colors.GREEN}No issues found{Colors.ENDC}")
|
||||
logging.info(f"No issues found for {input_file}")
|
||||
|
||||
# Print summary
|
||||
print("\nSummary of issues found:")
|
||||
if issues_found:
|
||||
print("\nIssue counts:")
|
||||
for issue_type, count in issue_counts.items():
|
||||
color = Colors.RED if count > 0 else Colors.GREEN
|
||||
print(f"{issue_type}: {color}{count}{Colors.ENDC}")
|
||||
|
||||
print("\nDetailed issues:")
|
||||
for file, issue in issues_found:
|
||||
print(f"\n{file}:")
|
||||
print(f"{Colors.RED} {issue}{Colors.ENDC}")
|
||||
else:
|
||||
print(f"{Colors.GREEN}No issues found in any files!{Colors.ENDC}")
|
||||
print("\nIssue counts:")
|
||||
for issue_type in issue_counts:
|
||||
print(f"{issue_type}: {Colors.GREEN}0{Colors.ENDC}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user