Created
June 3, 2025 21:54
-
-
Save amicojeko/70dced654c3dc40b3f52b75c3cf2052b to your computer and use it in GitHub Desktop.
Davinci Resolve Lua script to delete video segments without audio
This file contains hidden or 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
| -- rebuild_from_audio.lua – crea una timeline che contiene solo | |
| -- i segmenti dove l'audio esiste (isole dopo Detect Silence). | |
| -- da usare dopo aver fatto remove silence | |
| -------------------------------------------------- | |
| -- CONFIG | |
| local srcVTrack, srcATrack = 1, 1 -- tracce di partenza (dove c'è il materiale) | |
| local dstVTrack, dstATrack = 1, 1 -- tracce destinazione nella nuova timeline | |
| local newTLName = "AutoCut_fromAudio" | |
| -------------------------------------------------- | |
| print("=== rebuild_from_audio.lua ===") | |
| local pm = resolve:GetProjectManager() | |
| local proj = assert(pm:GetCurrentProject(), "Apri un progetto") | |
| local srcTL = assert(proj:GetCurrentTimeline(), "Apri una timeline") | |
| print("Timeline sorgente:", srcTL:GetName()) | |
| -------------------------------------------------- | |
| -- 1) prendi tutti i clip video sorgente | |
| local videoClips = srcTL:GetItemListInTrack("video", srcVTrack) or {} | |
| assert(#videoClips > 0, "Nessun clip video su V"..srcVTrack) | |
| print("Clip video trovati:", #videoClips) | |
| -------------------------------------------------- | |
| -- 2) prendi gli intervalli audio rimasti | |
| local keep = {} | |
| for _,ac in ipairs(srcTL:GetItemListInTrack("audio", srcATrack) or {}) do | |
| local s,e = ac:GetStart(), ac:GetEnd() | |
| table.insert(keep, {s,e}) | |
| print((" keep audio %d-%d"):format(s,e)) | |
| end | |
| assert(#keep>0, "Nessun segmento audio trovato") | |
| -------------------------------------------------- | |
| -- 3) crea timeline vuota | |
| local mp = proj:GetMediaPool() | |
| assert(mp, "MediaPool non disponibile") | |
| -- Aggiungi un identificatore unico al nome della timeline | |
| local timeStamp = os.date("%H%M%S") | |
| local uniqueTLName = newTLName .. "_" .. timeStamp | |
| local dstTL = mp:CreateEmptyTimeline(uniqueTLName) | |
| if not dstTL then | |
| -- Prova con un altro nome se fallisce | |
| uniqueTLName = newTLName .. "_retry_" .. timeStamp | |
| dstTL = mp:CreateEmptyTimeline(uniqueTLName) | |
| end | |
| assert(dstTL, "Impossibile creare una nuova timeline. Prova con un nome diverso o riavvia Resolve.") | |
| proj:SetCurrentTimeline(dstTL) | |
| print("Nuova timeline:", dstTL:GetName()) | |
| -------------------------------------------------- | |
| -- 4) per ogni intervallo audio ➜ trova clip video corrispondenti | |
| for i,seg in ipairs(keep) do | |
| local audioStart = seg[1] | |
| local audioEnd = seg[2] | |
| print(("Segmento audio %d: %d-%d"):format(i, audioStart, audioEnd)) | |
| -- Trova i clip video che si sovrappongono con questo segmento audio | |
| local overlappingClips = {} | |
| for _, videoClip in ipairs(videoClips) do | |
| local vStart = videoClip:GetStart() | |
| local vEnd = videoClip:GetEnd() | |
| -- Verifica se il clip video si sovrappone al segmento audio | |
| if not (vEnd <= audioStart or vStart >= audioEnd) then | |
| table.insert(overlappingClips, videoClip) | |
| print((" Clip video sovrapposto trovato: %d-%d"):format(vStart, vEnd)) | |
| end | |
| end | |
| -- Per ogni clip video sovrapposto, aggiungiamo il corrispondente segmento alla nuova timeline | |
| for _, vItem in ipairs(overlappingClips) do | |
| local vStart = vItem:GetStart() | |
| local vEnd = vItem:GetEnd() | |
| local mpi = vItem:GetMediaPoolItem() | |
| -- Calcola l'intersezione tra clip video e segmento audio | |
| local segStart = math.max(audioStart, vStart) | |
| local segEnd = math.min(audioEnd, vEnd) | |
| -- Calcola i frame sorgente corretti | |
| local vSrcOffset = vItem:GetStart() - vItem:GetSourceStartFrame() | |
| local srcIn = vItem:GetSourceStartFrame() + (segStart - vStart) | |
| local srcOut = srcIn + (segEnd - segStart) | |
| -- Posizionamento nella timeline di destinazione | |
| local recIn = segStart | |
| -- Crea il segmento nella nuova timeline | |
| local ci = { | |
| mediaPoolItem = mpi, | |
| startFrame = srcIn, | |
| endFrame = srcOut, | |
| recordFrame = recIn, | |
| trackIndex = dstVTrack, | |
| mediaType = 1, -- 1 = video only | |
| } | |
| local ai = { | |
| mediaPoolItem = mpi, | |
| startFrame = srcIn, | |
| endFrame = srcOut, | |
| recordFrame = recIn, | |
| trackIndex = dstATrack, | |
| mediaType = 2, -- 2 = audio only | |
| } | |
| mp:AppendToTimeline({ci}) -- video | |
| mp:AppendToTimeline({ai}) -- audio | |
| print((" → Aggiunto segmento: pos %d-%d, source %d-%d"):format(recIn, segEnd, srcIn, srcOut)) | |
| end | |
| end | |
| -------------------------------------------------- | |
| print("✅ Ricostruzione completata – rivedi la timeline '"..newTLName.."'") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment