Creating multiple videos with Avisynth
Asked Answered
M

3

8

I have a bunch of individual files that I want to each run through Avisynth. However, an AVS file can only create one video. As far as I know, there is no way to declare a variable's value from the command line.

I know that you can probably create a script that generates a bunch of AVS files and then somehow convert each AVS file to a video. However, since Avisynth is a scripting system, this seems kind of complicated. There must be some way to run different videos through a script, right?

What is the best way to do this? Thanks in advance.

Masseter answered 29/1, 2014 at 18:48 Comment(0)
L
4

I've never found a way to pass a command line parameter directly to a AVS script. Generating scripts on the fly is the only way I was able to get it working.

I know this is not the answer you're looking for - nevertheless two approaches for generating scripts:

Template script

I use this when I have a AVS script where the only parameter which changes is the source input file.

I have a script template.avs which expects a variable (v) containing the full path of the source video. A batch script then simply prepends the line with the variable for each video file, similar to this:

@echo off
if "%1" == "" (
    echo No input video found
    pause
    GOTO :EOF
)
set pth=%~dp0

:loop
IF "%1"=="" GOTO :EOF

echo v="%1">"%pth%_tmp.avs"
type "%pth%template.avs">>"%pth%_tmp.avs"

:: Do whatever you want with the script
:: I use virtualdub...
"%vdub%" /i "%pth%Template.vdscript" "%pth%_tmp.avs"

del "%pth%_tmp"

SHIFT
GOTO loop

This allows me to simply drag-and-drop several source videos onto the batch.

Import

Using the Import instruction, it is possible to externalize all the variable declarations into its own script.

Import("variables.avs")

This is useful when the template AVS script expects multiple variables.

Lecialecithin answered 29/1, 2014 at 22:37 Comment(2)
Thanks, I ended up writing a Python script to do something very similar to this. – Masseter
don't forget to declare varaible global if used in any function in your main avisynth script – Bevins
S
2

Another answer to this question would be letting the AviSynth script get its own name to point the file you want to process. If you want the script to work on movie.mp4, you can rename it to movie.mp4.avs. The script would be something like:

function GetVideoName()
{
    Try
    {
        assert(false)
    }
    Catch(err_msg)
    {
        err_msg = MidStr(err_msg, FindStr(err_msg, "(") + 1)
        filename = LeftStr(err_msg, StrLen(err_msg) - FindStr(RevStr(err_msg), "."))
        return filename
    }
}

video_to_process=GetVideoName()
#return BlankClip(color=$000000, pixel_type="RGB24").Subtitle("You would process the video [" + video_to_process + "]")
DirectShowSource(video_to_process, convertfps=true)

You can do the same operations on different videos just renaming the script (provided the videos and the .avs are in the same folder). Uncomment the next-to-last line to see what I mean.

Sericin answered 20/7, 2018 at 20:8 Comment(1)
This is genious. Using stack trace to extract current file name from inside is much simpler than generating/templating scripts with different content! One can just produce a bunch of symlinks pointing to single file for ease of editing only original script: for f in *.mkv; do ln -s process.avs "$f".avs; done – Td
C
2

It seems that each AviSynth script represents a single video.

To workaround this (in a similar way to marapet's answer), I've also developed a .BAT file whereby you can drag-and-drop video files upon it and an AVS file is created for each one and the path to the video is automatically inserted.

AviSynth Script Generator

I think this is a bit more flexible as it uses placeholders in the script. It can also optionally run ffmpeg (or whichever command you prefer) on each one to render and encode the final result.

Setup Instructions

  1. Save the following script as a .BAT file
  2. Create a subfolder under the .BAT called AviSynth Templates
  3. Create your master AVS script (e.g. master.avs) in this subfolder and use the placeholder [CLIP] wherever you want the video path to be injected. (You can also use [CLIP-NO-EXTENSION] to exclude the file extension if you have extra assets related to that video.)

    AviSource("[CLIP]")
    # ...do more tasks here...
    
  4. Drag and drop video files onto your BAT to create a customised AVS file for each one. If you drop the same video files onto the BAT again the AVS will be overwritten with a new version.

Create AVS files.bat

@ECHO OFF

:: INSTRUCTIONS:
:: 1. Create an AviSynth script 
:: 2. Use [CLIP] and/or [CLIP-NO-EXTENSION] as placeholders in the script. 
::    [CLIP-NO-EXTENSION] will exclude the file-extension in case you want to use it for including subtitles or other files that use the same base name.
::    e.g. AviSource("[CLIP]")
:: 3. Place the master .avs script in a folder called "AviSynth Templates", immediately beneath the folder containing this .BAT
:: 4. Drag and drop video files onto this BAT and each will be given an AVS file with the same name (video1.avi.avs will be created for video1.avi)
::    The placeholders will be filled in with the full absolute path of the dropped files.

SET TemplateName=master.avs
SET TemplatePath=%~dp0AviSynth Templates\%TemplateName%

echo Creating AVS scripts from master template %TemplatePath%...

:: Loop through every file dropped onto the .BAT
FOR %%A IN (%*) DO (

    REM :: Here we create a .AVS file for each video dropped onto the bat
    REM :: We read in the master script, replace the placeholders and then write the output to a text file using the video's filename and .avs extension
    REM ::
    REM ::    %%A - this contains the full path to the video file, including surrounding double-quotes
    REM ::    %%~A - this contains the full path to the video file, without surrounding double-quotes
    REM ::    %%~dpnA - this contains the full path to the video file, with drive, path and name (dpn) but no file extension (without quotes)
    echo Creating "%%~A.avs"
    powershell -Command "(Get-Content '%TemplatePath%').replace('[CLIP]', '%%~A').replace('[CLIP-NO-EXTENSION]', '%%~dpnA') | Out-File -encoding ASCII '%%~A.avs'"

    REM :: If you want to then run ffmpeg to render and transcode the AVS file you could run it here
    REM :: e.g. ffmpeg -i "%%~A.avs" "%%~dpnA.h264.mp4"

)

ECHO.
ECHO Script creation finished.
ECHO.

PAUSE
Caulis answered 24/9, 2019 at 10:19 Comment(2)
Not sure why I got a downvote. πŸ€” Happy to receive feedback on the script. – Caulis
Another commenter mentioned that video files containing a single quote will crash the script. If anyone can offer a simple fix for this, please post and let others know. – Caulis

© 2022 - 2024 β€” McMap. All rights reserved.