| 1 |
import subprocess |
| 2 |
import json |
| 3 |
import os |
| 4 |
|
| 5 |
def get_video_bitrate_and_resolution(file_path): |
| 6 |
""" |
| 7 |
Extract video bitrate and resolution using ffprobe |
| 8 |
""" |
| 9 |
try: |
| 10 |
# Run ffprobe to get video stream information in JSON format |
| 11 |
result = subprocess.run([ |
| 12 |
'ffprobe', |
| 13 |
'-v', 'quiet', |
| 14 |
'-print_format', 'json', |
| 15 |
'-show_streams', |
| 16 |
'-select_streams', 'v:0', |
| 17 |
file_path |
| 18 |
], capture_output=True, text=True) |
| 19 |
|
| 20 |
# Parse the JSON output |
| 21 |
probe_data = json.loads(result.stdout) |
| 22 |
|
| 23 |
# Extract bitrate and resolution |
| 24 |
video_stream = probe_data['streams'][0] |
| 25 |
bitrate = int(video_stream.get('bit_rate', 0)) / 1000 # Convert to kbps |
| 26 |
width = int(video_stream.get('width', 0)) |
| 27 |
height = int(video_stream.get('height', 0)) |
| 28 |
|
| 29 |
return bitrate, width, height |
| 30 |
|
| 31 |
except Exception as e: |
| 32 |
print(f"Error analyzing video: {e}") |
| 33 |
return None, None, None |
| 34 |
|
| 35 |
def categorize_bitrate(bitrate, width, height): |
| 36 |
""" |
| 37 |
Categorize bitrate based on resolution and bitrate |
| 38 |
""" |
| 39 |
# Categorization based on resolution and typical bitrate recommendations |
| 40 |
if width <= 0 or height <= 0: |
| 41 |
return "Unable to determine resolution" |
| 42 |
|
| 43 |
# Calculate pixels |
| 44 |
pixels = width * height |
| 45 |
|
| 46 |
# Bitrate categories for different resolutions |
| 47 |
categories = { |
| 48 |
# 4K (3840x2160) |
| 49 |
(3840 * 2160, float('inf')): { |
| 50 |
'low': (10000, 'Low bitrate for 4K'), |
| 51 |
'medium': (20000, 'Medium bitrate for 4K'), |
| 52 |
'high': (float('inf'), 'High bitrate for 4K') |
| 53 |
}, |
| 54 |
# 1080p (1920x1080) |
| 55 |
(1920 * 1080, 3840 * 2160): { |
| 56 |
'low': (5000, 'Low bitrate for 1080p'), |
| 57 |
'medium': (10000, 'Medium bitrate for 1080p'), |
| 58 |
'high': (float('inf'), 'High bitrate for 1080p') |
| 59 |
}, |
| 60 |
# 720p (1280x720) |
| 61 |
(1280 * 720, 1920 * 1080): { |
| 62 |
'low': (2500, 'Low bitrate for 720p'), |
| 63 |
'medium': (5000, 'Medium bitrate for 720p'), |
| 64 |
'high': (float('inf'), 'High bitrate for 720p') |
| 65 |
}, |
| 66 |
# SD (640x480 or lower) |
| 67 |
(0, 1280 * 720): { |
| 68 |
'low': (1000, 'Low bitrate for SD'), |
| 69 |
'medium': (2500, 'Medium bitrate for SD'), |
| 70 |
'high': (float('inf'), 'High bitrate for SD') |
| 71 |
} |
| 72 |
} |
| 73 |
|
| 74 |
# Find the right resolution category |
| 75 |
for (min_pixels, max_pixels), thresholds in categories.items(): |
| 76 |
if min_pixels < pixels <= max_pixels: |
| 77 |
for category, (threshold, description) in thresholds.items(): |
| 78 |
if bitrate <= threshold: |
| 79 |
return f"{category.capitalize()} Bitrate ({description})" |
| 80 |
|
| 81 |
return "Unable to categorize" |
| 82 |
|
| 83 |
def main(): |
| 84 |
# Prompt for file path |
| 85 |
file_path = input("Enter the full path to the video file: ").strip('"') |
| 86 |
|
| 87 |
# Validate file exists |
| 88 |
if not os.path.exists(file_path): |
| 89 |
print("File does not exist. Please check the path and try again.") |
| 90 |
return |
| 91 |
|
| 92 |
# Get bitrate and resolution |
| 93 |
bitrate, width, height = get_video_bitrate_and_resolution(file_path) |
| 94 |
|
| 95 |
# Check if analysis was successful |
| 96 |
if bitrate is None: |
| 97 |
print("Could not analyze the video file. Ensure ffprobe is installed and the file is a valid video.") |
| 98 |
return |
| 99 |
|
| 100 |
# Print detailed information |
| 101 |
print(f"\nVideo Analysis:") |
| 102 |
print(f"Resolution: {width}x{height}") |
| 103 |
print(f"Bitrate: {bitrate:.2f} kbps") |
| 104 |
|
| 105 |
# Categorize bitrate |
| 106 |
category = categorize_bitrate(bitrate, width, height) |
| 107 |
print(f"Bitrate Category: {category}") |
| 108 |
|
| 109 |
if __name__ == "__main__": |
| 110 |
main() |