Log in

View Full Version : Get filename from Clip?


zerowalker
8th January 2014, 05:00
How can i return the filename of a clip?
for example to turn:

Avisource("hello.avi")
to
hello

Guest
8th January 2014, 05:10
Mutate your thinking:

stream="hello.avi"
AviSource(stream)

Now you have the name in a variable as you need.

zerowalker
8th January 2014, 05:12
True, but i am trying to make a function that only makes use of the clip, else i would simply copy paste the file name and be done with it.

TurboPascal7
8th January 2014, 05:43
If you want something like:
function get_filename(clip c) { return some_way_to_get_the_filename(c) }
Give up. Unless the source filter you're using sets the filename as some global variable, you can't get it.
Why do you need this?

zerowalker
8th January 2014, 05:46
Well pretty much thatīs what i am trying to do.
Damn, thought it should be someway, i know how to get the script name and path through an error message,
and tried to find a way to make the avisource spit out an exception with the filename without luck.

I want it for simplicity, i am doing a function where i am retrieving date and time from the filename, and i donīt want to copy paste the filename each time, simply writing the function would do all the work.

vampiredom
8th January 2014, 06:17
i know how to get the script name and path through an error message

Actually, since 2.6, the error-method is not needed.
http://avisynth.nl/index.php/Internal_functions/Script_functions

zerowalker
8th January 2014, 06:27
Oh, well thatīs good.
hmm, is Avisource an internal function?
Meaning, i would have to ask an Avisynth developer to add "filename" variable?

vampiredom
8th January 2014, 06:36
Meaning, i would have to ask an Avisynth developer to add "filename" variable?

I do not think all that is really needed or advisable. Could you post your script? That might make it easier for someone to give you more specific advice on how you can do what you are trying to do.

innocenat
8th January 2014, 06:53
What happen when people pass you BlankClip? ColorBar? StackHorizontal? Overlay?

Guest
8th January 2014, 07:07
What happen when people pass you BlankClip? ColorBar? StackHorizontal? Overlay? Then it outputs BlankClip, ColorBar, StackHorizontal, or Overlay. :p

vampiredom
8th January 2014, 07:17
You know, not that it is remotely practical but ... you COULD encode the filename's chars into numeric values, then store these values as pixels in extra lines in the video then parse them back. :)

zerowalker
8th January 2014, 08:01
Here is the Script (Currently made so i have to write the filename as a string).

function TimeStamp(clip a,string filename,int DisplayTime)
{

err_msg=filename
filename3=RightStr(err_msg, FindStr(RevStr(err_msg), "\")-1)
#~ Blankclip(100).Subtitle(RightStr(filename3, 100), x=8, y=0, first_frame=0,font="Arial", size=18, text_color=$FFFF00, halo_color=$000000, align=7, spc=0, font_width=0.0, font_angle=0.0, interlaced=False)
gettime = RightStr(filename3,16)
time2 = LeftStr(gettime, StrLen(gettime) - 14)+":"+LeftStr(gettime, StrLen(gettime) - 11).RightStr(2)+":" +RightStr(gettime, StrLen(gettime) -6 ).LeftStr( StrLen(gettime)-14 )+":"
ms=Round(value(RightStr(filename3,7).LeftStr(3)))
date=RightStr(filename3, 27).LeftStr( StrLen(filename3)-27 )+"*"
framel=Ceil(FrameCount(a)*(1000/FrameRate(a)))+ms*2

#~ Blankclip(100).Subtitle(ms, x=8, y=0, first_frame=0,font="Arial", size=18, text_color=$FFFF00, halo_color=$000000, align=7, spc=0, font_width=0.0, font_angle=0.0, interlaced=False)

BlankClip(length=framel, width=344, height=50, pixel_type="YV12", fps=1000, fps_denominator=1, audio_rate=48000, channels=2, sample_type="16bit", color=$000000)
ShowSMPTE(offset=time2.RightStr( 10)+"00", font="Digital-7 Mono",x=90,y=22, size=32, text_color=$FFFFFF, halo_color=$000000, font_width=0.0, font_angle=0.0)
Subtitle(date, x=0, y=22, font="Digital-7 Mono", size=32, text_color=$FFFFFF, halo_color=$000000, align=7, spc=0, font_width=0.0, font_angle=0.0, interlaced=False)
Trim(ms,0).ShowTime(x=254,y=48,offset_f=0, font="Digital-7 Mono", size=32, text_color=$FFFFFF, halo_color=$000000, font_width=0.0, font_angle=0.0).ChangeFPS(30, linear=false)
c=last

DisplayTime <= 0 ? Eval("""
over=Overlay(a,c, x=10, y=10, opacity=1.0, mode="blend")
over.Subtitle(filename, x=400, y=5, first_frame=0,last_frame=300, font="Arial", size=35, text_color=$FFFF00, halo_color=$000000, align=7) ++ a.Trim(framecount(over),0)
""") : Eval("""
over=Overlay(a,c, x=10, y=10, opacity=1.0, mode="blend").Trim(0,Round((FrameRate(a)*DisplayTime)))
over.Subtitle(filename, x=400, y=5, first_frame=0, font="Arial", size=35, text_color=$FFFF00, halo_color=$000000, align=7) ++ a.Trim(framecount(over),0)
""")
}

EDIT:

The filename is supposed to be, X:\2013-12-22 00-41-10-168.xxx , you can have it in as much folders as you like, but it wonīt work with just the filename, it needs a path as well (as itīs how i currently made it).

ultim
8th January 2014, 09:31
You know, not that it is remotely practical but ... you COULD encode the filename's chars into numeric values, then store these values as pixels in extra lines in the video then parse them back. :)

Actually, there already are plugins using that approach to pass colorimetry hints. Not that I recommend it though. Obvious downsides are 1) complexity, 2) being destructive to the video (even if probably unnoticably), and 3) that no filter must be present that change pixels between such plugins, as they will destroy the information in the pixels.

IMHO, just use special variables (with well-distinguished names to avoid conflicts) for information passing. This approach is ofc also not perfect, like being unable to use the same variable for multiple clips with different property value. Hopefully avs+ will solve this in the future.

zerowalker
9th January 2014, 02:03
Okay i will ask the Developers, donīt think anyone actually cares, but i canīt see the hurt in adding one variable to Avisource, better ask than not i guess.


ultim: Wait, are you the Avisynth+ Developer?
If so, do you by any chance got time to add that function/variable, that just contains the filename and path?

Thanks

vampiredom
9th January 2014, 04:27
i canīt see the hurt in adding one variable to Avisource

You know, in concept, I do agree that being able to set custom clip properties would just about the handiest thing imaginable.

However, there would likewise be no harm (and a lot less complication) in you adding a filename parameter to your function ... and, unless I am misunderstanding something here, it looks like you already have.

function TimeStamp(clip a,string filename,int DisplayTime)

Also, if a is a clip, where is that clip coming from? I'm afraid I may be missing the obvious but I do not see the issue.

zerowalker
9th January 2014, 04:29
As you say, itīs 2 sides of the same coin or something.

Why i have added it in my function is because, itīs the only way.

But just writing: TimeStamp()
Would be much better.

I would gladly add it myself, but i am not a programmer of that caliber, we are talking extremely simple C# here.
Hence my option being to ask others, as shameful as it may be.

ultim
11th January 2014, 18:51
ultim: Wait, are you the Avisynth+ Developer?
If so, do you by any chance got time to add that function/variable, that just contains the filename and path?

Thanks

I would add it to Avs+, unfortunately I cannot because Avisynth(+) has no way to determine the source file name of a clip. From avisynth's point of view, frames of a clip just come from a blackbox (the filter), and only the filter knows where it gets its frames from. It is not an option to get the filename from the input arguments, because, likewise, Avisynth cannot know which argument contains the source filename - only the filter knows. There is a silent convention among filter developers that the first argument is the source file, but it actually does not need to be the case. Even if it were, Avs cannot really differentiate a source filter from a processing filter. And what if a source filter does not read from any file, like BlankClip?

So I cannot add such a variable that contains the source filename, because Avisynth itself honestly has no idea.

The only solution I see to this is if later new clip properties get added to clips. Then source filters could fill in the special property value that has the source path. But first this needs infrastructure support in Avs, which is planned but is currently totally missing, and after that all source filters will need to be modified to make use of this value.

zerowalker
12th January 2014, 07:42
Ah, so it's not possible to just modify Avisource and be done with it, All source filters use the same "path" so to speak?

If so, well that explains the hardship, i thought it would be way easier, pretty much just well, add a variable in Avisource and link it to the "Path" and then tell Avisynth that it exists in just Avisource.
But nice that it's someway under work, i can surely wait if it is this much madness to get it.

I can still use String, even if it isn't optimal, it's more convenient then the current work to get it working from the way you speak.

Thanks

ultim
12th January 2014, 14:51
Well, no, AviSource could be modified alone and then it would only work with AviSource. But without proper support in the core for clip properties, not even that would work correctly if you use multiple AviSource filters in the same script, so it wouldn't really be a step in the right direction. Also, the core should be free of filter-specific hacks.

zerowalker
12th January 2014, 14:55
Ah, well it's better for it to be done properly from ground then to use hacks, as it's pretty useless if it only works in some scenarios with no real guideline.

LoRd_MuldeR
13th January 2014, 04:10
The only solution I see to this is if later new clip properties get added to clips. Then source filters could fill in the special property value that has the source path.

Why not, similar to VapourSynth, make each clip store a map (i.e. a list of arbitrary key/value pairs) for the "meta info" stuff?

Then each filter, source filter or not, and even user functions could attach whatever info they like to the clip - rather than being limited to filling in only some pre-defined clip properties.

Of course there would be reserved keys for all the "standard" properties (width, height, fps, etc). And the old "fixed" clip properties would simply return the values for those keys.

vampiredom
13th January 2014, 04:13
Why not, similar to VapourSynth, add a map (i.e. a list of arbitrary key/value pairs) of "meta info" to each clip?

Best. Idea. Ever.

ultim
13th January 2014, 08:39
Why not, similar to VapourSynth, make each clip store a map (i.e. a list of arbitrary key/value pairs) for the "meta info" stuff?


That is exactly what we want to do. But I have only so much time, and first I'm finishing multi-threading support. Once that is done, we'll talk about what to tackle next.

martin53
18th January 2014, 21:03
I want it for simplicity, i am doing a function where i am retrieving date and time from the filename, and i donīt want to copy paste the filename each time, simply writing the function would do all the work.

While I absolutely appreciate future 'properties' extensions, please allow me to ask again why this specific function would be useful.

Because while it was useful to automatically determine 'a' filename, specifically the script name, in order to open e.g. a video source file with the same base name (I regularly use an AVS template for that purpose), I don't get the point why the clip source file name should be retrieved other than today from a function that is just part of the clip graph. I ask this because every avs script using an external clip contains the file name - namely in the source filter function parameter. A wrapper function like

function myAviSource(string name ...) { global gSourceClipName = name return AviSource(name...) }

will do this (and in fact my template has this functionality since it is also able to open playlists and display the names of the resp. clips as subtitles in a thumbsheet it can produce). The only difference is that the wrapper function can not be placed after the source filter.

If there really is a need to identify the name afterwards, because there is no access to the top part of the script, there is another, though clumsy workaround:

The Call plugin, together with SysInternal's Handle.exe CLI tool, allows to identify the files which are opened by the AVS viewer executable, e.g. AvsPmod. Unfortunately, the internally used kernel functions need administrator privilege, i.e. an AVS script which calls Handle.exe must be opened from a viewer which itself was opened with administrator privilege. There will be a bit more effort to identify the source clip among the files and return the string to the script, e.g through an intermediate file and RT_Stats.

StainlessS
19th January 2014, 00:36
I'm curious about how meta info would be handled via any filters, stripped or ortherwise handled.
What effect would say merge or crop have on meta data, or would meta data only be valid until
1st filter, would there be some kind of jumping upstream to derive some kinds of info from the
source filter. Sounds like a great idea, but not sure how practical.

TurboPascal7
19th January 2014, 07:20
Different clips should have different properties of course. You can't be sure if properties are valid across filter calls so you can't simply copy them.
Off the top of my head I see four solutions:
1) a script function like MergeProperties(a, b)
2) script-level properties, set on the ScriptEnvironment and global to this script
3) preservable properties, i.e. introducing a flag so that filter could specify some properties as preservable across filter calls when setting it (dangerous because who know what kind of filter will get called on you clip. Blankclip hardly preserves many properties for example). This also wastes memory.
4) recursive property getter. If a special flag is passed, child.GetPropery will try to search specified property on the child and if it's not found - any upstream clip of this child. It's not clear how to handle multiple upstream clips though as GenericVideoFilter knows only about one of those. Could simply ignore them or have some property merging function.

No idea which one is better (probably the 4th one?) or is there other solutions, additional thinking required.

vampiredom
19th January 2014, 16:14
No idea which one is better (probably the 4th one?) or is there other solutions, additional thinking required.

Call me crazy, but I would like preservable properties. A function like StripCustomProps() or some such could then be applied manually as needed.

As for the BlankClip() case [and others], perhaps it could be contextual? Like:

foo.BlankClip() # preserves properties
BlankClip(foo) # does not preserve properties

I know that is probably impossible but it illustrates how I picture these working.

Gavino
19th January 2014, 16:30
foo.BlankClip() and BlankClip(foo) are defined by the language to have exactly the same meaning.

vampiredom
19th January 2014, 16:56
foo.BlankClip() and BlankClip(foo) are defined by the language to have exactly the same meaning.

I know… or at least figured as much ;)

fvisagie
28th May 2014, 13:06
Pardon the late addition, but as this seems to be the definitive recent thread on the topic, allow me to add 2c.

While I absolutely appreciate future 'properties' extensions, please allow me to ask again why this specific function would be useful.

Because while it was useful to automatically determine 'a' filename, specifically the script name, in order to open e.g. a video source file with the same base name (I regularly use an AVS template for that purpose), I don't get the point why the clip source file name should be retrieved other than today from a function that is just part of the clip graph. I ask this because every avs script using an external clip contains the file name - namely in the source filter function parameter.

One major area of uses case is runtime. It's already possible to identify the current source frame at runtime. If in addition you can:

identify the current input file at runtime

then you can:

extract metadata for that frame and/or
look up externally stored metadata for that frame
and then you can:

"edit" subtitles without having to parse potentially complex script logic
generate new subtitle files
detect edits and generate scene change files, AvsPmod bookmarks and so on
etc.


Even without extracting or looking up metadata this ability will be very valuable for logging splices/scene changes in concatenated output (http://forum.doom9.org/showthread.php?p=1681933#post1681933) simply by detecting input file change-overs.

fvisagie
29th May 2014, 17:30
If in addition you can:

identify the current input file at runtime



It turns out that is actually currently possible (http://forum.doom9.org/showthread.php?p=1682255#post1682255).