├── macros ├── Examples │ ├── [3] ---.py │ ├── [0] Template example.py │ ├── [4] Secondary preview.py │ ├── [1] Batch example.py │ ├── [5] Encoding example.py │ ├── [6] Encoding example 2.py │ ├── [2] Image processing.py │ └── [3] Manual Telecide.py ├── Example (Resize) │ ├── [10] ---.py │ ├── [20] ---.py │ ├── [30] ---.py │ ├── [40] ---.py │ ├── [32] rrr bicubic.py │ ├── [33] rrr lanczos.py │ ├── [31] rrr bilinear.py │ ├── [42] CCC force mod 2.py │ ├── [41] ccc create new tab.py │ ├── [34] RRR spline36.py │ ├── [01].py │ ├── [03].py │ ├── [11].py │ ├── [13].py │ ├── [02].py │ ├── [04].py │ ├── [12].py │ ├── [14].py │ └── [21] Customized.py ├── DeleteFrame.py ├── DuplicateFrame.py ├── startup.txt ├── startup_avs.txt ├── Shift Bookmarks Div 2.py ├── Shift Bookmarks by frames.py ├── Bookmarks to Trims.py ├── Preview from current point.py ├── Bookmarks at Intervals.py ├── Random Clip Order.py ├── Bookmarks to Chapter.py ├── Selected trims to selections.py ├── Open Image Sequence.py ├── CopyPixelinfo.py ├── Extra │ ├── Save Image_rgb48.py │ └── DeleteEncodings.py ├── Run analysis pass.py ├── ConditionalReader file from bookmarks.py └── Import bookmarks from file.py ├── cfunc ├── Pre-Compiled.txt ├── x64 │ └── cfunc.pyd └── x86 │ └── cfunc.pyd ├── AvsP.ico ├── changelog.txt ├── help ├── images │ ├── donation.gif │ ├── logos │ │ ├── 1.gif │ │ └── img_background.gif │ ├── avsp_calltip.jpg │ ├── avsp_calltip2.jpg │ ├── avsp_calltip3.jpg │ ├── avsp_openwith.jpg │ ├── avsp_toolbar.jpg │ ├── avsp_cropeditor.jpg │ ├── avsp_templates.jpg │ ├── avsp_trimeditor.jpg │ ├── avsp_autocomplete.jpg │ ├── avsp_exportfilters.jpg │ ├── avsp_optionsfonts.jpg │ ├── avsp_videopreview.jpg │ ├── avsp_optionsfilters.jpg │ ├── avsp_optionsfilters2.jpg │ ├── avsp_optionsgeneral.jpg │ ├── avsp_toggletagafter.jpg │ ├── avsp_toggletagbefore.jpg │ ├── avsp_toggletagvideo.jpg │ ├── avsp_usersliderafter.jpg │ ├── avsp_userslidervideo.jpg │ ├── avsp_videobookmarks.jpg │ ├── avsp_usersliderbefore.jpg │ ├── avsp_usersliderdialog.jpg │ ├── avsp_usersliderdialog2.jpg │ ├── avsp_usersliderseparator.jpg │ └── avsp_customizevideostatusbar.jpg ├── stylesheets │ ├── voidspace_docutils2.css │ ├── rest2web.css │ └── default.css ├── Translation.html ├── Download.html ├── About.html └── Overview.html ├── tools ├── ToolsMenu.py ├── x264.presets.default └── ffmpeg.presets.default ├── translations └── translation_readme.txt ├── readme_d2v_based_template.txt ├── license_cpuid ├── readme_NumberWheel.txt ├── readme_FullscreenZoom.txt ├── readme_Tablist.txt ├── readme_Audio.txt ├── global_vars.py ├── readme_D3D_Window.txt ├── run.py ├── avs ├── types.h ├── capi.h └── config.h ├── readme_FastClip.txt ├── readme_resampleFilter.txt ├── readme_threads.txt ├── dpi.py ├── readme_applyFilters.txt ├── readme_LocateFrame.txt ├── func.py ├── readme_ScriptSelector.txt ├── readme_SplitClip.txt ├── cfunc.py ├── previewFilterExample.avs ├── previewFilterExample.txt ├── cpuid.py ├── README.md └── icons.py /macros/Examples/[3] ---.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[10] ---.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[20] ---.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[30] ---.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[40] ---.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[32] rrr bicubic.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[33] rrr lanczos.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[31] rrr bilinear.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[42] CCC force mod 2.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cfunc/Pre-Compiled.txt: -------------------------------------------------------------------------------- 1 | cfunc.py compiled private build -------------------------------------------------------------------------------- /macros/Example (Resize)/[41] ccc create new tab.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AvsP.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/AvsP.ico -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/changelog.txt -------------------------------------------------------------------------------- /cfunc/x64/cfunc.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/cfunc/x64/cfunc.pyd -------------------------------------------------------------------------------- /cfunc/x86/cfunc.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/cfunc/x86/cfunc.pyd -------------------------------------------------------------------------------- /help/images/donation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/donation.gif -------------------------------------------------------------------------------- /help/images/logos/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/logos/1.gif -------------------------------------------------------------------------------- /help/images/avsp_calltip.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_calltip.jpg -------------------------------------------------------------------------------- /help/images/avsp_calltip2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_calltip2.jpg -------------------------------------------------------------------------------- /help/images/avsp_calltip3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_calltip3.jpg -------------------------------------------------------------------------------- /help/images/avsp_openwith.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_openwith.jpg -------------------------------------------------------------------------------- /help/images/avsp_toolbar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_toolbar.jpg -------------------------------------------------------------------------------- /help/images/avsp_cropeditor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_cropeditor.jpg -------------------------------------------------------------------------------- /help/images/avsp_templates.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_templates.jpg -------------------------------------------------------------------------------- /help/images/avsp_trimeditor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_trimeditor.jpg -------------------------------------------------------------------------------- /macros/Example (Resize)/[34] RRR spline36.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # File Name: 3 | # Description: 4 | 5 | -------------------------------------------------------------------------------- /help/images/avsp_autocomplete.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_autocomplete.jpg -------------------------------------------------------------------------------- /help/images/avsp_exportfilters.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_exportfilters.jpg -------------------------------------------------------------------------------- /help/images/avsp_optionsfonts.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_optionsfonts.jpg -------------------------------------------------------------------------------- /help/images/avsp_videopreview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_videopreview.jpg -------------------------------------------------------------------------------- /help/images/avsp_optionsfilters.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_optionsfilters.jpg -------------------------------------------------------------------------------- /help/images/avsp_optionsfilters2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_optionsfilters2.jpg -------------------------------------------------------------------------------- /help/images/avsp_optionsgeneral.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_optionsgeneral.jpg -------------------------------------------------------------------------------- /help/images/avsp_toggletagafter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_toggletagafter.jpg -------------------------------------------------------------------------------- /help/images/avsp_toggletagbefore.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_toggletagbefore.jpg -------------------------------------------------------------------------------- /help/images/avsp_toggletagvideo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_toggletagvideo.jpg -------------------------------------------------------------------------------- /help/images/avsp_usersliderafter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_usersliderafter.jpg -------------------------------------------------------------------------------- /help/images/avsp_userslidervideo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_userslidervideo.jpg -------------------------------------------------------------------------------- /help/images/avsp_videobookmarks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_videobookmarks.jpg -------------------------------------------------------------------------------- /help/images/logos/img_background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/logos/img_background.gif -------------------------------------------------------------------------------- /help/images/avsp_usersliderbefore.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_usersliderbefore.jpg -------------------------------------------------------------------------------- /help/images/avsp_usersliderdialog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_usersliderdialog.jpg -------------------------------------------------------------------------------- /help/images/avsp_usersliderdialog2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_usersliderdialog2.jpg -------------------------------------------------------------------------------- /help/images/avsp_usersliderseparator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_usersliderseparator.jpg -------------------------------------------------------------------------------- /help/images/avsp_customizevideostatusbar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gispos/AvsPmod/HEAD/help/images/avsp_customizevideostatusbar.jpg -------------------------------------------------------------------------------- /macros/DeleteFrame.py: -------------------------------------------------------------------------------- 1 | frame = avsp.GetFrameNumber() 2 | avsp.InsertText('\nDeleteFrame(%i)' % frame) 3 | avsp.ShowVideoFrame(forceRefresh=True) -------------------------------------------------------------------------------- /macros/DuplicateFrame.py: -------------------------------------------------------------------------------- 1 | frame = avsp.GetFrameNumber() 2 | avsp.InsertText('\nDuplicateFrame(%i)' % frame) 3 | avsp.ShowVideoFrame(forceRefresh=True) -------------------------------------------------------------------------------- /macros/startup.txt: -------------------------------------------------------------------------------- 1 | # Insert your Python code and rename the file to "startup.pys" 2 | # the file does execute as macro at ProzessArguments (Comandline), for all files except "avs, vpy" -------------------------------------------------------------------------------- /macros/startup_avs.txt: -------------------------------------------------------------------------------- 1 | # Insert your Python code and rename the file to "startup_avs.pys" 2 | # the file does execute as macro at ProzessArguments (Comandline), only for "avs, vpy" files -------------------------------------------------------------------------------- /tools/ToolsMenu.py: -------------------------------------------------------------------------------- 1 | menuInfo = ( 2 | ('resize_calc', _('Resize calculator...'), _('Calculate an appropriate resize for the video')), 3 | ('session_info', _('Session info tool'), _('Gives session information for the opened folder/files')), 4 | (''), 5 | ('encoder_gui', _('Script encoder (CLI)'), _('Use an external command line encoder to save the current script')), 6 | ('avs2avi_gui', _('Script encoder (VFW)'), _('Use avs2avi to save the current script as an avi')), 7 | (''), 8 | ) -------------------------------------------------------------------------------- /macros/Shift Bookmarks Div 2.py: -------------------------------------------------------------------------------- 1 | # Written by GPo 2 | # Shift all bookmarks div 2. 3 | # Useful if bookmarks were set and you forgot to reduce the framerate from 50 to 25 with SelectEven(). 4 | 5 | try: 6 | try: 7 | bookmarks=[(b+-int(b//2), t) for b,t in avsp.GetBookmarkList( title=True )] 8 | except TypeError: 9 | bookmarks=[(b+-int(b//2)) for b in avsp.GetBookmarkList()] 10 | avsp.GetWindow().DeleteAllFrameBookmarks(bmtype=0) 11 | avsp.SetBookmark( bookmarks ) 12 | except: 13 | pass -------------------------------------------------------------------------------- /macros/Shift Bookmarks by frames.py: -------------------------------------------------------------------------------- 1 | # Written by wOxxOm 2 | try: 3 | shift=int(avsp.GetTextEntry(_('Introduce the number of frames:'), '', 4 | _('Shift bookmarks by # frames'), 'spin', 200)) 5 | try: 6 | bookmarks=[(b+shift, t) for b,t in avsp.GetBookmarkList( title=True )] 7 | except TypeError: 8 | bookmarks=[(b+shift) for b in avsp.GetBookmarkList()] 9 | avsp.GetWindow().DeleteAllFrameBookmarks() 10 | avsp.SetBookmark( bookmarks ) 11 | except: 12 | pass -------------------------------------------------------------------------------- /macros/Bookmarks to Trims.py: -------------------------------------------------------------------------------- 1 | # GPo 2020, AvsPmod macro Bookmarks to trims 2 | 3 | bmlist = avsp.GetBookmarkList(title=False) 4 | if not bmlist: 5 | avsp.MsgBox(_('No bookmarks defined.'), _('Error')) 6 | return 7 | 8 | bmlist.sort() 9 | count = len(bmlist) 10 | txt = '' 11 | 12 | for i in xrange(count): 13 | if i %2 == 0: 14 | txt += 'Trim(' + str(bmlist[i]) 15 | else: 16 | txt += ', ' + str(bmlist[i]) + ') ++ ' 17 | 18 | if count %2 == 0: 19 | txt = txt[:-4] 20 | else: 21 | txt += ', 0)' 22 | 23 | avsp.InsertText(txt, pos=None) -------------------------------------------------------------------------------- /macros/Example (Resize)/[01].py: -------------------------------------------------------------------------------- 1 | # PAL DV 4:3 - 59:54 2 | # above 'PAL DV 4:3 - 59:54' will be the name displayed on the menu, 3 | # because the filename contains no label 4 | 5 | # If several macros are doing very similar things, you can just write a 6 | # main one to handle all cases. Use callafter=True to ensure the main 7 | # macro runs after the current one returns. 8 | # In general, you should return a value, and then, the main macro can 9 | # retrieve it from the 'avsp.Last' variable. 10 | avsp.ExecuteMenuCommand(_('Customized'), callafter=True) 11 | return 59, 54 -------------------------------------------------------------------------------- /macros/Example (Resize)/[03].py: -------------------------------------------------------------------------------- 1 | # PAL DVD 4:3 - 16:15 2 | # above 'PAL DVD 4:3 - 16:15' will be the name displayed on the menu, 3 | # because the filename contains no label 4 | 5 | # If several macros are doing very similar things, you can just write a 6 | # main one to handle all cases. Use callafter=True to ensure the main 7 | # macro runs after the current one returns. 8 | # In general, you should return a value, and then, the main macro can 9 | # retrieve it from the 'avsp.Last' variable. 10 | avsp.ExecuteMenuCommand(_('Customized'), callafter=True) 11 | return 16, 15 12 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[11].py: -------------------------------------------------------------------------------- 1 | # NTSC DV 4:3 - 10:11 2 | # above 'NTSC DV 4:3 - 10:11' will be the name displayed on the menu, 3 | # because the filename contains no label 4 | 5 | # If several macros are doing very similar things, you can just write a 6 | # main one to handle all cases. Use callafter=True to ensure the main 7 | # macro runs after the current one returns. 8 | # In general, you should return a value, and then, the main macro can 9 | # retrieve it from the 'avsp.Last' variable. 10 | avsp.ExecuteMenuCommand(_('Customized'), callafter=True) 11 | return 10, 11 12 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[13].py: -------------------------------------------------------------------------------- 1 | # NTSC DVD 4:3 - 8:9 2 | # above 'NTSC DVD 4:3 - 8:9' will be the name displayed on the menu, 3 | # because the filename contains no label 4 | 5 | # If several macros are doing very similar things, you can just write a 6 | # main one to handle all cases. Use callafter=True to ensure the main 7 | # macro runs after the current one returns. 8 | # In general, you should return a value, and then, the main macro can 9 | # retrieve it from the 'avsp.Last' variable. 10 | avsp.ExecuteMenuCommand(_('Customized'), callafter=True) 11 | return 8, 9 12 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[02].py: -------------------------------------------------------------------------------- 1 | # PAL DV 16:9 - 118:81 2 | # above 'PAL DV 16:9 - 118:81' will be the name displayed on the menu, 3 | # because the filename contains no label 4 | 5 | # If several macros are doing very similar things, you can just write a 6 | # main one to handle all cases. Use callafter=True to ensure the main 7 | # macro runs after the current one returns. 8 | # In general, you should return a value, and then, the main macro can 9 | # retrieve it from the 'avsp.Last' variable. 10 | avsp.ExecuteMenuCommand(_('Customized'), callafter=True) 11 | return 118, 81 12 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[04].py: -------------------------------------------------------------------------------- 1 | # PAL DVD 16:9 - 64:45 2 | # above 'PAL DVD 16:9 - 64:45' will be the name displayed on the menu, 3 | # because the filename contains no label 4 | 5 | # If several macros are doing very similar things, you can just write a 6 | # main one to handle all cases. Use callafter=True to ensure the main 7 | # macro runs after the current one returns. 8 | # In general, you should return a value, and then, the main macro can 9 | # retrieve it from the 'avsp.Last' variable. 10 | avsp.ExecuteMenuCommand(_('Customized'), callafter=True) 11 | return 64, 45 12 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[12].py: -------------------------------------------------------------------------------- 1 | # NTSC DV 16:9 - 40:33 2 | # above 'NTSC DV 16:9 - 40:33' will be the name displayed on the menu, 3 | # because the filename contains no label 4 | 5 | # If several macros are doing very similar things, you can just write a 6 | # main one to handle all cases. Use callafter=True to ensure the main 7 | # macro runs after the current one returns. 8 | # In general, you should return a value, and then, the main macro can 9 | # retrieve it from the 'avsp.Last' variable. 10 | avsp.ExecuteMenuCommand(_('Customized'), callafter=True) 11 | return 40, 33 12 | -------------------------------------------------------------------------------- /macros/Example (Resize)/[14].py: -------------------------------------------------------------------------------- 1 | # NTSC DVD 16:9 - 32:27 2 | # above 'NTSC DVD 16:9 - 32:27' will be the name displayed on the menu, 3 | # because the filename contains no label 4 | 5 | # If several macros are doing very similar things, you can just write a 6 | # main one to handle all cases. Use callafter=True to ensure the main 7 | # macro runs after the current one returns. 8 | # In general, you should return a value, and then, the main macro can 9 | # retrieve it from the 'avsp.Last' variable. 10 | avsp.ExecuteMenuCommand(_('Customized'), callafter=True) 11 | return 32, 27 12 | -------------------------------------------------------------------------------- /translations/translation_readme.txt: -------------------------------------------------------------------------------- 1 | In order to translate AvsPmod, you will need a file named "translation_lng.py", 2 | where "lng" is the three-letter code corresponding to the language that is 3 | translated to (see ). 4 | 5 | If you are updating a translation from an older version, simply place the 6 | old "translation_lng.py" in the translations subdirectory and run AvsPmod. 7 | It will automatically update the translation file with all the new messages 8 | in the current version requiring translation. 9 | 10 | If you are translating for the first time, simply place an empty text file 11 | named "translation_lng.py" in the translations subdirectory and run AvsPmod. 12 | Open the translation file in your text editor of choice, and read the 13 | instructions within to begin translating the program. 14 | -------------------------------------------------------------------------------- /macros/Preview from current point.py: -------------------------------------------------------------------------------- 1 | # This opens an external player and previews the video from the current point rather than from the beginning 2 | # You need to edit the following line to point to a player on your computer 3 | 4 | exe = r'C:\Program Files (x86)\MPC HomeCinema\mpc-hc.exe' 5 | 6 | ###### 7 | import time 8 | trimmed = avsp.GetFrameNumber() 9 | originaltext = avsp.GetText() 10 | avsp.SetText(originaltext+"\ntrim("+str(trimmed)+',0)', index=None) 11 | success = avsp.RunExternalPlayer(exe) 12 | time.sleep(1) 13 | avsp.SetText(originaltext, index=None) 14 | ##### 15 | 16 | if not success: 17 | avsp.MsgBox( 18 | _('Failed to run the external player!\n\n' 19 | 'Open the macro file in the "Macros" subdirectory\n' 20 | 'with a text editor and edit the executable\n' 21 | 'directory appropriately!'), 22 | _('Error') 23 | ) -------------------------------------------------------------------------------- /macros/Examples/[0] Template example.py: -------------------------------------------------------------------------------- 1 | # This example shows how to create a custom template function, which 2 | # automatically gets the source filename via an open dialog box. These 3 | # types of macros can be made if you find AvsP's extension-based templates 4 | # too limiting. Note that the save command at the end of the macro was 5 | # commented out, feel free to uncomment it or simply save the script using 6 | # the regular program's interface. 7 | 8 | # Get the filename via an open dialog box 9 | filename = avsp.GetFilename() 10 | 11 | if filename: 12 | # Create a new tab 13 | avsp.NewTab() 14 | # Create and insert the script into the tab 15 | avsp.InsertText( 16 | 'AviSource("' + filename + '")\n' 17 | 'Sharpen(1.0)\n' 18 | 'Info()\n' 19 | ) 20 | # Show the video preview 21 | avsp.ShowVideoFrame() 22 | # Save the script 23 | #avsp.SaveScript(filename + '.avs') -------------------------------------------------------------------------------- /macros/Bookmarks at Intervals.py: -------------------------------------------------------------------------------- 1 | last_frame = avsp.GetVideoFramecount() - 1 2 | options = avsp.GetTextEntry( 3 | [_('Choose a frame step or a number of intervals'), 4 | [_('Frame step'), _('Number of intervals')], 5 | [_('Start frame'), _('End frame')], 6 | _('Clear bookmarks in the same range')], 7 | ['', [(0, 0), (0, 0)], [(0, 0, last_frame), (last_frame, 0, last_frame)]], 8 | _('Bookmarks at Intervals'), 9 | ['sep', ['spin', 'spin'], ['spin', 'spin'], 'check'], width=100) 10 | if options: 11 | step, intervals, start, end, clear = options 12 | else: 13 | return 14 | if clear: 15 | avsp.ClearBookmarks(start, end) 16 | if intervals: 17 | step = float(end - start + 1) / intervals 18 | if step: 19 | def float_range(start, end, step): 20 | while start <= end: 21 | yield start 22 | start += step 23 | avsp.SetBookmark(float_range (start, end, step)) 24 | -------------------------------------------------------------------------------- /readme_d2v_based_template.txt: -------------------------------------------------------------------------------- 1 | For the file extensions based templates there is a new modifier >< 2 | Everything between >< replaces the file extension, e.g. >*Tc*.mp2< and searched for the file. 3 | 4 | Example template for d2v: Source file is 'E:\Media\Red Planet.d2v' 5 | 6 | video=D2VSource(***) 7 | audio=LWLibavAudioSource(> Tc*.mp2<) 8 | audioDub(video, audio) 9 | 10 | So it will be found: E:\Media\Red Planet Tc*.mp2 11 | You can also use Tc*, then all files starting with 'E:\Media\Red Planet Tc' will be found. 12 | If more than one is found, the first one is taken in alphabetical order. 13 | 14 | A more extreme template example for d2v files: 15 | 16 | videoSource = ScriptDir() + [***] 17 | videoSource = Exist(videoSource) ? videoSource : *** 18 | audioSource = ScriptDir() + [> Tc*.mp2<] 19 | audioSource = Exist(audioSource) ? audioSource : > Tc*.mp2< 20 | video=D2VSource(videoSource) 21 | audio=LWLibavAudioSource(audioSource) 22 | audioDub(video, audio) 23 | 24 | -------------------------------------------------------------------------------- /macros/Examples/[4] Secondary preview.py: -------------------------------------------------------------------------------- 1 | # This example shows how to run an external player with macros. This 2 | # functionality is already provided with AvsP's external preview, but macros 3 | # allow you to define as many different external programs as you want. The 4 | # first argument to the function is the path to the executable (you'll have to 5 | # change this path to something appropriate for your pc). The second argument 6 | # to the function is any additional command line arguments you wish to pass to 7 | # the external program. 8 | 9 | exe = r'C:\Program Files\mplayer\mplayer.exe' 10 | args = '-fs -monitoraspect 16:9' 11 | success = avsp.RunExternalPlayer(exe, args) 12 | 13 | if not success: 14 | avsp.MsgBox( 15 | _('Failed to run the external player!\n\n' 16 | 'Open the macro file in the "Macros" subdirectory\n' 17 | 'with a text editor and edit the executable\n' 18 | 'directory appropriately!'), 19 | _('Error') 20 | ) -------------------------------------------------------------------------------- /macros/Examples/[1] Batch example.py: -------------------------------------------------------------------------------- 1 | # This example shows how to automatically generate multiple scripts given a 2 | # directory with several source files. Note that this example doesn't even 3 | # directly interact with the AvsP program itself, it's almost entirely using 4 | # pure Python for batch processing, with conviniece gui functions provided by 5 | # the avsp module. 6 | 7 | import os 8 | 9 | # Get the directory containing source files 10 | dirname = avsp.GetDirectory() 11 | 12 | if dirname: 13 | # Generate each of the avisynth scripts 14 | for filename in os.listdir(dirname): 15 | fullname = os.path.join(dirname, filename) 16 | if os.path.isfile(fullname): 17 | # Get the extension-based template string 18 | srctxt = avsp.GetSourceString(fullname) 19 | # Create the script string 20 | scripttxt = srctxt + '\n' + 'Sharpen(1.0)\nInfo()' 21 | # Write the script text to a file 22 | f = open(fullname + '.avs', 'w') 23 | f.write(scripttxt) 24 | f.close() -------------------------------------------------------------------------------- /macros/Random Clip Order.py: -------------------------------------------------------------------------------- 1 | # Imports all files from a directory and joins them in a random order 2 | # All files must have the same attributes such as size and framerate 3 | 4 | import os 5 | import random 6 | import string 7 | # Get the directory containing source files 8 | dirname = avsp.GetDirectory() 9 | 10 | if dirname: 11 | avsp.NewTab() 12 | scripttxt = '' 13 | counter = 0 14 | #import each clip 15 | for filename in os.listdir(dirname): 16 | fullname = os.path.join(dirname, filename) 17 | if os.path.isfile(fullname): 18 | counter += 1 19 | scripttxt += 'video' + str(counter) + ' = ' + avsp.GetSourceString(fullname) + '\n' 20 | scripttxt += '\n' 21 | #join clips together 22 | cliplist = [] 23 | cliptxt = '' 24 | while counter > 0: 25 | cliplist.append('video' + str(counter)) 26 | counter -= 1 27 | random.shuffle(cliplist) 28 | for clip in cliplist: 29 | cliptxt += clip + ' ++ ' 30 | cliptxt = cliptxt[:-4] #remove extra ++ from end 31 | scripttxt += cliptxt 32 | avsp.SetText(scripttxt) -------------------------------------------------------------------------------- /license_cpuid: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Anders Høst 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /macros/Examples/[5] Encoding example.py: -------------------------------------------------------------------------------- 1 | # This example is almost identical to the "Secondary preview" macro, the only 2 | # difference is that in this example, we are using the actual avs script instead 3 | # of creating a temporary preview.avs script. The macro saves any unsaved 4 | # changes and runs an external program using Python's subprocess module 5 | # (note that it is commented out, if you wish to use the macro you'll need to 6 | # uncomment the line and change the arguments appropriately for your specific 7 | # application). 8 | import subprocess 9 | 10 | # Automatically save any unsaved changes 11 | # Use avsp.SaveScriptAs() instead if you want to always prompt the user 12 | filename = avsp.SaveScript() 13 | 14 | # Run the external program using Python's subprocess module 15 | # The subprocess.Popen function takes in a list of command line arguments, 16 | # automatically taking care of any spaces in the filenames. 17 | exe = r'C:\Progam Files\ffmpeg\ffmpeg.exe' 18 | outputfilename = filename+'.avi' 19 | #subprocess.Popen([exe, filename, '-b', '500', outputfilename]) 20 | avsp.MsgBox(_('Encoding is disabled, please read the "Encoding example.py" macro for info')) -------------------------------------------------------------------------------- /readme_NumberWheel.txt: -------------------------------------------------------------------------------- 1 | GPo 2022, number wheel 2 | 3 | Editor: Changing numbers or true/false with the mouse wheel. 4 | 5 | Select an area containing numbers, press Ctrl or Shift or both and use the mouse wheel. Ctrl = 1, Shift = 5, Both = 10 6 | The first number group found is changed (maximum search depth for the first digit are 20 characters). 7 | If only the decimal part of a float number is selected: the last digit's are changed: (number is 2.25) default = 2.26, Shift = 2.30, Both = 2.35 8 | 9 | Recommended*: Select the numbers or true/false with a double-click, no pressing of Ctrl or Shift is required. Numbers are then changed by 1 10 | 11 | If the selection is made by double-click: 12 | The function must be deactivated by a single click. Or some functions are deactivated. 13 | You can change the decimal part rate (normal/fast) by a middle mouse click (the status bar gives feedback). 14 | The fast decimal part rate is: default = .1, Ctrl = .2, Shift = .5 also from 2.25 to (2.35, 2.45, 2.75) 15 | You can also change the numbers using the 'left' and 'right' keyboard keys 16 | 17 | true/false can now be changed either with (left down and right click) or (with the mouse wheel). 18 | -------------------------------------------------------------------------------- /macros/Bookmarks to Chapter.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | import os.path 3 | 4 | # run in thread 5 | try: 6 | bookmarks = avsp.GetBookmarkList(title=True) 7 | except TypeError: 8 | bookmarks = avsp.GetBookmarkList() 9 | bookmarks.sort() 10 | filename = avsp.GetSaveFilename( 11 | title=_('Save chapter file as...'), 12 | default=os.path.splitext( 13 | avsp.GetScriptFilename(propose='general', only='base'))[0], 14 | filefilter = '|'.join((_('Text files') + ' (*.txt)|*.txt', 15 | _('All files') + ' (*.*)|*.*'))) 16 | if not filename: 17 | return 18 | fps = avsp.GetVideoFramerate() 19 | text = [] 20 | chapter = 1 21 | for item in bookmarks: 22 | if type(item) is int: 23 | bookmark = item 24 | title = '' 25 | else: 26 | bookmark, title = item 27 | m, s = divmod(bookmark/fps, 60) 28 | h, m = divmod(m, 60) 29 | timecode = 'CHAPTER%02d=%02d:%02d:%06.3f\n' % (chapter, h ,m, s) 30 | if not title: 31 | title = 'Chapter %02d' % chapter 32 | title = 'CHAPTER%02dNAME=%s\n' % (chapter, title) 33 | text += [timecode, title] 34 | chapter +=1 35 | f = codecs.open(filename, 'w', 'utf-8') 36 | f.writelines(text) 37 | f.close() -------------------------------------------------------------------------------- /readme_FullscreenZoom.txt: -------------------------------------------------------------------------------- 1 | 2 | Automatic zoom in fullscreen mode. 3 | Program options > Misc2 > 'Fullscreen zoom', None, Normal, Resample, default Normal 4 | Note: Resample only works when the resample function is enabled. (Program Options > Misc2 > 'Show Resample zoom menu') 5 | 6 | None: 7 | Nothing happens. If the 'Save pos & zoom on tab change' option is checked, the previous fullscreen zoom will be restored for that tab. 8 | 9 | Normal zoom: 10 | Resample filters of the tab are turned off and zoom 'fill' is set. 11 | If you don't change tab in Fullscreen, all other tabs will keep the zoom if 'Save pos & zoom on tab change' is checked. 12 | If you switch tabs and this tab has a resample zoom, the resample function is disabled and this tab is set to zoom 'fill' when you exit full screen mode. 13 | All other tabs keep their zoom if 'Save pos & zoom on tab change' is on. 14 | 15 | Resample zoom: 16 | If Fullscreen is started and ended with the same tab, the zoom that existed before the fullscreen mode is restored. 17 | If a tab is changed in Fullscreen mode, this tab will retain the resample filter even after Fullscreen mode is ended. 18 | 19 | Big Note: 20 | - If Avisynth is trimmed too much with SetMemoryMax, all AvsPmod filters will take longer. 21 | - The Resample filter normally takes less than 1 second, but if the Avisynth memory is reduced too much, it can take 10 seconds. 22 | 23 | -------------------------------------------------------------------------------- /readme_Tablist.txt: -------------------------------------------------------------------------------- 1 | The 'Tablist' is started with a right click on the right edge of the video or editor window (20 pixels). 2 | 3 | Execute menu: 4 | 5 | In the context menu of the 'Tablist' there is a menu entry 'Execute menu', this entry must first be configured under Program Options > Misc 2 > 'Tablist execute menu'. 6 | Up to 10 custom menu entries can be added. The separator for a new entry is a , comma. The separator for the label and the command to be executed is a | 7 | And then there is a separator for searching the menu entries -> 8 | 9 | So: Save script|File -> Save script (displayed label|menu to be executed) 10 | Instead of writing the menu to be executed, the shortcut to the menu can also be used. Save script|Ctrl+Shift+S 11 | 12 | Macros can also be started from the Macros menu. An example for 3 menu entries (You can copy and paste it): 13 | Save script (GPo)|Macros -> Save script (GPo), Add tab to group 1|Video -> Add tab to group -> 1, Clear all tab groups|Video -> Add tab to group -> Clear all tab groups 14 | 15 | Separators and submenu: 16 | Use '-' for an separator and '>Name of menu' for indicate to put the next entrie in this submenu, indication of end is < 17 | Example: Save script|File -> Save script, >My Submenu, Bookmarks to script|Video -> Bookmarks -> Bookmarks to script, <, next entrie in main context menu 18 | 19 | ----------- 20 | 21 | MediaInfo: 22 | Watch the video 'Tablist', Help > Video tutorials & more 23 | 24 | -------------------------------------------------------------------------------- /readme_Audio.txt: -------------------------------------------------------------------------------- 1 | Don't expect too much from the 4K playback, but there is a useful function 'Audio scrubbing'. See below. 2 | 3 | For faster playback: 4 | There is a new option for the 'Resample Filter', you can enter a function after the avisynth resizer separated by a semicolon. 5 | As default if the options.dat not existing, a Prefetch(1) is used, so Spline36Resize;Prefetch(1) 6 | This gives me 30% more speed when using the 'Resample Filter'. 7 | Spline36Resize;sharpen(0.2).Prefetch(1) is also posible but makes it through the additional filter slower. 8 | 9 | I can playback 4K on a QHD monitor with 'Resample Filter,Prefetch(1)' without audio dropouts (max. ~29 fps). 10 | Use Video > Display > 'Fast YUV420 display conversion' or 'Prefetch RGB display conversion' for faster playback. 11 | 12 | Use 'Split Clip' (avsp_split) to temporarily turn off all subsequent filters for non-stuttering audio playback. 13 | Or use the D3D Window for faster 4K playback. 14 | ---------- 15 | 16 | Audio scrubbing: 17 | The number of frames to be played can be selected in the context menu of the play button. 18 | There is also the function 'Play scrub', which plays the audio of 36 video frames. Even if 'Audio scrubbing' is switched off. 19 | This function should work well in conjunction with 'Split View' for an audio synchronous check (original vs. encoded). 20 | If 'Split View' is activated, the audio of both clips will be played one after the other. With visual display of the currently used clip. 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /macros/Selected trims to selections.py: -------------------------------------------------------------------------------- 1 | # GPo 2020 2 | # Insert selected avisynth trims as trim editor selections 3 | # If the selection mark is present, the selection mark is deleted, 4 | # you can also delete individual selections in this way 5 | 6 | txt = avsp.GetSelectedText(index=None) 7 | if not txt: 8 | return 9 | 10 | self = avsp.GetWindow() 11 | txt = txt.lower() 12 | L = len('trim(') 13 | x2 = 0 14 | error = 0 15 | 16 | while 1: 17 | x1 = txt.find('trim(', x2) 18 | if x1 > -1: 19 | x2 = txt.find(')',x1+L) 20 | if x2 > -1: 21 | trim = txt[x1+L:x2] 22 | a = trim.split(',') 23 | if len(a) > 1: 24 | start = a[0].strip() 25 | stop = a[1].strip() 26 | if start.isdigit() and stop.isdigit(): 27 | self.AddFrameBookmark(int(start), 1, refreshVideo=False) 28 | self.AddFrameBookmark(int(stop), 2, refreshVideo=False) 29 | else: 30 | error += 1 31 | else: 32 | error += 1 33 | else: 34 | error += 1 35 | break 36 | else: 37 | break 38 | 39 | if error > 0: 40 | avsp.MsgBox(str(error) + ' trim error(s)\nCheck the selected trims', title='Error') 41 | return 42 | # if script focused, the script deletes the selected text when you press space key 43 | # so deselect the selection and focus the video window for play video with space key 44 | self.currentScript.ClearSelections() 45 | if self.previewWindowVisible: 46 | self.videoWindow.SetFocus() -------------------------------------------------------------------------------- /global_vars.py: -------------------------------------------------------------------------------- 1 | # AvsP - an AviSynth editor 2 | # 3 | # Copyright 2012, 2013 the AvsPmod authors 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit 18 | # http://www.gnu.org/copyleft/gpl.html . 19 | 20 | # global_vars - shared global variables 21 | # 22 | # Dependencies: 23 | # Python (tested on v2.6 and v2.7) 24 | 25 | try: _ 26 | except NameError: _ = lambda s:s 27 | 28 | # Application info 29 | name = 'AvsPmod' 30 | description = _('An AviSynth script editor') 31 | url = 'http://avspmod.github.io/' 32 | url2 = 'https://github.com/gispos/AvsPmod/' 33 | license = 'GNU GPL v2' 34 | version = '2.7.9.4' 35 | 36 | # stores the dpi scalling factor on startup 37 | ppi_factor = 1.0 38 | 39 | # Used to pass the shared library location to avisynth.py, don't touch 40 | avisynth_library_dir = '' 41 | 42 | # This will be improved on the future refactoring for wxPython Phoenix 43 | # and VapourSynth 44 | options = {} -------------------------------------------------------------------------------- /macros/Examples/[6] Encoding example 2.py: -------------------------------------------------------------------------------- 1 | # This macro is a more detailed version of the "Encoding example" macro. The 2 | # macro uses the avsp.GetTextEntry() function to retrieve multiple inputs from 3 | # the user, then runs the appropriate external program. The lines which 4 | # actually run the external program are commented out, if you wish to use the 5 | # macro you'll need to uncomment them and change the macro appropriately for 6 | # your specific application. 7 | 8 | import subprocess 9 | 10 | # Save any unsaved changes to the script and get the filename 11 | infile = avsp.SaveScript() 12 | 13 | # Get basic encoder options with a dialog box 14 | labels = [_('Bitrate:'), _('Output width:'), _('Output height:'), _('Output filename:')] 15 | defaults = ['500', '320', '240', infile+'.avi'] 16 | entries = avsp.GetTextEntry(labels, defaults, _('Enter encoder info')) 17 | 18 | if entries: 19 | # Run the encoder 20 | bitrate, width, height, outfile = entries 21 | if True: 22 | # SINGLE PASS MODE (run the encoder and give control back to AvsP) 23 | args = [ 24 | r'C:\Progam Files\ffmpeg\ffmpeg.exe', 25 | '-i', infile, 26 | '-s', width+'x'+height, 27 | '-b', bitrate, 28 | '-y', outfile, 29 | ] 30 | # subprocess.Popen(args) 31 | else: 32 | # MULTI-PASS MODE (you cannot use AvsP until both passes finish!) 33 | args = [ 34 | r'C:\Progam Files\ffmpeg\ffmpeg.exe', 35 | '-i', infile, 36 | '-s', width+'x'+height, 37 | '-b', bitrate, 38 | '-pass', '1', 39 | '-y', outfile, 40 | ] 41 | # Run the first pass 42 | # subprocess.call(args) 43 | # Run the second pass 44 | # args[-3] = '2' 45 | # subprocess.call(args) 46 | avsp.MsgBox(_('Encoding is disabled, please read the "Encoding example 2.py" macro for info')) -------------------------------------------------------------------------------- /macros/Example (Resize)/[21] Customized.py: -------------------------------------------------------------------------------- 1 | # Customized pixel ratio 2 | 3 | # If this macro is called by another macro, retrieve the return values 4 | # from 'avsp.Last'. Otherwise, pop up an input box. 5 | boolsize = False 6 | try: 7 | x, y = avsp.Last 8 | except: 9 | text = avsp.GetTextEntry(_('Enter a pixel ratio or new size. e.g. 40:33, 1.212 or 640x360'), '', _('Customized aspect ratio')) 10 | text = text.lower() 11 | try: 12 | if ':' in text: 13 | x, y = [int(s) for s in text.split(':')] 14 | elif 'x' in text: 15 | boolsize = True 16 | x, y = [int(s) for s in text.split('x')] 17 | else: 18 | x, y = float(text), 1 19 | except: 20 | return 21 | 22 | # calculate new size. exit if 1:1 or same size 23 | width, height = avsp.GetVideoWidth(), avsp.GetVideoHeight() 24 | if boolsize: 25 | if width == x and height == y: 26 | return 27 | width, height = x, y 28 | else: 29 | if x > y: 30 | width = int(float(width)*x/y) 31 | elif x < y: 32 | height = int(float(height)*y/x) 33 | else: 34 | return 35 | 36 | # retrieve menu item's state to create a suitable avs statement 37 | if avsp.IsMenuChecked(_('create new tab')): 38 | text = avsp.GetText() 39 | avsp.NewTab() 40 | avsp.SetText(text) 41 | 42 | if avsp.IsMenuChecked(_('force mod 2')): 43 | width += width%2 44 | height += height%2 45 | 46 | if avsp.IsMenuChecked(_('bilinear')): 47 | filter = 'BilinearResize' 48 | elif avsp.IsMenuChecked(_('bicubic')): 49 | filter = 'BicubicResize' 50 | elif avsp.IsMenuChecked(_('lanczos')): 51 | filter = 'LanczosResize' 52 | elif avsp.IsMenuChecked(_('spline36')): 53 | filter = 'Spline36Resize' 54 | 55 | # insert text and refresh preview 56 | text = '%s(%d, %d)' % (filter, width, height) 57 | avsp.InsertText(text) 58 | avsp.ShowVideoFrame(forceRefresh=True) -------------------------------------------------------------------------------- /readme_D3D_Window.txt: -------------------------------------------------------------------------------- 1 | Direct 3D Window 2 | ----------------- 3 | The D3D Window is mainly intended for UHD playback, when the normal drawing is too slow for that. 4 | At the moment all color formats (except RGB32) are displayed in YUV420P8. 5 | YUY2 is slower than YUV420P8 in my test when rendering directly, so it is also converted to YUV420P8. 6 | The matrix is taken over from the current matrix when opening the window. 7 | 8 | AvsPmod filters (Display Filter, Preview Filter) cannot be used, only 'Split Clip' is supported or the clip itself must be RGB32. 9 | Unfortunately, there are some problems with the keyboard shortcuts. 10 | Not all events of the keyboard are recognized, so I had to fix the shortcuts. 11 | 12 | Existing functions and shortcuts: 13 | double click = fullscreen or not or toggle fullsize/fullscreen 14 | mouse forward-backward = bookmark next-previous 15 | mouse wheel = frame step 16 | numpad 4,5 = frame step 17 | numpad 2,8 = jump custom units 18 | numpad 0 or numpad . or middle mouse = Close 19 | minus key = toggle 'Split Clip' 20 | key b = add or remove bookmark 21 | 22 | Docking option for the D3D Window (dock on video window). 23 | - My recommendation: top-right or bottom-right 24 | - Enabling: move the window in the desired monitor corner more then half size of the window outsite the corner. 25 | - Disabling: d3d window context menu Additional > 'Disable docking' 26 | 27 | 28 | Video Window Double Click Layout (not D3D Window) 29 | ------------------------------------------------- 30 | On the left side (width 50 pixels): 31 | ___ 32 | d3d fullscreen (top start, 0) 33 | ___ 34 | normal fullscreen (top start, 51 pixel), is fullsize then switch between fullsize/fullscreen. 35 | ___ 36 | normal fullsize (top start, half height) 37 | ___ 38 | d3d fullsize (top start, height - 50 pixel) 39 | ___ 40 | 41 | 42 | Doubel click layout right, width -50 pixel: 43 | ___ 44 | Resample Filter current script (top start, 0) 45 | ___ 46 | normal fullscreen (top start, 51 pixel) 47 | ___ 48 | normal fullsize (top start, half height) 49 | ___ 50 | Resample Filter all scripts (top start heigth -50 pixel) 51 | (Read the resample filter readme under help) 52 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | # AvsP - an AviSynth editor 2 | # 3 | # Copyright 2007 Peter Jang 4 | # 2010-2014 the AvsPmod authors 5 | # 6 | # Printing support based on stcprint.py from Peppy/Editra (wxWidgets license) 7 | # Copyright 2007 Cody Precord 8 | # 2009 Rob McMullen 9 | # 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 2 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, write to the Free Software 22 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit 23 | # http://www.gnu.org/copyleft/gpl.html . 24 | 25 | # Dependencies: 26 | # Python (tested on v2.6 and 2.7) 27 | # wxPython (tested on v2.8 Unicode and 2.9) 28 | # cffi and its dependencies (only for x86-64, tested on v0.9.2) 29 | # pycparser 30 | # Visual C++ 31 | # avisynth_c.h (only for x86-64, interface 5, or at least 3 + colorspaces 32 | # from 5, tested with the header used by x264) 33 | # Scripts: 34 | # avsp.py (main application) 35 | # wxp.py (general wxPython framework classes) 36 | # avisynth.py (Python AviSynth/AvxSynth wrapper, only for x86-32) 37 | # avisynth_cffi.py (Python AviSynth wrapper, only for x86-64) 38 | # pyavs.py (AvsP AviSynth support by loading AviSynth directly as a library) 39 | # pyavs_avifile.py (AvsP AviSynth support through Windows AVIFile routines) 40 | # icon.py (icons embedded in a Python script) 41 | # i18n.py (internationalization and localization) 42 | # global_vars.py (application info and other shared variables) 43 | 44 | import os, sys 45 | if hasattr(sys,'frozen'): 46 | sys.path.insert(0, os.path.dirname(sys.executable)) 47 | 48 | import avsp 49 | avsp.main() 50 | -------------------------------------------------------------------------------- /avs/types.h: -------------------------------------------------------------------------------- 1 | // Avisynth C Interface Version 0.20 2 | // Copyright 2003 Kevin Atkinson 3 | 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit 17 | // http://www.gnu.org/copyleft/gpl.html . 18 | // 19 | // As a special exception, I give you permission to link to the 20 | // Avisynth C interface with independent modules that communicate with 21 | // the Avisynth C interface solely through the interfaces defined in 22 | // avisynth_c.h, regardless of the license terms of these independent 23 | // modules, and to copy and distribute the resulting combined work 24 | // under terms of your choice, provided that every copy of the 25 | // combined work is accompanied by a complete copy of the source code 26 | // of the Avisynth C interface and Avisynth itself (with the version 27 | // used to produce the combined work), being distributed under the 28 | // terms of the GNU General Public License plus this exception. An 29 | // independent module is a module which is not derived from or based 30 | // on Avisynth C Interface, such as 3rd-party filters, import and 31 | // export plugins, or graphical user interfaces. 32 | 33 | #ifndef AVS_TYPES_H 34 | #define AVS_TYPES_H 35 | 36 | // Define all types necessary for interfacing with avisynth.dll 37 | 38 | #ifdef __cplusplus 39 | #include 40 | #else 41 | #include 42 | #endif 43 | 44 | // Raster types used by VirtualDub & Avisynth 45 | typedef unsigned int Pixel32; 46 | typedef unsigned char BYTE; 47 | 48 | // Audio Sample information 49 | typedef float SFLOAT; 50 | 51 | #ifdef __GNUC__ 52 | typedef long long int INT64; 53 | #else 54 | typedef __int64 INT64; 55 | #endif 56 | 57 | #endif //AVS_TYPES_H 58 | -------------------------------------------------------------------------------- /avs/capi.h: -------------------------------------------------------------------------------- 1 | // Avisynth C Interface Version 0.20 2 | // Copyright 2003 Kevin Atkinson 3 | 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit 17 | // http://www.gnu.org/copyleft/gpl.html . 18 | // 19 | // As a special exception, I give you permission to link to the 20 | // Avisynth C interface with independent modules that communicate with 21 | // the Avisynth C interface solely through the interfaces defined in 22 | // avisynth_c.h, regardless of the license terms of these independent 23 | // modules, and to copy and distribute the resulting combined work 24 | // under terms of your choice, provided that every copy of the 25 | // combined work is accompanied by a complete copy of the source code 26 | // of the Avisynth C interface and Avisynth itself (with the version 27 | // used to produce the combined work), being distributed under the 28 | // terms of the GNU General Public License plus this exception. An 29 | // independent module is a module which is not derived from or based 30 | // on Avisynth C Interface, such as 3rd-party filters, import and 31 | // export plugins, or graphical user interfaces. 32 | 33 | #ifndef AVS_CAPI_H 34 | #define AVS_CAPI_H 35 | 36 | #ifdef __cplusplus 37 | # define EXTERN_C extern "C" 38 | #else 39 | # define EXTERN_C 40 | #endif 41 | 42 | #ifdef MSVC 43 | #ifndef AVSC_USE_STDCALL 44 | # define AVSC_CC __cdecl 45 | #else 46 | # define AVSC_CC __stdcall 47 | #endif 48 | #else 49 | # define AVSC_CC 50 | #endif 51 | 52 | #define AVSC_INLINE static __inline 53 | 54 | #ifdef BUILDING_AVSCORE 55 | # define AVSC_EXPORT __declspec(dllexport) 56 | # define AVSC_API(ret, name) EXTERN_C AVSC_EXPORT ret AVSC_CC name 57 | #else 58 | # define AVSC_EXPORT EXTERN_C __declspec(dllexport) 59 | # ifndef AVSC_NO_DECLSPEC 60 | # define AVSC_API(ret, name) EXTERN_C __declspec(dllimport) ret AVSC_CC name 61 | # else 62 | # define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func) 63 | # endif 64 | #endif 65 | 66 | #endif //AVS_CAPI_H 67 | -------------------------------------------------------------------------------- /macros/Examples/[2] Image processing.py: -------------------------------------------------------------------------------- 1 | # This example shows how to use AvsP's macros to turn AviSynth into an 2 | # all-purpose image editor. It's similar to the batch example, but instead 3 | # of getting all sources in a directory and generating AviSynth scripts, this 4 | # macro gets all the bitmaps or jpgs in a directory and generates a bunch of 5 | # new pngs filtered according to the specified AviSynth functions. The 6 | # macro also shows how to get image properties such as width and height, 7 | # necessary in this example to ensure the width and height are both acceptable 8 | # for a ConvertToYV12() (assumming you are using YV12 specific filters). 9 | # Also demonstrated is the progress box, which shows elapsed and remaining 10 | # time and allows you to cancel the processing whenever you want. 11 | 12 | import os 13 | 14 | # Get the directory containing files 15 | dirname = avsp.GetDirectory() 16 | 17 | if dirname and avsp.GetText() == '': 18 | # Create the list of file names in the directory which are bitmaps or jpegs 19 | namelist = [] 20 | for name in os.listdir(dirname): 21 | if os.path.splitext(name)[1] in ('.bmp', '.jpg'): 22 | namelist.append(name) 23 | # Create a progress box 24 | pbox = avsp.ProgressBox(len(namelist), _('Processing images...')) 25 | # Generate each of the image files 26 | for i, filename in enumerate(namelist): 27 | fullname = os.path.join(dirname, filename) 28 | # Clear all the text in the tab 29 | avsp.SetText('') 30 | # Get the extension-based template string 31 | srctxt = avsp.GetSourceString(fullname) 32 | avsp.InsertText('%s\n' % srctxt) 33 | # Get the width and height of the video 34 | w = avsp.GetVideoWidth() 35 | h = avsp.GetVideoHeight() 36 | # Add borders to make the width and height mod 32 37 | wpad = 32 - w % 32 38 | hpad = 32 - h % 32 39 | txt = 'AddBorders(0,0,%i,%i)\n' % (wpad, hpad) 40 | avsp.InsertText(txt) 41 | # Add the rest of the script 42 | # (the crop at the end gets rid of any borders added earlier) 43 | avsp.InsertText( 44 | 'ConvertToYV12()\n' 45 | 'SwapUV()\n' 46 | 'Sharpen(1.0)\n' 47 | 'ConvertToRGB32()\n' 48 | 'Crop(0,0,-%i,-%i)\n' % (wpad, hpad) 49 | ) 50 | # Save the image as a png 51 | newname = os.path.join(dirname, filename+'.png') 52 | avsp.SaveImage(newname) 53 | # Update the progress box, exit if user canceled 54 | if not pbox.Update(i)[0]: 55 | break 56 | # Destroy the progress box 57 | pbox.Destroy() 58 | # Clear the remaining text 59 | avsp.SetText('') 60 | else: 61 | avsp.MsgBox(_('Macro aborted')) -------------------------------------------------------------------------------- /macros/Open Image Sequence.py: -------------------------------------------------------------------------------- 1 | """ 2 | GPo 2020, AvsPmod macro 'Open ImageSequence.py' 3 | Only useful for image names with consecutive frame numbers in a sequence. 4 | If the frame number is not consecutive, a new ImageSource is added. 5 | Uses all images in the selected directory that match the selected file name. 6 | Separate by file (frame) range numbers e.g.: 7 | Img_000000.png to Img_000020.png insert one ImageSource 8 | Img_000000.png to Img_000010.png and Img_000012.png to Img_000020.png insert two ImageSources 9 | 000001.png to 000010.png and 000012.png to 000020.png insert also two ImageSources 10 | """ 11 | import os 12 | 13 | filename = avsp.GetFilename(_('Select the Image'), filefilter= 14 | _('Images (bmp, jpg, png, tiff)') + '|*.bmp;*.jpg;*.png;*.tiff|' + 15 | _('All files (*.*)') + '|*.*') 16 | if not filename: 17 | return 18 | 19 | base_dir, name = os.path.split(filename) 20 | base_name, base_ext = os.path.splitext(name) 21 | alpha = '' 22 | files = [] 23 | clips = 0 24 | s = '' 25 | ss = '' 26 | base_dir = os.path.join(base_dir, '') 27 | 28 | # return the first non number chars 29 | def GetFirstAlpha(f): 30 | a = '' 31 | for n in f: 32 | if not n.isdigit(): 33 | a = ''.join([a,n]) 34 | else: 35 | break 36 | return a 37 | 38 | def GetFormat(f): 39 | return base_dir + alpha + '%0' + str(len(f)) + 'd' + base_ext 40 | 41 | if not base_name.isdigit(): 42 | alpha = GetFirstAlpha(base_name) 43 | if not base_name[len(alpha):].isdigit(): 44 | avsp.MsgBox('No valid range numbers in file name found') 45 | return 46 | 47 | # add all matched file names 48 | for f in os.listdir(base_dir): 49 | name, ext = os.path.splitext(f) 50 | if alpha: 51 | if alpha != name[:len(alpha)]: 52 | continue 53 | name = name[len(alpha):] 54 | if name.isdigit() and ext.lower() == base_ext.lower(): 55 | files.append(name) 56 | 57 | if len(files) < 1: 58 | avsp.MsgBox('No files to process') 59 | return 60 | files.sort() 61 | 62 | start = int(files[0]) 63 | for i in xrange(len(files)): 64 | if i > 0: 65 | last = int(files[i-1]) 66 | if int(files[i]) - last != 1: # if next frame number is not consecutive, create a new ImageSource 67 | clips += 1 68 | s += 'c%d=ImageSource("%s", start=%d, end=%d)\n' % (clips, GetFormat(files[i]), start, last) 69 | ss += 'c' + str(clips) + '+' 70 | start = int(files[i]) 71 | end = int(files[i]) 72 | 73 | clips += 1 74 | ss += 'c' + str(clips) 75 | s += 'c%d=ImageSource("%s", start=%d, end=%d)\n%s' % (clips, GetFormat(files[len(files)-1]), start, end, ss) 76 | avsp.InsertText(s) -------------------------------------------------------------------------------- /readme_FastClip.txt: -------------------------------------------------------------------------------- 1 | GPo 2023, AvsPmod 'Fast Clip', https://vimeo.com/user183482922 2 | 3 | Options > 'Use Ultra Fast Clip' 4 | 5 | If you don't know the 'Split Clip', please read the SplitClip readme beforehand. 6 | 7 | The flag is the same as for 'Split Clip', but Split Clip does not need to be switched on, only the flag /**avsp_split**/ is required. 8 | If /**avsp_split**/ is found in the script, a 'Fast Clip' can be created. 9 | 10 | In the normal case /**avsp_split**/ should be set after the SourceFilters and after audioDub(video, audio). 11 | You can also include heavy filters (set the heavy filters before the flag), but then the filters cannot be changed without reinitializing the 'Fast Clip'. 12 | 13 | Test it yourself (with and without 'Fast Clip'): 14 | After /**avsp_split**/ comment out a filter or switch it on again or change the parameters and reinitialise the script in between. 15 | 16 | This means, for example: 17 | That with a large video file that requires a long index process, a simple filter change such as sharpen(0.4) only takes milliseconds to set the new filter. 18 | If there are several filters after /**avsp_split**/, the effort for each filter is of course required. 19 | 20 | Hint: 21 | If a change is made before /**avsp_split**/ or a change is made in the 'Split Clip' filter, so: 22 | /**avsp_split 23 | sharpen(0.4) # > this is the Split Clip filter, it is used only when 'Split Clip' is enabled. 24 | **/ 25 | 26 | then the Fast Clip is switched off until no changes are made there. 27 | This includes blanks, it is a native comparison function designed for speed. 28 | Only lines that begins with # are ignored. But remove or add a line disables the Fast Clip. 29 | 30 | To update the part before /**avsp_split**/ there are the following possibilities: 31 | With F5 32 | Tab context menu 'Reload script' 33 | Make a change in the script before /**avsp_split**/ or in the 'Split Clip' filter part, see above. 34 | Release the script 35 | Disable 'Use Ultra Fast Clip' 36 | Comment out /**avsp_split**/ ( #/**avsp_split**/ ) 37 | 38 | And another big Hint: 39 | If you set variables after the flag, e.g var1 = True, then this variable is removed only when the complete script is reinitialized (see above). 40 | If the variable is only commented out, it remains valid. 41 | 42 | ################################################## 43 | var1 = 1 44 | var2 = var1 + 1 45 | result is 2 46 | 47 | var1 = 2 48 | var2 = var1 + 1 49 | result is 3 50 | 51 | #var1 = 2 commented out, but still in memory 52 | var2 = var1 + 1 53 | result is 3 54 | ################################################### 55 | 56 | So remember: 57 | Everything before the flag is always reinitialized when it is changed. Everything after the flag can be used to create a Fast Clip. 58 | However, the flag must not be in an 'if else' statement! And if __end__ or return is found before the flag, no Fast Clip can be created. -------------------------------------------------------------------------------- /avs/config.h: -------------------------------------------------------------------------------- 1 | // Avisynth C Interface Version 0.20 2 | // Copyright 2003 Kevin Atkinson 3 | 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation; either version 2 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program; if not, write to the Free Software 16 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit 17 | // http://www.gnu.org/copyleft/gpl.html . 18 | // 19 | // As a special exception, I give you permission to link to the 20 | // Avisynth C interface with independent modules that communicate with 21 | // the Avisynth C interface solely through the interfaces defined in 22 | // avisynth_c.h, regardless of the license terms of these independent 23 | // modules, and to copy and distribute the resulting combined work 24 | // under terms of your choice, provided that every copy of the 25 | // combined work is accompanied by a complete copy of the source code 26 | // of the Avisynth C interface and Avisynth itself (with the version 27 | // used to produce the combined work), being distributed under the 28 | // terms of the GNU General Public License plus this exception. An 29 | // independent module is a module which is not derived from or based 30 | // on Avisynth C Interface, such as 3rd-party filters, import and 31 | // export plugins, or graphical user interfaces. 32 | 33 | #ifndef AVS_CONFIG_H 34 | #define AVS_CONFIG_H 35 | 36 | // Undefine this to get cdecl calling convention 37 | #define AVSC_USE_STDCALL 1 38 | 39 | // NOTE TO PLUGIN AUTHORS: 40 | // Because FRAME_ALIGN can be substantially higher than the alignment 41 | // a plugin actually needs, plugins should not use FRAME_ALIGN to check for 42 | // alignment. They should always request the exact alignment value they need. 43 | // This is to make sure that plugins work over the widest range of AviSynth 44 | // builds possible. 45 | #define FRAME_ALIGN 64 46 | 47 | #if defined(_M_AMD64) || defined(__x86_64) 48 | # define X86_64 49 | #elif defined(_M_IX86) || defined(__i386__) 50 | # define X86_32 51 | #else 52 | # error Unsupported CPU architecture. 53 | #endif 54 | 55 | #if defined(_MSC_VER) 56 | # define MSVC 57 | #elif defined(__GNUC__) 58 | # define GCC 59 | #elif defined(__clang__) 60 | # define CLANG 61 | #else 62 | # error Unsupported compiler. 63 | #endif 64 | 65 | #if defined(GCC) 66 | # undef __forceinline 67 | # define __forceinline inline 68 | #endif 69 | 70 | #endif //AVS_CONFIG_H 71 | -------------------------------------------------------------------------------- /tools/x264.presets.default: -------------------------------------------------------------------------------- 1 | [2 Pass Very Slow] 2 | x264.exe --pass 1 --preset veryslow --bitrate $video_bitrate --zones $credits_frame,$last_frame,q=40 $extra_options --output NUL "$video_input" 3 | x264.exe --pass 2 --preset veryslow --bitrate $video_bitrate --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 4 | 5 | [2 Pass Medium] 6 | x264.exe --pass 1 --bitrate $video_bitrate --zones $credits_frame,$last_frame,q=40 $extra_options --output NUL "$video_input" 7 | x264.exe --pass 2 --bitrate $video_bitrate --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 8 | 9 | [2 Pass Very Fast] 10 | x264.exe --pass 1 --preset veryfast --bitrate $video_bitrate --zones $credits_frame,$last_frame,q=40 $extra_options --output NUL "$video_input" 11 | x264.exe --pass 2 --preset veryfast --bitrate $video_bitrate --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 12 | 13 | [1 Pass Very Slow] 14 | x264.exe --preset veryslow --bitrate $video_bitrate --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 15 | 16 | [1 Pass Medium] 17 | x264.exe --bitrate $video_bitrate --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 18 | 19 | [1 Pass Very Fast] 20 | x264.exe --preset veryfast --bitrate $video_bitrate --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 21 | 22 | [CRF Very Slow] 23 | x264.exe --preset veryslow --crf $video_quality --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 24 | 25 | [CRF Very Slow 10bit] 26 | x264.exe --output-depth 10 --preset veryslow --crf $video_quality --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 27 | 28 | [CRF Medium] 29 | x264.exe --crf $video_quality --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 30 | 31 | [CRF Medium 10bit] 32 | x264.exe --output-depth 10 --crf $video_quality --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 33 | 34 | [CRF Very Fast] 35 | x264.exe --preset veryfast --crf $video_quality --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 36 | 37 | [CRF Very Fast 10bit] 38 | x264.exe --output-depth 10 --preset veryfast --crf $video_quality --zones $credits_frame,$last_frame,q=40 $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" 39 | 40 | [lossless] 41 | x264.exe --preset ultrafast --crf 0 --zones $credits_frame,$last_frame, $extra_options --sar $par_x:$par_y --output "$video_output" "$video_input" -------------------------------------------------------------------------------- /readme_resampleFilter.txt: -------------------------------------------------------------------------------- 1 | GPo 2021, AvsPmod resample filter 2 | 3 | Resample (resize) filter: 4 | The resample filter is intended to reduce the video dimensions or, in exceptional cases, to enlarge it in order to be able 5 | to assess the quality better (antialiasing is deactivated when the resize filter is activated). 6 | It can also be used for better visible quality playback if the preview dimension needs to be adjusted. 7 | 8 | It behaves in the same way as if a resizer is used in the script, with the difference that the resize factor is changed dynamically. 9 | mod 2 is used, with the exception of the yv411 color format, then mod 4 is used. 10 | 11 | !! You must first enable the resample menu under Program options > Misc 2 > 'Show resample zoom menu' 12 | 13 | The Avisynth resizer can be entered under Options > 'Resample filter...' (only the name, no parameters, default 'Spline36Resize'). 14 | The resize factor can be selected in the zoom menu (fit,fill,50%,75%, 200% !) for all scripts (tabs) or 15 | only for the current tab if control is pressed when selecting the menu. 16 | or: 17 | Double click on the top right or bottom right of the video window (50x50 pixels * DPI scaling). 18 | Then the last globally changed value (fit or fill) is used, 'fit' is default at startup. 19 | If you double click above, the change only affects the current script. 20 | If you double click below it affects all scripts (tabs). 21 | or: 22 | In the upper area, press the left mouse button and zoom with the mouse wheel. 23 | or: 24 | Hold down the Shift key and use the mouse wheel. The zoom changes in 10% steps from 10 to 200% 25 | 26 | If fit or fill is selected, a new calculation of the dimension can be brought about by clicking on the script / video window separator. 27 | Normally this is never needed, at the moment only when the size of the program window is changed. 28 | 29 | The normal zoom can still be used with the mouse (left down and right click or mouse wheel). But then 'Antialiasing' is active is it enabled. 30 | 31 | There are two options for deactivating the resize filter: 32 | 1.) double click again on the upper or lower area (if a fixed zoom was set, a double click must follow). 33 | 2.) select a normal zoom factor with the keyboard (shortcut) or the video window context menu 34 | 35 | If not 'Save view pos on tab change' or 'Save pos & zoom on tab change' enabled then all tabs disables the resize filter. 36 | 37 | Certain functions are not possible with the resample filter: 38 | Crop dialog, read pixel values from avisynth. 39 | 40 | If a resize is active this is indicated in the status bar with an 'r' in front of zoom and dimensions. And with a green triangle at the top left. 41 | 42 | * Big Note: 43 | - If Avisynth is trimmed too much with SetMemoryMax, all AvsPmod filters will take longer. 44 | - The Resample filter normally takes less than 1 second, but if the Avisynth memory is reduced too much, it can take 10 seconds. 45 | 46 | -------------------------------------------------------------------------------- /readme_threads.txt: -------------------------------------------------------------------------------- 1 | Accessing in threads to clip create/release and get frame. 2 | on/off: Options menu > 'Accessing AviSynth in threads' 3 | 4 | This option takes precedence for Playback in threads. So if this option is set, the playback is also performed with threads. 5 | 6 | A user has reported that the threads lead to an immediate crash (CPU without AVX extended command). 7 | If the threads are causing problems on your system then you have to turn it off. 8 | 9 | On my system (Win10) initializing a clip with threads is about 15% faster and provides more security. 10 | Under Program Options > Misc 2 > 'Hide thread progress dialog' you can hide the progress dialog and showing when pressing Ctrl. 11 | Under Program Options > Misc 2 > 'Delay befor thread progress dialog appears' you can set the delay time. 12 | 13 | If a clip thread is canceled by the user while loading, it remains until the clip is returned by avisynth. 14 | Only when the thread has internally finished (avisynth has returned) can an attempt be made to reinitialize the clip. 15 | The same with frames, a new frame can only be requested when the frame thread has finished. 16 | 17 | For clip threads: 18 | If the thread is canceled by the user and the thread terminates later, an attempt is made to release the now abandoned clip (new option see below). 19 | If the clip is released, a message appears in the status bar and it buzzes 2 times. Then the clip can be reinitialized (memory has been released). 20 | Otherwise, it is better to restart the program. 21 | 22 | The whole should only be used for more script security. So that you can save your scripts even after a hanging avisynth. 23 | 24 | * New option Options > 'On cancel assign the clip later' 25 | AvsPmod should normally be closed after a thread has been canceled by the user. 26 | this option tries to assign the clip to the script after the user has canceled the thread and the thread has been terminated internally. 27 | nice for indexing, you can cancel the thread and working with another tab and a message appears if the clip process finished. 28 | but test it, it's a bit alpha or beta or whatever. It's going smoothly for me, but you never know what the user is doing. 29 | 30 | * New option Options > 'Use advanced frame thread' 31 | Normally a new thread is created for each frame that is loaded. 32 | If this option is activated (default), only one thread is created for each script that waits in the background for a frame to be loaded. 33 | In terms of speed, this option is a little faster on my system. But test it yourself. 34 | 35 | Another note about accessing Avisnth in threads: 36 | Even with threads it is easy to crash AvsPmod, the avisynth.dll is coupled with the main thread, 37 | if an error is triggered by a plugin and the plugin or avisynth crashes, AvsPmod is also torn into the abyss. 38 | The threads only help if avisynth does not return. 39 | Use program options > Save/Load > 'Backup session when previewing' and the accesses in threads to minimize the risk of losing the script. -------------------------------------------------------------------------------- /macros/CopyPixelinfo.py: -------------------------------------------------------------------------------- 1 | # GPo 2022, AvsPmod macro CopyPixelinfo.py v5 2 | ##### 3 | # If simple=False: 4 | # If multi=True then the macro waits 'timeout' (5 to 60) seconds for a mouse click, if there is no further click the result is output. 5 | # Hereby several values (clicks) can be output at once. 6 | # 7 | # If multi=False then the macro waits 'timeout' (5 to 60) seconds for a mouse click and then outputs the result. 8 | # The timeout can be canceled by hidden the video window (useful if multi=True). 9 | # 10 | # If simple=True: 11 | # Then it only works with shortcut (Pixelinfo depends on the mouse position) 12 | # No mouse click is waited for, the pixel value under the mouse pointer is copied immediately 13 | # 14 | # If includeXY=False then only the color values are copied (raw) 15 | # Valid values: 'xy', 'hex', 'rgb', 'rgba', 'yuv', 'yuva' 16 | # 17 | # If you don't want to write in the scrap window, set writeToScrap to False 18 | # This is just a template change it to your liking. For more read macros_readme.txt 19 | ##### 20 | 21 | ##### user settings 22 | # set one of the value: 'xy', 'hex', 'rgb', 'rgba', 'yuv', 'yuva' 23 | colorval = 'hex' 24 | # prefix e.g. for hex '$' 25 | prefix = '' 26 | # wait for multible clicks 27 | multi = False 28 | # timeout for waiting for a mouse click, valide range 5 to 60 seconds 29 | # Note: You can cancel the waiting time by hidden the video window (useful if multi=True) 30 | timeout = 10 31 | # if simple then it only works with shortcut 32 | simple = False 33 | # write to scrap window 34 | writeToScrap = True 35 | # includes also the position 36 | includeXY = True 37 | # draws a line to each clicked point, only if multi True and not simple 38 | drawLines = False 39 | # give an acoustic signal when done 40 | signal = True 41 | ##### end user settings 42 | 43 | s = '' 44 | self = avsp.GetWindow() 45 | colors = ('xy', 'hex', 'rgb', 'rgba', 'yuv', 'yuva') 46 | try: 47 | idx = colors.index(colorval) 48 | except ValueError: 49 | avsp.MsgBox('Invalid input value', 'CopyPixelinfo') 50 | return 51 | 52 | def GetValues(info): 53 | if idx == 0: 54 | return 'pos%s\n' % str(info) 55 | try: 56 | if includeXY: 57 | return 'pos%s, %s: %s\n' % (str(info[0]), colorval, prefix + str(info[1])) 58 | return prefix + str(info[1]).replace('(', '').replace(')', '') + '\n' 59 | except: 60 | return 'Error\n' 61 | 62 | if simple: 63 | info = self.GetPixelInfo(None) 64 | s = GetValues((info[0], info[idx])) if idx > 0 else GetValues(info[0]) 65 | else: 66 | if multi: 67 | lines = avsp.GetPixelInfo(color=colorval, wait=True, lines=drawLines, waitTimeout=timeout) 68 | if lines: 69 | for info in lines: 70 | s += GetValues(info) 71 | else: 72 | s = GetValues(avsp.GetPixelInfo(color=colorval, wait=False, lines=False, waitTimeout=timeout)) 73 | 74 | if s.strip(): 75 | if writeToScrap: 76 | avsp.WriteToScrap(s, pos=-1) 77 | self.SetClipboardText(s.strip()) 78 | if signal: 79 | from wx import _misc 80 | _misc.Bell() -------------------------------------------------------------------------------- /dpi.py: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # Name: dpi 3 | # Purpose: 4 | # 5 | # Author: GPo 6 | # 7 | # Created: 17.12.2020 8 | # Changed: 27.05.2022, calc font in pixels (more acurate) 9 | # Copyright: (c) GPo 2020 10 | # Licence: 11 | #------------------------------------------------------------------------------- 12 | import os 13 | import sys 14 | import ctypes 15 | import wx 16 | import global_vars 17 | 18 | ppi_factor = 1.0 19 | dpiAware = False 20 | dpiAwareness = 0 21 | 22 | def intPPI(n): 23 | return int(ppi_factor * n) 24 | 25 | def roundPPI(n): 26 | return round(ppi_factor * n) 27 | 28 | def floatPPI(n): 29 | return ppi_factor * float(n) 30 | 31 | def tuplePPI(n1, n2): 32 | return (int(ppi_factor * n1), int(ppi_factor * n2)) 33 | 34 | def SetFontPPI(obj, size_adj=0, force_adj=False): 35 | if ppi_factor > 1 or force_adj: 36 | try: 37 | font = obj.GetFont() 38 | if font.IsUsingSizeInPixels(): 39 | font.SetPixelSize(tuplePPI(font.GetPixelSize()[0], font.GetPixelSize()[1]+size_adj)) 40 | else: 41 | font.SetPointSize(intPPI(font.GetPointSize())+size_adj) 42 | except: 43 | return 44 | obj.SetFont(font) 45 | 46 | def SetFontSize(font, factor, size_adj=0, usePixel=True): 47 | try: 48 | if usePixel and font.IsUsingSizeInPixels(): 49 | font.SetPixelSize((int(font.GetPixelSize()[0]*factor), int(font.GetPixelSize()[1]*factor)+size_adj)) 50 | else: 51 | font.SetPointSize(int(font.GetPointSize()*factor)+size_adj) 52 | except: 53 | return 54 | 55 | 56 | class DPI(): 57 | def __init__(self): 58 | self.ppi_factor = 1.0 59 | self.dpiAware = False 60 | self.dpiAwareness = 0 61 | 62 | def GetPPIFactor(self, setPPI=False): 63 | if os.name != 'nt': 64 | return 1.0 65 | if self.dpiAware: 66 | return self.ppi_factor 67 | 68 | try: 69 | ctypes.windll.shcore.SetProcessDpiAwareness(2) # Win 10 (mode 2) monitor v2 (win10 sizes the non client areas) 70 | self.dpiAware = True 71 | self.dpiAwareness = 2 72 | except: 73 | try: 74 | ctypes.windll.user32.SetProcessDPIAware() # Win 8,7 (mode 1) windows borders, title bar may be to small 75 | self.dpiAware = True 76 | self.dpiAwareness = 1 77 | except: 78 | pass 79 | if self.dpiAware: 80 | pw, ph = wx.ScreenDC().GetPPI() 81 | #pw, ph = wx.GetDisplayPPI() 82 | if ph < 110: 83 | ph = 96.0 84 | try: 85 | self.ppi_factor = float(ph / 96.0) 86 | except: 87 | pass 88 | 89 | global dpiAware 90 | global dpiAwareness 91 | dpiAware = self.dpiAware 92 | dpiAwareness = self.dpiAwareness 93 | 94 | if setPPI: 95 | global ppi_factor 96 | ppi_factor = self.ppi_factor 97 | global_vars.ppi_factor = self.ppi_factor 98 | return self.ppi_factor 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /readme_applyFilters.txt: -------------------------------------------------------------------------------- 1 | # GPo, 2021 2 | 3 | # 'Apply filters' applies filters to a frame area selected in the timeline. 4 | # First create selections in the timeline with the Trim Editor and click with the right mouse button 5 | # on a selected area and select 'Apply filter' and the desired filter. 6 | 7 | ###### Parameters for the templates ################ 8 | # %start is replaced with selection start # 9 | # %stop is replaced with selection end # 10 | # %* is replaced with the script selected text # 11 | # %join joins the filters from each selected line # 12 | # %copy copies the selection to script end # 13 | # %> copies this line to all timeline selections # 14 | #################################################### 15 | 16 | ## Simple filter example ( You have to put the text cursor at the desired script insert position ): 17 | ApplyRange(%start, %stop, "sharpen", 0.4) or c1=Trim(%start, %stop).sharpen(0.4) 18 | 19 | ## Example with a single line (filter) selection in the script: 20 | # if a single line is selected, disabled filters # are enabled 21 | ApplyFilter(%start, %stop, """%*""") 22 | 23 | ## With a single line (filter) selection, but does not override the selection (filter is inserted at script end) 24 | ApplyFilter(%start, %stop, """%*%copy""") 25 | 26 | ## Below you can see an example with several lines (filters) selected in the script, disabled lines # are ignored 27 | # and comments after filter text e.g. sharpen(0.4) # my sharpener, are removed. 28 | 29 | ## Method: add preview filter, insert script selections, join the filters and apply the filters from start to stop 30 | # This two examples are included as default in the templates, when you have saved the function 'ApplyFilter' listed below, 31 | # you can run the template in the timeline selections popup menu. You can also change it, e.g. remove 'avsp_filter' 32 | # Script selections are always replaced with the result, but there is the parameter %copy if you use this parameter 33 | # the selected text (filters) are copied to the script end. 34 | 35 | ## for a single timeline selection 36 | /**avsp_filter 37 | filter = """\ 38 | %*%join 39 | \""" 40 | ApplyFilter(%start, %stop, filter) 41 | **/ 42 | 43 | ## for all timeline selections 44 | filter = """\ 45 | %*%join 46 | \""" 47 | %>ApplyFilter(%start, %stop, filter) # %> this text is added for all selections 48 | 49 | ## Manual multiple filter example (you can save it as template, Options > 'Apply filters...'): 50 | filter = """\ 51 | SmoothLevels(input_low=16, gamma=1.00, input_high=235, output_low=16, output_high=235, TVrange=True, Lmode=0, darkSTR=100, brightSTR=100, debug=False) 52 | \.SmoothTweak(brightness=0, contrast=1.00, saturation=1.00, hue1=0, hue2=0, TVrange=True, Lmode=0, limitSTR=100, debug=False) 53 | \.NonlinUSM(z=1.0, pow=1.2, str=0.25, rad=120) 54 | \.NonlinUSM(z=3, pow=1.2, str=0.22, rad=6) 55 | \""" 56 | ApplyFilter(%start, %stop, filter) 57 | # or %>ApplyFilter(%start, %stop, filter) for all selections 58 | 59 | 60 | ## ApplyFilter syntax, save it separate in your filters avsi file or as ApplyFilter.avsi 61 | # If you have a better alternative to the function ApplyFilter or a better procedure, please let me know. 62 | 63 | function ApplyFilter(clip c, int "start", int "end", string "filter"){ 64 | start = default(start, 0) 65 | end = default(end, 0) 66 | c 67 | end = end <= 0 ? FrameCount()-1 : end 68 | seg2 = Trim(start, end) 69 | seg2 = Eval("seg2." + filter) 70 | re = start == 0 ? seg2 : start == 1 ? Trim(0, -1) ++ seg2 : Trim(0, start-1) ++ seg2 71 | re = end < FrameCount-1 ? re ++ Trim(end + 1, 0) : re 72 | return re 73 | } 74 | 75 | -------------------------------------------------------------------------------- /readme_LocateFrame.txt: -------------------------------------------------------------------------------- 1 | GPo 2023, AvsPmod function 'Locate frame' https://vimeo.com/797835669 2 | Last update 01.10.2024, the old example video is not up to date, no variables or selections more needed. 3 | 4 | The wonderful 'LocateFrames' function from Doom9 member StainlessS is needed. 5 | https://www.mediafire.com/folder/hb26mthbjz7z6/StainlessS or http://www.sendspace.com/folder/2mwrco 6 | 7 | Locate frames searches for the current frame in another clip, but I do not know if anyone will find it useful, it was more for fun and interest. 8 | I use it to get the same frame from two clips (one shortened or recoded), for Split View synchronization. 9 | If the Split View function is activated, the found frame is displayed and the offset and group are set. 10 | 11 | For explanation: The partner script is the right tab next to the current tab. 12 | 13 | Both clips must be initialized and match in terms of dimensions and color space. 14 | The frame in the current script (tab) is searched for in the script to the right of it (the partner script). 15 | 16 | Out of date, possible but there is now an dialog. 17 | You can set optional parameters in the current script: 18 | find_start = -500 # optional default -500, can aslo be positive 19 | find_stop = 600 # optional default +600 20 | find_thresh= 3.0 # optional default 3.0 (the higher frames are found that match less (0 = 100% match)) 21 | find_mode = 1 # optional (0 or 1) default 1, 0 should not be used, can cause stop less start errors. 22 | 23 | If found frame threshold less then find_thresh, only the frame property window is displayed and the result is attached: 24 | LF_MODE=1 # the set mode is displayed only if mode 0 are set 25 | LF_FOUND=5453 # the found frame number in the partner tab (the right one) 26 | LF_DIFF=0,000000 # the difference to the current frame 27 | LF_OFFSET=453 # the offset to the current frame, can also be negative 28 | 29 | If Split View is switched on: 30 | The found frame is displayed in the right window and the 'Split View' is synchronized. 31 | This means that a common group and the frame offset are set. 32 | 'Freeze frame' should then be turned off or when scrolling to another frame, the frame of the non-active tab remains frozen. 33 | 34 | The optional Variables (for the left script): 35 | target_clip: 36 | if the right script has many frames or the initialization takes too long, the variable 'target_clip' in the current (left) script 37 | can be initialized with the source in the right script e.g. target_clip = AviSource("right clip file name"), but the target_clip must 38 | return the same output as the right script (dimension, length etc.). 39 | if the target_clipt is not set in the current script, the target_clip will then be automatically created at the first search, 40 | this is then displayed in the status bar on the left. 41 | 42 | find_start, find_stop: the names should be self-explanatory. 43 | 44 | find_tresh = 3.0 45 | the same as in LocateFrames thresh but is not set and is handled differently. 46 | in the partner script the found frame number is only set if the difference is less than thresh. 47 | if only one frame with a higher value is found, this will be only displayed in the frame properties. 48 | 49 | find_mode = 0: (should not be used, can couse stop less start errors) 50 | the start and stop are calculated from the current script frame position. 51 | find_mode = 1 (default) 52 | the start and stop are calculated from the partner script current frame position. 53 | In both cases it will stop when a match is 100%. 54 | 55 | 56 | 57 | 58 | ! Do not use any other filters, that slows down the compare process. 59 | 60 | -------------------------------------------------------------------------------- /help/stylesheets/voidspace_docutils2.css: -------------------------------------------------------------------------------- 1 | /* 2 | :Authors: Ian Bicking, Michael Foord 3 | :Contact: fuzzyman@voidspace.org.uk 4 | :Date: 2006/04/01 5 | :Version: 0.2.0 6 | :Copyright: This stylesheet has been placed in the public domain. 7 | 8 | Stylesheet for Docutils. 9 | Based on ``blue_box.css`` by Ian Bicking 10 | and ``default.css`` revision 3442 11 | Optimised for rest2web - http://www.voidspace.org.uk/python/rest2web/ 12 | */ 13 | 14 | @import url(default.css); 15 | 16 | em, i { 17 | /* Typically serif fonts have much nicer italics */ 18 | font-family: Times New Roman, Times, serif; 19 | } 20 | 21 | 22 | a.target { 23 | color: blue; 24 | } 25 | 26 | a.toc-backref { 27 | text-decoration: none; 28 | color: black; 29 | } 30 | 31 | a.toc-backref:hover { 32 | background-color: inherit; 33 | } 34 | 35 | a:hover { 36 | background-color: #cccccc; 37 | } 38 | 39 | div.attention, div.caution, div.danger, div.error, div.hint, 40 | div.important, div.note, div.tip, div.warning { 41 | background-color: #cccccc; 42 | padding: 3px; 43 | width: 80%; 44 | } 45 | 46 | div.admonition p.admonition-title, div.hint p.admonition-title, 47 | div.important p.admonition-title, div.note p.admonition-title, 48 | div.tip p.admonition-title { 49 | text-align: center; 50 | background-color: #999999; 51 | display: block; 52 | margin: 0; 53 | } 54 | 55 | div.attention p.admonition-title, div.caution p.admonition-title, 56 | div.danger p.admonition-title, div.error p.admonition-title, 57 | div.warning p.admonition-title { 58 | color: #cc0000; 59 | font-family: sans-serif; 60 | text-align: center; 61 | background-color: #999999; 62 | display: block; 63 | margin: 0; 64 | } 65 | 66 | h1, h2, h3, h4, h5, h6 { 67 | font-family: Helvetica, Arial, sans-serif; 68 | 69 | /*border: thin solid black;*/ 70 | 71 | /* This makes the borders rounded on Mozilla, which pleases me */ 72 | /*-moz-border-radius: 8px;*/ 73 | padding: 4px; 74 | /* Padding used to be 4px, changed by Justin */ 75 | } 76 | 77 | h1 { 78 | border: solid 1px rgb(175,175,175); 79 | border-left: solid 0.5em rgb(175,175,175); 80 | background-color: rgb(220,220,220); 81 | text-decoration: none; 82 | color: rgb(50,50,50); 83 | margin-top: 1em; 84 | } 85 | 86 | h1 a.toc-backref { 87 | color: #444444; 88 | } 89 | 90 | 91 | h2{ 92 | background-color: #ffffff; 93 | color: #ffffff; 94 | border-bottom:dashed 1px #6699bb; 95 | } 96 | 97 | h3, h4, h5, h6 { 98 | background-color: #ffffff; 99 | color: #ffffff; 100 | border-bottom:solid 1px #cccccc; 101 | } 102 | 103 | h2 a.toc-backref, h3 a.toc-backref, h4 a.toc-backref, h5 a.toc-backref, 104 | h6 a.toc-backref { 105 | color: #555555; 106 | } 107 | 108 | h1.title { 109 | text-align: center; 110 | background-color: #444499; 111 | color: #eeeeee; 112 | /*border: medium solid black;*/ 113 | border: solid 3px black; 114 | border-left: solid 0.5em black; 115 | border-right: solid 0.5em black; 116 | /*-moz-border-radius: 20px;*/ 117 | margin-top: 0em; 118 | } 119 | 120 | table.footnote { 121 | padding-left: 0.5ex; 122 | } 123 | 124 | table.citation { 125 | padding-left: 0.5ex 126 | } 127 | 128 | pre.literal-block, pre.doctest-block { 129 | border: thin black solid; 130 | padding: 5px; 131 | font-family: sans-serif; 132 | } 133 | 134 | .image { 135 | border-style : solid; 136 | border-width : 2px; 137 | } 138 | 139 | img.align-center { 140 | display: block; 141 | margin: auto; 142 | text-align: center; 143 | margin: 10px; 144 | } 145 | 146 | h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { 147 | font-size: 100%; 148 | } 149 | 150 | code, tt { 151 | color: #000066; 152 | } 153 | -------------------------------------------------------------------------------- /func.py: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # Name: func.py 3 | # Purpose: 4 | # 5 | # Author: GPo 6 | # 7 | # Created: 23.10.2021 8 | # Copyright: (c) GPo 2021 9 | # Licence: 10 | #------------------------------------------------------------------------------- 11 | import sys 12 | encoding = sys.getfilesystemencoding() 13 | 14 | def GetMatrixName(idx): 15 | namedict = { 16 | 0: 'RGB', 17 | 1: 'BT.709', 18 | 2: 'undef', 19 | #3: 'reserved', 20 | 4: 'FCC T47', 21 | 5: 'BT.470 B/G', 22 | 6: 'BT.601', 23 | 7: 'SMPTE ST 240', 24 | 8: 'YCgCo', 25 | 9: 'BT.2020ncl', 26 | 10: 'BT.2020cl', 27 | 11: 'SMPTE ST 2085', 28 | 12: 'Chroma ncl', 29 | 13: 'Chroma cl', 30 | 14: 'BT.2100', 31 | 15: 'IPT-C2', 32 | 16: 'YCGCO-R-E', 33 | 17: 'YCGCO-R-O' 34 | } 35 | if idx in namedict.keys(): 36 | return namedict[idx] 37 | return '..' 38 | 39 | def GetColorPrimariesName(idx): 40 | namedict = { 41 | 1: 'BT.709', 42 | 2: 'undef', 43 | #3: 'undef', 44 | 4: 'BT.470 M', 45 | 5: 'BT.470 BG', 46 | 6: 'SMPTE 170 M', 47 | 7: 'SMPTE 240 M', 48 | 8: 'Film', 49 | 9: 'BT.2020', 50 | 10: 'ST 428', 51 | 11: 'ST 431-2', 52 | 12: 'ST 432-1', 53 | 22: 'jedec-p22' 54 | } 55 | if idx in namedict.keys(): 56 | return namedict[idx] 57 | return '?' 58 | 59 | def GetChromaLocationName(idx): 60 | namedict = { 61 | 0: 'left', 62 | 1: 'center', 63 | 2: 'top-left', 64 | 3: 'top', 65 | 4: 'bottom-left', 66 | 5: 'bottom' 67 | } 68 | if idx in namedict.keys(): 69 | return namedict[idx] 70 | return '?' 71 | 72 | def GetFieldBasedName(idx): 73 | namedict = { 74 | 0:'progressive', 75 | 1:'bottom-field', 76 | 2:'top-field' 77 | } 78 | if idx in namedict.keys(): 79 | return namedict[idx] 80 | return '?' 81 | 82 | def GetTransferName(idx): 83 | namedict = { 84 | 1:'709', 85 | 2:'undef', 86 | 4:'470m', 87 | 5:'470bg', 88 | 6:'601', 89 | 7:'240m', 90 | 8:'linear', 91 | 9:'log100', 92 | 10:'log316', 93 | 11:'xvycc', 94 | 13:'srgb', 95 | 14:'2020_10', 96 | 15:'2020_12', 97 | 16:'st2084', 98 | 17:'428-1', 99 | 18:'std-b67' 100 | } 101 | if idx in namedict.keys(): 102 | return namedict[idx] 103 | return '?' 104 | 105 | def GetColorRangeName(idx): 106 | namedict = { 107 | 0:'full', 108 | 1:'limited' 109 | } 110 | if idx in namedict.keys(): 111 | return namedict[idx] 112 | return '?' 113 | 114 | def GetGOPClosedName(idx): 115 | namedict = { 116 | 0:'false', 117 | 1:'true' 118 | } 119 | if idx in namedict.keys(): 120 | return namedict[idx] 121 | return '?' 122 | 123 | 124 | 125 | """ test for system or utf8 encoding and return encoded string 126 | def EncodeString(s): 127 | try: 128 | tmp = s.encode(encoding) 129 | txt = tmp.decode(encoding) 130 | if txt == s: 131 | return s.encode(encoding, 'backslashreplace') 132 | else: 133 | return s.encode('utf8', 'backslashreplace') 134 | except UnicodeDecodeError: 135 | return s.encode(encoding, 'backslashreplace') 136 | """ 137 | """ 138 | def GetPropNameValue(key, value): 139 | propCharDict = { 140 | '_Matrix': func.GetMatrixName, 141 | '_Primaries': func.GetColorPrimariesName, 142 | '_ChromaLocation': func.GetChromaLocationName, 143 | '_FieldBased': func.GetFieldBasedName, 144 | '_Transfer': func.GetTransferName, 145 | '_ColorRange': func.GetColorRangeName, 146 | '_GOPClosed': func.GetGOPClosedName, 147 | } 148 | if key in propCharDict: 149 | return '[' + propCharDict[key](value) + ']' 150 | return '' 151 | """ 152 | -------------------------------------------------------------------------------- /readme_ScriptSelector.txt: -------------------------------------------------------------------------------- 1 | AvsPmod Script selector, GPo 20.08.2023 2 | 3 | Preliminary: 4 | Some functions in the script selector can only be used meaningfully if the scripts located on the hard disk also have unique names. 5 | This means not only file 1, file 2 etc. 6 | In my case almost all scripts (2500) have the name of the video file with .avs appended. 7 | So 'The Midnight Crime Story.mpg' = 'The Midnight Crime Story.mpg.avs' 8 | I have created a tab for each partition where avs files are located with the corresponding partition or folder name (E DVB, E, F, ...). 9 | Still tabs for favorites and a temp tab (Favor, Favor2, Temp) 10 | Of course you can also use it just as a kind of session file and insert the currently opened AvsPmod tabs. 11 | 12 | Find, Search and Update Functions: 13 | 'Add or Update all scripts' Insert or updates all opened AvsPmod scripts (tabs). 14 | 'Clear and Add all scripts' Clears the tab and insert all opened AvsPmod scripts (tabs). 15 | 'Add or update script' Insert or updated the current AvsPmod script (tab). 16 | 'Find current script' finds the current AvsPmod script (tab). 17 | 'Find script...' searches for scripts in all tabs and displays found scripts in a separate tab. These tabs should be deleted when they are no longer needed. 18 | 'Search in scripts' searches inside all scripts for the given text. These tabs should also be deleted when they are no longer needed. 19 | 'Search in Notes...' searches in all Nodes for the given text. These tabs should also be deleted when they are no longer needed. 20 | 21 | Probably the most important functions at the beginning: 22 | 'Find or Update from avs...' Searches with sub folders, the last opened dir is saved for the current tab for next use. 23 | 'Update selection from avs' The selected scripts are updated from avs files on the hard disk (no new files are added). 24 | 'Check existing 'Ctrl removes' All scripts in the current tab are checked for being present on the hard disk, if not exists and Ctrl was pressed the script is removed from the tab. 25 | 26 | Find duplicate functions: 27 | 'Find dup' find all duplicate names. 28 | 'Find dub (same tab)' find all duplicte names in the same tab. 29 | 'Find dup (dif)' find all duplicate names with different script text. 30 | 31 | Mouse events global: 32 | middle down finds the current AvsPmod script (tab) 33 | double click > 20 pixel selects or opens the script in AvsPmod 34 | Selections can be copied to/into another tab using drag and drop or use Edit > Copy and Paste 35 | 36 | Mouse events on the script list items: 37 | Name: 38 | left down < 22 pixels shows the saved Note as tip window (an asterisk indicates an existing note). 39 | left down (rigth - 22 pixel) shows the name as tip window if auto tooltip disabled 40 | double click < 22 pixels shows MediaInfo if the dll found in the systems or AvsPmod directory. 41 | double click (right - 22 pixels) shows the script in an separate window 42 | 43 | Bookmarks: 44 | double click = open AvsPThumb with bk6/bk3 file or with this script is no bk* file exists 45 | 46 | Path: 47 | left < 22 pixel displays the path as a tooltip if Auto-Tooltip is deactivated 48 | double click shows the script in an separate window 49 | 50 | Keyboard events: 51 | ESC = close 52 | del and numpad del = Removes selected scripts from current tab 53 | a to z and 0 to 9 = search for scripts in the current tab 54 | Hot key AvsPmod for open/close Script selector = close 55 | 56 | Note for Notes: 57 | Note can be saved Edit > 'Change note' 58 | Or the Note is read from the script if #note: is found in the script in the first 10 lines (the line must start with #note:) 59 | If a 'Note' is found in the script, the existing 'Note' is overwritten. 60 | 61 | Color Markers and Flag: 62 | Who wants to use it... it is available .) 63 | 64 | Disaster!: 65 | Tab Context Menu 'Disaster! reopen last data' 66 | If you accidentally delete all tabs or make another mistake, DO NOT CLOSE THE WINDOW! but use this menu, 67 | then the data will be loaded as it was before you started the Script Selector. 68 | 69 | 70 | -------------------------------------------------------------------------------- /readme_SplitClip.txt: -------------------------------------------------------------------------------- 1 | GPo 2022, AvsPmod 'Split Clip' 2 | 3 | The 'Split Clip' splits the main clip, this allows you to switch between a fast preview (without filters) and a normal preview. 4 | That's exactly what it's designed for, even though other things are possible, e.g. a quick comparison at different frame positions 5 | with another filter without having to create a new tab. 6 | 7 | The memory requirement is not much higher than for a single main clip since the second clip is derived from the first. 8 | If filters are also used for the 'Split Clip', this will of course increase the memory requirement. 9 | 10 | The 'Split Clip' is fully integrated (preview filter, pixel values, video information, frame properties, etc.), 11 | but the matrix can only be read if the 'Split Clip' enabled on refreshing the script, or use the frame properties to get the Matrix. 12 | So, after a script refresh, the Matrix is always read from the active clip. 13 | 14 | !! Do not set a 'Preview filter' area in a 'Split Clip' area and vice versa, this will cause an error. 15 | !! It is recommended not to comment out lines with /* in a 'Split Clip' or 'Preview filter' area, use only # 16 | !! The flag must not be in an 'if else' statement! And if __end__ or return is found before the flag, no Split Clip can be created. 17 | 18 | The split position must be written into the script. Everything after this flag will not be played with the 'Split Clip'. 19 | To create the 'Split Clip' the script must be reinitialized after setting the split position. /**avsp_split**/ 20 | 21 | To remove the 'Split Clip' the first flag (/**avsp_split) must be changed and the script must be reinitialized. 22 | This is not about switching, because that is fast, no it is the complete removal of the 'Split Clip' meant. 23 | 24 | Prefered way insert a space: /** avsp_split (this can be done with mouse button left down and right click) 25 | or insert character: /**#avsp_split or remove the 'Split Clip' area completely. 26 | 27 | Only if the start and end flag in a single line: /**avsp_split**/ one comment out is enough: #/**avsp_split**/ 28 | otherwise if the 'Split Clip' has filters and you do not comment out all lines there will be a syntax error 29 | and the filters are not disabled. 30 | 31 | Under Video > Additional > 'Restore split clip if enabled' you can select should 'Split Clip' restored after a script refresh. 32 | The timeline color indicates that 'Split Clip' is switched on or off. You can change the color in the context menu of the frame text field. 33 | 34 | You can insert a 'Split Clip' under Edit > Insert > 'Split Clip'. 35 | For me I have entered /**avsp_split**/ after the sourcfilter for all my source templates. 36 | 37 | Note: 38 | If 'Split Clip' is switched on or off for the first time after a frame change, the required time is the time the filters needs for the new frame. 39 | 40 | 41 | ### An example of a split without 'Split Clip' filters: 42 | 43 | video=LWLibavVideoSource(SourceFile) 44 | audio=LWLibavAudioSource(SourceFile) 45 | audioDub(video, audio) 46 | 47 | /**avsp_split**/ 48 | 49 | ## The next part is skipped by the 'Split Clip' 50 | QTGMC() 51 | MCTemporalDenoise() 52 | prefetch(4) 53 | 54 | 55 | ### Filters can be included in the 'Split Clip', then the syntax must look like this: 56 | 57 | video=LWLibavVideoSource(SourceFile) 58 | audio=LWLibavAudioSource(SourceFile) 59 | audioDub(video, audio) 60 | 61 | /**avsp_split 62 | Spline36Resize(1920, 1080) 63 | prefetch(2) 64 | **/ 65 | 66 | ## The next part is skipped by the 'Split Clip' 67 | QTGMC() 68 | MCTemporalDenoise() 69 | Spline36Resize(1920, 1080) 70 | prefetch(4) 71 | 72 | ### You can compare filters without having to create an extra tab: 73 | LWLibavVideoSource(SourceFile) 74 | /**avsp_split 75 | MCTemporalDenoise() 76 | prefetch(4) 77 | **/ 78 | MCDegrainSharp() 79 | prefetch(4) 80 | 81 | ### It also goes something like this (but only quick testet): 82 | # switches between SourceFile_1 and SourceFile_2 83 | 84 | LWLibavVideoSource(SourceFile_1) 85 | /**avsp_split 86 | LWLibavVideoSource(SourceFile_2) 87 | **/ 88 | 89 | 90 | -------------------------------------------------------------------------------- /macros/Extra/Save Image_rgb48.py: -------------------------------------------------------------------------------- 1 | # GPo 2024, Save Image_rgb48.py 2 | # save current frame as 48bit tiff or png file with ffmpeg 3 | 4 | import subprocess 5 | import os 6 | import sys 7 | self = avsp.GetWindow() 8 | 9 | ##### user settings 10 | # path to ffmpeg.exe 11 | ffmpeg = os.path.join(self.programdir, 'encoders\\ffmpeg.exe') 12 | 13 | # added the output to a new tab ( ImageReader or FFImageSource ) 14 | addNewTab = True 15 | 16 | # change the ImageReader for the new tab. FFImageSource("%s") or ImageReader("%s", pixel_type="RGB48") 17 | ImageReader = 'ImageReader("%s", pixel_type="RGB48")' 18 | 19 | # append frame number 20 | addFrameNr = True 21 | ##### 22 | 23 | script = self.currentScript 24 | if self.UpdateScriptAVI() is None or not self.previewOK(script): 25 | avsp.MsgBox('Script not initialized.') 26 | return 27 | frame = avsp.GetFrameNumber() 28 | trim = 'trim(%i, -1)' % frame 29 | txt = self.getCleanText(script.GetText()) 30 | txt = self.stripComment_2(txt) 31 | txt, encoding = self.GetEncodedText(script, txt, forceUtf8=False) 32 | scriptTxt = txt.strip() + '\n' + trim 33 | 34 | if not os.path.isfile(ffmpeg): 35 | avsp.MsgBox('ffmpeg not found.\nYou must change the "ffmpeg" variable in the macro.\n\n' + ffmpeg, 'Error') 36 | return 37 | 38 | default = self.options['imagesavedir'] 39 | tabTitle = self.scriptNotebook.GetPageText(self.scriptNotebook.GetSelection()) 40 | filterIdx = avsp.Options.get('filteridx', 0) 41 | 42 | if not os.path.isdir(default): 43 | default = '' 44 | if script.filename: 45 | base, ext = os.path.splitext(script.filename) 46 | if addFrameNr: 47 | default = '%s_%i' % (base, frame) 48 | else: 49 | default = base 50 | elif addFrameNr: 51 | if default: 52 | path = os.path.join(default, tabTitle) 53 | default = '%s_%i' % (path, frame) 54 | else: 55 | default = '%s_%i' % (tabTitle, frame) 56 | elif default: 57 | default = os.path.join(default, tabTitle) 58 | else: 59 | default = tabTitle 60 | 61 | filter = 'Tagged Image File (*.tif)|*.tif|Portable Network Graphics (*.png)|*.png' 62 | idx, outfile = avsp.GetSaveFilename(title='Save as', filefilter=filter, default=default, getfilteridx=True, setfilteridx=filterIdx) 63 | if not outfile: 64 | return 65 | imageType = 'tiff' if idx == 0 else 'png' 66 | 67 | self.options['imagesavedir'] = os.path.dirname(outfile) 68 | avsp.Options['filteridx'] = idx 69 | 70 | infile = os.path.join(self.toolsfolder, 'encode.avs') 71 | encoding_args = [ 72 | ffmpeg, 73 | '-ss', '00:00:00', 74 | '-i', infile, 75 | #'-pix_fmt', 'rgb48', 76 | '-vcodec', imageType, 77 | '-frames:v','1', 78 | '-update', '1', 79 | '-y', outfile, 80 | ] 81 | 82 | try: 83 | with open(infile, 'wb') as f: 84 | f.write(scriptTxt) 85 | f.close() 86 | except IOError as err: 87 | raise 88 | 89 | def utf8ify(list): 90 | return [item.encode(sys.getfilesystemencoding()) for item in list] 91 | 92 | def fileSizeToString(fsize, precision=0): 93 | if fsize < 1: 94 | return '0 B' 95 | suffixes = ['B','KB','MB','GB','TB'] 96 | suffixIndex = 0 97 | while fsize > 1024 and suffixIndex < 4: 98 | suffixIndex += 1 99 | fsize = fsize/1024.0 100 | if suffixIndex > 2 and precision == 0: 101 | precision = 2 102 | return '%.*f%s' % (precision, fsize, suffixes[suffixIndex]) 103 | 104 | encoding_errors = '' 105 | encoding_file_size = 0 106 | args = utf8ify(encoding_args) 107 | re = subprocess.call(args) 108 | if re != 0: 109 | encoding_errors = 'Code: %s\n%s\n' % (str(re), os.path.split(outfile)[1]) 110 | elif os.path.isfile(outfile): 111 | encoding_file_size += os.path.getsize(outfile) 112 | else: 113 | encoding_errors = 'Unknown error' 114 | 115 | if encoding_errors: 116 | avsp.MsgBox('Last encoding returns error\n' + encoding_errors, 'Error') 117 | elif addNewTab: 118 | ImageReader = ImageReader % outfile 119 | self.NewTab(text='#Filesize: %s\n%s' % (fileSizeToString(encoding_file_size), ImageReader)) 120 | 121 | -------------------------------------------------------------------------------- /tools/ffmpeg.presets.default: -------------------------------------------------------------------------------- 1 | [x264 CRF Slow] 2 | ffmpeg.exe -i "$video_input" -vcodec libx264 -preset slow -tune film -crf $video_quality -vf setsar=sar=$par_x/$par_y -acodec aac -b:a 192k -y "$video_output" 3 | 4 | [x264 CRF Medium] 5 | ffmpeg.exe -i "$video_input" -vcodec libx264 -preset medium -tune film -crf $video_quality -vf setsar=sar=$par_x/$par_y -acodec aac -b:a 192k -y "$video_output" 6 | 7 | [x264 lossless veryslow] 8 | ffmpeg.exe -i "$video_input" -vcodec libx264 -preset veryslow -qp 0 -vf setsar=sar=$par_x/$par_y -acodec aac -b:a 320k -y "$video_output" 9 | 10 | [x264 lossless slow] 11 | ffmpeg.exe -i "$video_input" -vcodec libx264 -preset slow -qp 0 -vf setsar=sar=$par_x/$par_y -acodec aac -b:a 320k -y "$video_output" 12 | 13 | [x264 lossless medium] 14 | ffmpeg.exe -i "$video_input" -vcodec libx264 -preset medium -qp 0 -vf setsar=sar=$par_x/$par_y -acodec aac -b:a 320k -y "$video_output" 15 | 16 | [x264 lossless ultra fast] 17 | ffmpeg.exe -i "$video_input" -vcodec libx264 -preset ultrafast -qp 0 -vf setsar=sar=$par_x/$par_y -acodec aac -b:a 320k -y "$video_output" 18 | 19 | [x265 CRF Slow] 20 | ffmpeg.exe -i "$video_input" -vcodec libx265 -preset slow -crf $video_quality -vf setsar=sar=$par_x/$par_y -acodec aac -b:a 192k -y "$video_output" 21 | 22 | [x265 CRF Medium] 23 | ffmpeg.exe -i "$video_input" -vcodec libx265 -crf $video_quality -vf setsar=sar=$par_x/$par_y -acodec aac -b:a 192k -y "$video_output" 24 | 25 | [x265 lossless slow] 26 | ffmpeg.exe -i "$video_input" -vcodec libx265 -preset slow -x265-params lossless=1 -vf setsar=sar=$par_x/$par_y -acodec aac -b:a 320k -y "$video_output" 27 | 28 | [x265 lossless medium] 29 | ffmpeg.exe -i "$video_input" -vcodec libx265 -preset medium -x265-params lossless=1 -vf setsar=sar=$par_x/$par_y -acodec aac -b:a 320k -y "$video_output" 30 | 31 | [x265 lossless ultra fast] 32 | ffmpeg.exe -i "$video_input" -vcodec libx265 -preset ultrafast -x265-params lossless=1 -vf setsar=sar=$par_x/$par_y -acodec aac -b:a 320k -y "$video_output" 33 | 34 | [svt-av1 CRF Slower] 35 | ffmpeg.exe -i "$video_input" -c:v libsvtav1 -crf $video_quality -preset 4 -svtav1-params -g=125 -svtav1-params tune=0 -svtav1-params film-grain-denoise=0 -vf setsar=sar=$par_x/$par_y -c:a aac -b:a 192k -y "$video_output" 36 | 37 | [svt-av1 CRF Slow] 38 | ffmpeg.exe -i "$video_input" -c:v libsvtav1 -crf $video_quality -preset 6 -svtav1-params -g=125 -svtav1-params tune=0 -svtav1-params film-grain-denoise=0 -vf setsar=sar=$par_x/$par_y -c:a aac -b:a 192k -y "$video_output" 39 | 40 | [svt-av1 CRF Medium] 41 | ffmpeg.exe -i "$video_input" -c:v libsvtav1 -crf $video_quality -preset 8 -svtav1-params -g=100 -svtav1-params tune=0 -svtav1-params film-grain-denoise=0 -vf setsar=sar=$par_x/$par_y -c:a aac -b:a 192k -y "$video_output" 42 | 43 | [nv_h264 VBR HQ] 44 | ffmpeg.exe -i "$video_input" -c:v h264_nvenc -preset slow -profile:v main -rc vbr_hq -b:v $video_bitrate_k -vf setsar=sar=$par_x/$par_y -c:a aac -b:a 192k -y "$video_output" 45 | 46 | [nv_h264 CQP] 47 | ffmpeg.exe -i "$video_input" -c:v h264_nvenc -preset slow -profile:v main -rc constqp -qp $video_quality -vf setsar=sar=$par_x/$par_y -c:a aac -b:a 192k -y "$video_output" 48 | 49 | [nv_h264 lossless] 50 | ffmpeg.exe -i "$video_input" -c:v h264_nvenc -preset slow -profile:v main -tune lossless -vf setsar=sar=$par_x/$par_y -c:a aac -b:a 320k -y "$video_output" 51 | 52 | [nv_h265 VBR HQ] 53 | ffmpeg.exe -i "$video_input" -c:v hevc_nvenc -preset slow -profile:v main -rc vbr_hq -b:v $video_bitrate_k -vf setsar=sar=$par_x/$par_y -c:a aac -b:a 192k -y "$video_output" 54 | 55 | [nv_h265 CQP] 56 | ffmpeg.exe -i "$video_input" -c:v hevc_nvenc -preset slow -profile:v main -rc constqp -qp $video_quality -vf setsar=sar=$par_x/$par_y -c:a aac -b:a 192k -y "$video_output" 57 | 58 | [av1_nvenc VBR] 59 | ffmpeg.exe -hwaccel cuda -hwaccel_output_format cuda -i "$video_input" -c:v av1_nvenc -preset slow -b:v $video_bitrate_k -vf setsar=sar=$par_x/$par_y -c:a aac -b:a 192k -y "$video_output" 60 | 61 | [av1_nvenc CQP] 62 | ffmpeg.exe -hwaccel cuda -hwaccel_output_format cuda -i "$video_input" -c:v av1_nvenc -rc constqp -qp $video_quality -g 250 -c:a aac -b:a 192k -y "$video_output" 63 | 64 | [DNxHR HQ 8bit] 65 | ffmpeg.exe -i "$video_input" -c:v dnxhd -profile:v dnxhr_hq -vf "format=yuv422p, setsar=sar=$par_x/$par_y" -c:a pcm_s16le "$video_output".mov -------------------------------------------------------------------------------- /macros/Run analysis pass.py: -------------------------------------------------------------------------------- 1 | ################################################################################# 2 | ## GPo 2022, AvsPmod macro 'Run analysis pass.py', last Update 18.10.2024 3 | ## Like menu 'Run analysis pass' but in a separate thread. 4 | ## Therefore you can continue working with AvsPmod on another tab (script). 5 | ## But it is a bit slower than 'Run analysis pass' from the AvsPmod tools menu. 6 | ################################################################################# 7 | 8 | import wx, threading, time, tempfile 9 | import pyavs, wxp 10 | 11 | # init_only > there are functions, e.g. the SceneLog DBSC from StainlessS that runs through its own frame loop 12 | # and then returns the result or writes it to a file. Set it to True, a dialog is then displayed and you can disable it. 13 | init_only = True 14 | 15 | self = avsp.GetWindow() 16 | script = self.currentScript 17 | 18 | if init_only: 19 | ID = wxp.MessageBox("Single pass is enabled 'init_only'. Change it?", 'Analysis pass', wx.YES_NO, self) 20 | if ID == wx.YES: 21 | init_only = False 22 | 23 | def runpass(progress, txt, filename, workdir, init_only): 24 | 25 | if init_only: 26 | initial_time = time.time() 27 | avsp.SafeCall(progress.Start) 28 | 29 | AVI = pyavs.AvsSimpleClipBase(txt, filename=filename, workdir=workdir) 30 | 31 | if not isinstance(AVI, pyavs.AvsSimpleClipBase) or not AVI.initialized: 32 | AVI = None 33 | avsp.SafeCall(progress.Close) 34 | avsp.SafeCall(avsp.MsgBox,'Cannot create AvsSimpleClipBase', 'Analysis pass error') 35 | return 36 | if AVI.error_message is not None: 37 | AVI = None 38 | avsp.SafeCall(progress.Close) 39 | avsp.SafeCall(avsp.MsgBox, AVI.error_message, 'Analysis pass error') 40 | return 41 | 42 | if init_only: 43 | AVI = None 44 | wx.Bell() 45 | st = time.strftime("%H:%M:%S", time.gmtime(time.time() - initial_time)) 46 | avsp.SafeCall(progress.Stop) 47 | avsp.SafeCall(progress.SetLabel, 'Finished at %s' % st, '') 48 | return 49 | 50 | frame_count = AVI.Framecount 51 | avsp.SafeCall(progress.SetLabel, 'Running analysis pass', '') 52 | avsp.SafeCall(progress.SetRange, frame_count) 53 | previous_frame = -1 54 | initial_time = previous_time = time.time() 55 | for frame in range(frame_count): 56 | AVI.clip.get_frame(frame) 57 | error = AVI.clip.get_error() 58 | if error: 59 | AVI = None 60 | avsp.SafeCall(progress.Close) 61 | avsp.SafeCall(avsp.MsgBox, u'\n\n'.join((_('Error requesting frame {number}').format(number=frame), error)), 'Error') 62 | return 63 | now = time.time() 64 | delta = now - previous_time 65 | elapsed_time = now - initial_time 66 | if delta >= 0.1: # then elapsed_time > 0, so no check is needed (if elapsed_time else 'INF') 67 | fps = (frame - previous_frame) / delta 68 | previous_time = now 69 | previous_frame = frame 70 | progress.remaining_time = frame_count * elapsed_time / (frame+1) - elapsed_time 71 | avsp.SafeCall(progress.Update, frame, _('Average %#.4g fps') % ((frame+1)/ elapsed_time), _('Frame %s/%s (%#.4g fps)') % (frame, frame_count, fps), True) 72 | if progress.Cancel: 73 | AVI = None 74 | avsp.SafeCall(progress.Close) 75 | return 76 | 77 | elapsed_time = time.time() - initial_time 78 | AVI = None 79 | wx.Bell() 80 | avsp.SafeCall(progress.Stop) 81 | avsp.SafeCall(progress.SetLabel, 'Finished (%s fps average)' % ('%#.4g' % (frame_count / elapsed_time) if elapsed_time else 'INF'), '*** live and let live ***') 82 | 83 | 84 | def run(script, init_only): 85 | filename = workdir = script.filename 86 | if not filename: 87 | workdir = tempfile.gettempdir() 88 | progress = wxp.ProgressDlg(self, 'Analysis pass', 'Process in progress', 'Waiting for clip initialization') 89 | th = threading.Thread(target=runpass, args=(progress, script.GetText(), filename, workdir, init_only,)) 90 | th.daemon = True 91 | th.start() 92 | 93 | wx.CallAfter(run, script, init_only) 94 | 95 | -------------------------------------------------------------------------------- /cfunc.py: -------------------------------------------------------------------------------- 1 | # cfunc 2 | 3 | import pyavs 4 | import sys 5 | import numpy 6 | 7 | x86_64 = sys.maxsize > 2**32 8 | if x86_64: 9 | import avisynth_cffi as avisynth 10 | else: 11 | import avisynth 12 | 13 | def CreateFastClip(self, scripttxt, useSplitClip, previewFilter, matrix, readmatrix, interlaced, swapuv, bit_depth): 14 | return None 15 | 16 | def CheckSplitClip(self, script, filename): 17 | try: 18 | self.main_clip = self.env.invoke('Eval', [script, filename]) 19 | except avisynth.AvisynthError as err: 20 | return err 21 | 22 | def CreateFilterClip(self, f_args='', fast_display_clip=False, update_yv12clip=False): 23 | self.preview_filter = None 24 | return None, '' 25 | 26 | def KillFilterClip(self, createDisplayClip=True): 27 | self.preview_filter = None 28 | if not self.initialized: 29 | return 30 | if createDisplayClip: 31 | self.CreateDisplayClip(self.matrix, self.interlaced, self.swapuv, self.bit_depth) 32 | 33 | def MixAudioToStereo(audio_buffer, chn, dtype, cdb=0.7, db=1.0): 34 | # L R C Lfe Ls Rs. (SMPTE order) 35 | buf = numpy.frombuffer(audio_buffer, dtype=dtype) 36 | c = buf.reshape(chn, len(buf)/chn, order='FORTRAN') 37 | if chn == 2: 38 | left = (c[0]*db).astype(dtype) 39 | right = (c[1]*db).astype(dtype) 40 | elif chn >= 8: 41 | left = ((c[0]*0.7 + c[4]*0.2 + c[6]*0.1 + c[2]*0.7*cdb)*db).astype(dtype) 42 | right = ((c[1]*0.7 + c[5]*0.2 + c[7]*0.1 + c[2]*0.7*cdb)*db).astype(dtype) 43 | elif chn >= 6: 44 | left = ((c[0]*0.7 + c[4]*0.3 + c[2]*0.7*cdb)*db).astype(dtype) 45 | right = ((c[1]*0.7 + c[5]*0.3 + c[2]*0.7*cdb)*db).astype(dtype) 46 | elif chn >= 4: 47 | left = ((c[0]*0.7 + c[2]*0.3)*db).astype(dtype) 48 | right = ((c[1]*0.7 + c[3]*0.3)*db).astype(dtype) 49 | elif chn == 3: 50 | left = ((c[0]*0.7 + c[2]*cdb)*db).astype(dtype) 51 | right = ((c[1]*0.7 + c[2]*cdb)*db).astype(dtype) 52 | else: 53 | left = (c[0]*db).astype(dtype) 54 | right = (c[0]*db).astype(dtype) 55 | return numpy.dstack((left, right)).tobytes() 56 | 57 | def MixAudio1(audio_buffer, chn, dtype, cdb=0.7, db=1.0): 58 | buf = numpy.frombuffer(audio_buffer, dtype=dtype) 59 | left = (buf*db).astype(dtype) 60 | right = (buf*db).astype(dtype) 61 | return numpy.dstack((left, right)).tobytes() 62 | 63 | def MixAudio2(audio_buffer, chn, dtype, cdb=0.7, db=1.0): 64 | if db == 1: return audio_buffer 65 | buf = numpy.frombuffer(audio_buffer, dtype=dtype) 66 | c = buf.reshape(chn, len(buf)/chn, order='FORTRAN') 67 | left = (c[0]*db).astype(dtype) 68 | right = (c[1]*db).astype(dtype) 69 | return numpy.dstack((left, right)).tobytes() 70 | 71 | def MixAudio3(audio_buffer, chn, dtype, cdb=0.7, db=1.0): 72 | buf = numpy.frombuffer(audio_buffer, dtype=dtype) 73 | c = buf.reshape(chn, len(buf)/chn, order='FORTRAN') 74 | left = ((c[0]*0.7 + c[2]*cdb)*db).astype(dtype) 75 | right = ((c[1]*0.7 + c[2]*cdb)*db).astype(dtype) 76 | return numpy.dstack((left, right)).tobytes() 77 | 78 | def MixAudio4(audio_buffer, chn, dtype, cdb=0.7, db=1.0): 79 | buf = numpy.frombuffer(audio_buffer, dtype=dtype) 80 | c = buf.reshape(chn, len(buf)/chn, order='FORTRAN') 81 | left = ((c[0]*0.7 + c[2]*0.3)*db).astype(dtype) 82 | right = ((c[1]*0.7 + c[3]*0.3)*db).astype(dtype) 83 | return numpy.dstack((left, right)).tobytes() 84 | 85 | def MixAudio6(audio_buffer, chn, dtype, cdb=0.7, db=1.0): 86 | buf = numpy.frombuffer(audio_buffer, dtype=dtype) 87 | c = buf.reshape(chn, len(buf)/chn, order='FORTRAN') 88 | left = ((c[0]*0.7 + c[4]*0.3 + c[2]*0.7*cdb)*db).astype(dtype) 89 | right = ((c[1]*0.7 + c[5]*0.3 + c[2]*0.7*cdb)*db).astype(dtype) 90 | return numpy.dstack((left, right)).tobytes() 91 | 92 | def MixAudio8(audio_buffer, chn, dtype, cdb=0.7, db=1.0): 93 | buf = numpy.frombuffer(audio_buffer, dtype=dtype) 94 | c = buf.reshape(chn, len(buf)/chn, order='FORTRAN') 95 | left = ((c[0]*0.7 + c[4]*0.2 + c[6]*0.1 + c[2]*0.7*cdb)*db).astype(dtype) 96 | right = ((c[1]*0.7 + c[5]*0.2 + c[7]*0.1 + c[2]*0.7*cdb)*db).astype(dtype) 97 | return numpy.dstack((left, right)).tobytes() 98 | 99 | # Experimental 100 | def LocateFrame(self, start=-500, stop=500, framenr=None, thresh=None, target_src='', target_clip=None): 101 | re = [-1, '', ''] 102 | return re 103 | 104 | -------------------------------------------------------------------------------- /previewFilterExample.avs: -------------------------------------------------------------------------------- 1 | /* 2 | GPo, 2021.01.03 3 | Examples of preview filter in AvsPmod. 4 | 5 | A 'Preview filter' allows an almost real-time view of parameter changes of a filter. 6 | With sliders a very fast visuel adjustment of the used filters is possible. Or use 'Number wheel' 7 | 8 | Avisynth filters that do not require a high CPU load are suitable as preview filters. The faster the avisynth filters are, the faster the preview can be created. 9 | It doesn't make sense to use MCTemporalDenoise in a preview filter. Suitable filters are sharpness, colors or similar filters. 10 | Preview filters are always processed as last filter, but 'prefetch' in the preview area only affects the preview filter. Outside of this, 'prefetch' only affects the source filter. 11 | The frame count of the preview filter must match the frame count of the source, or an error message is shown. 12 | 13 | Up to 5 filter sets can be created, each preview filter set must be declared as follows. 14 | */ 15 | 16 | # Youre source and source filters. 17 | #AviSource("Bla Bla.avi") 18 | #MCTemporalDenoise() 19 | # and now the fast preview filters 20 | 21 | /**avsp_filter 22 | Levels(0, 1.000, 255, 0, 255, coring=true) 23 | Tweak(hue=0.0, sat=1.0, bright=0, cont=1.0, coring=True, sse=False, startHue=0, endHue=360, maxSat=150, minSat=0, interp=16) 24 | **/ 25 | 26 | /* 27 | The sliders are only updated automatically when a preview filter is selected, or with a normal script update (refresh, reload, etc.) 28 | Or you must enable or disable the Preview Filter for an slider update. And there is also the possibility to read only the slider again (slider context menu) 29 | 30 | A possibility to see your own name in the 'Preview filter' menu. (multiple same names allowed) 31 | You just have to write something after 'avsp_filter' and the text in this line must be longer than 19 characters (including /**avsp_filter) 32 | Don't use an '&' in the name. I haven't checked all the characters, one or the other can cause problems. Use something else. 33 | */ 34 | 35 | /**avsp_filter color + sharpen 36 | #SmoothLevels(input_low=16, gamma=1.00, input_high=235, output_low=16, output_high=235, TVrange=True, Lmode=0, darkSTR=100, brightSTR=100, debug=False) 37 | #SmoothTweak(brightness=0, contrast=1.00, saturation=1.00, hue1=0, hue2=0, TVrange=True, Lmode=0, limitSTR=100, debug=False) 38 | #SmoothCurve(Ycurve="0-0;255-255", Ucurve="0-0;255-255", Vcurve="0-0;255-255", debug=False) 39 | #Highlighter(gblur=100, gradient=True, threshold=100, twopass=False, amount=20, method=0) 40 | #HighlightLimiter(gblur=100.0, gradient=True, threshold=160, twopass=False, amount=20, method=0) 41 | Sharpen(0.40) 42 | #NonlinUSM(z=3, str=2.0, rad=0.6) #sharpen 43 | #NonlinUSM(z=1.0, pow=1.2, str=0.2, rad=120.0) #contrast 44 | #NonlinUSM(z=3, pow=1.2, str=0.25, rad=6) #sharp+ 45 | #UnsharpMask(strength=60, radius=3, threshold=8) 46 | #TUnSharp(strength=80, thresholdL=6, thresholdU=40, radius=2, type=0, map=0, lim=2, gui=false) 47 | #SharpenComplex2(str0=2.0, str1=1.125, k0="3 14 3", k1="1 1 1", edgethr=0.2, debug=false) 48 | **/ 49 | 50 | /* 51 | If you now open the video menu 'Preview filter', these two filter sets should now be displayed. 52 | With a selection one of these filters becomes active. I have defined Ctrl + 'Numpad 0' to 'Numpad 5' to change the filter, change it yourself. 53 | You can save the filters, 'Preview filter' > 'Save preview filters' , but note! All previously saved filters will be deleted! 54 | You can restore all saved or individual sets (will be written into the script at last position). 55 | You can save or restore more then 5 filter sets, but only directly select the first 5 sets. 56 | 57 | You can also write the preview filter set in the first line and then the source filter, it makes no difference. 58 | In the event of a refresh or if the script has changed outside of the preview filter area, the preview filter is restored now since version 2.7.2.1 59 | When you are done with the settings, simply remove the filter flag start and end or set a comment flag # at the beginning of the line. 60 | 61 | And a final remark. For avisynth the area is only a block comment, 62 | for AvsPmod it is a filter, and no matter what is written in this area, an attempt is made to create a clip. 63 | 64 | I hope that I was understandable. 65 | */ 66 | 67 | -------------------------------------------------------------------------------- /previewFilterExample.txt: -------------------------------------------------------------------------------- 1 | /* 2 | GPo, 2021.01.03 3 | Examples of preview filter in AvsPmod. 4 | 5 | A 'Preview filter' allows an almost real-time view of parameter changes of a filter. 6 | With sliders a very fast visuel adjustment of the used filters is possible. Or use 'Number wheel' 7 | 8 | Avisynth filters that do not require a high CPU load are suitable as preview filters. The faster the avisynth filters are, the faster the preview can be created. 9 | It doesn't make sense to use MCTemporalDenoise in a preview filter. Suitable filters are sharpness, colors or similar filters. 10 | Preview filters are always processed as last filter, but 'prefetch' in the preview area only affects the preview filter. Outside of this, 'prefetch' only affects the source filter. 11 | The frame count of the preview filter must match the frame count of the source, or an error message is shown. 12 | 13 | Up to 5 filter sets can be created, each preview filter set must be declared as follows. 14 | */ 15 | 16 | # Youre source and source filters. 17 | #AviSource("Bla Bla.avi") 18 | #MCTemporalDenoise() 19 | # and now the fast preview filters 20 | 21 | /**avsp_filter 22 | Levels(0, 1.000, 255, 0, 255, coring=true) 23 | Tweak(hue=0.0, sat=1.0, bright=0, cont=1.0, coring=True, sse=False, startHue=0, endHue=360, maxSat=150, minSat=0, interp=16) 24 | **/ 25 | 26 | /* 27 | The sliders are only updated automatically when a preview filter is selected, or with a normal script update (refresh, reload, etc.) 28 | Or you must enable or disable the Preview Filter for an slider update. And there is also the possibility to read only the slider again (slider context menu) 29 | 30 | A possibility to see your own name in the 'Preview filter' menu. (multiple same names allowed) 31 | You just have to write something after 'avsp_filter' and the text in this line must be longer than 19 characters (including /**avsp_filter) 32 | Don't use an '&' in the name. I haven't checked all the characters, one or the other can cause problems. Use something else. 33 | */ 34 | 35 | /**avsp_filter color + sharpen 36 | #SmoothLevels(input_low=16, gamma=1.00, input_high=235, output_low=16, output_high=235, TVrange=True, Lmode=0, darkSTR=100, brightSTR=100, debug=False) 37 | #SmoothTweak(brightness=0, contrast=1.00, saturation=1.00, hue1=0, hue2=0, TVrange=True, Lmode=0, limitSTR=100, debug=False) 38 | #SmoothCurve(Ycurve="0-0;255-255", Ucurve="0-0;255-255", Vcurve="0-0;255-255", debug=False) 39 | #Highlighter(gblur=100, gradient=True, threshold=100, twopass=False, amount=20, method=0) 40 | #HighlightLimiter(gblur=100.0, gradient=True, threshold=160, twopass=False, amount=20, method=0) 41 | Sharpen(0.40) 42 | #NonlinUSM(z=3, str=2.0, rad=0.6) #sharpen 43 | #NonlinUSM(z=1.0, pow=1.2, str=0.2, rad=120.0) #contrast 44 | #NonlinUSM(z=3, pow=1.2, str=0.25, rad=6) #sharp+ 45 | #UnsharpMask(strength=60, radius=3, threshold=8) 46 | #TUnSharp(strength=80, thresholdL=6, thresholdU=40, radius=2, type=0, map=0, lim=2, gui=false) 47 | #SharpenComplex2(str0=2.0, str1=1.125, k0="3 14 3", k1="1 1 1", edgethr=0.2, debug=false) 48 | **/ 49 | 50 | /* 51 | If you now open the video menu 'Preview filter', these two filter sets should now be displayed. 52 | With a selection one of these filters becomes active. I have defined Ctrl + 'Numpad 0' to 'Numpad 5' to change the filter, change it yourself. 53 | You can save the filters, 'Preview filter' > 'Save preview filters' , but note! All previously saved filters will be deleted! 54 | You can restore all saved or individual sets (will be written into the script at last position). 55 | You can save or restore more then 5 filter sets, but only directly select the first 5 sets. 56 | 57 | You can also write the preview filter set in the first line and then the source filter, it makes no difference. 58 | In the event of a refresh or if the script has changed outside of the preview filter area, the preview filter is restored now since version 2.7.2.1 59 | When you are done with the settings, simply remove the filter flag start and end or set a comment flag # at the beginning of the line. 60 | 61 | And a final remark. For avisynth the area is only a block comment, 62 | for AvsPmod it is a filter, and no matter what is written in this area, an attempt is made to create a clip. 63 | 64 | I hope that I was understandable. 65 | */ 66 | 67 | -------------------------------------------------------------------------------- /macros/Extra/DeleteEncodings.py: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # Name: DeleteEncodings.py 3 | # Purpose: Deletes the files selected in the script from disk (PreviewEncode) 4 | # Deletes also the avs files e.g. star.mkv and star.mkv.avs 5 | # Several lines can be selected, but if there are more files in one line, 6 | # no file will be recognized in this line. 7 | # The files are first displayed in a list before they are deleted. 8 | # 9 | # Author: GPo 10 | # 11 | # Created: 11.06.2021, last change 25.05.2024 12 | # update 12.0.6.2021 13 | # dpi, addFile, fileSize, fix return wrong result, freeing the files before deleting 14 | # bugfix: 25.05.2024 15 | # Copyright: (c) GPo 2021 16 | # Licence: 17 | #------------------------------------------------------------------------------- 18 | import wx 19 | import os 20 | import dpi 21 | 22 | ################################################## 23 | ##### You use this script to your own risk ! ##### 24 | ################################################## 25 | 26 | # if True, another message is shown before deleting the files 27 | showWarn = True 28 | 29 | def deleteFiles(files): 30 | error = ok = notFound = 0 31 | for f in files: 32 | if os.path.isfile(f): 33 | try: 34 | os.remove(f) 35 | except: 36 | error += 1 37 | if not os.path.isfile(f): 38 | ok += 1 39 | else: notFound += 1 40 | return ok, notFound, error 41 | 42 | def addFile(fList, f): 43 | fSize = 0 44 | if not f in fList: 45 | fList.append(f) 46 | fSize = os.path.getsize(f) 47 | if os.path.isfile(f + '.avs'): 48 | fList.append(f + '.avs') 49 | fSize += os.path.getsize(f + '.avs') 50 | return fSize 51 | 52 | # input in Byte 53 | def fileSizeToString(fsize, precision=0): 54 | if fsize < 1: 55 | return '0 B' 56 | suffixes = ['B','KB','MB','GB','TB'] 57 | suffixIndex = 0 58 | while fsize > 1024 and suffixIndex < 4: 59 | suffixIndex += 1 60 | fsize = fsize/1024.0 61 | if suffixIndex > 2 and precision == 0: 62 | precision = 2 63 | return '%.*f%s' % (precision, fsize, suffixes[suffixIndex]) 64 | 65 | def showDlg(files, fSize, showWarn): 66 | dlg = wx.Dialog(None, wx.ID_ANY, _('Delete') + fSize, style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER) 67 | try: 68 | # PPI settings, but don't know if it needed for wx.Dialog 69 | #~dpi.SetFontPPI(dlg) 70 | okay = wx.Button(dlg, wx.ID_OK, _('OK')) 71 | cancel = wx.Button(dlg, wx.ID_CANCEL, _('Cancel')) 72 | btns = wx.StdDialogButtonSizer() 73 | btns.AddButton(okay) 74 | btns.AddButton(cancel) 75 | btns.Realize() 76 | textCtrl = wx.TextCtrl(dlg, wx.ID_ANY, size=dpi.tuplePPI(600,200), style=wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_DONTWRAP) 77 | textCtrl.AppendText('\n'.join(files)) 78 | dlgSizer = wx.BoxSizer(wx.VERTICAL) 79 | dlgSizer.Add(textCtrl, 1, wx.EXPAND) 80 | dlgSizer.Add(btns , 0, wx.EXPAND|wx.ALL, dpi.intPPI(10)) 81 | dlg.SetSizer(dlgSizer) 82 | dlgSizer.Layout() 83 | dlg.Fit() 84 | if dlg.ShowModal() != wx.ID_OK: 85 | return 86 | finally: 87 | dlg.Destroy() 88 | if showWarn and not avsp.MsgBox('Delete files from disk?', cancel=True): 89 | return 90 | # freeing the files if in use 91 | self = avsp.GetWindow() 92 | if self.currentScript.AVI is not None: 93 | self.HidePreviewWindow() 94 | self.OnMenuScriptReleaseMemory(None) 95 | # delete the files 96 | msg = '' 97 | ok, notFound, error = deleteFiles(files) 98 | if ok > 0: 99 | msg = '%i File(s) deleted\n' % ok 100 | if notFound > 0: 101 | msg += '%i File(s) not found\n' % notFound 102 | if error > 0: 103 | msg += '%i Error(s)' % error 104 | avsp.MsgBox(msg) 105 | 106 | txt = avsp.GetSelectedText() 107 | if not txt: 108 | avsp.MsgBox('You must first select the files') 109 | return 110 | fileSize = 0 111 | txtLines = txt.split('\n') 112 | files = [] 113 | for line in txtLines: 114 | sa = line.split('"') 115 | if len(sa) == 3: # bla("star.mkv", blabla 116 | if os.path.isfile(sa[1]): 117 | fileSize += addFile(files, sa[1]) 118 | elif len(sa) == 2: # C:\star.mkv", blabla 119 | f = '' 120 | if os.path.isfile(sa[0]): 121 | f = sa[0] 122 | elif os.path.isfile(sa[1]): 123 | f = sa[1] 124 | if f: 125 | fileSize += addFile(files, f) 126 | else: 127 | line = line.replace('"', '') 128 | if os.path.isfile(line): 129 | fileSize += addFile(files, line) 130 | 131 | if files: 132 | fSize = ' ' + fileSizeToString(fileSize) 133 | showDlg(files, fSize, showWarn) 134 | else: 135 | avsp.MsgBox('No file recognized or the file is not on the disk') 136 | -------------------------------------------------------------------------------- /macros/ConditionalReader file from bookmarks.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Generate a ConditionalReader file from the video bookmarks 4 | 5 | This macro takes the list of the current video bookmarks and generates a 6 | new text file to be used with ConditionalReader. Each frame can represent a 7 | single frame or the start or end of a range of frames. If the 'interpolation' 8 | option is selected (only valid for int and float), 'Value' must consist in 9 | two space-separated values. 10 | 11 | If a bookmark have a title, it can be used as its value instead of the one 12 | introduced in the prompt dialog. For ranges of frames, the value can be put 13 | in the title of either the start or end frame. When using interpolation the 14 | two values can be introduced both in the same bookmark or separately. 15 | 16 | More info on ConditionalReader: 17 | http://avisynth.nl/index.php/ConditionalReader 18 | 19 | 20 | Written by vdcrim 21 | Original macro idea by Bernardd 22 | """ 23 | 24 | # PREFERENCES 25 | 26 | default_type = 'Bool' 27 | default_default = '' 28 | default_value = '' 29 | default_bm_meaning = 'Single frames' 30 | default_use_title = True 31 | default_filename = ur'' # ur'' -> avs filename + suffix 32 | suffix = '.cr.txt' 33 | default_insert_path = True 34 | 35 | 36 | # ------------------------------------------------------------------------------ 37 | 38 | 39 | # Run in thread 40 | import sys 41 | import os.path 42 | 43 | # Get the bookmarks 44 | bmlist = avsp.GetBookmarkList(title=True) 45 | if not bmlist: 46 | avsp.MsgBox(_('There is not bookmarks'), _('Error')) 47 | return 48 | bmlist.sort() 49 | 50 | # Prompt for options 51 | if not default_filename: 52 | default_filename = os.path.splitext(avsp.GetScriptFilename(propose='general'))[0] 53 | default_filename += suffix 54 | txt_filter = (_('Text files') + ' (*.txt)|*.txt|' + _('All files') + '|*.*') 55 | while True: 56 | options = avsp.GetTextEntry( 57 | title=_('ConditionalReader file from bookmarks'), 58 | message=[[_('Type'), _('Default'), _('Value')], 59 | [_('Bookmarks represent...'), 60 | _("Override 'Value' with the bookmark's title")], 61 | _('ConditionalReader file'), 62 | _('Insert the ConditionalReader file path at the current ' 63 | 'cursor position') 64 | ], 65 | default=[[(_('Bool'), _('Int'), _('Float'), _('String'), default_type), 66 | (_('True'), _('False'), default_default), 67 | (_('True'), _('False'), default_value)], 68 | [(_('Single frames'), _('Ranges of frames'), 69 | _('Ranges of frames (with interpolation)'), default_bm_meaning), 70 | default_use_title], 71 | (default_filename, txt_filter), default_insert_path 72 | ], 73 | types=[['list_read_only', 'list_writable', 'list_writable'], 74 | ['list_read_only', 'check'], 'file_save', 'check'], 75 | width=415) 76 | if not options: 77 | return 78 | type, default, value, bm_meaning, use_title, filename, insert_path = options 79 | if not filename: 80 | avsp.MsgBox(_('An output path is needed'), _('Error')) 81 | elif (bm_meaning == _('Ranges of frames (with interpolation)') and 82 | type not in (_('Int'), _('Float'))): 83 | avsp.MsgBox(_('Interpolation only available for Int and Float'), _('Error')) 84 | else: break 85 | (default_type, default_default, default_value, default_bm_meaning, 86 | default_use_title, default_filename, default_insert_path) = options 87 | 88 | # Write the ConditionalReader file 89 | value_default = value.strip() 90 | text = ['Type {0}\n'.format(type)] 91 | if default: text.append(u'Default {0}\n'.format(default.strip())) 92 | if bm_meaning == _('Single frames'): 93 | for frame, title in bmlist: 94 | text.append(u'{0} {1}\n'.format(frame, 95 | title.strip() if use_title and title else value_default)) 96 | else: 97 | if len(bmlist) % 2 and not avsp.MsgBox(_('Odd number of bookmarks'), 98 | title=_('Warning'), cancel=True): 99 | return 100 | prefix = 'R' if bm_meaning == _('Ranges of frames') else 'I' 101 | for i, bm in enumerate(bmlist): 102 | if i%2: 103 | value = None 104 | if use_title: 105 | if bmlist[i-1][1]: 106 | value = bmlist[i-1][1].strip() 107 | if bm[1]: 108 | if value and bm_meaning != _('Ranges of frames'): 109 | value += ' ' + bm[1].strip() 110 | else: 111 | value = bm[1].strip() 112 | if not value: 113 | value = value_default 114 | else: 115 | value = value_default 116 | text.append(u'{0} {1} {2} {3}\n'.format( 117 | prefix, bmlist[i-1][0], bm[0], value)) 118 | text = [line.encode(sys.getfilesystemencoding()) for line in text] 119 | with open(filename, 'w') as file: 120 | file.writelines(text) 121 | if insert_path: 122 | avsp.InsertText(u'"{0}"'.format(filename), pos=None) 123 | -------------------------------------------------------------------------------- /help/stylesheets/rest2web.css: -------------------------------------------------------------------------------- 1 | /* 2 | :Authors: Michael Foord, Justin Fleming 3 | :Contact: fuzzyman@voidspace.org.uk 4 | :Date: 2006/04/01 5 | :Copyright: Copyright Voidspace.org.uk, 2006 6 | :License: BSD Revised License 7 | 8 | Stylesheet for rest2web - 9 | http://www.voidspace.org.uk/python/rest2web/ 10 | */ 11 | 12 | @import url(voidspace_docutils2.css); 13 | @import url(pysrc.css); 14 | 15 | h2 { 16 | background-color: #CCCCCC; 17 | color: #000000; 18 | } 19 | 20 | 21 | p.headertitle { 22 | color:#999999; 23 | font-size:1.2em; 24 | } 25 | 26 | a.image-reference:visited { 27 | color: #999999; 28 | } 29 | 30 | body { 31 | font-size: 62.5%; 32 | margin: 0em auto; 33 | padding: 0em; 34 | font-family: Verdana,Tahoma, Arial,sans-serif; 35 | } 36 | 37 | #wrap { 38 | width: 760px; 39 | margin: 0em auto; 40 | } 41 | 42 | img { 43 | border:0; 44 | } 45 | 46 | /**************/ 47 | /* HEADER */ 48 | /**************/ 49 | #header-section { 50 | padding:0; 51 | margin: 0; 52 | margin-bottom:1em; 53 | margin-top:0.5em; 54 | text-align:center; 55 | } 56 | 57 | #header { 58 | clear: both; 59 | margin: 0em 0em 0.5em 0em; 60 | border-top: solid 0.1em rgb(175,175,175); 61 | border-bottom: solid 0.1em rgb(175,175,175); 62 | background-color: rgb(235,235,235); 63 | text-transform: uppercase; 64 | line-height: 2.0em; 65 | height: 2.0em; 66 | color: rgb(50,50,50); 67 | } 68 | 69 | #header ul { 70 | margin: 0em; 71 | padding: 0em; 72 | list-style: none; 73 | font-weight: bold; 74 | font-size: 1.0em; 75 | } 76 | 77 | #header li { 78 | float: left; 79 | white-space: nowrap; 80 | } 81 | 82 | #header li a { 83 | display: block; 84 | padding: 0em 1.0em 0em 1.0em; 85 | background-color: rgb(235,235,235); 86 | text-decoration: none; 87 | color: rgb(50,50,50); 88 | } 89 | 90 | #header a:hover { 91 | background-color: rgb(220,220,220); 92 | text-transform: uppercase; 93 | text-decoration: none; 94 | color: rgb(50,50,50); 95 | } 96 | 97 | #header .selected { 98 | padding: 0em 0.5em 0em 0.5em; 99 | border-right: solid 0.1em rgb(175,175,175); 100 | background-color: rgb(220,220,220); 101 | color: rgb(50,50,50); 102 | } 103 | 104 | * html #header a {width:1%;} 105 | 106 | /***********************/ 107 | /*** LEFT COLUMN ***/ 108 | /***********************/ 109 | #left-column { 110 | width: 152px; 111 | vertical-align: top; 112 | background-color: rgb(255,255,255); 113 | font-size: 1.1em; 114 | color: rgb(50,50,50); 115 | } 116 | 117 | #left-navheader-first { 118 | display: block; 119 | margin: 1.0em 0em 0em 0em; 120 | padding: 0.3em; 121 | border-left: solid 0.5em rgb(235,235,235); 122 | background-color: rgb(220,220,220); 123 | text-transform: uppercase; 124 | text-decoration: none; 125 | font-weight: bold; 126 | color: rgb(50,50,50); 127 | text-align:center; 128 | } 129 | 130 | #sidie ul { 131 | width: 95%; 132 | padding: 0em; 133 | margin: 0em; 134 | list-style: none; 135 | } 136 | 137 | #sidie li { 138 | margin: 0em 0em 0em 0em; 139 | } 140 | .left-navheader { 141 | display: block; 142 | margin: 1.0em 0em 0.5em 0em; 143 | padding: 0.3em 0.7em 0.2em 0.4em; 144 | border-left: solid 0.5em rgb(235,235,235); 145 | background-color: rgb(220,220,220); 146 | text-transform: uppercase; 147 | text-decoration: none; 148 | font-weight: bold; 149 | color: rgb(50,50,50); 150 | } 151 | #sidie li a { 152 | display: block; 153 | padding: 0.3em 0.7em 0.2em 1.2em; 154 | border-left: solid 0.5em rgb(235,235,235); 155 | border-top: solid 0.1em rgb(200,200,200); 156 | background-color: rgb(235,235,235); 157 | text-decoration: none; 158 | font-weight: normal; 159 | color: rgb(50,50,50); 160 | height: 1.3em; 161 | } 162 | 163 | #sidie li a:hover { 164 | border-left: solid 0.5em rgb(175,175,175); 165 | background-color: rgb(220,220,220); 166 | text-decoration: none; 167 | color: rgb(50,50,50); 168 | } 169 | 170 | .sidieimg { 171 | text-align: center; 172 | margin-top: 10px; 173 | margin-left: 10px; 174 | vertical-align: middle; 175 | background-color: rgb(255,255,255); 176 | } 177 | 178 | /*************************/ 179 | #sidie2 a { 180 | text-decoration:none; 181 | } 182 | .sidie2title { 183 | margin:0; 184 | font-weight:bold; 185 | text-transform:uppercase; 186 | } 187 | 188 | #sidie2 p { 189 | margin:0; 190 | } 191 | #sidie2 p a:hover { 192 | background-color: rgb(220,220,220); 193 | } 194 | .sidie2indent { 195 | margin-left:1.5em; 196 | margin-top:0.5em; 197 | } 198 | /*************************/ 199 | 200 | /*************************/ 201 | /*** MIDDLE COLUMN ***/ 202 | /*************************/ 203 | 204 | /* Sections */ 205 | /************/ 206 | #middle-column { 207 | width: 592px; 208 | background-color: rgb(255,255,255); 209 | color: rgb(100,100,100); 210 | line-height: 1.3em; 211 | font-size: 1.2em; 212 | } 213 | 214 | #middle-column h1 {padding: 6px;} 215 | 216 | /*******************/ 217 | /*** FOOTER ***/ 218 | /*******************/ 219 | #footer { 220 | clear: both; 221 | height: 2.5em; 222 | margin: 1.0em 0em 1.0em 0em; 223 | padding: 0.25em 0em 0.3em 0em; 224 | border-top: solid 0.1em rgb(150,150,150); 225 | border-bottom: solid 0.1em rgb(150,150,100); 226 | background-color: rgb(220,220,220); 227 | text-align: center; 228 | color: rgb(100,100,100); 229 | font-size: 1.0em; 230 | } 231 | -------------------------------------------------------------------------------- /help/Translation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Translating AvsP 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 20 | 21 | 22 | 23 | 24 | 25 | 62 | 63 | 64 | 95 | 96 |
26 | 27 |
28 | 29 |
30 |
31 |

Translating AvsP

32 |

Creating a translation to different language for AvsP for is very easy. Included with the AvsP download is a file called "__translation.py". The first couple of lines in the file look like this:

33 |
 34 | # -*- coding: utf-8 -*-
 35 | 
 36 | # This file is used to translate the messages used in the AvsP interface.
 37 | # To use it, make sure it is named "translation.py" and is in the
 38 | # same directory as AvsP.exe.  Simply add translated messages next to each
 39 | # message (any untranslated messages will be shown in English).  You can type
 40 | # unicode text directly into this document - if you do, make sure to save it
 41 | # in the appropriate format.  If required, you can change the coding on the
 42 | # first line of this document to a coding appropriate for your translated
 43 | # language. DO NOT translate any words inside formatted strings (ie, any
 44 | # portions of the text which look like %(...)s, %(...)i, etc.)
 45 | 
 46 | messages = {
 47 |     "Find" : u"",
 48 |     "Replace" : u"",
 49 |     "Could not find docs for filter %(name)s!" : u"",
 50 | 
51 |

The file contains every translatable message in AvsP. To translate, simply add translated messages next to each message. For example, to translate the message "Find", modify the line to look like this:

52 |
 53 | "Find" : u"Finden",
 54 | 
55 |

(Now you know how to say "find" in German!) You can even type unicode directly into the file. Depending on the language and how you enter the text, you may need to change the coding in first line of the file.

56 |

Once you've translated the messages, simply rename the file to "translation.py" and make sure it's in the same directory as AvsP.exe. The next time you run AvsP you should see all your translated messages!

57 |

If you choose to translate AvsP to a new language, please post a message in the discussion on doom9's forum, and I will add the link to your translation on the download page.

58 |
59 | 60 |
61 |
65 |
66 |
67 | 84 |
85 | 86 | 87 |

88 | Donate via PayPal 89 |

90 | 91 | 92 | 93 |
94 |
97 | 98 |
99 | 100 | 101 | 104 |
105 | 106 | 107 | -------------------------------------------------------------------------------- /help/Download.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Download 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 20 | 21 | 22 | 23 | 24 | 25 | 51 | 52 | 53 | 84 | 85 |
26 | 27 |
28 | 29 |
30 |
31 |

Download

32 |

Download AvsP version 2.0.2 (4.9 MB)

33 |

Japanese translation (translated by niiyan)

34 |

Russian translation (translated by Fizick)

35 |

German translation (translated by Henrikx)

36 |

French translation (translated by Alain2)

37 |

Spanish translation (translated by zemog)

38 |

Portuguese translation (translated by Veiga)

39 |

Italian translation (translated by khs81)

40 |
41 |

Installation instructions

42 |

AvsP doesn't require program installation, doesn't write to the registry, and doesn't require installing any additional framework. To run the program, simply unzip it to a directory of your choosing and double-click AvsP.exe. Note to Windows 98 users: You will need to put unicows.dll in the same directory as AvsP.exe. Some older versions of AvsP came with this dll, if you don't have it you can download it from microsoft.

43 |

For those upgrading AvsP from a previous version, backup to a temporary folder any files with .dat or .ses extensions in the AvsP folder, as well as any custom macros or tools you may have made. Then delete all files from the AvsP folder, unzip the files from the new AvsP zip file into the folder, then restore backed up files to their appropriate folders. Note: Do not restore .dat files when upgrading from version 1.x.x to 2.x.x, as they are not compatible (you'll need to set your customizations again through the program interface).

44 |

If English is not your native language, you can download a translation file from one of the above links (read here for more info). If the translation file is for an older version of AvsP, it will still work, but some messages might not be translated and will appear in English.

45 |

If you find AvsP useful, feel free to donate using the "Make a Donation" button on the left column.

46 |
47 |
48 | 49 |
50 |
54 |
55 |
56 | 73 |
74 | 75 | 76 |

77 | Donate via PayPal 78 |

79 | 80 | 81 | 82 |
83 |
86 | 87 |
88 | 89 | 90 | 93 |
94 | 95 | 96 | -------------------------------------------------------------------------------- /cpuid.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (c) 2018 Anders Høst 4 | # 5 | 6 | #from __future__ import print_function 7 | 8 | import platform 9 | import os 10 | import ctypes 11 | from ctypes import c_uint32, c_int, c_long, c_ulong, c_size_t, c_void_p, POINTER, CFUNCTYPE 12 | 13 | # Posix x86_64: 14 | # Three first call registers : RDI, RSI, RDX 15 | # Volatile registers : RAX, RCX, RDX, RSI, RDI, R8-11 16 | 17 | # Windows x86_64: 18 | # Three first call registers : RCX, RDX, R8 19 | # Volatile registers : RAX, RCX, RDX, R8-11 20 | 21 | # cdecl 32 bit: 22 | # Three first call registers : Stack (%esp) 23 | # Volatile registers : EAX, ECX, EDX 24 | 25 | _POSIX_64_OPC = [ 26 | 0x53, # push %rbx 27 | 0x89, 0xf0, # mov %esi,%eax 28 | 0x89, 0xd1, # mov %edx,%ecx 29 | 0x0f, 0xa2, # cpuid 30 | 0x89, 0x07, # mov %eax,(%rdi) 31 | 0x89, 0x5f, 0x04, # mov %ebx,0x4(%rdi) 32 | 0x89, 0x4f, 0x08, # mov %ecx,0x8(%rdi) 33 | 0x89, 0x57, 0x0c, # mov %edx,0xc(%rdi) 34 | 0x5b, # pop %rbx 35 | 0xc3 # retq 36 | ] 37 | 38 | _WINDOWS_64_OPC = [ 39 | 0x53, # push %rbx 40 | 0x89, 0xd0, # mov %edx,%eax 41 | 0x49, 0x89, 0xc9, # mov %rcx,%r9 42 | 0x44, 0x89, 0xc1, # mov %r8d,%ecx 43 | 0x0f, 0xa2, # cpuid 44 | 0x41, 0x89, 0x01, # mov %eax,(%r9) 45 | 0x41, 0x89, 0x59, 0x04, # mov %ebx,0x4(%r9) 46 | 0x41, 0x89, 0x49, 0x08, # mov %ecx,0x8(%r9) 47 | 0x41, 0x89, 0x51, 0x0c, # mov %edx,0xc(%r9) 48 | 0x5b, # pop %rbx 49 | 0xc3 # retq 50 | ] 51 | 52 | _CDECL_32_OPC = [ 53 | 0x53, # push %ebx 54 | 0x57, # push %edi 55 | 0x8b, 0x7c, 0x24, 0x0c, # mov 0xc(%esp),%edi 56 | 0x8b, 0x44, 0x24, 0x10, # mov 0x10(%esp),%eax 57 | 0x8b, 0x4c, 0x24, 0x14, # mov 0x14(%esp),%ecx 58 | 0x0f, 0xa2, # cpuid 59 | 0x89, 0x07, # mov %eax,(%edi) 60 | 0x89, 0x5f, 0x04, # mov %ebx,0x4(%edi) 61 | 0x89, 0x4f, 0x08, # mov %ecx,0x8(%edi) 62 | 0x89, 0x57, 0x0c, # mov %edx,0xc(%edi) 63 | 0x5f, # pop %edi 64 | 0x5b, # pop %ebx 65 | 0xc3 # ret 66 | ] 67 | 68 | is_windows = os.name == "nt" 69 | is_64bit = ctypes.sizeof(ctypes.c_voidp) == 8 70 | 71 | class CPUID_struct(ctypes.Structure): 72 | _fields_ = [(r, c_uint32) for r in ("eax", "ebx", "ecx", "edx")] 73 | 74 | class CPUID(object): 75 | def __init__(self): 76 | self.initialized = False 77 | if platform.machine() not in ("AMD64", "x86_64", "x86", "i686"): 78 | #raise SystemError("Only available for x86") 79 | return 80 | 81 | if is_windows: 82 | if is_64bit: 83 | # VirtualAlloc seems to fail under some weird 84 | # circumstances when ctypes.windll.kernel32 is 85 | # used under 64 bit Python. CDLL fixes this. 86 | self.win = ctypes.CDLL("kernel32.dll") 87 | opc = _WINDOWS_64_OPC 88 | else: 89 | # Here ctypes.windll.kernel32 is needed to get the 90 | # right DLL. Otherwise it will fail when running 91 | # 32 bit Python on 64 bit Windows. 92 | self.win = ctypes.windll.kernel32 93 | opc = _CDECL_32_OPC 94 | else: 95 | opc = _POSIX_64_OPC if is_64bit else _CDECL_32_OPC 96 | 97 | size = len(opc) 98 | code = (ctypes.c_ubyte * size)(*opc) 99 | 100 | if is_windows: 101 | self.win.VirtualAlloc.restype = c_void_p 102 | self.win.VirtualAlloc.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_ulong, ctypes.c_ulong] 103 | self.addr = self.win.VirtualAlloc(None, size, 0x1000, 0x40) 104 | if not self.addr: 105 | #raise MemoryError("Could not allocate RWX memory") 106 | return 107 | else: 108 | self.libc = ctypes.cdll.LoadLibrary(None) 109 | self.libc.valloc.restype = ctypes.c_void_p 110 | self.libc.valloc.argtypes = [ctypes.c_size_t] 111 | self.addr = self.libc.valloc(size) 112 | if not self.addr: 113 | #raise MemoryError("Could not allocate memory") 114 | return 115 | 116 | self.libc.mprotect.restype = c_int 117 | self.libc.mprotect.argtypes = [c_void_p, c_size_t, c_int] 118 | ret = self.libc.mprotect(self.addr, size, 1 | 2 | 4) 119 | if ret != 0: 120 | #raise OSError("Failed to set RWX") 121 | return 122 | 123 | 124 | ctypes.memmove(self.addr, code, size) 125 | 126 | func_type = CFUNCTYPE(None, POINTER(CPUID_struct), c_uint32, c_uint32) 127 | self.func_ptr = func_type(self.addr) 128 | self.initialized = True 129 | 130 | def __call__(self, eax, ecx=0): 131 | struct = CPUID_struct() 132 | self.func_ptr(struct, eax, ecx) 133 | return struct.eax, struct.ebx, struct.ecx, struct.edx 134 | 135 | def __del__(self): 136 | if is_windows: 137 | self.win.VirtualFree.restype = c_long 138 | self.win.VirtualFree.argtypes = [c_void_p, c_size_t, c_ulong] 139 | self.win.VirtualFree(self.addr, 0, 0x8000) 140 | elif self.libc: 141 | # Seems to throw exception when the program ends and 142 | # libc is cleaned up before the object? 143 | self.libc.free.restype = None 144 | self.libc.free.argtypes = [c_void_p] 145 | self.libc.free(self.addr) 146 | 147 | """ 148 | if __name__ == "__main__": 149 | def valid_inputs(): 150 | cpuid = CPUID() 151 | for eax in (0x0, 0x80000000): 152 | highest, _, _, _ = cpuid(eax) 153 | while eax <= highest: 154 | regs = cpuid(eax) 155 | yield (eax, regs) 156 | eax += 1 157 | 158 | print(" ".join(x.ljust(8) for x in ("CPUID", "A", "B", "C", "D")).strip()) 159 | for eax, regs in valid_inputs(): 160 | print("%08x" % eax, " ".join("%08x" % reg for reg in regs)) 161 | """ 162 | 163 | -------------------------------------------------------------------------------- /help/stylesheets/default.css: -------------------------------------------------------------------------------- 1 | /* 2 | :Author: David Goodger 3 | :Contact: goodger@users.sourceforge.net 4 | :Date: $Date: 2005-09-08 09:54:28 +0100 (Thu, 08 Sep 2005) $ 5 | :Version: $Revision: 123 $ 6 | :Copyright: This stylesheet has been placed in the public domain. 7 | 8 | Default cascading style sheet for the HTML output of Docutils. 9 | */ 10 | 11 | /* "! important" is used here to override other ``margin-top`` and 12 | ``margin-bottom`` styles that are later in the stylesheet or 13 | more specific. See http://www.w3.org/TR/CSS1#the-cascade */ 14 | .first { 15 | margin-top: 0 ! important } 16 | 17 | .last, .with-subtitle { 18 | margin-bottom: 0 ! important } 19 | 20 | .hidden { 21 | display: none } 22 | 23 | a.toc-backref { 24 | text-decoration: none ; 25 | color: black } 26 | 27 | blockquote.epigraph { 28 | margin: 2em 5em ; } 29 | 30 | dl.docutils dd { 31 | margin-bottom: 0.5em } 32 | 33 | /* Uncomment (and remove this text!) to get bold-faced definition list terms 34 | dl.docutils dt { 35 | font-weight: bold } 36 | */ 37 | 38 | div.abstract { 39 | margin: 2em 5em } 40 | 41 | div.abstract p.topic-title { 42 | font-weight: bold ; 43 | text-align: center } 44 | 45 | div.admonition, div.attention, div.caution, div.danger, div.error, 46 | div.hint, div.important, div.note, div.tip, div.warning { 47 | margin: 2em ; 48 | border: medium outset ; 49 | padding: 1em } 50 | 51 | div.admonition p.admonition-title, div.hint p.admonition-title, 52 | div.important p.admonition-title, div.note p.admonition-title, 53 | div.tip p.admonition-title { 54 | font-weight: bold ; 55 | font-family: sans-serif } 56 | 57 | div.attention p.admonition-title, div.caution p.admonition-title, 58 | div.danger p.admonition-title, div.error p.admonition-title, 59 | div.warning p.admonition-title { 60 | color: red ; 61 | font-weight: bold ; 62 | font-family: sans-serif } 63 | 64 | /* Uncomment (and remove this text!) to get reduced vertical space in 65 | compound paragraphs. 66 | div.compound .compound-first, div.compound .compound-middle { 67 | margin-bottom: 0.5em } 68 | 69 | div.compound .compound-last, div.compound .compound-middle { 70 | margin-top: 0.5em } 71 | */ 72 | 73 | div.dedication { 74 | margin: 2em 5em ; 75 | text-align: center ; 76 | font-style: italic } 77 | 78 | div.dedication p.topic-title { 79 | font-weight: bold ; 80 | font-style: normal } 81 | 82 | div.figure { 83 | margin-left: 2em } 84 | 85 | div.footer, div.header { 86 | clear: both; 87 | font-size: smaller } 88 | 89 | div.line-block { 90 | display: block ; 91 | margin-top: 1em ; 92 | margin-bottom: 1em } 93 | 94 | div.line-block div.line-block { 95 | margin-top: 0 ; 96 | margin-bottom: 0 ; 97 | margin-left: 1.5em } 98 | 99 | div.sidebar { 100 | margin-left: 1em ; 101 | border: medium outset ; 102 | padding: 1em ; 103 | background-color: #ffffee ; 104 | width: 40% ; 105 | float: right ; 106 | clear: right } 107 | 108 | div.sidebar p.rubric { 109 | font-family: sans-serif ; 110 | font-size: medium } 111 | 112 | div.system-messages { 113 | margin: 5em } 114 | 115 | div.system-messages h1 { 116 | color: red } 117 | 118 | div.system-message { 119 | border: medium outset ; 120 | padding: 1em } 121 | 122 | div.system-message p.system-message-title { 123 | color: red ; 124 | font-weight: bold } 125 | 126 | div.topic { 127 | margin: 2em } 128 | 129 | h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, 130 | h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { 131 | margin-top: 0.4em } 132 | 133 | h1.title { 134 | text-align: center } 135 | 136 | h2.subtitle { 137 | text-align: center } 138 | 139 | hr.docutils { 140 | width: 75% } 141 | 142 | img.align-left { 143 | clear: left } 144 | 145 | img.align-right { 146 | clear: right } 147 | 148 | img.borderless { 149 | border: 0 } 150 | 151 | ol.simple, ul.simple { 152 | margin-bottom: 2em } 153 | 154 | li { 155 | margin-bottom: .2em } 156 | 157 | ol.arabic { 158 | list-style: decimal } 159 | 160 | ol.loweralpha { 161 | list-style: lower-alpha } 162 | 163 | ol.upperalpha { 164 | list-style: upper-alpha } 165 | 166 | ol.lowerroman { 167 | list-style: lower-roman } 168 | 169 | ol.upperroman { 170 | list-style: upper-roman } 171 | 172 | p {line-height: 1.5em;} 173 | 174 | p.attribution { 175 | text-align: right ; 176 | margin-left: 50% } 177 | 178 | p.caption { 179 | font-style: italic } 180 | 181 | p.credits { 182 | font-style: italic ; 183 | font-size: smaller } 184 | 185 | p.label { 186 | white-space: nowrap } 187 | 188 | p.rubric { 189 | font-weight: bold ; 190 | font-size: larger ; 191 | color: maroon ; 192 | text-align: center } 193 | 194 | p.sidebar-title { 195 | font-family: sans-serif ; 196 | font-weight: bold ; 197 | font-size: larger } 198 | 199 | p.sidebar-subtitle { 200 | font-family: sans-serif ; 201 | font-weight: bold } 202 | 203 | p.topic-title { 204 | font-weight: bold } 205 | 206 | pre.address { 207 | margin-bottom: 0 ; 208 | margin-top: 0 ; 209 | font-family: serif ; 210 | font-size: 100% } 211 | 212 | pre.line-block { 213 | font-family: serif ; 214 | font-size: 100% } 215 | 216 | pre.literal-block, pre.doctest-block { 217 | margin-left: 2em ; 218 | margin-right: 2em ; 219 | background-color: #eeeeee } 220 | 221 | span.classifier { 222 | font-family: sans-serif ; 223 | font-style: oblique } 224 | 225 | span.classifier-delimiter { 226 | font-family: sans-serif ; 227 | font-weight: bold } 228 | 229 | span.interpreted { 230 | font-family: sans-serif } 231 | 232 | span.option { 233 | white-space: nowrap } 234 | 235 | /* 236 | span.pre { 237 | white-space: pre } 238 | */ 239 | 240 | span.problematic { 241 | color: red } 242 | 243 | span.section-subtitle { 244 | /* font-size relative to parent (h1..h6 element) */ 245 | font-size: 80% } 246 | 247 | table.citation { 248 | border-left: solid thin gray } 249 | 250 | table.docinfo { 251 | margin: 2em 4em } 252 | 253 | table.docutils { 254 | margin-top: 0.5em ; 255 | margin-bottom: 0.5em } 256 | 257 | table.footnote { 258 | border-left: solid thin black } 259 | 260 | table.docutils td, table.docutils th, 261 | table.docinfo td, table.docinfo th { 262 | padding-left: 0.5em ; 263 | padding-right: 0.5em ; 264 | vertical-align: top } 265 | 266 | table.docutils th.field-name, table.docinfo th.docinfo-name { 267 | font-weight: bold ; 268 | text-align: left ; 269 | white-space: nowrap ; 270 | padding-left: 0 } 271 | 272 | h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, 273 | h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { 274 | font-size: 100% } 275 | 276 | tt.docutils { 277 | background-color: #eeeeee } 278 | 279 | ul.auto-toc { 280 | list-style-type: none } 281 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Version 2.7.9.4 GPo 2 | - With pinterf (pfmod) modifications 3 | - Avisynth header version 6 + needed part's from H8,H9 4 | - For more see changelog 5 | ##### AvsPmod needs write permissions in its own directory. So please do not unzip into a system program directory! 6 | ----- 7 | ### Mouse button combinations (for the new users) 8 | ##### On video window. 9 | - Press left and right click: changes zoom 100%, 200% 10 | - Press left and use mouse wheel: changes the zoom 11 | - Press Ctrl and double click on the video window increases the height a few pixels 12 | - If tab change for mouse browse buttons selected, press Ctrl or move the mouse on the slider area and bookmark jump is used. 13 | - When the mouse pointer is in the video slider area. Press Ctrl and use mouse browse buttons only trim editor marks would be selected 14 | - When the mouse pointer is in the video slider area. Press Alt and use mouse browse buttons only bookmarks with title would be selected 15 | 16 | ##### On script window: 17 | - Press left and right click: The # character is removed or added at the beginning of the selected lines 18 | - If a boolean selected (True, False) the value does change 19 | 20 | ##### On slider window: 21 | - If direct slider update enabled (only with preview filters), can then be deactivated by pressing Ctrl on slider move 22 | 23 | ##### On the status bar: 24 | - A right click open a context menu for the video slider range 25 | 26 | ##### Furthermore 27 | - On the video slider right click to add or remove a bookmark 28 | - Right click on a marked area in the video slider opens an area menu 29 | - Right click on the play or frame step button opens a selection menu 30 | - Standard functions for mouse middle button, browse buttons and the wheel can be set under Options. 31 | 32 | ##### Preview Filter: 33 | - Are an essential part of AvsPmod. They allow near real-time display of filter parameter changes. 34 | - Help > Preview filter example (readme) 35 | 36 | 37 | ##### Releases GPo: 38 | 39 | ### 40 | ----- 41 | 42 | What is AviSynth? 43 | ----------------- 44 | 45 | AviSynth is a powerful tool for video post-production. It provides ways 46 | of editing and processing videos. AviSynth works as a frameserver, 47 | providing instant editing without the need for temporary files. 48 | 49 | AviSynth itself does not provide a graphical user interface (GUI), but 50 | instead relies on a script system that allows advanced non-linear 51 | editing. While this may at first seem tedious and unintuitive, it is 52 | remarkably powerful and is a very good way to manage projects in a 53 | precise, consistent, and reproducible manner. Because text-based scripts 54 | are human readable, projects are inherently self-documenting. The 55 | scripting language is simple yet powerful, and complex filters can be 56 | created from basic operations to develop a sophisticated palette of 57 | useful and unique effects. 58 | 59 | 60 | What is AvsP? 61 | ------------- 62 | 63 | AvsP is at its core a tabbed text editor with features specific for 64 | creating AviSynth scripts. It has text editing features such as 65 | AviSynth-specific syntax highlighting and autocompletion to simplify the 66 | task of writing scripts. However, its primary advantage over other 67 | editors is its integrated video preview, which remains attached to the 68 | main window at all times. Comparing the visual results of several 69 | different scripts is as easy as writing the scripts into several 70 | different tabs and activating the video preview, switching between tabs 71 | gives instantaneous feedback on visual differences (anyone remember 72 | lining up multiple instances of VirtualDub and alt-tabbing?). 73 | Furthermore, the program offers a unique way for the user to define 74 | sliders for any number in the script, giving AviSynth a unique graphical 75 | interface never known before. The following are an outline of the 76 | program's main features: 77 | 78 | - Tabbed text editor 79 | - Avisynth-specific syntax highlighting and autocompletion 80 | - Integrated video preview for easy script comparison 81 | - Unique user-defined sliders for rapid filter setting comparison 82 | - Built-in crop editor in video preview 83 | - Bookmark any number of frames for quick access 84 | - Complete macro language using the Python programming language 85 | - Graphical front-end for command-line compression tool avs2avi 86 | 87 | 88 | What is AvsPmod? 89 | ---------------- 90 | 91 | The AvsP project was abandoned by its original author by late 2007. 92 | AvsPmod is an ongoing community effort to maintain and provide some 93 | enhancements to AvsP: 94 | 95 | - Improved syntax highlighting 96 | - Code folding 97 | - Improved function autocomplete 98 | - Importing of function definitions, including from online wiki 99 | - Snippets of text 100 | - Better Unicode support 101 | - HTML export and printing 102 | - Move, rename, group and undo close tabs 103 | - Video preview usability improvements 104 | - YUV -> RGB options for previewing 105 | - Support for AviSynth 2.6.0 new colorspaces 106 | - Autocrop 107 | - Bookmark titles 108 | - Improved macro API with several scripts included 109 | - Native *nix support through AvxSynth 110 | - Codebase updated to Python 2.7 and wxPython 2.8 111 | - Many bug fixes 112 | 113 | 114 | Running AvsPmod 115 | --------------- 116 | 117 | AviSynth, AviSynth+ (Windows) or AvxSynth (*nix) is required. When 118 | not using the AvsPmod builds, currently only supplied for Windows, 119 | the following is also needed: 120 | 121 | - Python 2.6-2.7 122 | - wxPython 2.8-2.9 123 | - Additionally for AviSynth+ x86-64 (Windows): 124 | - cffi module 125 | - pycparser module 126 | - Visual Studio 2008 127 | - avisynth_c.h 128 | 129 | In that case start AvsPmod by running avsp.py, i.e. `python -O avsp.py`, 130 | pythonw recommended on Windows. 131 | 132 | 133 | Updating to a new version 134 | ------------------------- 135 | 136 | To update AvsPmod just overwrite the previous files. Personal preferences 137 | and customizations are preserved. However note that edited macro scripts, 138 | preset files and translations must be backed up first. 139 | 140 | In case you want to backup the preferences or clean-up old files not longer 141 | used, these are the relevant files: 142 | 143 | - options.dat: main preferences 144 | - tools/*.dat: tool preferences 145 | - macros/macros.dat: macro preferences 146 | - _last_session_.ses: auto-saved session info 147 | 148 | Links GPo forked version 149 | ----- 150 | Discussion: 151 | 152 | 153 | Development: 154 | https://github.com/gispos/AvsPmod 155 | 156 | Releases: 157 | https://github.com/gispos/AvsPmod/releases 158 | 159 | Links original version 160 | ----- 161 | 162 | Development: 163 | 164 | 165 | Releases: 166 | 167 | 168 | Filter database wiki: 169 | 170 | 171 | Discussion: 172 | 173 | 174 | AvsP homepage: 175 | 176 | 177 | AviSynth wiki: 178 | 179 | 180 | AvxSynth wiki: 181 | 182 | 183 | 184 | --------------- 185 | AviSynth description extracted from the AviSynth wiki 186 | ([CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)) -------------------------------------------------------------------------------- /macros/Import bookmarks from file.py: -------------------------------------------------------------------------------- 1 | import re 2 | import cPickle 3 | 4 | filename = avsp.GetFilename(_('Select a file'), filefilter= 5 | _('All supported files') + '|*.txt;*.xml;*.ses;*.log;*.qp|' + 6 | _('Chapters Text files') + ' (*.txt)|*.txt|'+ 7 | _('Matroska XML files') + ' (*.xml)|*.xml|' + 8 | _('Celltimes files') + ' (*.txt)|*.txt|' + 9 | _('AvsP Session files') + ' (*.ses)|*.ses|' + 10 | _('TFM log files') + ' (*.log)|*.log|' + 11 | _('XviD log files') + ' (*.log)|*.log|' + 12 | _('QP files') + ' (*.qp)|*.qp|' + 13 | _('Timecode format v1 files') + ' (*.txt)|*.txt|' + 14 | _('All files') + ' (*.*)|*.*') 15 | if not filename: 16 | return 17 | 18 | lines = avsp.GetWindow().GetTextFromFile(filename)[0] 19 | 20 | bookmarkDict = {} 21 | 22 | # parsing QP-file 23 | if not bookmarkDict: 24 | try: 25 | for index in lines.strip().split('\n'): 26 | s=index.strip() 27 | if s!='': 28 | bookmarkDict[int(s.split(' ')[0])] = '' 29 | except: 30 | bookmarkDict = {} 31 | 32 | # parsing Timecode format v1: place a bookmark on every starting frame 33 | if not bookmarkDict: 34 | if lines.startswith('# timecode format v1'): 35 | match = re.search(r'^\s*assume\s*(\d*\.*\d+\.*\d*)', lines, re.M|re.I) 36 | base_fps = (match.group(1) if match else 'unknown') + ' fps' 37 | bookmarkDict[0] = base_fps 38 | for line in lines.splitlines(): 39 | if line and line[0].isdigit(): 40 | start, end, fps = line.split(',') 41 | bookmarkDict[int(start)] = fps + ' fps' 42 | bookmarkDict[int(end)+1] = base_fps 43 | 44 | # parsing SCXviD log 45 | if not bookmarkDict: 46 | try: 47 | if lines.startswith('# XviD 2pass stat file'): 48 | bookmarkDict=dict((i-3,'') for i,v in enumerate(lines.split('\n')) if v.startswith('i')) 49 | except: 50 | bookmarkDict = {} 51 | 52 | # parsing TFM output 53 | if not bookmarkDict: 54 | if lines.startswith('#TFM '): 55 | try: 56 | stats = lines.split('# FORMAT:') 57 | if len(stats)==5: 58 | sectionslice = (0,(2,-2),(2,-4),(2,-4),(2,-1)) 59 | section = lambda sectionidx: stats[sectionidx].strip().split('\n')[sectionslice[sectionidx][0]:sectionslice[sectionidx][1]] 60 | sectionisempty = lambda sectionidx: 'none detected' in stats[sectionidx] 61 | 62 | frameindent = 4 63 | frametitle = lambda line: line[line.find(' ',frameindent+1)+1:] 64 | framenum = lambda line: int(line[1:line.find(' ',frameindent)]) 65 | 66 | dCombed = dict( (framenum(L), frametitle(L)) for L in section(1) ) if not sectionisempty(1) else {} 67 | 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 {} 68 | dPossible = dict( (framenum(L), frametitle(L)) for L in section(3) ) if not sectionisempty(3) else {} 69 | 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 {} 70 | maxframe = max([max(d.keys()) if d.keys() else -1 for d in (dCombed, dPossible, dUBmatch)]) 71 | if maxframe == -1: 72 | avsp.MsgBox(_('Not combed or out of order frames'), _('Bookmarks from TFM file')) 73 | return 74 | s=avsp.GetTextEntry( \ 75 | [_('Combed') + ' (%d)' % len(dCombed),\ 76 | _('Possible') + ' (%d)' % len(dPossible),\ 77 | _('u,b,out-of-order') + ' (%d)' % len(dUBmatch),\ 78 | '',\ 79 | _('Min frame:'),\ 80 | _('Max frame:')],\ 81 | [True,True,True,'','0',str(maxframe)],\ 82 | _('TFM log parser'),\ 83 | ['check','check','check','sep','text','text'],\ 84 | 250 ) 85 | if not s: return 86 | 87 | if s[0]: bookmarkDict.update(dCombed) 88 | if s[1]: bookmarkDict.update(dPossible) 89 | if s[2]: bookmarkDict.update(dUBmatch) 90 | 91 | try: 92 | f1,f2=int(s[3]),int(s[4]) 93 | if f1!=0 or f2!=maxframe: 94 | bookmarkDict=dict( (f,t) for (f,t) in bookmarkDict.items() if f1<=f<=f2 ) 95 | except: 96 | pass 97 | 98 | avsp.GetWindow().GetStatusBar().SetStatusText( _('%d frames imported') % len(bookmarkDict) ) 99 | except: 100 | raise 101 | avsp.MsgBox(_('[COMBED FRAMES] section could not be parsed')) 102 | return 103 | 104 | # parsing chapters text files 105 | if not bookmarkDict: 106 | timeList = re.findall(r'(\d+)=(\d+):(\d+):(\d+\.\d+)', lines) 107 | if timeList: 108 | fps = avsp.GetVideoFramerate() 109 | titleDict = {} 110 | for index, title in re.findall(r'(\d+)NAME=(.*)', lines, re.I): 111 | titleDict[index] = title 112 | for index, hr, min, sec in timeList: 113 | sec = int(hr)*3600 + int(min)*60 + float(sec) 114 | bookmark = int(round(sec*fps)) 115 | bookmarkDict[bookmark] = titleDict.get(index, '') 116 | 117 | # parsing matroska xml files 118 | if not bookmarkDict: 119 | sections = re.findall(r'(.*?)', lines, re.I|re.S) 120 | fps = avsp.GetVideoFramerate() 121 | for text in sections: 122 | timecode = re.search(r'(\d+):(\d+):(\d+\.\d+)', text) 123 | if not timecode: 124 | continue 125 | title = re.search(r'(.*?)', text) 126 | hr, min, sec = timecode.groups() 127 | sec = int(hr)*3600 + int(min)*60 + float(sec) 128 | bookmark = int(round(sec*fps)) 129 | bookmarkDict[bookmark] = title.group(1) if title else '' 130 | 131 | # parsing celltime format - frame count content 132 | if not bookmarkDict: 133 | try: 134 | for index in lines.strip().split(): 135 | bookmarkDict[int(index)] = '' 136 | except: 137 | bookmarkDict = {} 138 | 139 | # parsing AvsP ssesion files 140 | if not bookmarkDict: 141 | try: 142 | f = open(filename, 'rb') 143 | session = cPickle.load(f) 144 | except: 145 | pass 146 | f.close() 147 | try: 148 | if 'bookmarks' in session: 149 | if 'bookMarkDict' in session: 150 | for bookmark, btype in session['bookmarks']: 151 | bookmarkDict[bookmark] = session['bookMarkDict'].get(bookmark, '') 152 | else: 153 | for bookmark, btype in session['bookmarks']: 154 | bookmarkDict[bookmark] = '' 155 | except: 156 | pass 157 | 158 | if bookmarkDict: 159 | bookmarkList = bookmarkDict.items() 160 | # Don't delete current bookmarks, update its title if supplied 161 | oldBookmarks = avsp.GetBookmarkList() 162 | for bookmark, title in bookmarkDict.items(): 163 | if bookmark in oldBookmarks: 164 | if title: 165 | bookmarkList.append((bookmark, title)) 166 | else: 167 | bookmarkList.remove((bookmark, title)) 168 | avsp.SetBookmark(bookmarkList) 169 | else: 170 | avsp.MsgBox(_('Bookmark file unrecognized!'), _('Error')) -------------------------------------------------------------------------------- /macros/Examples/[3] Manual Telecide.py: -------------------------------------------------------------------------------- 1 | # This is an advanced macro designed to aid in the process of manual 2 | # deinterlacing. In order to use this macro, you must first have a general 3 | # understanding of the Telecide AviSynth filter, otherwise most of the stuff 4 | # the macro does (and most of the description here) will be meaningless to 5 | # you. You can learn everything you need to know about the Telecide filter 6 | # from the Decomb tutorial and reference manual in the AviSynth help. 7 | # 8 | # The macro itself has three different modes - the first mode retrieves 9 | # the source file and sets up a script to help determine the field order, 10 | # the second mode creates several scripts related to the Telecide filter, 11 | # and the third mode writes override information to a text file, line by 12 | # line. The following is a general description of how to use the macro. 13 | # 14 | # To begin, first start up AvsP.exe and run the macro. It will prompt you for 15 | # the source file, then it creates a script with the top and bottom 16 | # fields of the video seperated and stacked vertically. Go through some of 17 | # the video frame by frame to determine the field order. When you determined 18 | # the field order, run the macro again, this time it will prompt you for the 19 | # field order (0 or 1), then it creates and saves four scripts. The first 20 | # script is the source with Telecide applied, the other three scripts 21 | # represent the frames which the filter Telecide can choose from, "current", 22 | # "next", and "previous". Once these scripts are open, go through the 23 | # Telecide script (the first script) frame by frame, starting from the 24 | # beginning. If you see an interlaced frame, look at the "current", 25 | # "next", and "previous" scripts to see if there's a better non-interlaced 26 | # frame. If so, running the macro again will record the frame number and the 27 | # letter "c", "n", or "p" (depending on which tab is currently selected) into 28 | # the override text file, and show the Telecide video again, this time with 29 | # the overridden frame. Note that running the macro when the first tab is 30 | # selected (the Telecide tab) is not appropriate, and the macro issues a 31 | # warning with a MsgBox. 32 | 33 | import os 34 | 35 | if avsp.GetTabCount() == 1 and avsp.GetText() == '': 36 | #== FIRST MODE ==# 37 | # Get the filename of the source to de-interlace from a dialog box 38 | filename = avsp.GetFilename(_('Open a source to Telecide')) 39 | if filename: 40 | # Make the script to determine field order 41 | # Note: the filename is stored on the first line, used by the second mode 42 | avsp.InsertText('# TELECIDE FILENAME: %s\n' % filename) 43 | srcstring = avsp.GetSourceString(filename) 44 | avsp.InsertText('src = %s\n' % srcstring) 45 | avsp.InsertText( 46 | 'top = src.AssumeTFF().SeparateFields().Subtitle("order = 1")\n' 47 | 'bot = src.AssumeBFF().SeparateFields().Subtitle("order = 0")\n' 48 | 'StackVertical(top, bot)\n' 49 | ) 50 | avsp.ShowVideoFrame(0) 51 | elif avsp.GetTabCount() == 1 and avsp.GetText().startswith('# TELECIDE FILENAME: '): 52 | #== SECOND MODE ==# 53 | # Get the filename of the source from the first line of the script 54 | firstline = avsp.GetText().split('\n')[0] 55 | filename = firstline.split('# TELECIDE FILENAME: ')[1] 56 | # If the filename somehow got mangled, get it again with a dialog box 57 | if not os.path.isfile(filename): 58 | avsp.MsgBox(_('Filename was mangled! Get it again!'), _('Error')) 59 | filename = avsp.GetFilename(_('Open a source to Telecide')) 60 | # Get the field order from the user, make sure it's either 0 or 1 61 | order = avsp.GetTextEntry(_('Enter the field order:')) 62 | try: 63 | order = int(order) 64 | if order not in (0,1): 65 | avsp.MsgBox(_('Must enter either a 0 or 1!')) 66 | except ValueError: 67 | avsp.MsgBox(_('Must enter an integer!')) 68 | # Make the Telecide-related scripts 69 | if filename and order in (0,1): 70 | # Close the field order script 71 | avsp.CloseTab(0) 72 | # Make the telecide override text file (empty for now) 73 | dir, base = os.path.split(filename) 74 | ovrName = 'telecide_override.txt' 75 | f = open(os.path.join(dir, ovrName), 'w') 76 | #~ f.write('\n') 77 | f.close() 78 | # Make the telecide script 79 | name = os.path.join(dir, 'telecideBase.avs') 80 | avsp.InsertText('# TELECIDE OVERRIDE NAME: %s\n' % os.path.join(dir, ovrName)) 81 | srcstring = avsp.GetSourceString(filename) 82 | avsp.InsertText('%s\n' % srcstring) 83 | avsp.InsertText('Telecide(order=%i, guide=1, post=0, show=true, ovr="%s")\n' % (order, ovrName)) 84 | avsp.SaveScript(name) 85 | # Make the "current" script 86 | name = os.path.join(dir, 'telecideCurrent.avs') 87 | avsp.NewTab() 88 | avsp.InsertText('%s\nSubtitle("Current")\n' % srcstring) 89 | avsp.SaveScript(name) 90 | # Make the "next" script 91 | name = os.path.join(dir, 'telecideNext.avs') 92 | avsp.NewTab() 93 | avsp.InsertText('src = %s\n' % srcstring) 94 | if order == 0: 95 | avsp.InsertText('sep = src.AssumeBFF().SeparateFields()\n') 96 | else: 97 | avsp.InsertText('sep = src.AssumeTFF().SeparateFields()\n') 98 | avsp.InsertText( 99 | 'first = sep.SelectEven().Trim(1,0)\n' 100 | 'second = sep.SelectOdd()\n' 101 | 'new = Interleave(first, second).Weave()\n' 102 | 'new.Subtitle("Next")\n' 103 | ) 104 | avsp.SaveScript(name) 105 | # Make the "previous" script 106 | name = os.path.join(dir, 'telecidePrevious.avs') 107 | avsp.NewTab() 108 | avsp.InsertText('src = %s\n' % srcstring) 109 | if order == 0: 110 | avsp.InsertText('sep = src.AssumeBFF().SeparateFields()\n') 111 | else: 112 | avsp.InsertText('sep = src.AssumeTFF().SeparateFields()\n') 113 | avsp.InsertText( 114 | 'first = sep.SelectEven()\n' 115 | 'second = sep.SelectOdd().DuplicateFrame(0).Trim(0, src.Framecount()-1)\n' 116 | 'new = Interleave(first, second).Weave()\n' 117 | 'new.Subtitle("Previous")\n' 118 | ) 119 | avsp.SaveScript(name) 120 | # Select the first tab and show the video preview 121 | avsp.SelectTab(0) 122 | avsp.ShowVideoFrame(0) 123 | elif avsp.GetTabCount() == 4 and avsp.GetText(0).startswith('# TELECIDE OVERRIDE NAME: '): 124 | #== THIRD MODE ==# 125 | # Get the filename of the override text file from the first line of the script 126 | firstline = avsp.GetText(0).split('\n')[0] 127 | filename = firstline.split('# TELECIDE OVERRIDE NAME: ')[1] 128 | # If the filename somehow got mangled, get it again with a dialog box 129 | if not os.path.isfile(filename): 130 | avsp.MsgBox(_('Override filename was mangled! Get it again!'), _('Error')) 131 | filename = avsp.GetFilename('Get the Telecide overrride text file') 132 | if filename: 133 | # Get the index of the currently selected tab 134 | index = avsp.GetCurrentTabIndex() 135 | if index == 0: 136 | # Don't write anything if base Telecide tab was selected 137 | avsp.MsgBox(_('Not allowed to select base Telecide tab!'), _('Error')) 138 | else: 139 | # Create the text to write depending on which tab was selected 140 | frame = avsp.GetFrameNumber() 141 | if index == 1: 142 | txt = '%s c\n' % frame 143 | elif index == 2: 144 | txt = '%s n\n' % frame 145 | elif index == 3: 146 | txt = '%s p\n' % frame 147 | # Write the text to the override file 148 | f = open(filename, 'a') 149 | f.write(txt) 150 | f.close() 151 | # Show the video of the Telecide script 152 | # Force the video to refresh (AviSynth script hasn't changed, but override file has) 153 | avsp.ShowVideoFrame(index=0, forceRefresh=True) 154 | else: 155 | # Unknown mode 156 | avsp.MsgBox(_('Unknown mode!'), _('Error')) 157 | -------------------------------------------------------------------------------- /icons.py: -------------------------------------------------------------------------------- 1 | # AvsP - an AviSynth editor 2 | # 3 | # Copyright 2007 Peter Jang 4 | # 2010-2012 the AvsPmod authors 5 | # 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit 19 | # http://www.gnu.org/copyleft/gpl.html . 20 | 21 | # icons - icons embedded in a Python script 22 | # 23 | # Dependencies: 24 | # Python (tested on v2.6 and v2.7) 25 | # wxPython (tested on v2.8 Unicode and v2.9) 26 | 27 | from wx.lib.embeddedimage import PyEmbeddedImage 28 | 29 | AvsP_icon = PyEmbeddedImage( 30 | "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAgZJ" 31 | "REFUWIXtl6FywjAch38pmN2RoXbH3bgZqlD0AYKo6gwvgmMPALzAHK+A2QPAISqK2dwUCgy3" 32 | "qblRu2WiJLTQJG2BMbG/IrmQ39fv0iQlxCrhkmVdNP0vAJTTOvn3Fy86IbFK5CgA/v3FgyBA" 33 | "pVLR/jEMQ/i+j+dNHwAwXQMIV+ATm+cBIfFFKMJrtRrCMMwcHi8BgomdCUICiHDbtg/C421d" 34 | "eBEIQqySDG+1WgeB++3xeKwNzwuRWAOUUu2ky+XSGCzKuwOmC/O41LdABeL7Pj6qfTSqUXv1" 35 | "Zpi90gDul+ATm6sslIFoxbbbbc55+tsXBxrd7vq7BogsFhIb0Xw+Vw7cbDZwXReDxTAKr0cw" 36 | "jbo+QFpQ7C0SYGtBOQ+lFIyxRN9j0wzh3en5DrZinQUA6HQ6GCyGGL0BjeudCW1pLCQATBYA" 37 | "wHEc+Xu2hQCKW0g9jH7TwgFAUQvdejELyuM4j4XVZ9RXxEIqgLCgg3AcB67rAq8zjLZ7QREL" 38 | "SgMCghCiBGGMIfCupAkgvwXtjYhYJWICYYyh1+tJCJOF/cp0JTOBUEolBJDBQl6ALCAC4mY2" 39 | "VFqYro8EMIGIQ2tkOiVjdwRyiu8CsaCCIAAQHduDZh/ey26MfPonkrignORaHjciNrHuuzkc" 40 | "OJGB/RJGvAe+A0gJPxvAPgigvqafFSBLXfzT7B/gBzi2CON/wMBrAAAAAElFTkSuQmCC") 41 | 42 | #---------------------------------------------------------------------- 43 | play_icon = PyEmbeddedImage( 44 | "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAH5J" 45 | "REFUWIXt1EESwCAIQ1GQ3v/GHbvqXiBpuoAD+N+MivsKU86S1gcwgN8DwnyH+ZYBvoCkroAB" 46 | "Kb0BJKT1CBEQyC/oQKDfsAKh7IEMhLqITiDyTXgxD79tuwRwEqYAMmEooBKGADrhFgARLgGQ" 47 | "4RSAET4CMMPvyDfhAAYgBzzIPiRzQVyedwAAAABJRU5ErkJggg==") 48 | 49 | #---------------------------------------------------------------------- 50 | pause_icon = PyEmbeddedImage( 51 | "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw" 52 | "SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA" 53 | "AACCSURBVFiF7dexCYAwEIXh/8TaMRzAMZxGHM4xrMUJrF3g2YYQSLpYvMAVCY/LB2kuIYme" 54 | "a+h6uwF/AIwtoYiYgSU5eiUdWWYFpuTolHRXm0uqFrABSuoqZK4ss7X07v4EBhhggAEGGGCA" 55 | "AQY0DaXAATzJ/i1kdrKhtKVx+GtmQG/AB4GqXmFNBqwqAAAAAElFTkSuQmCC") 56 | 57 | #---------------------------------------------------------------------- 58 | external_icon = PyEmbeddedImage( 59 | "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw" 60 | "SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA" 61 | "AAFiSURBVFiF7Za9SgNBFIXPmZn8WEgsrC21V7DwDUyTJoWVb2AbLO1EfA/tRFAQSxGLWEkK" 62 | "KwtrESxEUZLZY5EsjovGEJMdkD1w2d2ZO3u+3QtzhwAMAAfADu5tMBZGNRNzAOYBHEh6xZgy" 63 | "4y6clAqAAuD/AZCslGxpj+RI757GH6CklqU9JVmLAZBq3dFdk1yKBQBBi5a27ejqUQAGqoE4" 64 | "sbTbsQAAwJDcddYdkpyJAdCXsGForkgupEMEsIzPDhiGHUTaKcsAKsF1Fv2OeAbgLbApG5p2" 65 | "1ptg+PhAsdlV95IANKkPHCZDk4XoStqKvRPSAVhB/iV4pNjsqXfhANzgbyeiTngiIlnNmH2R" 66 | "oE6ipCHpHsi/GR0lStZS8zwBJGnHyzclvYQTLgfzZwibXv74u8lpA9x5+Yak258SplmCcy+/" 67 | "Osx8WgAiue/l65KefkueeAkkvQNojZofeycsAAqA+AAf/cVxOJ6qaHcAAAAASUVORK5CYII=") 68 | 69 | #---------------------------------------------------------------------- 70 | next_icon = PyEmbeddedImage( 71 | "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAHZJ" 72 | "REFUWIXt10sKACEMA9BU739k0RsM/aQoTLrtIg9sC5qNiZs1rqYLIIAAHsCE7Uq/DOhGuJ+g" 73 | "CxGagQ5EeAjZiNQWMBHpNWQhSneAgXj/EH3VwrZKvwRghKcBrPAUgBkeBrDDQ4COcDegKxwA" 74 | "TP8CAQT4PeAAzMIsUQFAh3wAAAAASUVORK5CYII=") 75 | 76 | #---------------------------------------------------------------------- 77 | skip_icon = PyEmbeddedImage( 78 | "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAH1J" 79 | "REFUWIXt10sKwDAIBNAxuf+RU7PqrhQ/IylUtwbmEaIQkTFxssbR9AY0oAEWwIRopn+XXuvx" 80 | "nOkGWIgwoBLhegMVCPcjZCNCU8BEhMeQhUjtAQbi+4vorRZUMv0UgBEeBrDCQwBmuBvADncB" 81 | "KsLNgKpwAJD+FzSgAb8HbDPFMErXwWvCAAAAAElFTkSuQmCC") 82 | 83 | #---------------------------------------------------------------------- 84 | spin_icon = PyEmbeddedImage( 85 | "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMElEQVR42mNkoBAwDm8D/hNj" 86 | "ASEDCLqSGAPwqiPWAJxq6eICisKAolggCowawMAAAGI5BxGNrXGkAAAAAElFTkSuQmCC") 87 | 88 | #---------------------------------------------------------------------- 89 | checked_icon = PyEmbeddedImage( 90 | "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAWElEQVR42s2RQQoAIAgE82c+" 91 | "3Z8ZHYwsgxUh2kOHckbYqBVD4xARzYLMTE5gF0jW+acCjeZRgXUECeamDU4J7O2AM4IWwWgH" 92 | "eoMzJWoEV77xdwEKW5ygkg43FHEROvSJLgAAAABJRU5ErkJggg==") 93 | 94 | #---------------------------------------------------------------------- 95 | unchecked_icon = PyEmbeddedImage( 96 | "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVR42mNkoBAwgogDBw78" 97 | "J1Wjg4MDI4oBMAFiALL6UQNGDRhuBhCrGQZQDKAEAABsPGgR8pSNpgAAAABJRU5ErkJggg==") 98 | 99 | #---------------------------------------------------------------------- 100 | smile_icon = PyEmbeddedImage( 101 | "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAwNJ" 102 | "REFUOI1lk11Mm3UUxn//f8sKLLQbhQrd+ArQroOaZWMGGMwLlyyZgPFKXUx2Iy6LF7pdeqHR" 103 | "zOiWmPkRRW8k3rgY9YJ4sRiMqN0cc+qW0c6NlQJV6Nv3pYwBsgFve7xo3eb2JM/NyTnP8+Tk" 104 | "HKW0gweRTpkynTjP1MQvrK7mqNraRiDURV39FvVgr7pfwDQs+WPkRVwqga/CS1mZl7V1zV+p" 105 | "ea7EZjFuejn8ymnqG+4J3RVIJsYkHT3EtlAdG+trQBcDCmwNt4W1BZvfLk/zzbe/c7D/C3a3" 106 | "tysAZ97ZkEysh117w1BWw+3VHCWuyryFEyhzIFmLzifClJZ6GBx4nsmJpDQ01iqUdnBpuE/E" 107 | "elZEXpd3T/UKIPv37xCR0yLypfT1PSaAnHyzV2T5hAx9/py8/EKnKO1Ap2eT4q9YBK8X8BD5" 108 | "aQaAkZE4sAEo5scfbuRro3/Dxk0EGrbiLl1n4saEOG/NXaBmswdUEZDl668O8cmn2zlwYDfg" 109 | "AhTR2NsMDY1y+EgHkGWTuxi/v5prYxHUheFj0taSQldvAXwFevILJAvoQhIHsAxYzMVMhiMJ" 110 | "zFvFOO2sk9U7WUrQJBImtv0PgUCQexsUYAUoIhq7jtdl43I4yOZyOIs2oN2+TtJGBrCZSc3R" 111 | "2zNYcMwB6wUCaPqeGiAzs8Tyis18ZoFgqAtdWd3B+OQca1PzdO9poqPLR3//h4XIJQUqnjn4" 112 | "Dk/va6a1rY7r8QyWZRJs2ZM/pMH398n2xjV27dyGfsTP0WNnOHsuTVd3M5KDyM/j9Oxt5I3j" 113 | "T3L5/AyR0TjWzRWOn/peKaUdpI2MfPZeK93trbQEa/EE/CxOLxI5l0KJpqOtjs2Vbn69aHDp" 114 | "yixj0RivnTxLlb9C3T3l+HhcPjrRzo5wLcGmJnwVbtzuUtZtTcq4w2RyibFrSaanZnn1rTM0" 115 | "BwPqoWeyzEUZ+OAIU+PfUeUrp7zch21rUsY8hrlAKPw4Lx39mEqf5+Fnuh+WuSRXo6P8efUi" 116 | "IkL40U6CoZ3/G/wP/wJ3xTm0DZwlTwAAAABJRU5ErkJggg==") 117 | 118 | #---------------------------------------------------------------------- 119 | question_icon = PyEmbeddedImage( 120 | "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACI0lEQVQ4jYWTwUsbQRTGfzOx" 121 | "SWZN06R4CcKeikQLpUJdmlrwppfmouip4KVQaKEI/SN66lGhIF57K7156m1FTSCUSkrQRLAQ" 122 | "4mVziDXo7Ganh26KyGo/eAwPvvfm+96bEcTjMfAamIryn8An4Pt1oogpfm5Z1seZmZkHhUIh" 123 | "C9DpdHrVarXZ7/ffA+5VciKmwYfZ2dlnY2NjOUCGYSiVUiqfz989OTm5B3y5SpbXip8AxVwu" 124 | "l9Vao7XG93183yefz2eBYsS5EQeO45wvLCyYbrf7L1zXNfPz88ZxnHPg4DYLT8fHx6dGR0fv" 125 | "NBoNXNdlMBgwPT1NvV6n3W777Xb7G/D1JgurlUplTwgRHB8f02q16PV6nJ6e4nleUKlU9oDV" 126 | "22YAsH54eNgFKBaLzM3NsbW1xf7+fhdYv83/VbRWVlZMs9k029vbZnl52QCtOOJITP5mqGxt" 127 | "bQ0hBEqpodp3wAYQxDVzgM/A0dLSkimXy6bT6ZidnR1TLpfN4uKiAY4ijjMsGm7hpWVZG7Zt" 128 | "PyqVSoUgCJBSMjk5ied51Go1tNZMTEzcD8PQvry8fOH7vgf8GD7leqlUKkopZTKZRClFMpnk" 129 | "7OwMgEwmg9aai4sLfN9nMBiEu7u7DeDhCGABdjqdllJKUqkUSilSqRTZbBZjDEEQkEgkEEIg" 130 | "pcQYIwEbsAR/f95b4BXQB35H0Qd0pDAdXZSJTgvYBNZFNHk7ZiP/QwD8+gOTQ9W5+jdpxQAA" 131 | "AABJRU5ErkJggg==") 132 | 133 | #---------------------------------------------------------------------- 134 | ok_icon = PyEmbeddedImage( 135 | "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9i" 136 | "ZSBJbWFnZVJlYWR5ccllPAAAAWVJREFUeNpi/P//PwNdgVsnw38QJkuzYxvD/3c/JoIxiE2y" 137 | "5idfmv/P2sQAxk+/NoJdwkKs5sV5zQzbj9QyMLAyMDACxb7/f4eqyB1omjsWvzkBNd/+XPR/" 138 | "1h6G/zOBePZehv+XPsX/d4J4wRiu6MqnOCCGS0DEW4GKPyb8n30Q6OwDQM2HQJoTUDWDbD37" 139 | "we//7GNABUcZ/p967//foZkBjEFskPgsoPgcIH36gz+qZiBggfuHmYHhH1Dqwq2NDLVpNmBJ" 140 | "EJuBCehnIFZTsWOomLaRYV8VgwlQ6izMAJB+Y5c2hjOlqboMj59cZvj3j4EBlrYYgbJMQM2y" 141 | "MroMXbMvM+xF0wwCQHsZnt/by7DlheCrNAd7WYYfPz4x/AfZCpRhBsaRiIQsw4Q5t7FqRgcg" 142 | "l/xf+Zz7/9wbDGAMYrug+ZkQMHYFalj9khuMXUnUDDfEExgznp3kaYYbQqxmRkqzM0CAAQBW" 143 | "bMG1YQFlxwAAAABJRU5ErkJggg==") 144 | 145 | #---------------------------------------------------------------------- 146 | rectangle_icon = PyEmbeddedImage( 147 | "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABXElEQVR42sXSv0vDQBQH8O9d" 148 | "ErUVp/ojCAoiiDjU/hAHlzq5WXBRu1pBEAc3J/EPcHIRWpFODv4Bzro4CEXQWRBc1FYpUps0" 149 | "lzTnpeqU10UFH2S6y4f3fe8YflnsT4F6sybfnCdwppGXfekjFh1FxIiyECA8IU9ut1CxbqDz" 150 | "HhIQXgOT/YtYmtoLA5ZoyEJ5GU2/Co0ZJOC2bJi9SeTTxxRgyWI5B0c+K6CL7qBlwYymsZYu" 151 | "EIATdJCDi4qaQWdgKJJCfqYYBhoBcJWDp1XBuYogw+N2PQsD3Smsz3YADi9VB7wKXTPAuDr8" 152 | "OpUK81sMwrUwGEliY65IRzg4X1VDfGnPoP1z8MlP4DvCcF8Cm5kjogPxLvfPVmCLGjROb8FR" 153 | "EUZicWwvEFtourbcPc2i8voAQ6ffgS3qiI9nsJMthYGgru8v5N2jekg6sQUVw/MFEmPzmDCn" 154 | "aeAn9f/AByV0jxHGo4HSAAAAAElFTkSuQmCC") 155 | 156 | #---------------------------------------------------------------------- 157 | dragdrop_cursor = PyEmbeddedImage( 158 | "iVBORw0KGgoAAAANSUhEUgAAAA4AAAAYCAYAAADKx8xXAAAAhElEQVR42q3TgQ6AIAgE0OP/" 159 | "P9qspcM8hNtya6z0jSAyAK1fBnHZC6HiB/YFM5PwhM+NgBeo4A1WMYUVHMIMH+EJpzDCWY0s" 160 | "0Q7vw9VvyianNBBsViX43UxxVIMEZ60++g4v+155NA76bvvIMi7PyNs1mhHJXzHOZRnDxv2a" 161 | "EaUYdTWLF10UqgXtrhCoAAAAAElFTkSuQmCC") -------------------------------------------------------------------------------- /help/About.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | About 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 20 | 21 | 22 | 23 | 24 | 25 | 97 | 98 | 99 | 130 | 131 |
26 | 27 |
28 | 29 |
30 |
31 |

About

32 | 42 |
43 |

About AvsP

44 |

AvsP was written using the Python programming language and the wxPython graphical user interface framework. AvsP started as a personal project of mine, where I wanted to create a straightforward way to compare the effects of different AviSynth filters. The concept for the program remained in my head for some time, since I never did gui programming before and didn't really know where to begin. I tried to learn several gui frameworks (win32, mfc, wtl), but failed pretty miserably. Eventually I found out about Python, and then wxPython, which made things much easier for me to learn, and things started rolling from there. Since then I've rewritten the program from scratch twice, and I felt that this most recent incarnation was good enough such that members of the AviSynth community could benefit from it as well.

45 |

Similar to AviSynth itself, AvsP is open source and distributed under the GPL license. The source code is included in every release in the src folder.

46 |
47 |
48 |

About this website

49 |

This website was generated using rest2web, a python library designed to turn restructured text into html. I have absolutely zero html or css skills, and yet I was able to construct this website completely from plain text files, all thanks to rest2web. It's really a great tool for people like me who know little html/css or for people who are just not interested in maintaining a website with unreadable html files.

50 |

The video source seen in various AvsP screenshots came from a Super Mario Bros. 3 speed run, check out http://speeddemosarchive.com if you're interested in finding out more. It's some pretty amazing stuff, and a fun way to watch the endings to games you never were good enough to beat :) .

51 |
52 |
53 |

About the flash tutorial

54 |

The flash tutorial for AvsP was created using Wink, which is free software for creating flash-based presentations. I can't give this program enough praise - it takes complicated tasks such as screenshot capturing, text captioning, and time-based cursor positioning, and makes it so easy to use you practically don't need to read any help or tutorial files. Trust me, if you ever have the chance to make a presentation using Wink, you'll knock the socks off anyone who sees it.

55 |
56 |
57 |

Acknowledgements

58 |

AvsP could never have existed without AviSynth, so I wanted to thank its creator Ben Rudiak-Gould and all of AviSynth's current developers for their hard work. I really believe that AviSynth is an excellent tool for both video editing as well as a healthy introduction to programming for non-programmers, so I'm happy to make any contribution that I can.

59 |

I also want to extend my thanks to the doom9 community, who have made innummerable suggestions for the development of AvsP (take a look at the changelogs to see what I'm talking about). They have continually provided well-thought out feature suggestions and criticisms which have fueled AvsP's development, making it a much better program than I could have ever accomplished on my own.

60 |
61 |
62 |

Testimonials

63 |

AvsP was designed to be an advanced video editing tool with never-before-seen features, and yet it remains so easy to use that it has developed a reputation for being a great tool for AviSynth newbies. Here's some things people are saying about AvsP:

64 |

This is super cool. 65 | --Richard Berg

66 |

I can't thank you enough!!! This program is outstanding! I've been waiting for something just like this for a long time, and never expected to get something this outstanding. It's a lot like the options that some filters have in Vdub where there is a preview button so you can see changes made in the video as you mess with the filters options but instead of only a few filters it seems to work with just about anything.. I've actually never figured out a way to make any filter in avisynth to work like those filters in vdub with the preview button. This is soo great you have made me soo happy! 67 | --mimage

68 |

Well, I have to say that this program is a revolution in AviSynth usage for me. I was looking for something like this for a long time. May be I just didn't know right programs or tools, but everything what I tried was a way way way less powerful than AvsP. Thank you, qwerpoi, great job! 69 | --Dr.D

70 |

just discovered this app today.. it's awesome. thanks for all your work. 71 | --wuziq

72 |

I can imagine the length of your to-do-list . It has many aficionados. I am one of them . Thank you very much. 73 | --krieger2005

74 |

This is a GREAT tool for beginners like me. Thanks man :) 75 | --Bh4i

76 |

thank you for this awesome Avs script editor/previewer! So awesome that I have almost completely stopped using VDubMod for my editing/previewing task. 77 | --Champs

78 |

Wow, I just tried AvsP and I absolutely love it! I've never even considered using anything besides notepad, but this has definately become my default avs editor! 79 | --Zarxrax

80 |

A big THANKS for the great tool!! 81 | --doxville

82 |

I'm in awe. It works so well and smoothly, like magic. And only a few weeks ago it was new! It's always nice to see promising software fulfilled. 83 | --foxyshadis

84 |

Big thanks - what a beatiful program :) 85 | --communist

86 |

Great program! Just what I needed, EXACTLY what I needed. Thank you for it! 87 | --Ignus2

88 |

This is the tool! 89 | --Veiga

90 |

This tool is amazing! I've just been learning/using Avisynth for a month now and I don't know how I missed AvsP until now. For the first time, this weekend, I was able to actually see instant differences between plugins that I couldn't decide on before. Now I feel like I am really using the best items and settings for my material in my script. I really love this program. THANKS! 91 | --IceManTX

92 |
93 |
94 | 95 |
96 |
100 |
101 |
102 | 119 |
120 | 121 | 122 |

123 | Donate via PayPal 124 |

125 | 126 | 127 | 128 |
129 |
132 | 133 |
134 | 135 | 136 | 139 |
140 | 141 | 142 | -------------------------------------------------------------------------------- /help/Overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Overview of AvsP 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 20 | 21 | 22 | 23 | 24 | 25 | 95 | 96 | 97 | 128 | 129 |
26 | 27 |
28 | 29 |
30 |
31 |

Overview of AvsP

32 |
33 |

Contents

34 | 44 |
45 |
46 |

About AviSynth

47 |

Before talking about AvsP, we have to first discuss a bit about AviSynth. AviSynth is a tool for editing video through the use of simple text documents (referred to as "scripts"). If you've never used AviSynth before, here's a quick example of how it works. Let's say you have an avi file on your hard drive, "C:\test.avi". Put the following text in a new text document:

48 |
 49 | AviSource("C:\test.avi")
 50 | Blur(1.0)
 51 | 
52 |

Save the text document as "C:\test.avs" (note the file extension!), then open the document with your media player of choice (windows media player, media player classic, mplayer, etc). If AviSynth is intalled on your computer, you should see the original video with a blurred image. Cool! AviSynth gives you a very quick and easy way to perform all sorts of complex video operations, such as cropping, resizing, fade in/out, etc, without the need for a clunky and hard-to-learn graphical user interface, and best of all, it's free. If you do any sort of video editing on your computer, or ever even intend on doing any video editing in the future, 53 | you have no excuse, go and install AviSynth right now.

54 |
55 |
56 |

About AvsP

57 |

Now that you know something about AviSynth, let's get back to the issue at hand and talk about AvsP. AvsP is essentially a text editor designed to help create AviSynth scripts. 58 | The question which naturally comes up is "An AviSynth script is just a text file, I already have a great text editor, why should I use something else to make scripts?" Ah, that's a valid question, glad you brought it up. Here are a couple of things to consider.

59 |
60 |

Comparing video

61 |

The first thing to note is that by using a simple text editor like Notepad to create AviSynth scripts, you end up having to do a lot of juggling between multiple programs. You create a script in Notepad, in order to see the resulting video you need to open the script in a media player or video editing program (many people use VirtualDub to preview their AviSynth scripts). If you made a typo in the script or if you don't like the final result, you go back to Notepad and repeat the process. That's really not so bad, but it gets much worse if you want to compare the output of one script to another. Let's say you were using Notepad as your text editor and VirtualDub as your external video program, and you wanted to compare the video of two different scripts at a specific position in the video, say frame 50. Here's a list of the necessary steps:

62 |
    63 |
  • Create and save a script in Notepad
  • 64 |
  • Create and save a second script in Notepad
  • 65 |
  • Open VirtualDub, load the first script
  • 66 |
  • Go to frame 50 in VirtualDub (keyboard shortcut Ctrl-G works well)
  • 67 |
  • Open another instance of VirtualDub, load the second script
  • 68 |
  • Go to frame 50 in this instance of VirtualDub
  • 69 |
  • Try and align the two instances of VirtualDub (easiest by maximizing both windows)
  • 70 |
  • Compare videos by quickly switching between the two windows (keyboard shortcut Alt-Tab works best)
  • 71 |
72 |

Them's a lot of steps! What's worse is when you want to compare the video at a different frame, you have to go to the appropriate frame number twice, once for each instance of VirtualDub. AvsP avoids this ugly mess by having a video preview built right in, no need to deal with juggling windows. And since it's a tabbed text editor, comparing multiple scripts becomes remarkably easy, no running and lining up multiple programs, no jumping to a position multiple times. Furthermore, AvsP offers a unique feature called user sliders, which allows for instant comparison of varying filter strengths, something that is impossible to accomplish with a simple text editor.

73 |
74 |
75 |

Inserting filenames

76 |

Another thing that tends to be difficult when making AviSynth scripts with a simple text editor is typing in filenames. AviSynth scripts often contain quite a few filenames, whether they are video sources, AviSynth plugins you want to load, or even other AviSynth scripts you wish to import. Typing in "C:\test.avi" like in the earlier example is easy enough, but unless you keep all your files on "C:\", you'll more likely have to type something like:

77 |
78 | "C:\Documents and Settings\John Doe\My Documents\My Videos\Trip to Hawaii\New Folder\test.avi"
79 |

This of course can get pretty annoying if you have a bunch of video files, all in different folders on your computer. AvsP solves this problem by offering a slew of different methods to add filenames to your script, from selecting 80 | video sources from a file open dialog box using custom templates to dragging-and-dropping any number of files from windows explorer.

81 |
82 |
83 |

AviSynth "awareness"

84 |

One final issue I'll mention about using a simple text editor to create AviSynth scripts is that a simple text editor isn't "Avisynth aware". AviSynth is in essence a programming language (albeit a simple and easy to use programming language). If you've ever used a programmed in a language such as C/C++, Java, Python, etc, then you know most programmers demand advanced language-specific text features in their editors, such as syntax highlighting, autocompletion, and calltips. These features are a requirement for any modern programming editor, as they improve overall efficiency and reduce user error when working with a specific programming language. AviSynth as a language benefits from having such features as well, it can be a handy way to remember specific filters or even learn about new ones. AvsP provides such facilities in its text editing components, and even offers easy-to-use ways for the user to edit or add new entries to the language database.

85 |
86 |
87 |
88 |

Conclusion

89 |

This overview has just scratched the surface in terms of the number of features AvsP has to offer. Hopefully some of you are convinced by now to give it a shot. Even still, somewhere in my head I can still hear some people saying "Well, my text editor allows you to open the text file with an external program with a simple keyboard shortcut" or "My text editor can syntax highlight ANY language by creating a definition file", etc. This is all true, and if you're satisfied with your text editor for making AviSynth scripts, I'm not trying to convince you that yours is bad and you shouldn't use it. But I will say that I don't think any text editor has all the AviSynth-specific features that AvsP has in one place - so while I won't claim that AvsP is a better text editor than fill-in-the-blank for editing arbitrary text files, I will go ahead and say that in my opinion it is a better AviSynth script editor. 'Nuff said.

90 |
91 |
92 | 93 |
94 |
98 |
99 |
100 | 117 |
118 | 119 | 120 |

121 | Donate via PayPal 122 |

123 | 124 | 125 | 126 |
127 |
130 | 131 |
132 | 133 | 134 | 137 |
138 | 139 | 140 | --------------------------------------------------------------------------------