-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshrinker.py
73 lines (48 loc) · 2.56 KB
/
shrinker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
from enum import Enum
import subprocess
import json
import time
import sys
FILE_SIZE_LIMIT_IN_BYTES = 10485760 # 10 * 1024 * 1024
FILE_SIZE_LIMIT_STR = f'{FILE_SIZE_LIMIT_IN_BYTES // 1024 // 1024}mb'
FileSizeLimit = Enum('FileSizeLimit', ['OVER', 'UNDER'])
def get_file_path():
return sys.argv[1]
def get_data(file_path):
stdout = subprocess.run(f'.\\ffprobe.exe -i "{file_path}" -v quiet -print_format json -show_streams -show_format', capture_output=True, encoding='UTF-8').stdout
data_json = json.loads(stdout)
return data_json
def check_file_size(file_path):
data = get_data(file_path)
if int(data['format']['size']) < FILE_SIZE_LIMIT_IN_BYTES:
return FileSizeLimit.UNDER
return FileSizeLimit.OVER
def split_video(file_path, output_path, output_file_video, output_file_audio):
subprocess.run(f'.\\ffmpeg.exe -i "{file_path}" -y -c:v copy -an "{output_path + output_file_video}" -c:a copy -vn "{output_path + output_file_audio}"')
def merge_video(file_path_1, file_path_2, output_path, output_file_name):
subprocess.run(f'.\\ffmpeg.exe -i "{file_path_1}" -i "{file_path_2}" -y -c copy "{output_path + output_file_name}"')
def determine_target_bitrate(video_file_path, audio_file_path):
video_data = get_data(video_file_path)
audio_data = get_data(audio_file_path)
reduction_coefficient = int(video_data['format']['size']) / (FILE_SIZE_LIMIT_IN_BYTES - int(audio_data['format']['size']))
target_bitrate = int(video_data['streams'][0]['bit_rate']) / reduction_coefficient
return target_bitrate
def change_bitrate(file_path, output_path, output_file_name, target_bitrate):
subprocess.run(f'.\\ffmpeg.exe -i "{file_path}" -y -b:v {target_bitrate} -maxrate:v {target_bitrate} -bufsize 750K "{output_path + output_file_name}"')
def main():
original_file_path = get_file_path()
try:
if check_file_size(original_file_path) == FileSizeLimit.UNDER:
print(f'\nFile is already under {FILE_SIZE_LIMIT_STR}.')
time.sleep(2)
sys.exit(0)
except KeyError as e:
print('\nInvalid file format.')
time.sleep(2)
sys.exit(1)
split_video(original_file_path, '.\\tmp\\', 'video_only.mp4', 'audio_only.mp4')
target_bitrate = determine_target_bitrate('.\\tmp\\video_only.mp4', '.\\tmp\\audio_only.mp4')
change_bitrate('.\\tmp\\video_only.mp4', '.\\tmp\\', 'changed_bitrate.mp4', target_bitrate)
merge_video('.\\tmp\\changed_bitrate.mp4', '.\\tmp\\audio_only.mp4', original_file_path, f'_{FILE_SIZE_LIMIT_STR}.mp4')
if __name__ == "__main__":
main()