Skip to content

Instantly share code, notes, and snippets.

@costa
Created July 7, 2023 19:56
Show Gist options
  • Save costa/ce2ca4a2370e14a01fd87d4864cc247c to your computer and use it in GitHub Desktop.
Save costa/ce2ca4a2370e14a01fd87d4864cc247c to your computer and use it in GitHub Desktop.
|o|
# NOTE Run me like this: | <ffmprb> <OUT-PATH>
# NOTE for previewing
# video_output_options = {resolution: Ffmprb::HD_720p, fps: 30, encoder: 'libx264'}
# NOTE for further processing:
video_output_options = {resolution: Ffmprb::HD_4K, fps: 60, encoder: 'huffyuv'}
# NOTE for viewing
# video_output_options = {resolution: Ffmprb::HD_1080p, fps: 60, encoder: 'libx265'}
# NOTE for dev
# video_output_options = {}
class InputSlideCropper
def initialize(inp, cols = 1, rows = 1)
fail "not much of a slideshow" unless
rows > 0 && cols > 0 && rows + cols > 2
@inp = inp
@h1 = 1.0/(@rows = rows)
@w1 = 1.0/(@cols = cols)
end
def slide(col = 1, row = 1)
fail "hey, I don't have that many (#{col}, #{row}) cols/rows, just #{@cols}, #{@rows}" unless
row <= @rows && col <= @cols
@inp.crop top: @h1 * (row - 1), bottom: @h1*(@rows - row), left: @w1 * (col - 1), right: @w1*(@cols - col)
end
end
inp_face =
input('/media/2023/07/06/Movie Recording 2023-07-06 at 07.55.00.mov')
inp_face_1 =
input('/media/2023/07/06/Movie Recording 2023-07-06 at 07.55.00.mov')
inp_face_2 =
input('/media/2023/07/06/Movie Recording 2023-07-06 at 07.55.00.mov')
inp_face_3 =
input('/media/2023/07/06/Movie Recording 2023-07-06 at 07.55.00.mov')
inp_ols = InputSlideCropper.new(
input('/media/2023/06/28/media_ 2023_06_28 proj_ costashapiro.com_works_ad - spaced.png', loop: true),
2, 5
)
inp_mus =
input('/media/3000booking.de/Timboletti - Elektronisk Folke Dans - Guestmix.mp3')
.volume(0.09)
LENGTH = 439
output o, video: video_output_options do # 07:19
overlays = []
curr_time = 0
define_singleton_method :paste do |from, to, inp=inp_face|
lay inp.cut(from: from, to: to)
curr_time += to - from
end
#hl0 - coming in
paste 20, 26, inp_face
overlays << [inp_ols.slide(1, 1), curr_time, 18]
#hl1
paste 361, 380, inp_face_1
paste 26, 33, inp_face
#hl2
paste 223, 248, inp_face_2
paste 33, 58, inp_face
#hl0 + coming in
overlays << [inp_ols.slide(1, 2), curr_time, 6]
paste 12, 26, inp_face_3
paste 94, 108, inp_face
overlays << [inp_ols.slide(2, 2), curr_time, 12]
paste 108, 131, inp_face
overlays << [inp_ols.slide(2, 3), curr_time, 6]
paste 131, 155, inp_face
overlays << [inp_ols.slide(1, 3), curr_time, 54]
paste 155, 330, inp_face
overlays << [inp_ols.slide(1, 4), curr_time, 18]
paste 330, 360, inp_face
overlays << [inp_ols.slide(2, 4), curr_time, 6]
paste 360, 396, inp_face
overlays << [inp_ols.slide(1, 5), curr_time, 6]
paste 396, 420, inp_face
overlays << [inp_ols.slide(2, 5), curr_time, 12]
paste 420, 437, inp_face
fail "Script-internal error: total LENGTH !~ #{curr_time}" unless
(curr_time - LENGTH).abs < 1
# NOTE suppose the logo is at (2, 1),
# the overlays are sequential and at least couple of seconds apart
# and the logo comes up after the first overlay and disappears before the last
inp_logo = inp_ols.slide(2, 1)
before_at = 0
overlays.each do |inp, at, len|
unless before_at == 0
overlay inp_logo.cut(to: at - before_at - 2), at: before_at + 1
end
overlay inp.cut(to: len), at: at
before_at = at + len
end
overlay inp_mus.cut(to: LENGTH - 6*2), at: 6
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment