diff --git a/Bookmarks from file.py b/Bookmarks from file.py new file mode 100644 index 0000000..ba15767 --- /dev/null +++ b/Bookmarks from file.py @@ -0,0 +1,216 @@ +#mod by GPo 2017 + +import re +import cPickle + +filename = avsp.GetFilename(_('Select a file'), filefilter= + _('All supported files') + '|*.txt;*.xml;*.ses;*.log;*.qp|' + + _('Chapters Text files') + ' (*.txt)|*.txt|'+ + _('Matroska XML files') + ' (*.xml)|*.xml|' + + _('Celltimes files') + ' (*.txt)|*.txt|' + + _('AvsP Session files') + ' (*.ses)|*.ses|' + + _('Avisynth files') + ' (*.avs)|*.avs|' + + _('TFM log files') + ' (*.log)|*.log|' + + _('XviD log files') + ' (*.log)|*.log|' + + _('QP files') + ' (*.qp)|*.qp|' + + _('Timecode format v1 files') + ' (*.txt)|*.txt|' + + _('All files') + ' (*.*)|*.*') +if not filename: + return + +lines = avsp.GetWindow().GetTextFromFile(filename)[0] + +bookmarkDict = {} +Book_Ident = u'#Bookmarks:' + +# parsing QP-file (GPo change for title in bookmarks) parse simple txt file +if not bookmarkDict: + try: + for index in lines.strip().split('\n'): + s = index.strip() + if s != '': + a = {} + title = '' + a = s.split(' ') + if a[0].isdigit(): + if len(a) > 1: + title = str(a[1]) + if len(a) > 2: + title = title + ' ' + str(a[2]) + bookmarkDict[int(a[0])] = title + except: + bookmarkDict = {} + +## parse Bookmarks from avs file. #Bookmarks: 32 ,122 MyTitle,544 +def findBookmarks_txt(): + txt = {} + txt = avsp.GetText(index=None, clean=False).split('\n') + for s in txt: + #if s.find(Book_Ident) > -1: + if s.strip().startswith(Book_Ident): + return s.strip(Book_Ident) + return '' + +## Ein Leerzeichen im title erlaubt +if not bookmarkDict: + try: + ss = findBookmarks_txt() + if ss != '': + for index in ss.split(','): + s = index.strip() + if s != '': + a = {} + title = '' + a = s.split(' ') + if a[0].isdigit(): + if len(a) > 1: + title = str(a[1]) + if len(a) > 2: + title = title + ' ' + str(a[2]) + bookmarkDict[int(a[0])] = title + except: + bookmarkDict = {} + +################################################################# + +# parsing Timecode format v1: place a bookmark on every starting frame +if not bookmarkDict: + if lines.startswith('# timecode format v1'): + match = re.search(r'^\s*assume\s*(\d*\.*\d+\.*\d*)', lines, re.M|re.I) + base_fps = (match.group(1) if match else 'unknown') + ' fps' + bookmarkDict[0] = base_fps + for line in lines.splitlines(): + if line and line[0].isdigit(): + start, end, fps = line.split(',') + bookmarkDict[int(start)] = fps + ' fps' + bookmarkDict[int(end)+1] = base_fps + +# parsing SCXviD log +if not bookmarkDict: + try: + if lines.startswith('# XviD 2pass stat file'): + bookmarkDict=dict((i-3,'') for i,v in enumerate(lines.split('\n')) if v.startswith('i')) + except: + bookmarkDict = {} + +# parsing TFM output +if not bookmarkDict: + if lines.startswith('#TFM '): + try: + stats = lines.split('# FORMAT:') + if len(stats)==5: + sectionslice = (0,(2,-2),(2,-4),(2,-4),(2,-1)) + section = lambda sectionidx: stats[sectionidx].strip().split('\n')[sectionslice[sectionidx][0]:sectionslice[sectionidx][1]] + sectionisempty = lambda sectionidx: 'none detected' in stats[sectionidx] + + frameindent = 4 + frametitle = lambda line: line[line.find(' ',frameindent+1)+1:] + framenum = lambda line: int(line[1:line.find(' ',frameindent)]) + + dCombed = dict( (framenum(L), frametitle(L)) for L in section(1) ) if not sectionisempty(1) else {} + dGrouped = dict( (int(F), frametitle(L)) for L in section(2) for F in re.split('[\s,]',L[frameindent:])[:-2] ) if not sectionisempty(2) else {} + dPossible = dict( (framenum(L), frametitle(L)) for L in section(3) ) if not sectionisempty(3) else {} + dUBmatch = dict( (int(F),L[-1]) for L in section(4) for F in re.split('[\s,]',L[frameindent:-2]) ) if not sectionisempty(4) else {} + maxframe = max([max(d.keys()) if d.keys() else -1 for d in (dCombed, dPossible, dUBmatch)]) + if maxframe == -1: + avsp.MsgBox(_('Not combed or out of order frames'), _('Bookmarks from TFM file')) + return + s=avsp.GetTextEntry( \ + [_('Combed') + ' (%d)' % len(dCombed),\ + _('Possible') + ' (%d)' % len(dPossible),\ + _('u,b,out-of-order') + ' (%d)' % len(dUBmatch),\ + '',\ + _('Min frame:'),\ + _('Max frame:')],\ + [True,True,True,'','0',str(maxframe)],\ + _('TFM log parser'),\ + ['check','check','check','sep','text','text'],\ + 250 ) + if not s: return + + if s[0]: bookmarkDict.update(dCombed) + if s[1]: bookmarkDict.update(dPossible) + if s[2]: bookmarkDict.update(dUBmatch) + + try: + f1,f2=int(s[3]),int(s[4]) + if f1!=0 or f2!=maxframe: + bookmarkDict=dict( (f,t) for (f,t) in bookmarkDict.items() if f1<=f<=f2 ) + except: + pass + + avsp.GetWindow().GetStatusBar().SetStatusText( _('%d frames imported') % len(bookmarkDict) ) + except: + raise + avsp.MsgBox(_('[COMBED FRAMES] section could not be parsed')) + return + +# parsing chapters text files +if not bookmarkDict: + timeList = re.findall(r'(\d+)=(\d+):(\d+):(\d+\.\d+)', lines) + if timeList: + fps = avsp.GetVideoFramerate() + titleDict = {} + for index, title in re.findall(r'(\d+)NAME=(.*)', lines, re.I): + titleDict[index] = title + for index, hr, min, sec in timeList: + sec = int(hr)*3600 + int(min)*60 + float(sec) + bookmark = int(round(sec*fps)) + bookmarkDict[bookmark] = titleDict.get(index, '') + +# parsing matroska xml files +if not bookmarkDict: + sections = re.findall(r'(.*?)', lines, re.I|re.S) + fps = avsp.GetVideoFramerate() + for text in sections: + timecode = re.search(r'(\d+):(\d+):(\d+\.\d+)', text) + if not timecode: + continue + title = re.search(r'(.*?)', text) + hr, min, sec = timecode.groups() + sec = int(hr)*3600 + int(min)*60 + float(sec) + bookmark = int(round(sec*fps)) + bookmarkDict[bookmark] = title.group(1) if title else '' + +# parsing celltime format - frame count content +if not bookmarkDict: + try: + for index in lines.strip().split(): + bookmarkDict[int(index)] = '' + except: + bookmarkDict = {} + +# parsing AvsP ssesion files +if not bookmarkDict: + try: + f = open(filename, 'rb') + session = cPickle.load(f) + except: + pass + f.close() + try: + if 'bookmarks' in session: + if 'bookMarkDict' in session: + for bookmark, btype in session['bookmarks']: + bookmarkDict[bookmark] = session['bookMarkDict'].get(bookmark, '') + else: + for bookmark, btype in session['bookmarks']: + bookmarkDict[bookmark] = '' + except: + pass + +if bookmarkDict: + bookmarkList = bookmarkDict.items() + # Don't delete current bookmarks, update its title if supplied + #oldBookmarks = avsp.GetBookmarkList() + #for bookmark, title in bookmarkDict.items(): + #if bookmark in oldBookmarks: + #if title: + #bookmarkList.append((bookmark, title)) + #else: + #bookmarkList.remove((bookmark, title)) + # GPo delete old bookmarks + avsp.GetWindow().DeleteAllFrameBookmarks() + avsp.SetBookmark(bookmarkList) +else: + avsp.MsgBox(_('Bookmark file unrecognized!'), _('Error')) \ No newline at end of file diff --git a/Insert Trims from bookmarks (multi-line)GPo.py b/Insert Trims from bookmarks (multi-line)GPo.py new file mode 100644 index 0000000..b5751c1 --- /dev/null +++ b/Insert Trims from bookmarks (multi-line)GPo.py @@ -0,0 +1,23 @@ +# GPo 2020 +import wx + +bmlist = avsp.GetBookmarkList(title=False) +if not bmlist: + wx.MessageBox(_('No bookmarks defined.'), _('Error'), style=wx.OK|wx.ICON_ERROR) + return + +bmlist.sort() +count = len(bmlist) +txt = 'c0=Trim(0, {})\n'.format(bmlist[0]-1) +c = 1 +for i in xrange(count): + if i < count-1: + start = bmlist[i] + end = bmlist[i+1]-1 + else: + start = bmlist[i] + end = 0 + txt += 'c{}=Trim({}, {})\n'.format(c, start, end) + c += 1 + +avsp.InsertText(txt, pos=None) \ No newline at end of file diff --git a/Next tab to current frame time.py b/Next tab to current frame time.py new file mode 100644 index 0000000..4f2ddaa --- /dev/null +++ b/Next tab to current frame time.py @@ -0,0 +1,33 @@ +# GPo 2020, Next tab to current frame time.py +# Changes the tab and shows the video frame from the previous frame time code +# So there must be a second tab with a changed frame rate + +import wx +self = avsp.GetWindow() + +script = self.currentScript +if script.AVI is None: + wx.Bell() + return + +frame = self.GetFrameNumber() +try: + tc = frame/self.MacroGetVideoFramerate() +except: + wx.Bell() + return + +self.SelectTab(index=None, inc=1) +script = self.currentScript + +try: + frame = int(round(tc * self.MacroGetVideoFramerate())) +except: + wx.Bell() + return + +if frame < 0 or (script.AVI and frame >= script.AVI.Framecount): + wx.Bell() + return + +self.ShowVideoFrame(frame) \ No newline at end of file diff --git a/SCFile to bookmarks .py b/SCFile to bookmarks .py new file mode 100644 index 0000000..6d4ff80 --- /dev/null +++ b/SCFile to bookmarks .py @@ -0,0 +1,54 @@ +import wx +re=avsp.GetTextEntry(_('Start from first scene:'), True, + _('Select scene start'), 'check', 200) +if re == '': + return + +filename = avsp.GetFilename(_('Select the scene file'), filefilter= + _('Log files') + '|*.log|' + + _('Log and Text files') + '|*.txt;*.log|' + + _('All files') + ' (*.*)|*.*') + +if not filename: + return +self = avsp.GetWindow() +txt = self.GetTextFromFile(filename)[0] +txt = txt.strip() +first = re +bookmarkDict = {} +lines = txt.split('\n') +count = len(lines) + +try: + for index, line in enumerate(lines): + s = line.strip() + if not s.isdigit(): + raise + if first: + if index == 0: + bookmarkDict[int(s)] = 1 + if index < count -1: + s = lines[index+1].strip() + if not s.isdigit(): break + bookmarkDict[int(s)-1] = 2 + elif index % 2 == 0: + bookmarkDict[int(s)] = 1 + if index < count -1: + s = lines[index+1].strip() + if not s.isdigit(): break + bookmarkDict[int(s)-1] = 2 + elif index > 0 and index % 2 != 0: + bookmarkDict[int(s)] = 1 + if index < count -1: + s = lines[index+1].strip() + if not s.isdigit(): break + bookmarkDict[int(s)-1] = 2 +except: + bookmarkDict = {} + avsp.MsgBox(_('Error reading scenes'), _('Error')) + +if bookmarkDict: + items = bookmarkDict.items() + for i, item in enumerate(items): + value, bmtype = item + self.AddFrameBookmark(value, bmtype, refreshVideo=False) \ No newline at end of file diff --git a/Save Image with frame number.py b/Save Image with frame number.py new file mode 100644 index 0000000..b786905 --- /dev/null +++ b/Save Image with frame number.py @@ -0,0 +1,105 @@ +# GPo 2018, AvsPmod macro save image + +""" +# find source file name for the image name and not the avs or script filename +# search for my pattern and find the source filename (sourceFile, videosource... etc) +# finds also ScriptDir() + "My Video.mkv" +# doesn't override any file +# +# My default AvsPmod templates eg 'mkv, ts, etc..': +# +# SourceFile = ScriptDir() + [***] +# SourceFile = Exist(SourceFile) ? SourceFile : *** +# video=LWLibavVideoSource(SourceFile, cache=False) +# audio=LWLibavAudioSource(SourceFile, cache=False) +# audioDub(video, audio) +""" + +import os +import sys + +# enable Input for filename if source file not found +# else filename is tab name (script name) +doMessage=True + +sourceFile='' +fileName='' +# save as jpg +fnExt='.jpg' +# jpg Quality +jpgQ=90 +framenr='' + +# enable this for frame number, does not override existing files +framenr= '_' + str(avsp.GetFrameNumber()) + +# for test +#fileName= avsp.GetScriptFilename() + +if not fileName: + sep = '"' + txt = avsp.GetText(index=None, clean=False) + i = txt.lower().find('sourcefile : "') + if i < 0: + i = txt.lower().find('videosource("') + if i < 0: + i = txt.lower().find('source("') + if i > -1: + s = txt[i : len(txt)] + #avsp.MsgBox(s, cancel = True) + a = {} + a = s.split(sep) + if len(a) > 1: + fileName = a[1] + else: + i = txt.lower().find('scriptdir') + if i > -1: + s = txt[i : len(txt)] + a = {} + a = s.split(sep) + if len(a) > 1: + fileName = os.path.join(avsp.GetScriptFilename(propose='general', only='dir'), a[1]) + +# if source not found, remove the avs ext and hopefully the source have the same name +if not fileName: + fileName=os.path.splitext(avsp.GetScriptFilename(propose='general'))[0]# remove '.avs' + +fileName = fileName.encode(sys.getfilesystemencoding()) + +if os.path.isfile(fileName): + sourceFile = fileName + fileName = os.path.splitext(fileName)[0] + if fileName: + fileName += framenr +else: + dir=avsp.GetScriptFilename(propose='general', only='dir') + fn=os.path.splitext(avsp.GetScriptFilename(propose='general', only='base'))[0] + framenr + if dir: + dir = dir.encode(sys.getfilesystemencoding()) + fn = fn.encode(sys.getfilesystemencoding()) + if doMessage: + tx = avsp.GetTextEntry(message=dir, default=fn, title='Enter Filename to save the Image', types='text', width=300) + if not tx: + return + else: + tx = fn + fileName = os.path.join(dir, tx) + +if fileName: + if os.path.isfile(fileName + fnExt): + i = 2 + s = fileName + while os.path.isfile(s + fnExt): + s = fileName + ' (' + str(i) + ')' + i += 1 + fileName = s + fnExt + else: + fileName += fnExt + #fileName=fileName.encode(sys.getfilesystemencoding()) + +#avsp.MsgBox(fileName, cancel = True) +fileName=avsp.SaveImage(filename=fileName, framenum=None, index=None, default='', quality=jpgQ) + +if fileName and sourceFile: +# for other uses + pass \ No newline at end of file diff --git a/Save Image.py b/Save Image.py new file mode 100644 index 0000000..205f7e9 --- /dev/null +++ b/Save Image.py @@ -0,0 +1,105 @@ +# GPo 2018, AvsPmod macro save image + +""" +# find source file name for the image name and not the avs or script filename +# search for my pattern and find the source filename (sourceFile, videosource... etc) +# finds also ScriptDir() + "My Video.mkv" +# doesn't override any file +# +# My default AvsPmod templates eg 'mkv, ts, etc..': +# +# SourceFile = ScriptDir() + [***] +# SourceFile = Exist(SourceFile) ? SourceFile : *** +# video=LWLibavVideoSource(SourceFile, cache=False) +# audio=LWLibavAudioSource(SourceFile, cache=False) +# audioDub(video, audio) +""" + +import os +import sys + +# enable Input for filename if source file not found +# else filename is tab name (script name) +doMessage=True + +sourceFile='' +fileName='' +# save as jpg +fnExt='.jpg' +# jpg Quality +jpgQ=90 +framenr='' + +# enable this for frame number, does not override existing files +#framenr= '_' + str(avsp.GetFrameNumber()) + +# for test +#fileName= avsp.GetScriptFilename() + +if not fileName: + sep = '"' + txt = avsp.GetText(index=None, clean=False) + i = txt.lower().find('sourcefile : "') + if i < 0: + i = txt.lower().find('videosource("') + if i < 0: + i = txt.lower().find('source("') + if i > -1: + s = txt[i : len(txt)] + #avsp.MsgBox(s, cancel = True) + a = {} + a = s.split(sep) + if len(a) > 1: + fileName = a[1] + else: + i = txt.lower().find('scriptdir') + if i > -1: + s = txt[i : len(txt)] + a = {} + a = s.split(sep) + if len(a) > 1: + fileName = os.path.join(avsp.GetScriptFilename(propose='general', only='dir'), a[1]) + +# if source not found, remove the avs ext and hopefully the source have the same name +if not fileName: + fileName=os.path.splitext(avsp.GetScriptFilename(propose='general'))[0]# remove '.avs' + +fileName = fileName.encode(sys.getfilesystemencoding()) + +if os.path.isfile(fileName): + sourceFile = fileName + fileName = os.path.splitext(fileName)[0] + if fileName: + fileName += framenr +else: + dir=avsp.GetScriptFilename(propose='general', only='dir') + fn=os.path.splitext(avsp.GetScriptFilename(propose='general', only='base'))[0] + framenr + if dir: + dir = dir.encode(sys.getfilesystemencoding()) + fn = fn.encode(sys.getfilesystemencoding()) + if doMessage: + tx = avsp.GetTextEntry(message=dir, default=fn, title='Enter Filename to save the Image', types='text', width=300) + if not tx: + return + else: + tx = fn + fileName = os.path.join(dir, tx) + +if fileName: + if os.path.isfile(fileName + fnExt): + i = 2 + s = fileName + while os.path.isfile(s + fnExt): + s = fileName + ' (' + str(i) + ')' + i += 1 + fileName = s + fnExt + else: + fileName += fnExt + #fileName=fileName.encode(sys.getfilesystemencoding()) + +#avsp.MsgBox(fileName, cancel = True) +fileName=avsp.SaveImage(filename=fileName, framenum=None, index=None, default='', quality=jpgQ) + +if fileName and sourceFile: +# for other uses + pass \ No newline at end of file