Log in

View Full Version : changefps vapoursynth?


cheyrn
23rd November 2014, 01:40
I have had about 20 minutes exposure to vapoursynth. How can I do the equivalent of:

changefps(assumefps(clip, 23.999), 30)

I see AssumeFPS but not ChangeFPS.

TheFluff
23rd November 2014, 08:43
Vapoursynth doesn't have ChangeFPS because it doesn't want you to think about a "FPS". It has per-frame timestamps instead. AssumeFPS is just a silly name for a function that generates such timestamps.

If you really, really want to convert to a constant framerate you can either tell the source filter to output that, or you can write your own version. It should be sorta trivial, I'd start with generating a list of one timestamp per output frame at the desired framerate and then write a few lines of Python that selects the time with the closest timestamp in the input. Maybe someone's already done it.

Myrsloik
23rd November 2014, 13:50
I just haven't bothered to add such a filter since it's very specialized. Here's how you can currently do it using FrameEval, the general function that can do anything if you try hard enough. Here it's trying really hard.

import vapoursynth as vs
import functools
import math

target_fps_num = 30
target_fps_den = 1

core = vs.get_core()
source_clip = <somesource>
source_clip = core.std.AssumeFPS(source_clip, fpsnum=23999, fpsden=1000)

def frame_adjuster(n, clip, target_fps_num, target_fps_den):
real_n = math.floor(n / (target_fps_num / target_fps_den * clip.fps_den / clip.fps_num))
one_frame_clip = clip[real_n] * (len(clip) + 100)
return one_frame_clip

attribute_clip = core.std.BlankClip(source_clip, length=math.floor(len(source_clip) * target_fps_num / target_fps_den * source_clip.fps_den / source_clip.fps_num), fpsnum=target_fps_num, fpsden=target_fps_den)
adjusted_clip = core.std.FrameEval(attribute_clip, functools.partial(frame_adjuster, clip=source_clip, target_fps_num=target_fps_num, target_fps_den=target_fps_den))
adjusted_clip.set_output()

cheyrn
25th November 2014, 03:34
Thank you. I'm still chewing on that example.

How do I write a clip to the filesystem in some encoding? I tried adjusted_clip.output(f) where f is a file handle and the resulting file is data. But, I don't know what format.

Oh, passing y4m=True results in y4m format video. For example, adjusted_clip.output(f, y4m=True).

http://wiki.multimedia.cx/index.php?title=YUV4MPEG2

I was unaware of this format.

Oh oh. I think I am supposed to use vspipe. So, with adjusted_clip.set_output() and no output method call:

vspipe -y blah.vpy vlah.y4m
ffmpeg -i vlah.y4m rlah.mp4

foxyshadis
25th November 2014, 06:47
If you want to write to disk, you can also just use regular set_output() and open it in VirtualDub (GUI or command line) to save to your favorite VFW codec. You can export directly to VFW from Python, but since there's no plugins for it yet, that requires some serious Python & Win32 skills.

The main purpose of vspipe and y4m is piping, so you never hit the disk:
vspipe -y blah.vpy - | ffmpeg -i - rlah.mp4

cheyrn
25th November 2014, 21:01
How do I open the output in virtualdub? I thought set_output was like identifying the equivalent of "last" in avisynth. If I run a vapoursynth script with python nothing is produced as far as I can tell. If I use the output method something is output.

Or, if I am supposed to open the script as if it were an avs script. I named my script something.vpy andif I open it in virtualdub 1.10.4 it says AVI import error.

Mystery Keeper
25th November 2014, 22:07
How do I open the output in virtualdub? I thought set_output was like identifying the equivalent of "last" in avisynth. If I run a vapoursynth script with python nothing is produced as far as I can tell. If I use the output method something is output.

Or, if I am supposed to open the script as if it were an avs script. I named my script something.vpy andif I open it in virtualdub 1.10.4 it says AVI import error.
You ARE supposed to name the script .vpy and open it in VirtualDub (unless you're using vspipe). But mind that both VS and VD should be the same version: either 32 or 64 bits.