Ejemplo n.º 1
0
def truncate(seq, **kwargs):
	""" truncate clips to absolute framerange. Everything outside start-end range will get dropped or clipped """
	start = get_frame(kwargs['start'], kwargs['fps'], kwargs['tc_start'])
	end = get_frame(kwargs['end'], kwargs['fps'], kwargs['tc_start'])	

	n = 0 # n stores length of previous clips combined
	h = seq.frame_amount() # default to trim head and tail fully
	t = seq.frame_amount()

	for clip in seq.clips:

		# Each clip can be described as line
		# frame = step * increment + offset

		offset = clip['start']
		inc = clip['increment']
		clip_len = get_clip_len(clip)

		# Solve steps where clip passes frames start and end
		t1 = ((start - offset) / float(inc))
		t2 = ((end - offset) / float(inc))

		# This is the range where t1,t2 solve and our clip overlap
		range_start = max(min(t1, t2), 0)
		range_end = min(max(t1, t2), clip_len - 1)

		# If range start and end are in logical order our clip contains frames that will survive the trimming
		# if several clips fit the bill, min() makes sure that we trim keeping as many of them as possible still in seq.
		if range_start <= range_end:
			h = min(h, n + int(ceil(range_start)))
			t = min(t, (seq.frame_amount() - 1) - (n + int(floor(range_end))))

		n += clip_len

	return h, t
Ejemplo n.º 2
0
def offset(seqlist, **kwargs):

	def offset_each(seq, amount):
		""" simple offset by X frames """
		def offset_clip(clip, amount):
			clip['start'] += amount
			clip['end'] += amount
			return clip
		ret_seq = copy.deepcopy(seq)
		try:
			ret_seq.clips = map(offset_clip, ret_seq.clips, [amount] * len(ret_seq.clips))
		except AttributeError:
			pass
		return ret_seq

	def calculate_offset(new, old):
		return new - old

	def offset_based_on_start(seqlist, new_start):
		ret = []
		for seq in seqlist:
			try:
				amount = calculate_offset(new_start, seq.clips[0]['start'])
				ret.append(offset_each(seq, amount))
			except AttributeError:
				ret.append(seq)

		return ret

	def offset_based_on_end(seqlist, new_end):
		ret = []
		for seq in seqlist:
			try:
				amount = calculate_offset(new_end, seq.clips[-1]['end'])
				ret.append(offset_each(seq, amount))
			except AttributeError:
				ret.append(seq)

		return ret

	ret_seqs = []

	if kwargs.has_key('amount'):
		# Simple offset by amount
		amount = get_frame(kwargs['amount'], kwargs['fps'], kwargs['tc_start'])
		ret_seqs = map(offset_each, seqlist, [amount] * len(seqlist))
	else:
		if kwargs.has_key('start_at'):
			ret_seqs = offset_based_on_start(seqlist, get_frame(kwargs['start_at'], kwargs['fps'], kwargs['tc_start']))
		if kwargs.has_key('end_at'):
			ret_seqs = offset_based_on_end(seqlist, get_frame(kwargs['end_at'], kwargs['fps'], kwargs['tc_start']))

	return ret_seqs
Ejemplo n.º 3
0
def minseq(original_seqlist, modified_seqlist, **kwargs):
	amount = get_frame(kwargs['amount'], kwargs['fps'])
	if amount <= 1: return original_seqlist, modified_seqlist # Early terminate for short min limit

	clean_list = filter(lambda pair: not is_single(pair[1]), zip(original_seqlist, modified_seqlist)) # Purge nonsequence items
	long_seqs = filter(lambda pair: pair[1].frame_amount() >= amount, clean_list)

	if long_seqs != []:
		return zip(*long_seqs)
	else:
		return [], []
Ejemplo n.º 4
0
def trim(seq, **kwargs):
	""" trim by 'head' and 'tail' from start and end of seq """
	
	# If we are provided with integer, input refers to amount of actual frames to trim
	# If it is timecode it means trim N seconds:frames so we need to calculate how many actual frames this means
	# in the context of this sequence as this might skip frames

	try:
		h = int(kwargs['head'])
		t = int(kwargs['tail'])

	except ValueError:		
		head = get_frame(kwargs['head'], kwargs['fps'])
		tail = get_frame(kwargs['tail'], kwargs['fps'])
		
		first_frame, last_frame = get_relative_frames(seq, head, tail)
		if first_frame != None and last_frame !=None:
			h, t = truncate(seq, start=first_frame, end=last_frame, fps=kwargs['fps'], tc_start=0)
		else:
			h = seq.frame_amount()
			t = h

	return h, t
Ejemplo n.º 5
0
def head_tail(seq, **kwargs):
	""" get N frames from head or tail of seq, returns instruction usable with absolute_trim_sequence """	

	def absolute_head_tail(seq, is_head, amount):
		""" Simple case of taking 'amount' frames from head or tail """
		if is_head:
			h = 0
			t = seq.frame_amount() - amount
			if t < 0: t = 0
		else:
			h = seq.frame_amount() - amount
			t = 0
			if h < 0: h = 0

		return h, t

	def relative_head_tail(seq, is_head, amount):
		""" how many frames to remove from seq, if amount refers to timecode. """
		#	We assume that person giving timecode is actually interested shortening the clip by certain time amount
		#	and whether sequence skips frames or not is not relevant 
		#	test.[0-50x2@@@@].dpx --head 25 takes 25 first filenames and becomes test.[0-48x2@@@@].dpx
		#	test.[0-50x2@@@@].dpx --head 01:00 takes one second of sequence (numbers 0-24) and becomes test.[0-24x2@@@@].dpx
		
		seq_len = max(seq.clips[-1]['end'], seq.clips[0]['start']) - min(seq.clips[0]['start'], seq.clips[-1]['end']) + 1 # Sequence length in timecode, not actual frames 

		if is_head:
			first_frame, last_frame = get_relative_frames(seq, 0, seq_len - amount)
		else:
			first_frame, last_frame = get_relative_frames(seq, seq_len - amount, 0)

		if first_frame != None and last_frame != None:
			h, t = truncate(seq, start=first_frame, end=last_frame, fps=kwargs['fps'], tc_start=0)
		else:
			h = seq.frame_amount()
			t = h

		return h, t

	is_head = kwargs['is_head']

	try:
		# We are passed frames, take literally 'amount' frames from head or tail
		amount = int(kwargs['amount'])
		return absolute_head_tail(seq, is_head, amount)

	except ValueError:
		# We are passed timecode, figure out what that means in terms of absolute frames
		amount = get_frame(kwargs['amount'], kwargs['fps'])
		return relative_head_tail(seq, is_head, amount)
Ejemplo n.º 6
0
def maxseq(original_seqlist, modified_seqlist, **kwargs):
	amount = get_frame(kwargs['amount'], kwargs['fps'])
	ret_original = []
	ret_modified = []

	for pair in zip(original_seqlist, modified_seqlist):
		if is_single(pair[1]):
			ret_original.append(pair[0])
			ret_modified.append(pair[1])
		else:
			if pair[1].frame_amount() <= amount:
				ret_original.append(pair[0])
				ret_modified.append(pair[1])

	return ret_original, ret_modified