Created
June 11, 2016 06:06
-
-
Save Fire-/2c3472619202cf6ae29dd26a8e0aa0d7 to your computer and use it in GitHub Desktop.
fps reflow alteration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### 0 | |
## Uses motion vectors to change the framerate of a file with motion blur instead of standard duplication or decimation | |
## Requires: | |
# ffmpeg | |
# vapoursynth http://www.vapoursynth.com/ | |
# ffms2 vs plugin https://github.com/FFMS/ffms2/blob/master/doc/ffms2-vapoursynth.md | |
# mvtools vs plugin https://github.com/dubhater/vapoursynth-mvtools | |
### 1 | |
## Snip the part you want, or use the whole file, either way | |
## if you do not need to snip, or to re-encode, omit this step. | |
# ffmpeg -ss 1 -i INPUT_FILE -ss 1 -force_key_frames "expr:gte(t,n_forced*2)" -c:a copy -c:v libx264 -preset ultrafast -qp 10 OUTPUT_FILE | |
### 2 | |
## get the duration of this file, you'll need it later | |
# ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 INPUT_FILE | |
# 28.775000 | |
## ^ = END_TIMESTAMP | |
### 3 | |
## replace file variable string with your output filename | |
## run this to generate your output file, replacing INPUT_FILE, END_TIMESTAMP, and FINAL_OUTPUT with tthe first file ( for audio ), the first file's duration ( from ffprobe ), and your designated output filename, respectively | |
# vspipe -p -y reflow.vpy - | ffmpeg -thread_queue_size 8192 -y -i pipe: -i INPUT_FILE -map 0:v:0 -map 1:a:0 -c:a copy -c:v libx264 -preset slow -crf 18 -force_key_frames "expr:gte(t,n_forced*2)" -to END_TIMESTAMP FINAL_OUTPUT.mp4 | |
### | |
import vapoursynth as vs | |
core = vs.get_core() | |
file = r'OUTPUT_FILE.mp4' # change this | |
destination_framerate = 40 # 40 for twitter | |
input_framerate = 60 # whatever your input framerate is supposed to be | |
source_framerate_numerator = int(input_framerate * 1e8) | |
source_framerate_denominator = int(1e8) | |
destination_framerate_numerator = int(destination_framerate * 1e4) | |
destination_framerate_denominator = int(1e4) | |
#TODO: feed from input argument if possible ( not possible with vspipe? ) | |
clip = core.ffms2.Source(source=file, seekmode=0) | |
# resize to 1080p because twitter can't consume 1440p | |
#TODO: only downscale if greater than 1080 | |
clip = core.resize.Lanczos(clip=clip, width=1920, height=1080) | |
# append 10s blank clip because of some dumb bug that stalls video track several seconds before end | |
#TODO: solve this a better way | |
clip = clip + core.std.BlankClip(clip) | |
# Needed because clip FPS is missing and assuming on the import screws the export framerate | |
clip = core.std.AssumeFPS(clip, fpsnum = source_framerate_numerator, fpsden = source_framerate_denominator) | |
print("Reflowing from ",source_framerate_numerator/source_framerate_denominator," fps to ",destination_framerate_numerator/destination_framerate_denominator," fps.") | |
# prepare mvtools "super" clip | |
sup = core.mv.Super(clip, pel=1, hpad=8, vpad=8) | |
# forward motion vector analysis | |
bvec = core.mv.Analyse(sup, blksize=4, isb=True , chroma=True, search=3, searchparam=1, truemotion=True) | |
# backward motion vector analysis | |
fvec = core.mv.Analyse(sup, blksize=4, isb=False, chroma=True, search=3, searchparam=1, truemotion=True) | |
# motion vector blurring | |
clip = core.mv.FlowBlur(clip, sup, bvec, fvec, blur=100, thscd2=12) | |
# motion vector reflow fps decimation | |
clip = core.mv.FlowFPS(clip, sup, bvec, fvec, num=destination_framerate_numerator, den=destination_framerate_denominator, thscd2=12, blend=False) | |
# block based fps decimation, if desired instead. Comment ^ if uncommented. | |
#clip = core.mv.BlockFPS(clip, sup, bvec, fvec, num=destination_framerate_numerator, den=destination_framerate_denominator, mode=3, thscd2=12) | |
# set the clip as ready to output for the receiving application. | |
clip.set_output() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment