Created
December 16, 2020 19:00
-
-
Save iluvcapra/943f4956be7e14168125154bc60df4e7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Detect Cuts.lua | |
Jamie Hardt 16 Dec 2020 | |
]] | |
ScriptExtKey = "COM_SQUAD51ENTERPRISES_DETECTCUTS" | |
FFmpegPathKey = "FFMPEG_PATH" | |
LastThresholdKey = "LAST_THRESHOLD" | |
function Get_FFMpeg_Path () | |
local function test_ffmpeg (test_path) | |
return os.execute(test_path .. " -t 1.0 -f lavfi -i 'color=black' -filter:v 'scdet=t=3.0' -f null /dev/null") -- on my system os.execute returns a boolean | |
end | |
local path = nil | |
if reaper.HasExtState(ScriptExtKey, FFmpegPathKey) then | |
path = reaper.GetExtState(ScriptExtKey, FFmpegPathKey) | |
else | |
local retval = reaper.MB("FFMpeg is required for this action, find the path to your FFmpeg executable now or click Cancel.","Detect Cuts",1) | |
if retval == 1 then | |
retval, path = reaper.GetUserFileNameForRead("/usr/local/bin/", "Find FFMpeg executable", "") | |
if retval then | |
reaper.SetExtState(ScriptExtKey,FFmpegPathKey,path, true) | |
return Get_FFMpeg_Path() -- tail call | |
end | |
else | |
return nil | |
end | |
end | |
if test_ffmpeg (path) then | |
return path | |
else | |
reaper.MB("Working FFMpeg could not be found at " .. path .. ".", "Detect Cuts Error",0) | |
reaper.DeleteExtState(ScriptExtKey, FFmpegPathKey, true) | |
return Get_FFMpeg_Path() -- tail call | |
end | |
end | |
local ffmpeg_path = Get_FFMpeg_Path() | |
if ffmpeg_path == nil then return else ffmpeg_path = ffmpeg_path .. " -hide_banner" end | |
function Iterate_cuts ( file_path, detection_threshold, start_offset, length ) | |
local args = " " | |
if start_offset ~= nil then | |
args = args .. "-ss " .. string.format("%f", start_offset) .. " " | |
end | |
if length ~= nil then | |
args = args .. "-t " .. string.format("%f", length) .. " " | |
end | |
args = args .. "-i \"" .. file_path .. "\" -filter:v 'scdet=t=" .. | |
string.format("%f",detection_threshold) .. ":s=1,metadata=print:file=-' -f null - 2>/dev/null" | |
local ffmpeg_read = io.popen(ffmpeg_path .. args, "r") | |
local line = nil | |
return function () | |
while true do | |
line = ffmpeg_read:read("*l") | |
if line == nil then break end | |
local pts_time = line:match("pts_time:(%d+)%.") | |
if pts_time ~= nil then | |
local time = tonumber(pts_time) | |
local time_parts = line:match("pts_time:%d+%.(%d+)") | |
if time_parts ~= nil then | |
time = tonumber(pts_time .. "." .. time_parts) | |
end | |
return time, line | |
end | |
end | |
end | |
end | |
local count = reaper.CountSelectedMediaItems(0) | |
if count > 1 then | |
reaper.MB("Please select one object. Cut detection only works on single media files.", "Cut Detection",0) | |
return | |
elseif count == 0 then | |
reaper.MB("Please select a video media object.", "Cut Detection",0) | |
return | |
end | |
local selected = reaper.GetSelectedMediaItem(0,0) | |
local selected_take = reaper.GetTake(selected, 0) | |
local source = reaper.GetMediaItemTake_Source(selected_take) | |
local filename = reaper.GetMediaSourceFileName(source, "") | |
local source_type = reaper.GetMediaSourceType(source, "") | |
if source_type ~= "VIDEO" then | |
reaper.MB("Please select a video media object.", "Cut Detection",0) | |
return | |
end | |
local default_threshold = 5.0 | |
if reaper.HasExtState(ScriptExtKey, LastThresholdKey) then | |
default_threshold = tonumber(reaper.GetExtState(ScriptExtKey, LastThresholdKey)) | |
end | |
local result, rvals = reaper.GetUserInputs("Cut Detection with ffmpeg",1,"Detection Threshold",tostring(default_threshold)) | |
if result then | |
local position = reaper.GetMediaItemInfo_Value(selected, "D_POSITION") | |
local length = reaper.GetMediaItemInfo_Value(selected, "D_LENGTH") | |
local start_offset = reaper.GetMediaItemTakeInfo_Value(selected_take, "D_STARTOFFS") | |
local this_threshold = tonumber(rvals) | |
reaper.SetExtState(ScriptExtKey, LastThresholdKey, tostring(this_threshold), true) | |
local n = 1 | |
for time, line in Iterate_cuts(filename, this_threshold, start_offset, length) do | |
-- reaper.SetEditCurPos(time+position, false, false) | |
-- reaper.Main_OnCommandEx(40012,0,0) | |
-- SPLIT: 40012 | |
reaper.AddProjectMarker(0, false, time + position, 0., "Cut: " .. line, n) | |
n = n + 1 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment