News:

--

Main Menu

[Wiki] Avisynth propsal

Started by hinterwaeldler, January 15, 2015, 12:15:01 AM

Previous topic - Next topic

hinterwaeldler

Hi,

after AQUAR asked, how to use a different port between ADM and avisynth, here is a purpose for the Wiki (which should be edited by someone with a better spelling).

As I am not sure about the used syntax, i will use:
= HEADER 1 = and == HEADER 2 == for headlines
<code></code> for blocks (or however to call the thing with the gray background color).
Starting point is above == Example output ==

I hope the copy/paste of the file in here did not destroyed in the indenting (file is appended too)

Avidemux will try to contact AvsProxy over the socket on port 9999, if not further specified or the default value is modified.

== Specify the  used port ==
Per default Avidemux and AvsProxy will communicate via the default port 9999. This can be modified using a command line parameter or set a different default port in the settings of Avidemux.The later  only modifies the used port where Avidemux tries to connect to.
The default port and if Avidemux ask, can be influence within the settings:
<img>The one in the attachment</img>
If always ask is selected, it will use the given port. If not the default port will be used, as long as no command line option is given.

To specify the port via command line use:
    <i>--avisynth-port</i> for Avidemux
and
    <i>--port</i> for AvsProxy


In the current state, avsproxyGui is not able, to modify the port at all and can only serve the data on port 9999
== Example output ==


The rest should be placed somewhere above the credits or so


= Helper scripts =
Some scripts which can simplify the workflow
== Avisynth Start after Edit ==
Written, tested and in use under Linux. It might work under windows with the help of cygwin/mingw/... too (don't forget to remove the wine prefix).
This script first calls the assigned editor and afterwards AvsProxy.
The port to use can be specfied with <i>--port</i>

To get the script up, set AVSSPROXY_PATH to the path, where avsproxy.exe is placed
<code>
#!bin/bash
EDITOR="vim"
AVSPROXY_PATH="/path/to/avsproxy.exe"
DEFAULT_PORT=9999
if [ $# -eq 3 ];then
        parA=$(echo $1 | tr A-Z a-z)
        if [ "$parA" = "--port" ]; then
                shift
                if [ ! -z "$1" -a "$1" -eq "$1" 1> /dev/null ];then
                        if [ $1 -lt 0 ];then
                                echo "Port Is not allowed t obe less then zero!"
                                exit 2
                        fi
                        port=$1
                else
                        echo "$1 is not a number"
                        exit 2
                fi
        else
                echo "unkown parameter given"
                exit 2
        fi
        shift
else
        port=$DEFAULT_PORT
fi

if [ $# -eq 1 ]; then
       $EDITOR $1
        wine $AVSPROXY_PATH --port $port $1
else
        printf "\t$0\t[--port PORT_NUMBER]\tFILE\n"
        exit 2
fi
</code>

== Run a queue of MpegTs  process with automatic port determination ==
!! IMPORTANT PRE NOTE !!
The calling script has not been translated to make use of avidemux 2.6 yet!  Use version 2.5 (apply the patches given in here: http://avidemux.org/smuf/index.php/topic,10686.0.html as they have never been added to the upstream code)


To simplify the batch process the following two scripts can be used. The first is the calling process. The second a port arbiter, which offers a range of ports, which can be used and must be given free it's after usage.
As the second script is written in python, it must be installed on the system and started, before the calling script is triggered.
The calling script was meant to be used under linux and makes use of netcat, which must be installed on the system.

In addition to the needs, there must have been done some preparations:
* Split of audio and video with [url=http://neuron2.net/dgmpgdec/dgmpgdec.html]DGIndex[/url]
* Generation of the avisynth scripts
* Generation of the Avidemux run script (Don't forget to remove the audio/video source part in here)
* Modify the source and output definitions at the bottom of the script accordingly:
    <i>encode</i> Specifies an encoding with 4 parameters:
     $1 = Input avisynth script
     $2 = First frame to store
     $3 = Last frame to store
     $4 = Filename
=== Calling script ===
<code>
AVSPROXY_PATH="/path/to/avsproxy.exe"
NC_COMMAND="nc localhost 9998"
CMD_REQUEST="request_port"
CMD_RELEASE="release_port"

# create the avisynth input file
AVS_INPUT="avsInput"
i=1
while [ -e ${AVS_INPUT} ]; do
    AVS_INPUT="avsInput$i"
    let i=$i+1
done

function checkBasePara(){
        if [ ${BASE_FOLDER:0:1} = "~" ];then
                BASE_FOLDER=$HOME${BASE_FOLDER:1}
        fi
}

function run(){
        wine AVSPROXY_PATH --port $PORT $1".avs" & sleep 10
        avidemux2_cli ${AVS_INPUT} --avisynth-port $PORT --external-mp3 $1" "*.mp2 --begin $2 --end $3 --run $JS_FILE --output-format ${OUTPUT_CONTAINER} --save $BASE_FOLDER"/"$4"${OUTPUT_POSTFIX}"
        echo  $CMD_RELEASE $PORT | $NC_COMMAND
}
function encode(){
        PORT=$(echo $CMD_REQUEST | $NC_COMMAND)
        run $1 $2 $3 $4 &
}

## output definitions
OUTPUT_CONTAINER="Matroska"
OUTPUT_POSTFIX=".mkv"
BASE_FOLDER="/where/the/should/be/written/to"
# The Avidemux script to call
JS_FILE="cosmo.js"
# A prefix
checkBasePara


## source definitions
# e.g. convert the Example script within the following frame ranges and store it to ex1 to ex3: [0-123], [42-4711] and [12-3456]
encode Example   0  123    ex1
encode Example  42 4711 ex2
encode Example  23 3456 ex3

rm ${AVS_INPUT}
<code>

=== Port arbiter ===
Only allow access to one port at a time.
If more process request a port, as currently available, the requests without a response will block (delay until there is a port free)
<code>
import sys
import socket

def sendAndClose(client, data):
        client.sendall((str(data)+"\n").encode())
        client.shutdown(socket.SHUT_RDWR)
        client.close()

#Command definition
CMD_GETPORT          = "request_port"
CMD_RELEASEPORT      = "release_port"
CMD_SETPORT_COUNT    = "set_portcount"
CMD_SETPORT_FIRST    = "set_firstport"
CMD_GETPORT_COUNT    = "get_portcount"
CMD_GETPORT_FIRST    = "get_firstport"
CMD_GETPORT_FREE     = "get_freeports"
CMD_GETPORT_FREE_CNT = "get_freeport_cnt"
CMD_HELP             = "help"
CMD_EXIT             = "exit"


def determineLongestCmd():
        maxLength = len(CMD_GETPORT)
        cur = len(CMD_RELEASEPORT)
        if maxLength < cur:
                maxLength = cur
        cur = len(CMD_SETPORT_COUNT)
        if maxLength < cur:
                maxLength = cur
        cur = len(CMD_SETPORT_FIRST)
        if maxLength < cur:
                maxLength = cur
        cur = len(CMD_GETPORT_COUNT)
        if maxLength < cur:
                maxLength = cur
        cur = len(CMD_GETPORT_FIRST)
        if maxLength < cur:
                maxLength = cur
        cur = len(CMD_GETPORT_FREE)
        if maxLength < cur:
                maxLength = cur
        cur = len(CMD_GETPORT_FREE_CNT)
        if maxLength < cur:
                maxLength = cur
        cur = len(CMD_HELP)
        if maxLength < cur:
                maxLength = cur
        cur = len(CMD_EXIT)
        if maxLength < cur:
                maxLength = cur
        return maxLength

def printCmd(cmd, description):
        cmd="\t"+cmd
        for i in range( len(cmd), determineLongestCmd()):
                cmd += " "
        cmd += "\t"+description+"\n"
        return cmd

PORT_IS_USED = True

DEFAULT_PORT_COUNT = 3
DEFAULT_FIRST_PORT = 6666

# local definitions
availablePorts = []
firstPort = DEFAULT_FIRST_PORT
waitingClients = []
usedPorts = {}

def getPort(client):
        portToUse = -1
        for i in range(0,len(availablePorts)):
                if availablePorts[i] != PORT_IS_USED:
                        availablePorts[i] = PORT_IS_USED
                        portToUse = firstPort + i
                        usedPorts[str(portToUse)] = i
                        break
        if portToUse != -1:
                client.sendall(str(portToUse).encode())
                client.shutdown(socket.SHUT_RDWR)
                client.close()
        else:
                waitingClients.insert(0,client)


def changePortCount(newCount, availablePorts):
        newPorts = []
        for i in range (0,newCount):
                if i < len(availablePorts):
                        newPorts.append(availablePorts[i])
                else:
                        newPorts.append(not PORT_IS_USED)
        return newPorts

# first part of the main; reading a different port argument
initPort = 9998
if (len(sys.argv)) > 1:
        try:
                p = int(sys.argv[1].strip())
                if p > 1023 and p < 65537:
                        initPort = p
        except:
                pass
availablePorts = changePortCount(DEFAULT_PORT_COUNT, availablePorts)

# bind the socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
        sock.bind(('localhost', initPort))
        sock.listen(5)

        # handle the connection
        while True:
                (client, port) = sock.accept()
                data =""
                data = client.recv(64)
                if (len(data) > 0):
                        data = str(data,'UTF-8').strip().lower()

                if data == CMD_GETPORT:
                        getPort(client)

                elif data[0:len(CMD_RELEASEPORT)] == CMD_RELEASEPORT:
                        remainingText = data[len(CMD_RELEASEPORT):].strip()
                        portIdx = usedPorts.pop(remainingText, -1)
                        if (portIdx == -1):
                                client.sendall(("Given port was not in use\n").encode())
                        elif (portIdx < len(availablePorts)):
                                availablePorts[int(portIdx)] = not PORT_IS_USED
                                if (len(waitingClients) != 0):
                                        getPort(waitingClients.pop())
                        client.shutdown(socket.SHUT_RDWR)
                        client.close()

                elif data == CMD_GETPORT_FIRST:
                        sendAndClose(client, firstPort)

                elif data[0:len(CMD_SETPORT_FIRST)] == CMD_SETPORT_FIRST:
                        remainingText = data[len(CMD_SETPORT_FIRST):].strip()
                        try:
                                p = int(remainingText)
                                if p > 1023 and p < 65537:
                                        firstPort = p
                                        client.shutdown(socket.SHUT_RDWR)
                                        client.close()
                                else:
                                        raise Exception
                        except:
                                sendAndClose(client,"The argument is not a valid port. Must be a value between 1024 and 65536")

                elif data == CMD_GETPORT_COUNT:
                        sendAndClose(client, len(availablePorts))

                elif data[0:len(CMD_SETPORT_COUNT)] == CMD_SETPORT_COUNT:
                        remainingText = data[len(CMD_SETPORT_COUNT):].strip()
                        try:
                                newCount = int(remainingText)
                                if newCount < 1:
                                        raise Exception
                                availablePorts = changePortCount(newCount, availablePorts)
                                client.close()
                        except:
                                sendAndClose(client, "Invalid new port count given. Must be a value > 0")

                elif data == CMD_GETPORT_FREE_CNT or data == CMD_GETPORT_FREE:
                        freePorts = []
                        for i in range (0,len(availablePorts)):
                                if (availablePorts[i] != PORT_IS_USED):
                                        freePorts.append(firstPort + i)
                        if data == CMD_GETPORT_FREE:
                                client.sendall(("available ports : ").encode())
                                if (len(freePorts) != 0) :
                                        client.sendall(str(freePorts[0]).encode())
                                        for i in range (1,len(freePorts)):
                                                client.sendall((", "+str(freePorts[i])).encode())
                                else :
                                        client.sendall(("none").encode())
                                sendAndClose(client, "")
                        else :
                                sendAndClose(client,len(freePorts))

                elif data == CMD_EXIT:
                        client.shutdown(socket.SHUT_RDWR)
                        client.close()
                        sock.close()
                        break


                else:
                        if data != CMD_HELP:
                                client.sendall(("Given argument '"+data+"' unkown!\n\n").encode())
                        sendAndClose(client,"The known commands are:\n"\
                                + printCmd(CMD_GETPORT,          "Get the next free port. Blocks if no port is free") \
                                + printCmd(CMD_RELEASEPORT,      "port_number \t Release port_number usage") \
                         + printCmd(CMD_GETPORT_FIRST,    "Returns the lowest port number") \
                                + printCmd(CMD_SETPORT_FIRST,    "port_number \t Set the lowest port to use. Used ports are not affected.") \
                                + printCmd(CMD_GETPORT_COUNT,    "Returns amount of ports which can be used at once.") \
                                + printCmd(CMD_SETPORT_COUNT,    "new_port_count \t Set the amount of useable ports. ") \
                                + printCmd(CMD_GETPORT_FREE,     "display the available ports") \
                                + printCmd(CMD_GETPORT_FREE_CNT, "display the available port count") \
                                + printCmd(CMD_HELP,             "Prints this help") \
                                + printCmd(CMD_EXIT,             "Exit the server") \
                        )





# close the socket
except:
        print("Fehler")
        traceback.print_exec()
        pass
sock.close()
</code>

mean