2014-04-29 12:11:39 +00:00
|
|
|
-- This script uses the lavfi cropdetect filter to automatically
|
|
|
|
-- insert a crop filter with appropriate parameters for the currently
|
|
|
|
-- playing video.
|
|
|
|
--
|
|
|
|
-- It registers the key-binding "C" (shift+c), which when pressed,
|
|
|
|
-- inserts the filter vf=lavfi=cropdetect. After 1 second, it then
|
|
|
|
-- inserts the filter vf=crop=w:h:x:y, where w,h,x,y are determined
|
|
|
|
-- from the vf-metadata gathered by cropdetect. The cropdetect filter
|
|
|
|
-- is removed immediately after the crop filter is inserted as it is
|
|
|
|
-- no longer needed.
|
|
|
|
--
|
|
|
|
-- If the "C" key is pressed again, the crop filter is removed
|
|
|
|
-- restoring playback to its original state.
|
|
|
|
--
|
|
|
|
-- Since the crop parameters are determined from the 1 second of video
|
|
|
|
-- between inserting the cropdetect and crop filters, the "C" key
|
|
|
|
-- should be pressed at a position in the video where the crop region
|
|
|
|
-- is unambiguous (i.e., not a black frame, black background title
|
|
|
|
-- card, or dark scene).
|
|
|
|
--
|
|
|
|
-- The default delay between insertion of the cropdetect and
|
|
|
|
-- crop filters may be overridden by adding
|
|
|
|
--
|
|
|
|
-- --lua-opts=autocrop.detect_seconds=<number of seconds>
|
|
|
|
--
|
|
|
|
-- to mpv's arguments. This may be desirable to allow cropdetect more
|
|
|
|
-- time to collect data.
|
|
|
|
|
2014-04-29 11:07:25 +00:00
|
|
|
script_name=string.gsub(mp.get_script_name(),"lua/","")
|
|
|
|
cropdetect_label=string.format("%s-cropdetect",script_name)
|
|
|
|
crop_label=string.format("%s-crop",script_name)
|
2014-04-11 11:50:06 +00:00
|
|
|
|
2014-04-29 11:07:25 +00:00
|
|
|
-- number of seconds to gather cropdetect data
|
|
|
|
detect_seconds = tonumber(mp.get_opt(string.format("%s.detect_seconds", script_name)))
|
|
|
|
if not detect_seconds then
|
|
|
|
detect_seconds = 1
|
2014-04-11 11:50:06 +00:00
|
|
|
end
|
2014-04-29 11:07:25 +00:00
|
|
|
|
|
|
|
function del_filter_if_present(label)
|
|
|
|
-- necessary because mp.command('vf del @label:filter') raises an
|
|
|
|
-- error if the filter doesn't exist
|
|
|
|
local vfs = mp.get_property_native('vf')
|
|
|
|
for i,vf in pairs(vfs) do
|
|
|
|
if vf['label'] == label then
|
|
|
|
table.remove(vfs, i)
|
|
|
|
mp.set_property_native('vf', vfs)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
function autocrop_start()
|
|
|
|
-- if there's a crop filter, just remove it and exit
|
|
|
|
if del_filter_if_present(crop_label) then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
-- insert the cropdetect filter
|
|
|
|
ret=mp.command(
|
|
|
|
string.format(
|
|
|
|
'vf add @%s:lavfi=graph="cropdetect=limit=24:round=2:reset=0"',
|
|
|
|
cropdetect_label
|
|
|
|
)
|
|
|
|
)
|
|
|
|
-- wait to gather data
|
|
|
|
mp.add_timeout(detect_seconds, do_crop)
|
|
|
|
end
|
|
|
|
|
|
|
|
function do_crop()
|
|
|
|
require 'mp.msg'
|
|
|
|
-- get the metadata
|
|
|
|
local cropdetect_metadata = mp.get_property_native(
|
|
|
|
string.format('vf-metadata/%s', cropdetect_label)
|
|
|
|
)
|
|
|
|
-- use it to crop if its valid
|
|
|
|
if cropdetect_metadata then
|
|
|
|
if cropdetect_metadata['lavfi.cropdetect.w']
|
|
|
|
and cropdetect_metadata['lavfi.cropdetect.h']
|
|
|
|
and cropdetect_metadata['lavfi.cropdetect.x']
|
|
|
|
and cropdetect_metadata['lavfi.cropdetect.y']
|
|
|
|
then
|
|
|
|
mp.command(string.format('vf add @%s:crop=%s:%s:%s:%s',
|
|
|
|
crop_label,
|
|
|
|
cropdetect_metadata['lavfi.cropdetect.w'],
|
|
|
|
cropdetect_metadata['lavfi.cropdetect.h'],
|
|
|
|
cropdetect_metadata['lavfi.cropdetect.x'],
|
|
|
|
cropdetect_metadata['lavfi.cropdetect.y']))
|
|
|
|
else
|
|
|
|
mp.msg.error(
|
|
|
|
"Got empty crop data. You might need to increase detect_seconds."
|
|
|
|
)
|
|
|
|
end
|
|
|
|
else
|
|
|
|
mp.msg.error(
|
|
|
|
"No crop data. Was the cropdetect filter successfully inserted?"
|
|
|
|
)
|
|
|
|
mp.msg.error(
|
|
|
|
"Does your version of ffmpeg/libav support AVFrame metadata?"
|
|
|
|
)
|
|
|
|
end
|
|
|
|
-- remove the cropdetect filter
|
|
|
|
del_filter_if_present(cropdetect_label)
|
|
|
|
end
|
|
|
|
|
|
|
|
mp.add_key_binding("C","auto_crop",autocrop_start)
|