Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

Domains: forum.doom9.org / forum.doom9.net / forum.doom9.se

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 15th May 2009, 08:49   #1  |  Link
tin3tin
Registered User
 
tin3tin's Avatar
 
Join Date: Mar 2005
Posts: 366
How to open a (EDL)text file and parse it?

I been thinking about how to open a text file and how to parse it afterwards - things which would be useful for working with .edl or unsupported subtitle formats directly in avisynth script.

Some years ago avisynth strings seemed to be able to hold a limited number of characters, now it seems to be higher(anyone know how many?). Anyway this opens a possibility to work with huge scripts as strings which can be executed with the Eval command. So that part seems to be possible.

However I can't find a way to load/read/import a text file into a string. And then run through the string - until the end of the string - parsing it on a line by line basis.

Ex. script(not working):
Code:
My_edl_string=ImportString("My_edl_file.edl")

My_edl_script=""#global variable the final avisynth script

My_edl_script=ParseString(My_Parser, My_edl_string)# Run through string and apply the named function to a line at a time until the end of the string.

function My_Parser(string CurrentLine)
{
findstr(CurrentLine, "avi")=0 ? :My_edl_script=My_edl_script&"Directshowsource("&chr(34)&CurrentLine&chr(34)&")"#example adding of parser script to My_edl_script
}

Eval(My_edl_string)# And finally convert the the generated script into a clip.
Well as you can see I'm missing idears for ways to import textfiles into a string and also parse the string one line at the time until the end of the string.

I guess if I somehow could count the number of line breaks in the string I could make a blankclip with a length of that number and use animate to call the parser function for each line, but how would I get it to count the number of line breaks and also how would I get the parser function to find and parse the line with the animated frame corresponding number?
__________________
DVD slideshow GUI(Freeware).

Last edited by tin3tin; 24th August 2012 at 07:21.
tin3tin is offline   Reply With Quote
Old 15th May 2009, 12:37   #2  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,442
The script language provides no primitives for reading files, but it would be trivial to implement ImportString as a plugin function in C++ - just read the file contents into a buffer and return it as a string.

Tasks like parsing, unless the format is very simple, are probably best handled by a plugin too.
If you really want to do it in the script language, the outer part (looping over the lines) is relatively simple using a recursive function.
Pseudocode:
Code:
function ParseLines(string text) {
  if (text contains NL) #use findStr( text, chr(10))
    Parse(leftStr(...)) + ParseLines(rightStr(...))
  else
    Parse(text)
}
Personally (YMMV), I would go for combining the whole thing into a single plugin which both reads the file and parses its contents.
Gavino is offline   Reply With Quote
Old 15th May 2009, 14:27   #3  |  Link
tin3tin
Registered User
 
tin3tin's Avatar
 
Join Date: Mar 2005
Posts: 366
I'm still close to nowhere when it comes to C++, so pluginwriting is out of my limits.

Actually a part of what I'm after has allready been worked on here: An EDL2AVS converter - it was never finished. It imports all source clips with DirectShowSource. I guess most people would like to be able to change how source clips are imported. Ex. if the source clip is a .avs you would want to use 'Import' instead.

What I'm dreaming of is a way to simplify the link between a NLE GUI and avisynth script and some sort of EDL parser would make that process much easier. So I'm thinking why not use the EDL format most NLEs are using for that purpose? Info on the EDL format here.

The reason for keeping the string importer and the string parser separate is that you then could code a string inside your script you would want to parse.

And the reason for having the parser separate from the 'Eval' is of course that you could edit it or writetofile and such.

Here is an edl importer for Blender written in python.
__________________
DVD slideshow GUI(Freeware).

Last edited by tin3tin; 15th May 2009 at 14:32.
tin3tin is offline   Reply With Quote
Old 17th May 2009, 20:48   #4  |  Link
tin3tin
Registered User
 
tin3tin's Avatar
 
Join Date: Mar 2005
Posts: 366
Well, I've been trying to figure the C++ stuff out, but it takes time to figure the most simple things out when you're trying to figure a new coding language out. And this compiling stuff is no fun for a noob like me...

Anyway, I've come across this C++ EDL to AAF project - which might be giant step forward for someone with some C++ knowledge in making a EDLsource plugin for avisynth. It seems to come down to change the aaf stuff to avisynth commands and then output it as a video clip(There are EDL examples included in the EDLaaf download).

Link here.
__________________
DVD slideshow GUI(Freeware).
tin3tin is offline   Reply With Quote
Old 17th May 2009, 23:14   #5  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,442
If you're not comfortable using C++, why not try a different approach? Use a language you are familiar with to write a standalone EDL to AVS converter whose output is an Avisynth script.

It may be less user-friendly than doing the conversion directly inside Avisynth, but doing it this way will let you concentrate on the details of the task rather than fighting with an unfamiliar language. At some later point, when you are more proficient in C++, you could then rewrite the program in that language using the experience gained the first time around, and convert it to a plugin.
Gavino is offline   Reply With Quote
Old 18th May 2009, 10:23   #6  |  Link
tin3tin
Registered User
 
tin3tin's Avatar
 
Join Date: Mar 2005
Posts: 366
My DVD slideshow GUI is basically an Avisynth script generator for making slideshows(GUI in wxBasic). However the resulting scripts have become insanely complicated and therefore not really the way to progress if you would want to make an NLE like gui for Avisynth.

I should get started learning some C++ and I'm working on it. And so far I've figured out how to load the edl file into the buffer n C++.

The two links above is sourcecode for edl to blender written in python (like AvsP) and the sourcecode for edl to aaf in C++.
__________________
DVD slideshow GUI(Freeware).
tin3tin is offline   Reply With Quote
Old 25th August 2012, 06:59   #7  |  Link
tin3tin
Registered User
 
tin3tin's Avatar
 
Join Date: Mar 2005
Posts: 366
With StainlessS' new RT_Stats plugin it is now possible to read and pass textfiles, so I had to try to write up a proof of concept import of EDL script. It only reads video clips with cuts for now.
I think working with arrays are needed to just open videofiles once and to pass the various functions. Let me know if you have some ideas on how to pass the lines in a clever way.

Code:
# Load a CMX formatted EDL into Avisynth
# As a proof of concept here's a script reading the video clips with cuts and pass them to avs script which finally is eval'ed and a clip is returned.
# Gscript by Gavino and RT_Stats by StainlessS is needed.

#~ THE EDL FORMAT
    #~ Comments can appear at the beginning of the EDL file (header) or between the edit lines in the EDL. The first block of comments in the file is defined to be the header comments and they are associated with the EDL as a whole. Subsequent comments in the EDL file are associated with the first edit line that appears after them.
    #~ Edit Entries
    #~ <filename|tag>  <EditMode>  <TransitionType>[num]  [duration]  [srcIn]  [srcOut]  [recIn]  [recOut]
    #~ * <filename|tag>: Filename or tag value. Filename can be for an MPEG file, Image file, or Image file template. Image file templates use the same pattern matching as for command line glob, and can be used to specify images to encode into MPEG. i.e. /usr/data/images/image*.jpg
    #~ * <EditMode>: 'V' | 'A' | 'VA' | 'B' | 'v' | 'a' | 'va' | 'b' which equals Video, Audio, Video_Audio edits (note B or b can be used in place of VA or va).
    #~ * <TransitonType>: 'C' | 'D' | 'E' | 'FI' | 'FO' | 'W' | 'c' | 'd' | 'e' | 'fi' | 'fo' | 'w'. which equals Cut, Dissolve, Effect, FadeIn, FadeOut, Wipe.
    #~ * [num]: if TransitionType = Wipe, then a wipe number must be given. At the moment only wipe 'W0' and 'W1' are supported.
    #~ * [duration]: if the TransitionType is not equal to Cut, then an effect duration must be given. Duration is in frames.
    #~ * [srcIn]: Src in. If no srcIn is given, then it defaults to the first frame of the video or the first frame in the image pattern. If srcIn isn't specified, then srcOut, recIn, recOut can't be specified.
    #~ * [srcOut]: Src out. If no srcOut is given, then it defaults to the last frame of the video - or last image in the image pattern. if srcOut isn't given, then recIn and recOut can't be specified.
    #~ * [recIn]: Rec in. If no recIn is given, then it is calculated based on its position in the EDL and the length of its input.
    #~ [recOut]: Rec out. If no recOut is given, then it is calculated based on its position in the EDL and the length of its input. first frame of the video. 
    #~ For srcIn, srcOut, recIn, recOut, the values can be specified as either timecode, frame number, seconds, or mps seconds. i.e.
    #~ [tcode | fnum | sec | mps], where:
    #~ * tcode : SMPTE timecode in hh:mm:ss:ff
    #~ * fnum : frame number (the first decodable frame in the video is taken to be frame 0).
    #~ * sec : seconds with 's' suffix (e.g. 5.2s)
    #~ * mps : seconds with 'mps' suffix (e.g. 5.2mps). This corresponds to the 'seconds' value displayed by Windows MediaPlayer.

# Example from Lightworks
    #~ TITLE: Edit #1   FORMAT: CMX3600
    #~ 001  VJ0K006W V    C         00:00:19:05 00:00:41:07 00:00:00:00 00:00:22:02
    #~ 002  E00B00CU AA   C         00:00:19:05 00:00:41:07 00:00:00:00 00:00:22:02
     #~ COMMENT: AUDIO MAPPING   FROM CH1 TO CH2
    #~ 003  VJ0K006W V    C         00:00:00:00 00:00:18:18 00:00:22:02 00:00:40:20
    #~ 003  900      V    D    025  00:00:01:00 00:00:03:06 00:00:40:20 00:00:43:01
    #~ 004  E00B00CU AA   C         00:00:00:00 00:00:19:05 00:00:22:02 00:00:41:07
     #~ COMMENT: AUDIO MAPPING   FROM CH1 TO CH2
    #~ 005  E00B00CU AA   C         00:00:34:12 00:00:36:06 00:00:41:07 00:00:43:01
     #~ COMMENT: AUDIO MAPPING   FROM CH1 TO CH2
    #~ 006     BL    AA/V C         00:00:00:00 00:00:22:02 00:00:43:01 00:01:05:03

loadplugin("gscript.dll")
loadplugin("RT_Stats.dll")

MY_EDL="Edit.edl"                                                                  # The Edl file to be converted
MY_DIRECTORY="C:\MATERIAL\"                                                 # Where the sourcefiles are located
MY_EXTENTION="AVI"                                                               # The extention of all the source files
MY_FPS=25                                                                              # FPS for the project
blankclip(1,20,20)

EDL2AVS( MY_EDL, MY_DIRECTORY, MY_EXTENTION, MY_FPS)

function EDL2AVS(MY_EDL, MY_DIRECTORY, MY_EXTENTION, MY_FPS)
{
GScript("""
    MY_AVSSCRIPT=""+chr(13)+chr(10)
    EDLLIST=RT_ReadTxtFromFile(MY_EDL)                    # Read the EDL file
    LINESNR=RT_TxtQueryLines(EDLLIST)                     # Query Number of lines in String.

        CLIPNR=0
        For(i=0,LINESNR-1) {                               #Count video clips
            LINE=RT_TxtGetLine(EDLLIST,i)                     # Get one line at a time
            if (FindStr(RightStr(LINE,StrLen(LINE)-4)," V    C")>0){
             CLIPNR=CLIPNR+1
            }
        }
        if (CLIPNR>0) {MY_AVSSCRIPT=MY_AVSSCRIPT+"video = "+CHR(92)+chr(13)+chr(10)}    # Add Video first line    

        CLIPCNT=1
        For(i=0,LINESNR-1) 
        {
            LINE=RT_TxtGetLine(EDLLIST,i)                     # Get one line at a time
            #if ( LeftStr(LINE,4)==string(int(value(LeftStr(LINE,4)))) ) 
            #{          
                if (FindStr(RightStr(LINE,StrLen(LINE)-4)," V    C")>0){          # Find Vide and Cut
                    IMPFILE=MidStr(LINE,6,FindStr(RightStr(LINE,StrLen(LINE)-4)," V    C")-2)
                    HI=VALUE(MidStr(LINE,FindStr(LINE, "         ")+9,2))         # Read the INPOINT
                    MI=VALUE(MidStr(LINE,FindStr(LINE, "         ")+9+3,2))
                    SI=VALUE(MidStr(LINE,FindStr(LINE, "         ")+9+6,2))
                    FI=VALUE(MidStr(LINE,FindStr(LINE, "         ")+9+9,2))
                    INPOINT=tc(INT(HI), INT(MI), INT(SI), INT(FI), MY_FPS)
                    HO=VALUE(MidStr(LINE,FindStr(LINE, "         ")+9+12,2))      # Read the OUTPOINT
                    MO=VALUE(MidStr(LINE,FindStr(LINE, "         ")+9+15,2))
                    SO=VALUE(MidStr(LINE,FindStr(LINE, "         ")+9+18,2))
                    FO=VALUE(MidStr(LINE,FindStr(LINE, "         ")+9+21,2))
                    OUTPOINT=tc(INT(HO), INT(MO), INT(SO), INT(FO), MY_FPS)                    
                    MY_AVSSCRIPT=MY_AVSSCRIPT+"DirectshowSource("+CHR(34)+MY_DIRECTORY+IMPFILE+"."+MY_EXTENTION+CHR(34)+").TRIM("+string(INPOINT)+","+string(OUTPOINT)+")"
 
                     IF (CLIPCNT<CLIPNR) 
                     {
                              MY_AVSSCRIPT=MY_AVSSCRIPT+" + "+CHR(92)+chr(13)+chr(10)
                              CLIPCNT=CLIPCNT+1
                     } else if (CLIPCNT==CLIPNR){MY_AVSSCRIPT=MY_AVSSCRIPT+chr(13) + chr(10)}             
                }     
            #}
        }
        if (CLIPCNT>1) {MY_AVSSCRIPT=MY_AVSSCRIPT+"Video"+chr(13) + chr(10)} 
        
        return geval(MY_AVSSCRIPT)                        
""")
#WriteFileStart("MY_AVSSCRIPT.txt", """ MY_AVSSCRIPT """)
}


Function tc(int h, int m, int s, int f, int fps)
{
mt = h*60+m
todrop = (mt/10)*18 + ((mt%10==0) ? 0 : 2*(mt%10-1))
result = (mt*60+s)*fps+f - todrop
return result
}
Example EDL from Lightworks:
Code:
TITLE: Edit #1   FORMAT: CMX3600
001  VJ0K006W V    C         00:00:19:05 00:00:41:07 00:00:00:00 00:00:22:02
002  E00B00CU AA   C         00:00:19:05 00:00:41:07 00:00:00:00 00:00:22:02
 COMMENT: AUDIO MAPPING   FROM CH1 TO CH2
003  VJ0K006W V    C         00:00:00:00 00:00:18:18 00:00:22:02 00:00:40:20
003  900      V    D    025  00:00:01:00 00:00:03:06 00:00:40:20 00:00:43:01
004  E00B00CU AA   C         00:00:00:00 00:00:19:05 00:00:22:02 00:00:41:07
 COMMENT: AUDIO MAPPING   FROM CH1 TO CH2
005  E00B00CU AA   C         00:00:34:12 00:00:36:06 00:00:41:07 00:00:43:01
 COMMENT: AUDIO MAPPING   FROM CH1 TO CH2
006     BL    AA/V C         00:00:00:00 00:00:22:02 00:00:43:01 00:01:05:03
For testing - just change VJ0K006W to a video file(without extention) on your computer.
__________________
DVD slideshow GUI(Freeware).

Last edited by tin3tin; 25th August 2012 at 07:12.
tin3tin is offline   Reply With Quote
Old 25th August 2012, 13:34   #8  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
If working with larger strings, may come across this problem:
http://forum.doom9.org/showthread.php?t=164212

Shall also be adding a func to write a file.
As far as the RT_Stats thing is concerned, Chr(13) is removed on input from text file leaving only chr(10)
as the line separator.
However, internally it (RT_TxtGetLine & RT_TxtQueryLines) will use either Chr(13), Chr(10) or the pair of them
(in either order) as a separator.
When writing using Avisynth WriteFileStart, chr(10) will be replaced by Chr(13),Chr(10).
Never write Chr(10),Chr(13) sequence as a line separator for file output, notepad and other software
will get very confused if you do (EDIT: I think but not sure, that using Chr(13),Chr(10) in WriteFileStart
may result in Chr(13),Chr(13),Chr(10) on output, and a confused Notepad etc,check it out).

Might be best to avoid using Chr(13) and stick to Chr(10) only for everything.

Further:
RT_TxtGetLine strips Any Chr(13) or Chr(10) and return just a bare string.

Have implemented multi wildcards in extension for RT_WriteFileList, eg

"D:\VID\*.AVI|MP*G"
"D:\Pics\*.BMP|JP*G|PNG"

Next version.

EDITED:
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 25th August 2012 at 15:23.
StainlessS is online now   Reply With Quote
Old 26th August 2012, 20:38   #9  |  Link
tin3tin
Registered User
 
tin3tin's Avatar
 
Join Date: Mar 2005
Posts: 366
Thank you again for your plugin! Doing this stuff would have been impossible without it. On Chr(13)+Chr(10). I'll have to check if geval/eval will work with only chr(10).
__________________
DVD slideshow GUI(Freeware).
tin3tin is offline   Reply With Quote
Old 26th August 2012, 21:40   #10  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
Eval works fine with just Chr(10), Dont know but guess that Avisynth strips Carriage Returns during script load,
they are not really necessary. (File read ops in text mode auto strip CR)
Have changed the QueryBorderCrop() thing to use Chr(10) (did use 13) for next release.
At the time I did that, was considering a sort of two dimensional array but cannot ensure that a user would
stick to that.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 29th August 2012 at 21:14.
StainlessS is online now   Reply With Quote
Old 27th August 2012, 01:46   #11  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
Update is here:
http://forum.doom9.org/showthread.php?t=165479
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 30th August 2012 at 15:17.
StainlessS is online now   Reply With Quote
Old 31st August 2012, 17:43   #12  |  Link
Zarxrax
Registered User
 
Join Date: Dec 2001
Posts: 1,228
tin3tin, not sure if you would be interested but I believe you can achieve an edl importer via a macro in Avspmod. Avspmod macros basically let you write code in Python and then create or modify an avs script with it. Python is generally considered to be a fairly easy language.
Zarxrax is offline   Reply With Quote
Old 10th September 2012, 20:09   #13  |  Link
tin3tin
Registered User
 
tin3tin's Avatar
 
Join Date: Mar 2005
Posts: 366
That might be an idea, however I can't code python. There is a Python script here for importing edl in Blender. So all the parsing is done in Python code all ready. What is left is to change the Blender commands to Avisynth.
__________________
DVD slideshow GUI(Freeware).
tin3tin is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 09:31.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.