Skip to content

Commit

Permalink
New Main function VFRSplice()
Browse files Browse the repository at this point in the history
  • Loading branch information
mawen1250 committed Jul 24, 2016
1 parent 8d3f083 commit 71c293a
Showing 1 changed file with 96 additions and 1 deletion.
97 changes: 96 additions & 1 deletion mvsfunc.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
################################################################################################################################
## mvsfunc - mawen1250's VapourSynth functions
## 2016.04
## 2016.07
################################################################################################################################
## Requirments:
## fmtconv
Expand All @@ -11,6 +11,7 @@
## ToRGB
## ToYUV
## BM3D
## VFRSplice
################################################################################################################################
## Runtime functions:
## PlaneStatistics
Expand Down Expand Up @@ -1090,6 +1091,100 @@ def BM3D(input, sigma=None, radius1=None, radius2=None, profile1=None, profile2=
################################################################################################################################


################################################################################################################################
## Main function: VFRSplice()
################################################################################################################################
## Splice multiple clips with different frame rate, and output timecode file.
## Each input clip is CFR(constant frame rate).
## The output clip is VFR(variational frame rate).
################################################################################################################################
## Basic parameters
## clips {clip}: any number of clips to splice
## each clip should be CFR
## tcfile {str}: timecode file output
## default: None
## v2 {bool}: timecode format
## True for v2 output and False for v1 output
## default: True
## precision {int}: precision of time and frame rate
## a decimal number indicating how many digits should be displayed after the decimal point for a fixed-point value
## default: 6
################################################################################################################################
def VFRSplice(clips, tcfile=None, v2=None, precision=None):
# Set VS core and function name
core = vs.get_core()
funcName = 'VFRSplice'

# Arguments
if isinstance(clips, vs.VideoNode):
clips = [clips]
elif isinstance(clips, list):
for clip in clips:
if not isinstance(clip, vs.VideoNode):
raise TypeError(funcName + ': each element in \"clips\" must be a clip!')
if clip.fps_num == 0 or clip.fps_den == 0:
raise ValueError(funcName + ': each clip in \"clips\" must be CFR!')
else:
raise TypeError(funcName + ': \"clips\" must be a clip or a list of clips!')

if tcfile is not None and not isinstance(tcfile, str):
raise TypeError(funcName + ': \"tcfile\" must be a str!')

if v2 is None:
v2 = True
elif not isinstance(v2, int):
raise TypeError(funcName + ': \"v2\" must be a bool!')

if precision is None:
precision = 6
elif not isinstance(precision, int):
raise TypeError(funcName + ': \"precision\" must be an int!')

# Fraction to str function
def frac2str(num, den, precision=6):
return '{:<.{precision}F}'.format(num / den, precision=precision)

# Timecode file
if tcfile is None:
pass
else:
# Get timecode v1 list
cur_frame = 0
tc_list = []
index = 0
for clip in clips:
if index > 0 and clip.fps_num == tc_list[index - 1][2] and clip.fps_den == tc_list[index - 1][3]:
tc_list[index - 1] = (tc_list[index - 1][0], cur_frame + clip.num_frames - 1, clip.fps_num, clip.fps_den)
else:
tc_list.append((cur_frame, cur_frame + clip.num_frames - 1, clip.fps_num, clip.fps_den))
cur_frame += clip.num_frames
index += 1

# Write to timecode file
ofile = open(tcfile, 'w')
if v2: # timecode v2
olines = ['# timecode format v2\n']
frames = tc_list[len(tc_list) - 1][1] + 1
time = 0 # ms
for tc in tc_list:
frame_duration = 1000 * tc[3] / tc[2] # ms
for frame in range(tc[0], tc[1] + 1):
olines.append('{:<.{precision}F}\n'.format(time, precision=precision))
time += frame_duration
else: # timecode v1
olines = ['# timecode format v1\n', 'Assume {}\n'.format(frac2str(tc_list[0][2], tc_list[0][3], precision))]
for tc in tc_list:
olines.append('{},{},{}\n'.format(tc[0], tc[1], frac2str(tc[2], tc[3], precision)))
try:
ofile.writelines(olines)
finally:
ofile.close()

# Output spliced clip
return core.std.Splice(clips, mismatch=True)
################################################################################################################################





Expand Down

0 comments on commit 71c293a

Please sign in to comment.