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. |
![]() |
#1 | Link |
Registered User
Join Date: Jun 2007
Location: Washington, DC
Posts: 130
|
Cue Points / Frames
Is there a way to add a Cue Point to an Avisynth output? Basically I'm thinking of something like
Code:
a1=AviSource() a2=AviSource().AddCue('Starting a2') a1+a2 Alternatively, I could create my own, if I had a way to tell what frame I was on when a2 started, but that doesn't seem possible with the Avisynth scripting language (I'm thinking of an event that would be fired upon rendering, that's much more OOP-like). The end result could even just be a file with two columns, FrameNumber and event string (or timecode and event string). I don't think this is possible, but I'm continually amazed at what Avisynth can do, so I figured I'd ask. Thx, Tac |
![]() |
![]() |
![]() |
#2 | Link |
Registered User
Join Date: Sep 2005
Location: 100011110010001000001 10000011111111000001
Posts: 221
|
Maybe this will do the job (beware, I havent' actually tested it
![]() Code:
cue_text = "Starting a2" a1=AviSource() a2=AviSource() a2 = ScriptClip(a2, """ return current_frame > 0 \ ? last \ : last.WriteFile("cue_file.txt", "cue_text", flush=true) """) a1+a2
__________________
AVSLib, a free extension library for Avisynth. Current version: 1.1.0 (beta), 14/05/2007. [ Home page | Download page ] |
![]() |
![]() |
![]() |
#3 | Link |
Registered User
Join Date: Jun 2007
Location: Washington, DC
Posts: 130
|
Thanks! I had just found the Runtime Environment, but wasn't quite sure how to use to to achieve the cue points.
Can this be written as a function, e.g. Code:
a2.add_cue("a2") function add_cue(clip c, string cue_text) { ScriptClip(c, """ return current_frame > 0 \ ? last \ : last.WriteFile("cue_file.txt", cue_text, flush=true) """) } Hmm, may need some more time to think about this one, there's some interesting possibilities here. Thanks for getting me started. Tac |
![]() |
![]() |
![]() |
#4 | Link |
Registered User
Join Date: Sep 2005
Location: 100011110010001000001 10000011111111000001
Posts: 221
|
The problem is that cue_text must be a variable in script scope, not a function argument. In addition, if you observe carefully my example, you'll see that I have enclosed cue_text in quotes at the WriteFile call; you must pass the name of the variable in WriteFile, not the content of the variable.
Thus your example must be written and be used as follows: Code:
function add_cue(clip c, string script_var_name) { ScriptClip(c, """ return current_frame > 0 \ ? last \ : last.WriteFile("cue_file.txt", script_var_name, flush=true) """) } cue2 = "a2" cue3 = "a3" cue4 = "a4" a1 = AviSource() a2 = AviSource().add_cue("cue2") a3 = AviSource().add_cue("cue3") a4 = AviSource().add_cue("cue4") a1 + a2 + a3 + a4 Code:
function add_cue(clip c, string script_var_name, bool "clear") { keep = Default(clear, true) ScriptClip(c, """ return current_frame > 0 \ ? last \ : last.WriteFile("cue_file.txt", script_var_name, append=keep, flush=true) """) }
__________________
AVSLib, a free extension library for Avisynth. Current version: 1.1.0 (beta), 14/05/2007. [ Home page | Download page ] |
![]() |
![]() |
![]() |
#5 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
Since WriteFile already operates within the runtime environment, and has a convenient conditional variant, I think you can do away with ScriptClip and just write
Code:
function add_cue(clip c, string filename, string script_var_name, bool "keep") { keep = Default(keep, true) WriteFileIf(c, filename, "current_frame==0", script_var_name, append=keep, flush=true) } |
![]() |
![]() |
![]() |
#6 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
A further refinement - I think tac wanted the overall frame number to appear in the cue file too.
That's a bit trickier because the only place that info is known is at the end of the filter chain and we want it to be available to add_cue. However, the magic of AviSynth's run-time features comes to the rescue again. Extend add_cue to be: Code:
function add_cue(clip c, string filename, string script_var_name, bool "keep") { keep = Default(keep, true) WriteFileIf(c, filename, "current_frame==0", "cueFrame", script_var_name, append=keep, flush=true) } Code:
FrameEvaluate("cueFrame=current_frame") Code:
file="cue.txt" # might need to be full path name? text=": starting a2" a1=BlankClip(100).Subtitle("A1") a2=BlankClip(100).Subtitle("A2").add_cue(file, "text") a1+a2 FrameEvaluate("cueFrame=current_frame") For those new to this runtime stuff, it's important to realise that the variable cueFrame is not just set once at the end (where it would be equivalent to Framecount()), but is continuously updated for each frame of the complete video. Thus the relevant value is available to WriteFileIf (inside add_cue), to be written when the appropriate condition is triggered, (ie when rendering the first frame of the clip to which add_cue is applied). Last edited by Gavino; 30th May 2008 at 13:57. Reason: Added explanation |
![]() |
![]() |
![]() |
#7 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
To follow up my own post yet again (sorry), this version removes the nuisance that the cue text had to be passed indirectly as the name of a variable, as decribed by gzarkadas in post #4.
Code:
function add_cue(clip c, string filename, string cue, bool "keep") { keep = Default(keep, true) cue = chr(34)+cue+chr(34) WriteFileIf(c, filename, "current_frame==0", "cueFrame", cue, append=keep, flush=true) } |
![]() |
![]() |
![]() |
#8 | Link |
Resize Abuser
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
|
I opened up notepad and typed in ALT-034. nice its a ". would tripple quotes """ work instead of char(34)?
__________________
Mine: KenBurnsEffect/ZoomBox CutFrames Helped: DissolveAGG ColorBalance LQ Animation Fixer |
![]() |
![]() |
![]() |
#9 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
If you're asking could the line
Code:
cue = chr(34)+cue+chr(34) Code:
cue = """cue""" However, you've made me realise that it would be safer as Code:
cue = chr(34)+chr(34)+chr(34)+cue+chr(34)+chr(34)+chr(34) # triple-quote the string |
![]() |
![]() |
![]() |
#10 | Link |
Registered User
Join Date: Jun 2007
Location: Washington, DC
Posts: 130
|
I'm now trying to do the reverse of what I was going to do with this thread. Basically I'm implementing a closed caption system, and was planning to use ConditionalReader to do so, but it appears that the only types for ConditionalReader are book, int and float. I'm surprised, I would have thought strings would be easy to implement, e.g.
file.txt Code:
Type string Default "" (or just nothing) R 10 180 First Caption R 185 250 Second Caption Code:
ScriptClip("subtitle(myvar)") ConditionalReader("file.txt", "myvar", false) Thx, Tac |
![]() |
![]() |
![]() |
#11 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
Quote:
Having said that, it certainly wouldn't be beyond the wit of man... Last edited by Gavino; 7th July 2008 at 20:17. |
|
![]() |
![]() |
![]() |
#12 | Link | |
Registered User
Join Date: Sep 2005
Location: 100011110010001000001 10000011111111000001
Posts: 221
|
Quote:
1. Put all your captions in a multiline string starting with an empty line (that is hit <Enter> after the opening three doublequotes): Code:
global captions = """ First Caption Second Caption ... N-th Caption """ Code:
Type int Default 0 R 10 180 1 R 185 250 2 Code:
LoadLibrary("avslib") ... #assumes global captions is set by the code-snippet above ... dummy = ArraySetDelimiter(CRLF) ScriptClip("subtitle(captions.ArrayGet(myvar))") ConditionalReader("file.txt", "myvar", false)
__________________
AVSLib, a free extension library for Avisynth. Current version: 1.1.0 (beta), 14/05/2007. [ Home page | Download page ] |
|
![]() |
![]() |
![]() |
#13 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
Nice solution, gzarkadas.
Is there a possible overhead in adding empty subtitles? If so, it might be faster to use Code:
... ScriptClip("myvar > 0 ? subtitle(captions.ArrayGet(myvar)) : last") ... |
![]() |
![]() |
![]() |
#14 | Link | |
Registered User
Join Date: Sep 2005
Location: 100011110010001000001 10000011111111000001
Posts: 221
|
Quote:
![]()
__________________
AVSLib, a free extension library for Avisynth. Current version: 1.1.0 (beta), 14/05/2007. [ Home page | Download page ] |
|
![]() |
![]() |
![]() |
#15 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
Quote:
Of course, the real test is for tacman1123 to try it out and if it's fast enough for him, then fine. ![]() And if he wants most frames to end up with captions, my 'optimisation' won't help anyway. ![]() |
|
![]() |
![]() |
![]() |
#16 | Link |
Registered User
Join Date: Jun 2007
Location: Washington, DC
Posts: 130
|
@gzarkadas: What's the limit on ArrayCreate()? Even using the \ at the end of a line, I run into a problem with a 107 element array (strings total about 2000 characters).
Also, I'm getting the error that ArraySetDelimiter isn't found, is that a different version? I'm using the latest, 1-1-0 beta. Thanks, this method appears to be working for me, using a global captions=ArrayCreate("one", "two", etc.) This fails: Code:
LoadLibrary("avslib", CONFIG_AVSLIB_FULL) global captions=ArrayCreate("Scn 1 (0-19)", \ "Scn 2 (20-29)", \ "Scn 3 (30-31)", \ "Scn 4 (32-51)", \ "Scn 5 (52-54)", \ "Scn 6 (55-55)", \ "Scn 7 (56-56)", \ "Scn 8 (57-76)", \ "Scn 9 (77-99)", \ "Scn 10 (100-100)", \ "Scn 11 (101-101)", \ "Scn 12 (102-103)", \ "Scn 13 (104-109)", \ "Scn 14 (110-110)", \ "Scn 15 (111-111)", \ "Scn 16 (112-113)", \ "Scn 17 (114-114)", \ "Scn 18 (115-115)", \ "Scn 19 (116-123)", \ "Scn 20 (124-146)", \ "Scn 21 (147-176)", \ "Scn 22 (177-202)", \ "Scn 23 (203-204)", \ "Scn 24 (205-206)", \ "Scn 25 (207-208)", \ "Scn 26 (209-210)", \ "Scn 27 (211-212)", \ "Scn 28 (213-214)", \ "Scn 29 (215-216)", \ "Scn 30 (217-218)", \ "Scn 31 (219-220)", \ "Scn 32 (221-222)", \ "Scn 33 (223-224)", \ "Scn 34 (225-226)", \ "Scn 35 (227-228)", \ "Scn 36 (229-230)", \ "Scn 37 (231-231)", \ "Scn 38 (232-232)", \ "Scn 39 (233-243)", \ "Scn 40 (244-245)", \ "Scn 41 (246-246)", \ "Scn 42 (247-247)", \ "Scn 43 (248-253)", \ "Scn 44 (254-259)", \ "Scn 45 (260-273)", \ "Scn 46 (274-294)", \ "Scn 47 (295-295)", \ "Scn 48 (296-296)", \ "Scn 49 (297-298)", \ "Scn 50 (299-299)", \ "Scn 51 (300-300)", \ "Scn 52 (301-301)", \ "Scn 53 (302-303)", \ "Scn 54 (304-304)", \ "Scn 55 (305-305)", \ "Scn 56 (306-306)", \ "Scn 57 (307-307)", \ "Scn 58 (308-338)", \ "Scn 59 (339-341)", \ "Scn 60 (342-343)", \ "Scn 61 (344-344)", \ "Scn 62 (345-345)", \ "Scn 63 (346-346)", \ "Scn 64 (347-348)", \ "Scn 65 (349-349)", \ "Scn 66 (350-350)", \ "Scn 67 (351-351)", \ "Scn 68 (352-352)", \ "Scn 69 (353-353)", \ "Scn 70 (354-355)", \ "Scn 71 (356-356)", \ "Scn 72 (357-357)", \ "Scn 73 (358-358)", \ "Scn 74 (359-362)", \ "Scn 75 (363-364)", \ "Scn 76 (365-366)", \ "Scn 77 (367-367)", \ "Scn 78 (368-368)", \ "Scn 79 (369-371)", \ "Scn 80 (372-372)", \ "Scn 81 (373-373)", \ "Scn 82 (374-374)", \ "Scn 83 (375-375)", \ "Scn 84 (376-376)", \ "Scn 85 (377-379)", \ "Scn 86 (380-380)", \ "Scn 87 (381-381)", \ "Scn 88 (382-383)", \ "Scn 89 (384-384)", \ "Scn 90 (385-386)", \ "Scn 91 (387-390)", \ "Scn 92 (391-391)", \ "Scn 93 (392-393)", \ "Scn 94 (394-394)", \ "Scn 95 (395-395)", \ "Scn 96 (396-397)", \ "Scn 97 (398-398)", \ "Scn 98 (399-399)", \ "Scn 99 (400-400)", \ "Scn 100 (401-401)", \ "Scn 101 (402-413)", \ "Scn 102 (414-429)", \ "Scn 103 (430-433)", \ "Scn 104 (434-500)", \ "Scn 105 (501-509)", \ "Scn 106 (510-576)", \ "Scn 107 (577-6095)") # return a valid video clip colorbars.KillAudio() Last edited by tacman1123; 22nd November 2008 at 00:05. Reason: added code to script |
![]() |
![]() |
![]() |
#17 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
Quote:
Code:
global captions = """ First Caption Second Caption ... N-th Caption """ |
|
![]() |
![]() |
![]() |
#18 | Link |
Registered User
Join Date: Jun 2007
Location: Washington, DC
Posts: 130
|
No, although since I'm having a problem with the SetDelimiter call, I'm using ArrayCreate, e.g. ArrayCreate("one", "two" ...), but it fails as well. I thought at first it might be a line limit length in avisynth scripts, but couldn't find any documentation about that. Figured it'd be best to go with the \ format, since I could post it here without horizontal scrolling.
|
![]() |
![]() |
![]() |
#20 | Link |
Registered User
Join Date: Jun 2007
Location: Washington, DC
Posts: 130
|
The error is "Invalid Arguments to Function ArrayCreate()" I imagine there is some limit, and I've exceeded it, but perhaps I can figure out how to merge an array and add them in chunks. I've modified the script above to show the error if you run it, to see it work without the error simply remove a bunch of the middle elements.
A more significant issue is that Code:
a=a.ScriptClip("subtitle(captions.ArrayGet(myvar))") a.ConditionalReader(root + video_code + "_range.txt", "myvar", false) I had an idea about skipping the array and assigning each string a variable, but I can't figure out how to dynamically create a variable made up of a prefix and a number. That is, what I want to do is make scriptclip calls to subtitle(caption1), subtitle(caption2), etc. I can create caption1="one", etc., but am not sure how to get from myvar to "caption" + myvar, and have that new variable be evaluated. I think that's what I want to do. Tac |
![]() |
![]() |
![]() |
Thread Tools | Search this Thread |
Display Modes | |
|
|