-
Notifications
You must be signed in to change notification settings - Fork 1
/
vlccrop.lua
141 lines (123 loc) · 4.87 KB
/
vlccrop.lua
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
-- vlc style crop for mpv
-- uses hotey 'c', same as VLC
-- https://github.com/kism/mpvscripts
require "mp.msg"
require "mp.options"
local crop_option = 0
local cropstring = string.format("%s-crop", mp.get_script_name())
local command_prefix = 'no-osd' --set this to null to debug
function get_target_ar(file_ar)
local result
-- Handling the current crop status in this function since its scope needs to transcent this function
crop_option = crop_option + 1
if crop_option == 1 then
mp.osd_message("Crop: 16:10")
result = 16 / 10
elseif crop_option == 2 then
mp.osd_message("Crop: 16:9")
result = 16 / 9
elseif crop_option == 3 then
mp.osd_message("Crop: 4:3")
result = 4 / 3
elseif crop_option == 4 then
mp.osd_message("Crop: 1.85:1")
result = 1.85 / 1
elseif crop_option == 5 then
mp.osd_message("Crop: 2.21:1")
result = 2.21 / 1
elseif crop_option == 6 then
mp.osd_message("Crop: 2.35:1")
result = 2.35 / 1
elseif crop_option == 7 then
mp.osd_message("Crop: 2.39:1")
result = 2.39 / 1
elseif crop_option == 8 then
mp.osd_message("Crop: 5:3")
result = 5 / 3
elseif crop_option == 9 then
mp.osd_message("Crop: 5:4")
result = 5 / 4
elseif crop_option == 10 then
mp.osd_message("Crop: 1:1")
result = 1 / 1
elseif crop_option == 11 then
mp.osd_message("Crop: 9:16")
result = 9 / 16
else
mp.osd_message("Crop: Default")
crop_option = 0
result = file_ar
end
return result
end
function has_video()
for _, track in pairs(mp.get_property_native('track-list')) do
if track.type == 'video' and track.selected then
return not track.albumart
end
end
return false
end
function on_press()
-- If it's not cropable, exit.
if not has_video() then
mp.msg.warn("autocrop only works for videos.")
return
end
-- Get current video fields, this doesnt take into consideration pixel aspect ratio
local width = mp.get_property_native("width")
local height = mp.get_property_native("height")
local aspect = mp.get_property_native("video-params/aspect")
local par = mp.get_property_native("video-params/par")
local new_w
local new_h
local new_x
local new_y
-- Get target aspect ratio
target_ar = get_target_ar(aspect)
mp.msg.info("Cropping Video, Target Aspect Ratio: " .. tostring(target_ar))
-- Compare target AR to current AR, crop height or width depending on what is needed
-- The if statements
if target_ar < aspect * 0.99 then
-- Reduce width
new_w = (height * target_ar) / par -- New width is the width multiple by the aspect ratio, adjusted for the PAR (pixel aspect ratio) incase it's not 1:1
new_h = height -- Height stays the same since we only ever crop one axis in this script
new_x = (width - new_w) / 2 -- Width - new width will equal the total space cropped, since its evenly cropped from both sides the offset needs to be halved
new_y = 0 -- This along with the height being the video height means that it will crop zero pixels
elseif target_ar > aspect * 1.01 then
-- Reduce height
new_w = width -- See new_h above
new_h = (width * (1 / target_ar)) * par -- See new_w above, need to adjust for PAR but it's in the reverse direction
new_x = 0 -- See new_y above
new_y = (height - new_h) / 2 -- See new_h above
else
-- So if the target aspect ratio is the same as the source (or within 1%), )
mp.msg.verbose("Target aspect ratio = source aspect ratio, removing filter")
cleanup() -- remove the crop filter
return -- exit the function before we apply that crop
end
-- Apply crop
mp.command(string.format("%s vf pre @%s:lavfi-crop=w=%s:h=%s:x=%s:y=%s",
command_prefix, cropstring, new_w, new_h, new_x, new_y))
end
function cleanup()
mp.msg.verbose("Cleanup")
-- This looks for applied filters that match the filter that we are using, then removes them
local filters = mp.get_property_native("vf")
for index, filter in pairs(filters) do
mp.msg.verbose("Applied Crop : " .. tostring(filter["label"]))
mp.msg.verbose("Comparing to : " .. tostring(cropstring))
if filter["label"] == cropstring then
mp.msg.info("Removing Crop")
mp.command(string.format('%s vf remove @%s', command_prefix, cropstring))
return true
end
end
return false
end
function on_start()
cleanup()
crop_option = 0 -- Reset crop option
end
mp.add_key_binding("c", "toggle_crop", on_press)
mp.register_event("file-loaded", on_start)