Skip to content

Commit

Permalink
workflow enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
dfaker committed Jun 12, 2023
1 parent 15d8832 commit c4538b7
Show file tree
Hide file tree
Showing 10 changed files with 294 additions and 31 deletions.
30 changes: 30 additions & 0 deletions src/beatDetect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

import subprocess as sp
import numpy as np

RATE = 44100
sample = r'C:\Users\baxter001\VideoEditor\music\Beat Banger | Zoe The Hiena OST | Official Visual [Uo7BnWKbKfA].mp3'

proc = sp.Popen(['ffmpeg', '-y', '-i', sample, '-ac', '1', '-filter_complex', "[0:a]anull,aresample={}:async=1".format(RATE), '-map', '0:a', '-c:a', 'pcm_u8', '-f', 'data', '-'],stdout=sp.PIPE)

dt = np.dtype(np.uint8)
dt = dt.newbyteorder('<')

outs,errs = proc.communicate()
outs = np.frombuffer(outs, dtype=dt).flatten()

ch = np.abs(np.fft.fft(outs))
ys = np.multiply(20, np.log10(ch))
xs = np.arange(len(outs), dtype=float)
y_avg = np.mean(ys)

low_freq = [ys[i] for i in range(len(xs))]
low_freq_avg = np.mean(low_freq)

bass = low_freq[:int(len(low_freq)/2)]
bass_avg = np.mean(bass)

beats = np.where(ys<bass_avg)
print(ys.shape)
print(beats[0].shape)
print((beats[0]/RATE).astype(int))
23 changes: 22 additions & 1 deletion src/cutselectionController.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ def __init__(self,ui,initialFiles,videoManager,ffmpegService,ytdlService,voiceAc

self.ui.after(50, self.loadInitialFiles)

def getRangeDetails(self,rid):
fn = self.getcurrentFilename()
rangeDetails = self.videoManager.getRangeDetailsForClip(fn,rid)
return rangeDetails

def setDragDur(self,dur):
self.ui.setDragDur(dur)

Expand Down Expand Up @@ -247,7 +252,7 @@ def removefileIfLoaded(self,filename):
if fileRemoved:
self.ui.updateSummary(None)
self.ui.updateFileListing(self.files)
self.setUiDirtyFlag()
self.ui.setUiDirtyFlag()

def handleGlobalKeyEvent(self,evt):
pass
Expand Down Expand Up @@ -299,6 +304,9 @@ def initialisePlayer(self):
self.player.observe_property('container-fps', self.handleMpvFPSChange)

self.overlay = None

def setPlaybackSpeed(self,speed):
self.player.speed = speed

def close_ui(self):

Expand Down Expand Up @@ -554,6 +562,19 @@ def getRangesForClip(self,filename):
def getCurrentPlaybackPosition(self):
return self.currentTimePos

def updateLabelForRid(self,rid,label):
filename = self.getcurrentFilename()
self.videoManager.updateLabelForClip(filename,rid,label)

def getLabelForRid(self,rid):
filename = self.getcurrentFilename()
return self.videoManager.getLabelForClip(filename,rid)

def updatePointForRid(self,rid,pos,seconds):
filename = self.getcurrentFilename()
self.updatePointForClip(filename,rid,pos,seconds)
self.ui.setUiDirtyFlag(specificRID=rid)

def updatePointForClip(self,filename,rid,pos,seconds):
clipped = False

Expand Down
65 changes: 60 additions & 5 deletions src/cutselectionUi.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
import logging
import time
import subprocess as sp
from .modalWindows import PerfectLoopScanModal,YoutubeDLModal,TimestampModal,VoiceActivityDetectorModal,Tooltip,CutSpecificationPlanner
from .timeLineSelectionFrameUI import TimeLineSelectionFrameUI

from pygubu.widgets.scrolledframe import ScrolledFrame
from .modalWindows import PerfectLoopScanModal, YoutubeDLModal, TimestampModal, VoiceActivityDetectorModal, Tooltip, CutSpecificationPlanner, EditSubclipModal

from .timeLineSelectionFrameUI import TimeLineSelectionFrameUI

from pygubu.widgets.scrolledframe import ScrolledFrame

fastSeekLock = threading.RLock()

Expand Down Expand Up @@ -187,6 +187,10 @@ def __init__(self, master=None, controller=None,globalOptions={},*args, **kwargs
self.dragPreviewPosVar = tk.StringVar()
self.dragPreviewPosVar.trace("w", self.dragPreviewPosCallback)

self.playbackSpeed = globalOptions.get('defaultPlaybackSpeed',0.1)
self.playbackSpeedVar = tk.StringVar(self,'1')
self.playbackSpeedVar.trace("w", self.playbackSpeedCallback)

self.frameSliceLength = ttk.Frame(self.labelFrameSlice)
self.labelSiceLength = ttk.Label(self.frameSliceLength)
self.labelSiceLength.config(text="Slice Length")
Expand Down Expand Up @@ -259,6 +263,43 @@ def __init__(self, master=None, controller=None,globalOptions={},*args, **kwargs
self.framePreviewPos.config(height="200", width="200")
self.framePreviewPos.pack(fill="x", pady="0", side="top")







self.framePlaybackSpeed = ttk.Frame(self.labelFrameSlice)
self.labelPlaybackSpeed = ttk.Label(self.framePlaybackSpeed)
self.labelPlaybackSpeed.config(text="Play Speed")
self.labelPlaybackSpeed.pack(side="left",pady="0")
self.entryPlaybackSpeed = ttk.Spinbox(
self.framePlaybackSpeed,
textvariable=self.playbackSpeedVar,
from_=0.0,
to=20.0,
increment=0.01,
)

Tooltip(self.entryPlaybackSpeed,text='Playback speed multiplier.')


self.entryPlaybackSpeed.pack(side="right")
self.framePlaybackSpeed.config(height="200", width="200")
self.framePlaybackSpeed.pack(fill="x", pady="0", side="top")













self.loopModeVar = tk.StringVar()

self.loopOptions = ['Loop current','Loop all']
Expand Down Expand Up @@ -574,6 +615,10 @@ def setPausedStatus(self,paused):
def jumpClips(self,dir):
self.controller.jumpClips(dir)

def canvasPopupRangeProperties(self, rid):
scm = EditSubclipModal(master=self,controller=self.controller, rid=rid)
scm.mainloop()

def addSubclipByTextRange(self,controller,totalDuration):
initial=''
try:
Expand Down Expand Up @@ -739,7 +784,9 @@ def getCurrentlySelectedRegion(self):
def clearCurrentlySelectedRegion(self):
return self.frameTimeLineFrame.clearCurrentlySelectedRegion()

def confirmWithMessage(self,messageTitle,message,icon='warning'):
def confirmWithMessage(self,messageTitle,message,icon='warning',allowCancel=False):
if allowCancel:
return messagebox.askyesnocancel(messageTitle,message,icon=icon)
return messagebox.askquestion(messageTitle,message,icon=icon)

def jumpBack(self):
Expand Down Expand Up @@ -793,6 +840,14 @@ def targetTrimChangeCallback(self, *args):
if self.controller is not None:
self.controller.updateProgressStatistics()


def playbackSpeedCallback(self, *args):
try:
value = float(self.playbackSpeedVar.get())
self.controller.setPlaybackSpeed(value)
except Exception as e:
logging.error('Exception playbackSpeedCallback',exc_info=e)

def dragPreviewPosCallback(self, *args):
try:
value = float(self.dragPreviewPosVar.get())
Expand Down Expand Up @@ -1001,7 +1056,7 @@ def loadImageFile(self):
fileList = askopenfilenames(initialdir=initialdir,filetypes=filetypes)
duration=None
if len(fileList)>0:
duration = simpledialog.askfloat("Create video from still images", "What should the durtation of the new video clips be?",parent=self,minvalue=0.0, maxvalue=100000.0)
duration = simpledialog.askfloat("Create video from still images", "What should the durtation of the new video clips be in seconds?",parent=self, minvalue=0.0, maxvalue=100000.0)
for filename in fileList:
if filename is not None and len(filename)>0:
writeBackPath = os.path.abspath(os.path.dirname(filename))
Expand Down
2 changes: 2 additions & 0 deletions src/encodingUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ def logffmpegEncodeProgress(proc, processLabel, initialEncodedSeconds, totalExpe

statusCallback('Encoding '+processLabel, ( ((totalExpectedEncodedSeconds-initialEncodedSeconds)/2) + (currentEncodedTotal/2)+initialEncodedSeconds)/totalExpectedEncodedSeconds, lastEncodedPSNR=psnr, encodeStage='Encoding Final', currentSize=sizeNow, encodePass='Two Pass Mode Pass 2' )

except ValueError as ve:
logging.error("Awaiting timestamp in encode progress")
except Exception as e:
logging.error("Encode progress Exception", exc_info=e)
ln=b''
Expand Down
3 changes: 3 additions & 0 deletions src/mergeSelectionController.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ def __init__(self,ui,videoManager,ffmpegService,filterController,cutController,c
self.ui.setController(self)
self.videoManager.addSubclipChangeCallback(self.ui.videoSubclipDurationChangeCallback)

def getLabelForRid(self, rid):
return self.videoManager.getLabelForClip('',rid)

def autoConvert(self):
self.ui.updateSelectableVideos()
self.ui.clearSequence(includeProgress=False)
Expand Down
45 changes: 35 additions & 10 deletions src/mergeSelectionUi.py
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,9 @@ def __init__(self, master=None,defaultProfile='None', globalOptions={}, *args, *
self.mergeStyles = ['Individual Files - Output each individual subclip as a separate file.',
'Sequence - Join the subclips into a sequence.',
'Grid - Pack videos into variably sized grid layouts.',
'Stream Copy - Ignore all filters and percorm no conversions, just stream cut and join the clips.']
'Stream Copy - Ignore all filters and percorm no conversions, just stream cut and join the clips.',
#'Full Source Reencode - Ignore all filters, timestamps, make no temporary files, just re-encode the full source.',
]

self.mergeStyleVar.set(self.mergeStyles[0])

Expand Down Expand Up @@ -1912,7 +1914,10 @@ def encodeCurrent(self):
self.encoderProgress.append(encodeProgressWidget)
outputPrefix = self.filenamePrefixValue
if self.automaticFileNamingValue:
outputPrefix = self.convertFilenameToBaseName(clip.filename)
if len(self.controller.getLabelForRid(clip.rid)):
outputPrefix = self.convertFilenameToBaseName(self.controller.getLabelForRid(clip.rid),getBasename=False)
else:
outputPrefix = self.convertFilenameToBaseName(clip.filename)
self.controller.encode(self.encodeRequestId,
'STREAMCOPY',
encodeSequence,
Expand Down Expand Up @@ -1976,7 +1981,10 @@ def encodeCurrent(self):
if self.automaticFileNamingValue:
try:
print(encodeSequence)
outputPrefix = self.convertFilenameToBaseName(encodeSequence[0][0][1])
if len(self.controller.getLabelForRid(encodeSequence[0][0][0])):
outputPrefix = self.convertFilenameToBaseName(self.controller.getLabelForRid(encodeSequence[0][0][0]),getBasename=False)
else:
outputPrefix = self.convertFilenameToBaseName(encodeSequence[0][0][1])
except Exception as e:
print(e)

Expand Down Expand Up @@ -2030,7 +2038,10 @@ def encodeCurrent(self):
outputPrefix = self.filenamePrefixValue
if self.automaticFileNamingValue:
try:
outputPrefix = self.convertFilenameToBaseName(self.sequencedClips[0].filename)
if len(self.controller.getLabelForRid(self.sequencedClips[0].rid)):
outputPrefix = self.convertFilenameToBaseName(self.controller.getLabelForRid(self.sequencedClips[0].rid),getBasename=False)
else:
outputPrefix = self.convertFilenameToBaseName(self.sequencedClips[0].filename)
except:
pass

Expand Down Expand Up @@ -2081,7 +2092,10 @@ def encodeCurrent(self):
self.encoderProgress.append(encodeProgressWidget)
outputPrefix = self.filenamePrefixValue
if self.automaticFileNamingValue:
outputPrefix = self.convertFilenameToBaseName(clip.filename)
if len(self.controller.getLabelForRid(clip.rid)):
outputPrefix = self.convertFilenameToBaseName(self.controller.getLabelForRid(clip.rid),getBasename=False)
else:
outputPrefix = self.convertFilenameToBaseName(clip.filename)

self.controller.encode(self.encodeRequestId,
'CONCAT',
Expand Down Expand Up @@ -2156,25 +2170,36 @@ def updatedPredictedDuration(self):
))

if self.automaticFileNamingVar.get():
for sv in self.sequencedClips[:1]:
self.filenamePrefixVar.set( self.convertFilenameToBaseName(sv.filename) )
for sv in self.sequencedClips[:1]:
if len(self.controller.getLabelForRid(sv.rid)):
self.filenamePrefixVar.set( self.convertFilenameToBaseName(self.controller.getLabelForRid(sv.rid),getBasename=False))
else:
self.filenamePrefixVar.set( self.convertFilenameToBaseName(sv.filename) )
else:
namefound=False
for col in self.gridColumns:
for sv in col['clips']:
try:
self.filenamePrefixVar.set( self.convertFilenameToBaseName(sv.filename) )
if len(self.controller.getLabelForRid(sv.rid)):
self.filenamePrefixVar.set( self.convertFilenameToBaseName(self.controller.getLabelForRid(sv.rid),getBasename=False))
else:
self.filenamePrefixVar.set( self.convertFilenameToBaseName(sv.filename) )
namefound = True
break
except Exception as e:
print(e)
if namefound:
break

def convertFilenameToBaseName(self,filename):
def convertFilenameToBaseName(self,filename, getBasename=True):

whitespaceChars = '-_. '
usableChars = string.ascii_letters+string.digits+whitespaceChars
basenameList = ''.join(x for x in os.path.basename(filename).rpartition('.')[0] if x in usableChars)
if getBasename:
basenameList = ''.join(x for x in os.path.basename(filename).rpartition('.')[0] if x in usableChars)
else:
basenameList = ''.join(x for x in filename if x in usableChars)

for c in whitespaceChars:
basenameList = basenameList.replace(c,'-')
basename = ''
Expand Down
Loading

0 comments on commit c4538b7

Please sign in to comment.