Thursday, March 31, 2022

FFmpeg - Concatenating Videos with Blend Transition


 

I received an anonymous comment on a past post FFMpeg Blending specifically asking how two video files could be concatenated with a blending effect transition.  

Note: anonymous commenter/reader, if you find yourself returning and find this post useful please drop a quick comment so I know the effort in addressing your question wasn't a lost. Thanks!

In past posts I feel we've covered most of the necessary filtering examples as well as concatenation of videos, it's a not-so-simple matter of putting them all together.  Let's start with constraints/complications that can bite you.


Constraints/Complications

Input Files

If your input files come from a uniform source (e.g. your phone, video camera, snippets from a larger video file) you may not have to worry about these factors.  For this example however, we will grab a couple videos from YouTube from different sources so we will have to address some issues.  

In general, your input files need to be similarly formatted.  Similar frame rates, video resolutions and audio tracks.  I've wasted more hours than I care to mention forgetting to take care in this step, let that be a word of caution to emphasize take a few minutes to check this beforehand to avoid making the mistakes I've made.  Best-case, if your formats don't match you get slapped in the face with an error from FFmpeg, worse case it succeeds in delivering a video that looks like garbage leaving you with an Easter Egg Hunt in finding the issue.  When in doubt, enforce some standard format prior to doing anything more sophisticated.

Let's start with video resolution; your input files (for concatenation and blends) need to be identically sized, not kinda similarly sized, but identically sized.  Source files that have different aspect ratios are particularly problematic because resizing them may not give you the required sizing leaving you to crop/pad accordingly.  

A consistent frame rate (FPS) is necessary for time-based filters, like the blending, make sure your frame rate (FPS) is identical for both input videos, otherwise you'll encounter unexpected results that may resemble this;

A consistent auto track existence; just shy of a bazillion times I've attempted to concatenate two videos only to find my audio tracks absent/stalling.  For example, applying an image snippet before/after a video results in stalling or absent audio until I relearn that I need to apply an empty audio track to the image video, otherwise concatenation doesn't know how to properly handle concatenation of one video with audio and another without.  All your source media for concatenation should all have an audio track or none have an audio tracks.  Mixing and matching will only give you headaches in the end.


Example

Let's move on to our example.

Let's snag two videos from YouTube

$ youtube-dl -f mp4 -o yt-stingray.mp4 https://www.youtube.com/watch?v=aXTk9VPZ4Gg


$  youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=_oHpWw7L3d4

Examining these files, you'll find they are aren't uniform in resolution or framerate.
$ ffprobe -i yt-stingray.mp4 
ffprobe version 4.2.2 Copyright (c) 2007-2019 the FFmpeg developers
  built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.12) 20160609
  configuration: --enable-libx264 --enable-nonfree --enable-gpl --enable-libfreetype --enable-libmp3lame --enable-libzmq
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'yt-stingray.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2019-05-22T15:56:25.000000Z
  Duration: 00:47:09.44, start: 0.000000, bitrate: 397 kb/s
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, smpte170m), 480x360 [SAR 1:1 DAR 4:3], 299 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Metadata:
      creation_time   : 2019-05-22T15:56:25.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 05/22/2019.
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 95 kb/s (default)
    Metadata:
      creation_time   : 2019-05-22T15:56:25.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 05/22/2019.

$ ffprobe -i yt-hardcastle01.mp4 
ffprobe version 4.2.2 Copyright (c) 2007-2019 the FFmpeg developers
  built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.12) 20160609
  configuration: --enable-libx264 --enable-nonfree --enable-gpl --enable-libfreetype --enable-libmp3lame --enable-libzmq
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'yt-hardcastle01.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    encoder         : Google
  Duration: 00:01:48.62, start: 0.000000, bitrate: 1362 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 1232 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
    Metadata:
      handler_name    : ISO Media file produced by Google Inc.
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
    Metadata:
      handler_name    : ISO Media file produced by Google Inc.

Concatenation 

Even with differing video resolutions and framerates, you can find reasonable success with simple concatenating of the video files.  FFmpeg will adopt the video resolution and framerate of the 1st input file and apply it throughout the output file.  Swapping the order of the above files results in the end resolution of the output file.
$ cat videoXX.mp4.txt
file 'yt-stingray.mp4'
file 'yt-hardcastle01.mp4'

$ ffmpeg -y -f concat -i videoXX.mp4.txt videoXX.mp4

This concatenation order results in 480x360 23.98 fps, while reversing the file order results in 1280x720 29.97 fps; often leaving you scratch your head.

Sometimes this will give you the result you're looking for, other times it may not.  I find it's in my best interest to do the scaling prior to concatenation, cropping and/or padding as I prefer.  Additionally, becoming overly reliant on FFmpeg 'doing it for you' avoids understanding what's going on only to bite you in the butt when you try something more complicated (e.g. like blending).


Blending

The blending effect we will be utilizing is a pixel-wide operations, one-by-one each frame is generated by 'blending' the corresponding pixels from each input file into the pixel in the destination frame.  If the two input media aren't identically scaled the blending falls apart because it lacks corresponding pixels.  FFmpeg errors out with an error resembling this;

[Parsed_amerge_0 @ 0x2e8b1c0] No channel layout for input 1
[Parsed_amerge_0 @ 0x2e8b1c0] Input channel layouts overlap: output layout will be determined by the number of distinct input channels
[Parsed_blend_2 @ 0x2dc7c80] First input link top parameters (size 480x360) do not match the corresponding second input link bottom parameters (size 1280x720)
[Parsed_blend_2 @ 0x2dc7c80] Failed to configure output pad on Parsed_blend_2
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #1:0
Conversion failed!

This is FFmpegs way of saying that your input videos aren't uniformly sized.

Scaling input files with a variety of aspect ratios is always challenging, I find for me scaling to a specific video size w/optional padding seems to work well for me.

Let's scale our input videos to 1280x720, applying padding if necessary, and force a uniform 30/1 frame rate;

$ ffmpeg -i yt-stingray.mp4 -vf "scale=-1:720,pad=1280:ih:(ow-iw)/2" -r 30/1-strict -2 yt-stingray-scaled.mp4
$ ffmpeg -i yt-hardcastle.mp4 -vf "scale=-1:720,pad=1280:ih:(ow-iw)/2" -r 30/1 -strict -2 yt-hardcastle-scaled.mp4

We are left with uniformly 1280x720 30/1 fps videos that can be blended.

Before we demonstrate the use of the blending filter, simple blending 'generally' begins being applied right away, not quite what we want if we want to play the first video until near completion, then blend into the next video.  While you absolutely can do it in a single sequence of commands, it would require adjusting the 1st video presentation time stamp (PTS) to start immediately, adjust the 2nd video PTS to nearly the duration of video1 (play this, then this) and then apply blending at the end of video1.  Personally, that's a recipe for a migraine, so an alternative is to break the two videos into segments and stitch them back together, so that's the tactic we'll use in our example.

Since these video source files are so large, let's shrink them down a bit for our example.  Let's grab 10 sec intervals to work with as they'll be processed quicker and a bit easier to understand.

$ ffmpeg -i yt-stingray-scaled.mp4 -ss 4 -t 10 -strict -2 clip01-scaled.mp4
$ ffmpeg -i yt-hardcastle-scaled.mp4 -ss 4 -t 10 -strict -2 clip02-scaled.mp4

So, we are looking for an end effect of playing the first 8 seconds of clip01-scaled.mp4, then apply a 2-sec blending transition, then continue to play video clip02-scaled.mp4.  That's our bogey.

We can achieve this by splitting the videos into 4 segments;
  • segment1.mp4 : first 8 seconds of clip01-scaled.mp4
  • segment2.mp4 : last 2 seconds of clip01-scaled.mp4
  • segment3.mp4 : first 2 seconds of clip02-scaled.mp4
  • segment4.mp4 : last 8 seconds of clip02-scaled.mp4
With these 4 segments, we will apply the blending transition to segment2 & segment3, then restitch the blended clip between segment1 and segment4.  That's the plan.  Let's walk thru that.

$ ffmpeg -i clip01-scaled.mp4 -t 8.032000 -target ntsc-dvd -strict -2 segment1.mp4
$ ffmpeg -i clip01-scaled.mp4 -ss 8.032000 -target ntsc-dvd -strict -2 segment2.mp4
$ ffmpeg -i clip02-scaled.mp4 -ss 0 -t 2 -target ntsc-dvd -strict -2 segment3.mp4
$ ffmpeg -i clip02-scaled.mp4 -ss 2 -target ntsc-dvd -strict -2 segment4.mp4

Let's blend segment2 and segment3; at the beginning of the output file we are attempting to utilize video1 frame blend factor of 100%, video2 frame of 0%, at the end of the clip reversing to 0% video1, 100% video2.  A time-based linear progression over the duration of the video clip.

$ ffmpeg -i segment2.mp4 -i segment3.mp4 -filter_complex "[0:v]setpts=PTS-STARTPTS[v0],[1:v]setpts=PTS-STARTPTS[v1],[v0][v1]blend=all_expr='A*(1-(T/2))+B*(T/2)'" -filter_complex "amerge=inputs=2" -ac 2 -shortest -target ntsc-dvd segment2a.mp4

It's possible that the input files have a non-zero PTS start time, which is later used (as time variable T), so we're forcing both video file PTS values to start at zero.  That way, the timestamp from both videos is uniform.  The blend filter A*factor1+B*factor2, each factor in the range of [0,1].  The amerge command similarly attempts to blend both audio tracks together.

With a clip duration of 2 seconds, T/2 is a linear progression from 0 to 1 working well for our 2nd video blending factor.  Wishing a decreasing blending factor for the 1st video (1-(T/2)) works.  Pay specific attention to the video duration component (e.g. 2), it needs to align with the length of the videos, otherwise the blending factors will exceed [0,1] and give you an effect that can only compare to dropping acid.  The ''-shortest' option may, or may not, be necessary, your mileage may vary.  I've added because without it sometimes I observe a slight delay in the re-assembled video.

Reassembling Video Clips

Let's reassemble our intro, outtro and blended clips into our final video.

$ cat video.mp4.txt 
file 'segment1.mp4'
file 'segment2a.mp4'
file 'segment4.mp4'

$ ffmpeg -y -f concat -i video.mp4.txt video.mp4

We're left with our final video.




The full Makefile, for those interested in re-creating a little less manually and may ease applying to your own source files.  Notice the ffprobe commands are used to automate the extraction of video durations, the TransitionDuration=2 implies a 2-second blending duration between the two videos.

$ cat -n Makefile 
     1 TransitionDuration=2
     2 all: video.mp4
     3
     4 segment1.mp4 : clip01-scaled.mp4
     5 ${SH} ffmpeg -i $< -t $(shell echo $(shell ffprobe -loglevel quiet -show_format $< -show_entries format=duration | grep duration | cut -f 2 -d '=') -${TransitionDuration} | bc) -target ntsc-dvd -strict -2 $@
     6
     7 segment2.mp4 : clip01-scaled.mp4
     8 ${SH} ffmpeg -i $< -ss $(shell echo $(shell ffprobe -loglevel quiet -show_format $< -show_entries format=duration | grep duration | cut -f 2 -d '=') -${TransitionDuration} | bc) -target ntsc-dvd -strict -2 $@
     9
    10 segment3.mp4 : clip02-scaled.mp4
    11 ${SH} ffmpeg -i $< -ss 0 -t $(shell echo ${TransitionDuration} -1 | bc) -target ntsc-dvd -strict -2 $@
    12
    13 segment4.mp4 : clip02-scaled.mp4
    14 ${SH} ffmpeg -i $< -ss ${TransitionDuration} -target ntsc-dvd -strict -2 $@
    15
    16 segment2a.mp4 : segment2.mp4 segment3.mp4
    17 ${SH} ffmpeg -i $(shell echo $^ | cut -f 1 -d ' ') -i $(shell echo $^ | cut -f 2 -d ' ') -filter_complex "[0:v]setpts=PTS-STARTPTS[v0],[1:v]setpts=PTS-STARTPTS[v1],[v0][v1]blend=all_expr='A*(1-(T/${TransitionDuration}))+B*(T/${TransitionDuration})'" -filter_complex "amerge=inputs=2" -ac 2 -shortest -target ntsc-dvd $@
    18
    19 video.mp4: segment1.mp4 segment2a.mp4 segment4.mp4
    20 ${SH} rm $@.txt | true
    21 ${SH} for f in $^; do echo "file '$$f'" >> $@.txt; done
    22 ${SH} ffmpeg -y -f concat -i $@.txt $@
    23 ${SH} mplayer $@
    24
    25 clip01.mp4: yt-stingray.mp4
    26 ${SH} ffmpeg -i $< -ss 4 -t 10 -strict -2 $@
    27
    28 clip02.mp4: yt-hardcastle01.mp4
    29 ${SH} ffmpeg -i $< -ss 9 -t 10 -strict -2 $@
    30
    31 yt-stingray.mp4:
    32 ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=aXTk9VPZ4Gg
    33
    34 yt-hardcastle01.mp4:
    35 ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=_oHpWw7L3d4
    36
    37 %-scaled.mp4: %.mp4
    38 ${SH} ffmpeg -i $< -vf "scale=-1:720,pad=1280:ih:(ow-iw)/2" -strict -2 $@
    39
    40
    41 clean:
    42 ${RM} *.mp4


Cheers.




Monday, March 21, 2022

Concatenating Non-Uniformly Scaled Videos w/FFmpeg

 Big hair, mullets and acid-washed jeans...the 1980's introduced us to a number of iconic treasures.  But, for me, and many young teenage boys I yearned for the iconic "throaty V8's" that took center stage during the nightly broadcasts.  My hand-painted Schwinn was magically transformed by imagination as we cruised around the neighborhood.


With that memory in mind, I collected a number of these marvelous machines (in a variety of formats/resolutions) and using the magic of FFmpeg created a video.

In past posts I've cheered the use of 'makefiles' with FFmpeg, believing they are a great match for one another; Atypical Uses for Makefiles


A series of videos are first downloaded from YouTube, sectioned into short clips (where the automobile is taking center stage), stitching them together, re-adding a soundtrack until we have N videos, one for each TV series.  Then, these videos are stitched together while applying a uniform scaling giving us one final video with them all.

While this could be accomplished with a single, monstrous Makefile, I felt it was easier to organize each tv series into it's own makefile (e.g. makefile.stingray), each included into the organizing makefile (e.g. Makefile).

 

  cat -n Makefile
     1    ClipW=1280
     2    ClipH=720
     3    Fps=30/1
     4    include makefile.stingray
     5    include makefile.miamivice
     6    include makefile.hardcastle
     7    include makefile.ateam
     8    include makefile.fallguy
     9    include makefile.knightrider
    10    include makefile.airwolf
    11    include makefile.dukes
    12    include makefile.magnum
    13   
    14    all: video.mp4
    15   
    16    #video.mp4: stingray-scaled.mp4 miamiVice-scaled.mp4 hardcastle-scaled.mp4 aTeam-scaled.mp4 fallGuy-scaled.mp4 knightRider-scaled.mp4 airwolf-scaled.mp4 dukes-scaled.mp4 magnum-scaled.mp4
    17    video.mp4: stingray-scaled.mp4 miamiVice-scaled.mp4 hardcastle-scaled.mp4 aTeam-scaled.mp4 fallGuy-scaled.mp4 knightRider-scaled.mp4 airwolf-scaled.mp4 dukes-scaled.mp4 magnum-scaled.mp4
    18        ${SH} rm $@.txt | true
    19        ${SH} for f in $^; do echo "file '$$f'" >> $@.txt; done
    20        ${SH} ffmpeg -y -f concat -i $@.txt $@
    21        ${SH} mplayer $@
    22   
    23   
    24    go: stingray-scaled.mp4
    25   
    26    %-scaled.mp4: %.mp4
    27    #    ${SH} ffmpeg -y -i $< -filter_complex "scale=${ClipW}:-2,scale=-2:${ClipH},pad=${ClipW}:${ClipH}:(ow-iw)/2:(oh-ih)/2" -r ${Fps} -acodec copy $@
    28        ${SH} ffmpeg -y -i $< -filter_complex "scale=${ClipW}:-2,scale=-2:${ClipH},scale=${ClipW}:${ClipH},pad=${ClipW}:${ClipH}:(ow-iw)/2:(oh-ih)/2" -r ${Fps} -acodec copy $@
    29   
    30    littleClean:
    31        ${SH} find . -name "*.mp4" ! -name 'yt-*.mp4' -delete
    32        ${RM} *.mp3
    33        ${RM} *.txt
    34   
Pay special attention to the 'scaled' target, this can take a variety of video resolutions (equal-to or smaller-than 1280x720) and scales them to 1280x720 w/padding.  It's always a hassle wrangling videos into a uniform size so they can be concatenated, these makefile targets do precisely that.

In an attempt to be thorough, I'll slap in the subordinate makefiles below, each snags a youtube video(s), creates a clip, extracts the theme song, concatenates the clips together and re-applys the audio channel.

$ cat -n makefile.stingray
     1    all:
     2   
     3    yt-stingray.mp4:
     4        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=aXTk9VPZ4Gg
     5   
     6    stingray.mp3: yt-stingray.mp4
     7        ${SH} ffmpeg -i $< -ss 35 -t 85 -vn -strict -2 $@
     8   
     9    sr-clip01.mp4: yt-stingray.mp4
    10        ${SH} ffmpeg -i $< -ss 4 -t 2 -strict -2 $@
    11   
    12    sr-clip02.mp4: yt-stingray.mp4
    13        ${SH} ffmpeg -i $< -ss 26 -t 1.0 -strict -2 $@
    14   
    15    sr-clip03.mp4: yt-stingray.mp4
    16        ${SH} ffmpeg -i $< -ss 33.30 -t 1.0 -strict -2 $@
    17   
    18    sr-clip04.mp4: yt-stingray.mp4
    19        ${SH} ffmpeg -i $< -ss 37.00 -t 16.0 -strict -2 $@
    20   
    21    sr-clip05.mp4: yt-stingray.mp4
    22        ${SH} ffmpeg -i $< -ss 61.50 -t 1.0 -strict -2 $@
    23   
    24    sr-clip06.mp4: yt-stingray.mp4
    25        ${SH} ffmpeg -i $< -ss 1643.00 -t 6.0 -strict -2 $@
    26   
    27    sr-clip07.mp4: yt-stingray.mp4
    28        ${SH} ffmpeg -i $< -ss 1874.50 -t 3.0 -strict -2 $@
    29   
    30    sr-clip08.mp4: yt-stingray.mp4
    31        ${SH} ffmpeg -i $< -ss 2083.00 -t 6.0 -strict -2 $@
    32   
    33    sr-clip09.mp4: yt-stingray.mp4
    34        ${SH} ffmpeg -i $< -ss 2126.50 -t 10.5 -strict -2 $@
    35   
    36    sr-clip10.mp4: yt-stingray.mp4
    37        ${SH} ffmpeg -i $< -ss 2142.00 -t 2.0 -strict -2 $@
    38   
    39    sr-clip11.mp4: yt-stingray.mp4
    40        ${SH} ffmpeg -i $< -ss 2149.00 -t 6.0 -strict -2 $@
    41   
    42    sr-clip12.mp4: yt-stingray.mp4
    43        ${SH} ffmpeg -i $< -ss 2243.00 -t 1.6 -strict -2 $@
    44   
    45    sr-clip13.mp4: yt-stingray.mp4
    46        ${SH} ffmpeg -i $< -ss 2246.00 -t 12.0 -strict -2 $@
    47   
    48    sr-clip14.mp4: yt-stingray.mp4
    49        ${SH} ffmpeg -i $< -ss 2260.00 -t 10.0 -strict -2 $@
    50   
    51    sr-clip15.mp4: yt-stingray.mp4
    52        ${SH} ffmpeg -i $< -ss 2278.75 -t 1.0 -strict -2 $@
    53   
    54    sr-clip16.mp4: yt-stingray.mp4
    55        ${SH} ffmpeg -i $< -ss 2282.0 -t 2.5 -strict -2 $@
    56   
    57    sr-clip17.mp4: yt-stingray.mp4
    58        ${SH} ffmpeg -i $< -ss 2285.5 -t 1.0 -strict -2 $@
    59   
    60    sr-clip18.mp4: yt-stingray.mp4
    61        ${SH} ffmpeg -i $< -ss 2290.5 -t 0.25 -strict -2 $@
    62   
    63    sr-clip19.mp4: yt-stingray.mp4
    64        ${SH} ffmpeg -i $< -ss 2293.0 -t 0.50 -strict -2 $@
    65   
    66    sr-clip20.mp4: yt-stingray.mp4
    67        ${SH} ffmpeg -i $< -ss 2298.0 -t 1.00 -strict -2 $@
    68   
    69    sr-clip21.mp4: yt-stingray.mp4
    70        ${SH} ffmpeg -i $< -ss 2304.0 -t 3.00 -strict -2 $@
    71   
    72    sr-clip22.mp4: yt-stingray.mp4
    73        ${SH} ffmpeg -i $< -ss 2310.0 -t 2.00 -strict -2 $@
    74   
    75    sr-clip23.mp4: yt-stingray.mp4
    76        ${SH} ffmpeg -i $< -ss 2317.0 -t 4.00 -strict -2 $@
    77   
    78    sr-clip24.mp4: yt-stingray.mp4
    79        ${SH} ffmpeg -i $< -ss 2325.0 -t 2.00 -strict -2 $@
    80   
    81    sr-clip25.mp4: yt-stingray.mp4
    82        ${SH} ffmpeg -i $< -ss 2328.5 -t 2.00 -strict -2 $@
    83   
    84    sr-clip26.mp4: yt-stingray.mp4
    85        ${SH} ffmpeg -i $< -ss 2332.0 -t 0.50 -strict -2 $@
    86   
    87    sr-clip27.mp4: yt-stingray.mp4
    88        ${SH} ffmpeg -i $< -ss 2334.0 -t 1.00 -strict -2 $@
    89   
    90    sr-clip28.mp4: yt-stingray.mp4
    91        ${SH} ffmpeg -i $< -ss 2336.0 -t 1.00 -strict -2 $@
    92   
    93    sr-clip29.mp4: yt-stingray.mp4
    94        ${SH} ffmpeg -i $< -ss 2354.0 -t 1.50 -strict -2 $@
    95   
    96    sr-clip30.mp4: yt-stingray.mp4
    97        ${SH} ffmpeg -i $< -ss 2361.0 -t 14.00 -strict -2 $@
    98   
    99    sr-videoAn.mp4: sr-clip01.mp4 sr-clip04.mp4 sr-clip02.mp4 sr-clip03.mp4 sr-clip08.mp4 sr-clip09.mp4 sr-clip11.mp4 sr-clip12.mp4 sr-clip13.mp4 sr-clip15.mp4 sr-clip16.mp4 sr-clip17.mp4 sr-clip18.mp4 sr-clip19.mp4 sr-clip20.mp4 sr-clip22.mp4 sr-clip24.mp4 sr-clip27.mp4 sr-clip28.mp4 sr-clip29.mp4 sr-clip30.mp4
   100        ${SH} for f in `echo $^`; do echo "file '$$f'" >> $@.txt; done;
   101        ${SH} ffmpeg -y -f concat -i $@.txt -an $@
   102        ${RM} $@.txt
   103   
   104    stingray.mp4: sr-videoAn.mp4 stingray.mp3
   105        ${SH} ffmpeg -i $< -i $(shell echo $^ | cut -f 2 -d ' ') -strict -2 $@
   106   
   107    clean:
   108        ${RM} sr*.mp4
$ cat -n makefile.stingray
     1    all:
     2   
     3    yt-stingray.mp4:
     4        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=aXTk9VPZ4Gg
     5   
     6    stingray.mp3: yt-stingray.mp4
     7        ${SH} ffmpeg -i $< -ss 35 -t 85 -vn -strict -2 $@
     8   
     9    sr-clip01.mp4: yt-stingray.mp4
    10        ${SH} ffmpeg -i $< -ss 4 -t 2 -strict -2 $@
    11   
    12    sr-clip02.mp4: yt-stingray.mp4
    13        ${SH} ffmpeg -i $< -ss 26 -t 1.0 -strict -2 $@
    14   
    15    sr-clip03.mp4: yt-stingray.mp4
    16        ${SH} ffmpeg -i $< -ss 33.30 -t 1.0 -strict -2 $@
    17   
    18    sr-clip04.mp4: yt-stingray.mp4
    19        ${SH} ffmpeg -i $< -ss 37.00 -t 16.0 -strict -2 $@
    20   
    21    sr-clip05.mp4: yt-stingray.mp4
    22        ${SH} ffmpeg -i $< -ss 61.50 -t 1.0 -strict -2 $@
    23   
    24    sr-clip06.mp4: yt-stingray.mp4
    25        ${SH} ffmpeg -i $< -ss 1643.00 -t 6.0 -strict -2 $@
    26   
    27    sr-clip07.mp4: yt-stingray.mp4
    28        ${SH} ffmpeg -i $< -ss 1874.50 -t 3.0 -strict -2 $@
    29   
    30    sr-clip08.mp4: yt-stingray.mp4
    31        ${SH} ffmpeg -i $< -ss 2083.00 -t 6.0 -strict -2 $@
    32   
    33    sr-clip09.mp4: yt-stingray.mp4
    34        ${SH} ffmpeg -i $< -ss 2126.50 -t 10.5 -strict -2 $@
    35   
    36    sr-clip10.mp4: yt-stingray.mp4
    37        ${SH} ffmpeg -i $< -ss 2142.00 -t 2.0 -strict -2 $@
    38   
    39    sr-clip11.mp4: yt-stingray.mp4
    40        ${SH} ffmpeg -i $< -ss 2149.00 -t 6.0 -strict -2 $@
    41   
    42    sr-clip12.mp4: yt-stingray.mp4
    43        ${SH} ffmpeg -i $< -ss 2243.00 -t 1.6 -strict -2 $@
    44   
    45    sr-clip13.mp4: yt-stingray.mp4
    46        ${SH} ffmpeg -i $< -ss 2246.00 -t 12.0 -strict -2 $@
    47   
    48    sr-clip14.mp4: yt-stingray.mp4
    49        ${SH} ffmpeg -i $< -ss 2260.00 -t 10.0 -strict -2 $@
    50   
    51    sr-clip15.mp4: yt-stingray.mp4
    52        ${SH} ffmpeg -i $< -ss 2278.75 -t 1.0 -strict -2 $@
    53   
    54    sr-clip16.mp4: yt-stingray.mp4
    55        ${SH} ffmpeg -i $< -ss 2282.0 -t 2.5 -strict -2 $@
    56   
    57    sr-clip17.mp4: yt-stingray.mp4
    58        ${SH} ffmpeg -i $< -ss 2285.5 -t 1.0 -strict -2 $@
    59   
    60    sr-clip18.mp4: yt-stingray.mp4
    61        ${SH} ffmpeg -i $< -ss 2290.5 -t 0.25 -strict -2 $@
    62   
    63    sr-clip19.mp4: yt-stingray.mp4
    64        ${SH} ffmpeg -i $< -ss 2293.0 -t 0.50 -strict -2 $@
    65   
    66    sr-clip20.mp4: yt-stingray.mp4
    67        ${SH} ffmpeg -i $< -ss 2298.0 -t 1.00 -strict -2 $@
    68   
    69    sr-clip21.mp4: yt-stingray.mp4
    70        ${SH} ffmpeg -i $< -ss 2304.0 -t 3.00 -strict -2 $@
    71   
    72    sr-clip22.mp4: yt-stingray.mp4
    73        ${SH} ffmpeg -i $< -ss 2310.0 -t 2.00 -strict -2 $@
    74   
    75    sr-clip23.mp4: yt-stingray.mp4
    76        ${SH} ffmpeg -i $< -ss 2317.0 -t 4.00 -strict -2 $@
    77   
    78    sr-clip24.mp4: yt-stingray.mp4
    79        ${SH} ffmpeg -i $< -ss 2325.0 -t 2.00 -strict -2 $@
    80   
    81    sr-clip25.mp4: yt-stingray.mp4
    82        ${SH} ffmpeg -i $< -ss 2328.5 -t 2.00 -strict -2 $@
    83   
    84    sr-clip26.mp4: yt-stingray.mp4
    85        ${SH} ffmpeg -i $< -ss 2332.0 -t 0.50 -strict -2 $@
    86   
    87    sr-clip27.mp4: yt-stingray.mp4
    88        ${SH} ffmpeg -i $< -ss 2334.0 -t 1.00 -strict -2 $@
    89   
    90    sr-clip28.mp4: yt-stingray.mp4
    91        ${SH} ffmpeg -i $< -ss 2336.0 -t 1.00 -strict -2 $@
    92   
    93    sr-clip29.mp4: yt-stingray.mp4
    94        ${SH} ffmpeg -i $< -ss 2354.0 -t 1.50 -strict -2 $@
    95   
    96    sr-clip30.mp4: yt-stingray.mp4
    97        ${SH} ffmpeg -i $< -ss 2361.0 -t 14.00 -strict -2 $@
    98   
    99    sr-videoAn.mp4: sr-clip01.mp4 sr-clip04.mp4 sr-clip02.mp4 sr-clip03.mp4 sr-clip08.mp4 sr-clip09.mp4 sr-clip11.mp4 sr-clip12.mp4 sr-clip13.mp4 sr-clip15.mp4 sr-clip16.mp4 sr-clip17.mp4 sr-clip18.mp4 sr-clip19.mp4 sr-clip20.mp4 sr-clip22.mp4 sr-clip24.mp4 sr-clip27.mp4 sr-clip28.mp4 sr-clip29.mp4 sr-clip30.mp4
   100        ${SH} for f in `echo $^`; do echo "file '$$f'" >> $@.txt; done;
   101        ${SH} ffmpeg -y -f concat -i $@.txt -an $@
   102        ${RM} $@.txt
   103   
   104    stingray.mp4: sr-videoAn.mp4 stingray.mp3
   105        ${SH} ffmpeg -i $< -i $(shell echo $^ | cut -f 2 -d ' ') -strict -2 $@
   106   
   107    clean:
   108        ${RM} sr*.mp4
$ cat -n makefile.miamivice
     1    yt-miamiVice01.mp4:
     2        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=JmFyFqTJprg
     3   
     4    yt-miamiVice02.mp4:
     5        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=dEjXPY9jOx8
     6   
     7    miamiVice.mp3: yt-miamiVice02.mp4
     8        ${SH} ffmpeg -i $< -vn $@
     9   
    10    #56-78
    11    mv-clip01.mp4: yt-miamiVice01.mp4
    12        ${SH} ffmpeg -i $< -ss 56 -t 22 $@
    13        ${SH} mplayer $@
    14   
    15    #84.5-87
    16    mv-clip02.mp4: yt-miamiVice01.mp4
    17        ${SH} ffmpeg -i $< -ss 84.5 -t 2.5 $@
    18        ${SH} mplayer $@
    19   
    20    #114-118
    21    mv-clip03.mp4: yt-miamiVice01.mp4
    22        ${SH} ffmpeg -i $< -ss 114 -t 4 $@
    23        ${SH} mplayer $@
    24   
    25    #122-127
    26    mv-clip04.mp4: yt-miamiVice01.mp4
    27        ${SH} ffmpeg -i $< -ss 122 -t 5 $@
    28        ${SH} mplayer $@
    29   
    30    #131-142
    31    mv-clip05.mp4: yt-miamiVice01.mp4
    32        ${SH} ffmpeg -i $< -ss 131 -t 11 $@
    33        ${SH} mplayer $@
    34   
    35    #153-160
    36    mv-clip06.mp4: yt-miamiVice01.mp4
    37        ${SH} ffmpeg -i $< -ss 154.5 -t 7 $@
    38        ${SH} mplayer $@
    39   
    40    #169-174
    41    mv-clip07.mp4: yt-miamiVice01.mp4
    42        ${SH} ffmpeg -i $< -ss 169 -t 5 $@
    43        ${SH} mplayer $@
    44   
    45    #183-190
    46    mv-clip08.mp4: yt-miamiVice01.mp4
    47        ${SH} ffmpeg -i $< -ss 183 -t 7 $@
    48        ${SH} mplayer $@
    49   
    50    #193-194
    51    mv-clip09.mp4: yt-miamiVice01.mp4
    52        ${SH} ffmpeg -i $< -ss 193 -t 1 $@
    53        ${SH} mplayer $@
    54   
    55    #198-204
    56    mv-clip10.mp4: yt-miamiVice01.mp4
    57        ${SH} ffmpeg -i $< -ss 198 -t 5 $@
    58        ${SH} mplayer $@
    59   
    60    #254-265
    61    mv-clip11.mp4: yt-miamiVice01.mp4
    62        ${SH} ffmpeg -i $< -ss 254 -t 11 $@
    63        ${SH} mplayer $@
    64   
    65    mv-videoAn.mp4: mv-clip01.mp4 mv-clip04.mp4 mv-clip02.mp4 mv-clip03.mp4 mv-clip08.mp4 mv-clip09.mp4 mv-clip11.mp4
    66        ${SH} for f in `echo $^`; do echo "file '$$f'" >> $@.txt; done;
    67        ${SH} ffmpeg -y -f concat -i $@.txt -an $@
    68        ${RM} $@.txt
    69   
    70    miamiVice.mp4: mv-videoAn.mp4 miamiVice.mp3
    71        ${SH} ffmpeg -i $< -i $(shell echo $^ | cut -f 2 -d ' ') -strict -2 $@
    72   
    73   
$ cat -n makefile.hardcastle
     1    yt-hardcastle01.mp4:
     2        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=_oHpWw7L3d4
     3   
     4   
     5    yt-hardcastle02.mp4:
     6        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=J2_G1CNaeFs
     7   
     8    hardcastle.mp3: yt-hardcastle01.mp4
     9        ${SH} ffmpeg -i $< -ss 8.3 -t 91.6 -vn -strict -2 $@
    10   
    11    hm-clip01.mp4: yt-hardcastle01.mp4
    12        ${SH} ffmpeg -i $< -ss 8.3 -t 16.00 -strict -2 $@
    13   
    14    hm-clip02.mp4: yt-hardcastle01.mp4
    15        ${SH} ffmpeg -i $< -ss 82.3 -t 0.5 -strict -2 $@
    16   
    17    hm-clip03.mp4: yt-hardcastle01.mp4
    18        ${SH} ffmpeg -i $< -ss 89.5 -t 12.0 -strict -2 $@
    19   
    20    hm-clip04.mp4: yt-hardcastle02.mp4
    21        ${SH} ffmpeg -i $< -ss 31.5 -t 3.5 -strict -2 $@
    22   
    23    hm-clip05.mp4: yt-hardcastle02.mp4
    24        ${SH} ffmpeg -i $< -ss 40.0 -t 3.0 -strict -2 $@
    25   
    26    hm-clip06.mp4: yt-hardcastle02.mp4
    27        ${SH} ffmpeg -i $< -ss 51.0 -t 2.0 -strict -2 $@
    28   
    29    hm-clip07.mp4: yt-hardcastle02.mp4
    30        ${SH} ffmpeg -i $< -ss 68.5 -t 7.0 -strict -2 $@
    31   
    32    hm-clip08.mp4: yt-hardcastle02.mp4
    33        ${SH} ffmpeg -i $< -ss 84.5 -t 25.5 -strict -2 $@
    34   
    35    hm-clip09.mp4: yt-hardcastle02.mp4
    36        ${SH} ffmpeg -i $< -ss 116.0 -t 8.0 -strict -2 $@
    37   
    38    hm-clip10.mp4: yt-hardcastle02.mp4
    39        ${SH} ffmpeg -i $< -ss 133.0 -t 5.0 -strict -2 $@
    40   
    41    hm-clip11.mp4: yt-hardcastle02.mp4
    42        ${SH} ffmpeg -i $< -ss 143.5 -t 5.0 -strict -2 $@
    43   
    44    hm-videoAn.mp4: hm-clip01.mp4 hm-clip02.mp4 hm-clip04.mp4 hm-clip05.mp4 hm-clip06.mp4 hm-clip07.mp4 hm-clip08.mp4 hm-clip09.mp4 hm-clip10.mp4 hm-clip11.mp4 hm-clip03.mp4
    45        ${SH} for f in `echo $^`; do echo "file '$$f'" >> $@.txt; done;
    46        ${SH} ffmpeg -y -f concat -i $@.txt -an $@
    47        ${RM} $@.txt
    48   
    49    hardcastle.mp4: hm-videoAn.mp4 hardcastle.mp3
    50        ${SH} ffmpeg -i $< -i $(shell echo $^ | cut -f 2 -d ' ') -strict -2 $@
    51   
    52   
    53   
$ cat -n makefile.ateam
     1    yt-aTeam00.mp4:
     2        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=wyz_2DEah4o
     3   
     4    yt-aTeam01.mp4:
     5        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=orxNlmQSMg8
     6   
     7    yt-aTeam02.mp4:
     8        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=nn5gY7LK8Mc
     9   
    10    yt-aTeam03.mp4:
    11        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=ZgUBogpF-M8
    12   
    13    yt-aTeam04.mp4:
    14        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=TP0LowFsi9Q
    15   
    16    yt-aTeam05.mp4:
    17        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=7BcPko1RYv0
    18   
    19    at-clip01.mp4: yt-aTeam01.mp4
    20        ${SH} ffmpeg -i $< -ss 0 -t 10 -strict -2 $@
    21   
    22    at-clip02.mp4: yt-aTeam01.mp4
    23        ${SH} ffmpeg -i $< -ss 13 -t 9 -strict -2 $@
    24   
    25    at-clip03.mp4: yt-aTeam02.mp4
    26        ${SH} ffmpeg -i $< -ss 1.3 -t 2.0 -strict -2 $@
    27   
    28    at-clip04.mp4: yt-aTeam02.mp4
    29        ${SH} ffmpeg -i $< -ss 5.5 -t 0.25 -strict -2 $@
    30   
    31    at-clip05.mp4: yt-aTeam02.mp4
    32        ${SH} ffmpeg -i $< -ss 9.5 -t 5 -strict -2 $@
    33   
    34    at-clip06.mp4: yt-aTeam02.mp4
    35        ${SH} ffmpeg -i $< -ss 30 -t 2.5 -strict -2 $@
    36   
    37    at-clip07.mp4: yt-aTeam02.mp4
    38        ${SH} ffmpeg -i $< -ss 34.5 -t 1 -strict -2 $@
    39   
    40    at-clip08.mp4: yt-aTeam02.mp4
    41        ${SH} ffmpeg -i $< -ss 40 -t 2 -strict -2 $@
    42   
    43    at-clip09.mp4: yt-aTeam02.mp4
    44        ${SH} ffmpeg -i $< -ss 50 -t 3.5 -strict -2 $@
    45   
    46    at-clip10.mp4: yt-aTeam02.mp4
    47        ${SH} ffmpeg -i $< -ss 64 -t 5 -strict -2 $@
    48   
    49    at-clip11.mp4: yt-aTeam02.mp4
    50        ${SH} ffmpeg -i $< -ss 75.5 -t 1.5 -strict -2 $@
    51   
    52    at-clip12.mp4: yt-aTeam02.mp4
    53        ${SH} ffmpeg -i $< -ss 79 -t 7 -strict -2 $@
    54   
    55    at-clip13.mp4: yt-aTeam03.mp4
    56        ${SH} ffmpeg -i $< -ss 311 -t 7 -vf scale=486:360 -r 25/1 -strict -2 $@
    57   
    58    at-clip14.mp4: yt-aTeam04.mp4
    59        ${SH} ffmpeg -i $< -ss 218 -t 3 -vf scale=486:360 -r 25/1 -strict -2 $@
    60   
    61    at-clip15.mp4: yt-aTeam04.mp4
    62        ${SH} ffmpeg -i $< -ss 224 -t 1 -vf scale=486:360 -r 25/1 -strict -2 $@
    63   
    64    at-clip16.mp4: yt-aTeam04.mp4
    65        ${SH} ffmpeg -i $< -ss 228 -t 2 -vf scale=486:360 -r 25/1 -strict -2 $@
    66   
    67    at-clip17.mp4: yt-aTeam04.mp4
    68        ${SH} ffmpeg -i $< -ss 238 -t 1 -vf scale=486:360 -r 25/1 -strict -2 $@
    69   
    70    at-clip18.mp4: yt-aTeam04.mp4
    71        ${SH} ffmpeg -i $< -ss 243 -t 5 -vf scale=486:360 -r 25/1 -strict -2 $@
    72   
    73    at-clip19.mp4: yt-aTeam05.mp4
    74        ${SH} ffmpeg -i $< -ss 112 -t 5 -vf scale=486:360 -r 25/1 -strict -2 $@
    75   
    76    at-clip20.mp4: yt-aTeam02.mp4
    77        ${SH} ffmpeg -y -i $< -ss 81 -t 5 -strict -2 temp.$@
    78        ${SH} ffmpeg -i temp.$@ -filter:v "setpts=2.5*PTS" -strict -2 $@
    79   
    80    aTeam.mp3: yt-aTeam00.mp4
    81        ${SH} ffmpeg -y -i $< -vn -t 75 -strict -2 $@
    82   
    83    at-videoAn.mp4: at-clip01.mp4 at-clip02.mp4 at-clip03.mp4 at-clip04.mp4 at-clip05.mp4 at-clip06.mp4 at-clip07.mp4 at-clip08.mp4 at-clip09.mp4 at-clip10.mp4 at-clip11.mp4 at-clip12.mp4 at-clip13.mp4 at-clip14.mp4 at-clip15.mp4 at-clip16.mp4 at-clip17.mp4 at-clip18.mp4 at-clip19.mp4 at-clip20.mp4
    84        ${SH} for f in `echo $^`; do echo "file '$$f'" >> $@.txt; done;
    85        ${SH} ffmpeg -y -f concat -i $@.txt -an $@
    86        ${RM} $@.txt
    87   
    88    aTeam.mp4: at-videoAn.mp4 aTeam.mp3
    89        ${SH} ffmpeg -y -i $< -i $(shell echo $^ | cut -f 2 -d ' ') -strict -2 $@
    90   
$ cat -n makefile.fallguy
     1    yt-fallguy01.mp4:
     2        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=iNizcrfnQ4E
     3   
     4    yt-fallguy02.mp4:
     5        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=0dxtiOqK8qg
     6   
     7    yt-fallguy03.mp4:
     8        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=dj9ev40C30M
     9   
    10    yt-fallguy04.mp4:
    11        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=s1uhbxz_Xfc
    12   
    13    yt-fallguy05.mp4:
    14        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=atZtkZdIWeM
    15   
    16    fg-clip01.mp4: yt-fallguy01.mp4
    17        ${SH} ffmpeg -i $< -ss 0 -t 4 -strict -2 $@
    18   
    19    fg-clip02.mp4: yt-fallguy02.mp4
    20        ${SH} ffmpeg -i $< -ss 61 -t 3 -strict -2 $@
    21   
    22    fg-clip03.mp4: yt-fallguy02.mp4
    23        ${SH} ffmpeg -i $< -ss 81 -t 3 -strict -2 $@
    24   
    25    fg-clip04.mp4: yt-fallguy02.mp4
    26        ${SH} ffmpeg -i $< -ss 101 -t 3 -strict -2 $@
    27   
    28    fg-clip05.mp4: yt-fallguy02.mp4
    29        ${SH} ffmpeg -i $< -ss 217 -t 5 -strict -2 $@
    30   
    31    fg-clip06.mp4: yt-fallguy02.mp4
    32        ${SH} ffmpeg -i $< -ss 248 -t 5 -strict -2 $@
    33   
    34    fg-clip07.mp4: yt-fallguy02.mp4
    35        ${SH} ffmpeg -i $< -ss 289 -t 3 -strict -2 $@
    36   
    37    fg-clip08.mp4: yt-fallguy02.mp4
    38        ${SH} ffmpeg -i $< -ss 5 -t 9 -strict -2 $@
    39   
    40    fg-clip09.mp4: yt-fallguy02.mp4
    41        ${SH} ffmpeg -i $< -ss 17 -t 9 -strict -2 $@
    42   
    43    fg-clip10.mp4: yt-fallguy02.mp4
    44        ${SH} ffmpeg -i $< -ss 28.5 -t 5.5 -strict -2 $@
    45   
    46    fg-clip11.mp4: yt-fallguy02.mp4
    47        ${SH} ffmpeg -i $< -ss 38.5 -t 1.5 -strict -2 $@
    48   
    49    fg-clip12.mp4: yt-fallguy02.mp4
    50        ${SH} ffmpeg -i $< -ss 42 -t 2.5 -strict -2 $@
    51   
    52    fg-clip13.mp4: yt-fallguy02.mp4
    53        ${SH} ffmpeg -i $< -ss 46.5 -t 5.5 -strict -2 $@
    54   
    55    fg-clip14.mp4: yt-fallguy02.mp4
    56        ${SH} ffmpeg -i $< -ss 54 -t 6 -strict -2 $@
    57   
    58    fg-clip15.mp4: yt-fallguy02.mp4
    59        ${SH} ffmpeg -i $< -ss 62 -t 3 -strict -2 $@
    60   
    61    fg-clip16.mp4: yt-fallguy02.mp4
    62        ${SH} ffmpeg -i $< -ss 66 -t 36 -strict -2 $@
    63   
    64    fg-clip17.mp4: yt-fallguy02.mp4
    65        ${SH} ffmpeg -i $< -ss 106 -t 24 -strict -2 $@
    66   
    67    fg-clip18.mp4: yt-fallguy02.mp4
    68        ${SH} ffmpeg -i $< -ss 137 -t 12 -strict -2 $@
    69   
    70    fg-clip19.mp4: yt-fallguy02.mp4
    71        ${SH} ffmpeg -i $< -ss 151 -t 19 -strict -2 $@
    72   
    73    fg-clip20.mp4: yt-fallguy02.mp4
    74        ${SH} ffmpeg -i $< -ss 178 -t 2 -strict -2 $@
    75   
    76    fg-clip21.mp4: yt-fallguy02.mp4
    77    #    ${SH} ffmpeg -i $< -ss 188 -t 222 -strict -2 $@
    78    #    ${SH} ffmpeg -i $< -ss 188 -t 165 -strict -2 $@
    79        ${SH} ffmpeg -i $< -ss 188 -t 23 -strict -2 $@
    80   
    81    fallGuy.mp3: yt-fallguy01.mp4
    82        ${SH} ffmpeg -i $< -ss 0 -t 106 -vn -strict -2 $@
    83   
    84    fg-videoAn.mp4: fg-clip01.mp4 fg-clip02.mp4 fg-clip03.mp4 fg-clip04.mp4 fg-clip05.mp4 fg-clip06.mp4 fg-clip07.mp4 fg-clip08.mp4 fg-clip09.mp4 fg-clip10.mp4 fg-clip11.mp4 fg-clip12.mp4 fg-clip13.mp4 fg-clip14.mp4 fg-clip15.mp4 fg-clip16.mp4 fg-clip17.mp4 fg-clip18.mp4 fg-clip19.mp4 fg-clip20.mp4 fg-clip21.mp4
    85        ${SH} for f in `echo $^`; do echo "file '$$f'" >> $@.txt; done;
    86        ${SH} ffmpeg -y -f concat -i $@.txt -an $@
    87        ${RM} $@.txt
    88   
    89    fallGuy.mp4: fg-videoAn.mp4 fallGuy.mp3
    90        ${SH} ffmpeg -i $< -i $(shell echo $^ | cut -f 2 -d ' ') -strict -2 $@
    91   
$ cat -n makefile.knightrider
     1    yt-knightrider01.mp4:
     2        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=oNyXYPhnUIs
     3   
     4    yt-knightrider02.mp4:
     5        ${SH} youtube-dl -f mp4 -o $@ https://youtu.be/hfRiedxPQhs
     6   
     7    yt-knightrider03.mp4:
     8        ${SH} youtube-dl -f mp4 -o $@ https://youtu.be/LcG5jQPrOOQ
     9   
    10    yt-knightrider04.mp4:
    11        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=FBQ0PSxPRjc
    12   
    13    yt-knightrider05.mp4:
    14        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=rkBcGP256Ng
    15   
    16    yt-knightrider06.mp4:
    17        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=lVElVZlnTG0
    18   
    19    yt-knightrider07.mp4:
    20        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=mWDZsKSGoVg
    21   
    22    kr-clip01.mp4: yt-knightrider01.mp4
    23        ${SH} ffmpeg -i $< -ss 4 -t 27 -target ntsc-dvd $@
    24   
    25    kr-clip02.mp4: yt-knightrider01.mp4
    26        ${SH} ffmpeg -i $< -ss 53 -t 7 -target ntsc-dvd $@
    27   
    28    kr-clip03.mp4: yt-knightrider01.mp4
    29        ${SH} ffmpeg -i $< -ss 65 -t 0.5 -target ntsc-dvd $@
    30   
    31    #kr-clip04.mp4: yt-knightrider01.mp4
    32    #    ${SH} ffmpeg -i $< -ss 67 -t 10 -target ntsc-dvd $@
    33   
    34   
    35    knightRider.mp3: yt-knightrider01.mp4
    36        ${SH} ffmpeg -i $< -ss 4 -t 76 -vn $@
    37   
    38    kr-clip04.mp4: yt-knightrider02.mp4
    39        ${SH} ffmpeg -i $< -ss 285 -t 1 -target ntsc-dvd $@
    40   
    41    kr-clip05.mp4: yt-knightrider02.mp4
    42        ${SH} ffmpeg -i $< -ss 295 -t 4 -target ntsc-dvd $@
    43   
    44    kr-clip06.mp4: yt-knightrider02.mp4
    45        ${SH} ffmpeg -i $< -ss 315 -t 1 -target ntsc-dvd $@
    46   
    47    kr-clip07.mp4: yt-knightrider02.mp4
    48        ${SH} ffmpeg -i $< -ss 330 -t 10 -target ntsc-dvd $@
    49   
    50    kr-clip08.mp4: yt-knightrider02.mp4
    51        ${SH} ffmpeg -i $< -ss 347 -t 3 -target ntsc-dvd $@
    52   
    53    kr-clip09.mp4: yt-knightrider02.mp4
    54        ${SH} ffmpeg -i $< -ss 352 -t 5 -target ntsc-dvd $@
    55   
    56    kr-clip10.mp4: yt-knightrider02.mp4
    57        ${SH} ffmpeg -i $< -ss 362 -t 5 -target ntsc-dvd $@
    58   
    59    kr-clip11.mp4: yt-knightrider01.mp4
    60        ${SH} ffmpeg -i $< -ss 67 -t 10 -target ntsc-dvd $@
    61   
    62    kr-clip12.mp4: yt-knightrider06.mp4
    63        ${SH} ffmpeg -i $< -ss 4.2 -t 10 -target ntsc-dvd $@
    64   
    65   
    66    kr-videoAn.mp4: kr-clip01.mp4 kr-clip02.mp4 kr-clip03.mp4 kr-clip04.mp4 kr-clip05.mp4 kr-clip06.mp4 kr-clip07.mp4 kr-clip08.mp4 kr-clip12.mp4 kr-clip11.mp4
    67        ${SH} for f in `echo $^`; do echo "file '$$f'" >> $@.txt; done;
    68        ${SH} ffmpeg -y -f concat -i $@.txt -an $@
    69        ${RM} $@.txt
    70        ${SH} mplayer $@
    71   
    72   
    73    knightRider.mp4: kr-videoAn.mp4 knightRider.mp3
    74        ${SH} ffmpeg -y -i $< -i $(shell echo $^ | cut -f 2 -d ' ') -strict -2 $@
    75   
    76   
$ cat -n makefile.airwolf
     1    yt-airwolf01.mp4:
     2        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=B10AXxnZGto
     3   
     4    yt-airwolf02.mp4:
     5        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=55VuB724n6Y
     6   
     7    yt-airwolf03.mp4:
     8        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=dnHY4rhNRKU
     9   
    10    airwolf.mp3: yt-airwolf01.mp4
    11        ${SH} ffmpeg -i $< -vn -strict -2 $@
    12   
    13   
    14    aw-clip01.mp4: yt-airwolf01.mp4
    15        ${SH} ffmpeg -i $< -ss 1 -t 39 -strict -2 -target ntsc-dvd $@
    16   
    17    aw-clip02.mp4: yt-airwolf01.mp4
    18        ${SH} ffmpeg -i $< -ss 74 -t 6 -strict -2 -target ntsc-dvd $@
    19   
    20    aw-clip03.mp4: yt-airwolf02.mp4
    21        ${SH} ffmpeg -i $< -ss 28 -t 12 -strict -2 -target ntsc-dvd $@
    22   
    23    aw-clip04.mp4: yt-airwolf02.mp4
    24    #    ${SH} ffmpeg -i $< -ss 130 -t 50 -strict -2 -target ntsc-dvd $@
    25        ${SH} ffmpeg -i $< -ss 130 -t 48 -strict -2 -target ntsc-dvd $@
    26   
    27    aw-clip05.mp4: yt-airwolf02.mp4
    28        ${SH} ffmpeg -i $< -ss 201 -t 2 -strict -2 -target ntsc-dvd $@
    29   
    30    aw-clip06.mp4: yt-airwolf02.mp4
    31        ${SH} ffmpeg -i $< -ss 209 -t 19 -strict -2 -target ntsc-dvd $@
    32   
    33    aw-clip07.mp4: yt-airwolf02.mp4
    34        ${SH} ffmpeg -i $< -ss 240 -t 4 -strict -2 -target ntsc-dvd $@
    35   
    36    aw-clip08.mp4: yt-airwolf02.mp4
    37        ${SH} ffmpeg -i $< -ss 254 -t 4 -strict -2 -target ntsc-dvd $@
    38   
    39    aw-clip09.mp4: yt-airwolf02.mp4
    40        ${SH} ffmpeg -i $< -ss 265 -t 3 -strict -2 -target ntsc-dvd $@
    41   
    42    aw-clip10.mp4: yt-airwolf02.mp4
    43        ${SH} ffmpeg -i $< -ss 550 -t 10 -strict -2 -target ntsc-dvd $@
    44   
    45    aw-clip11.mp4: yt-airwolf02.mp4
    46        ${SH} ffmpeg -i $< -ss 735 -t 40 -strict -2 -target ntsc-dvd $@
    47   
    48    aw-videoAn.mp4: aw-clip01.mp4 aw-clip04.mp4
    49        ${SH} for f in `echo $^`; do echo "file '$$f'" >> $@.txt; done;
    50        ${SH} ffmpeg -y -f concat -i $@.txt -an $@
    51        ${RM} $@.txt
    52   
    53    airwolf.mp4: aw-videoAn.mp4 airwolf.mp3
    54        ${SH} ffmpeg -i $< -i $(shell echo $^ | cut -f 2 -d ' ') -strict -2 $@
    55   
$ cat -n makefile.dukes
     1    yt-dukes01.mp4:
     2        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=67gig0f4HLo
     3   
     4    yt-dukes02.mp4:
     5        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=2iMBQ-bXQIE
     6   
     7    yt-dukes03.mp4:
     8        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=pWuVWNSNWnM
     9   
    10    dukes.mp3: yt-dukes01.mp4
    11        ${SH} ffmpeg -i $< -vn -t 61 -strict -2 $@
    12   
    13    dukes.mp4: dh-videoAn.mp4 dukes.mp3
    14        ${SH} ffmpeg -i $< -i $(shell echo $^ | cut -f 2 -d ' ') -strict -2 $@
    15   
    16    dh-clip01.mp4: yt-dukes01.mp4
    17        ${SH} ffmpeg -i $< -ss 3 -t 7 -strict -2 $@
    18        ${SH} mplayer $@
    19   
    20    dh-clip02.mp4: yt-dukes01.mp4
    21        ${SH} ffmpeg -i $< -ss 15 -t 1.5 -strict -2 $@
    22        ${SH} mplayer $@
    23   
    24    dh-clip03.mp4: yt-dukes01.mp4
    25        ${SH} ffmpeg -i $< -ss 52.5 -t 8 -strict -2 $@
    26        ${SH} mplayer $@
    27   
    28    dh-clip04.mp4: yt-dukes02.mp4
    29        ${SH} ffmpeg -i $< -ss 94.5 -t 4 -strict -2 $@
    30        ${SH} mplayer $@
    31   
    32    #dh-clip05.mp4: yt-dukes02.mp4
    33    #    ${SH} ffmpeg -i $< -ss 177.5 -t 4.5 -strict -2 $@
    34    #    ${SH} mplayer $@
    35   
    36    dh-clip06.mp4: yt-dukes02.mp4
    37        ${SH} ffmpeg -i $< -ss 212 -t 3.5 -strict -2 $@
    38        ${SH} mplayer $@
    39   
    40    dh-clip07.mp4: yt-dukes02.mp4
    41        ${SH} ffmpeg -i $< -ss 561.5 -t 10 -strict -2 $@
    42        ${SH} mplayer $@
    43   
    44    dh-clip08.mp4: yt-dukes03.mp4
    45        ${SH} ffmpeg -i $< -ss 18 -t 3.25 -strict -2 $@
    46        ${SH} mplayer $@
    47   
    48    dh-clip09.mp4: yt-dukes03.mp4
    49        ${SH} ffmpeg -i $< -ss 24 -t 2.5 -strict -2 $@
    50        ${SH} mplayer $@
    51   
    52    #dh-clip10.mp4: yt-dukes03.mp4
    53    #    ${SH} ffmpeg -i $< -ss 29 -t 13 -strict -2 $@
    54    #    ${SH} mplayer $@
    55   
    56    dh-clip11.mp4: yt-dukes03.mp4
    57        ${SH} ffmpeg -i $< -ss 68 -t 5.5 -strict -2 $@
    58        ${SH} mplayer $@
    59   
    60    dh-clip12.mp4: yt-dukes03.mp4
    61        ${SH} ffmpeg -i $< -ss 78 -t 13 -strict -2 $@
    62        ${SH} mplayer $@
    63   
    64    dh-videoAn.mp4: dh-clip01-scaled.mp4 dh-clip02-scaled.mp4 dh-clip04-scaled.mp4 dh-clip06-scaled.mp4 dh-clip07-scaled.mp4 dh-clip08-scaled.mp4 dh-clip09-scaled.mp4 dh-clip11-scaled.mp4 dh-clip12-scaled.mp4 dh-clip03-scaled.mp4
    65        ${SH} for f in `echo $^`; do echo "file '$$f'" >> $@.txt; done;
    66        ${SH} ffmpeg -y -f concat -i $@.txt -an $@
    67        ${RM} $@.txt
    68   
$ cat -n makefile.magnum
     1    yt-magnum01.mp4:
     2        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=xIaXl7SqkBw
     3   
     4    yt-magnum02.mp4:
     5        ${SH} youtube-dl -f mp4 -o $@ https://www.youtube.com/watch?v=CICbxj1PF74
     6   
     7    magnum.mp3: yt-magnum01.mp4
     8        ${SH} ffmpeg -i $< -vn -t 61 -strict -2 $@
     9   
    10    magnum.mp4: mp-videoAn.mp4 magnum.mp3
    11        ${SH} ffmpeg -i $< -i $(shell echo $^ | cut -f 2 -d ' ') -strict -2 $@
    12   
    13    mp-clip01.mp4: yt-magnum01.mp4
    14        ${SH} ffmpeg -i $< -ss 16 -t 4 -strict -2 $@
    15   
    16    mp-clip02.mp4: yt-magnum01.mp4
    17        ${SH} ffmpeg -i $< -ss 40.5 -t 1.5 -strict -2 $@
    18   
    19    #mp-clip03.mp4: yt-magnum02.mp4
    20    #    ${SH} ffmpeg -i $< -ss 0 -t 22 -strict -2 $@
    21   
    22    mp-clip04.mp4: yt-magnum02.mp4
    23        ${SH} ffmpeg -i $< -ss 24 -t 6 -strict -2 $@
    24   
    25    mp-clip05.mp4: yt-magnum02.mp4
    26        ${SH} ffmpeg -i $< -ss 32.5 -t 1 -strict -2 $@
    27   
    28    #mp-clip06.mp4: yt-magnum02.mp4
    29    #    ${SH} ffmpeg -i $< -ss 38.5 -t 2.5 -strict -2 $@
    30    #
    31    #mp-clip07.mp4: yt-magnum02.mp4
    32    #    ${SH} ffmpeg -i $< -ss 47 -t 2.5 -strict -2 $@
    33   
    34    #mp-clip08.mp4: yt-magnum02.mp4
    35    #    ${SH} ffmpeg -i $< -ss 58 -t 17 -strict -2 $@
    36    #
    37    #mp-clip09.mp4: yt-magnum02.mp4
    38    #    ${SH} ffmpeg -i $< -ss 77.5 -t 15 -strict -2 $@
    39   
    40    mp-clip10.mp4: yt-magnum02.mp4
    41        ${SH} ffmpeg -i $< -ss 101 -t 20 -strict -2 $@
    42   
    43    mp-clip11.mp4: yt-magnum02.mp4
    44        ${SH} ffmpeg -i $< -ss 123 -t 3 -strict -2 $@
    45   
    46    mp-clip12.mp4: yt-magnum02.mp4
    47        ${SH} ffmpeg -i $< -ss 127 -t 12 -strict -2 $@
    48   
    49    mp-videoAn.mp4: mp-clip01.mp4 mp-clip02.mp4 mp-clip04.mp4 mp-clip05.mp4 mp-clip10.mp4 mp-clip11.mp4 mp-clip12.mp4
    50        ${SH} for f in `echo $^`; do echo "file '$$f'" >> $@.txt; done;
    51        ${SH} ffmpeg -y -f concat -i $@.txt -an $@
    52        ${RM} $@.txt

Friday, April 16, 2021

Quarantine What's Ups

 As our pandemic takes it's second revolution around the sun the list of things to occupy the surplus of time has taken a hit.  Here are but a number of things I spent time with in 2020 in an attempt to keep busy.


Grow a Beard

In the spirit of the 'decade of the unnecessary beard' I stepped forward and extended the traditional facial follicle growing season from the normal Nov-Dec to Nov-Feb, two additional months of woolly cultivation. 


Culinary Activities

Like most home-bound folks, I took a crack at baking my own bread, with modest success.  Gone were the Sunday morning breakfast outings, replaced with DIY breakfasts which got better in time.  Crepes and french toast made a play into the rotation with hashbrowns and waffles/pancakes taking front seat most pretty frequently.  Our love for asian cuisine, particularly Thai, still satisfied by take-out from our favorite restaurant occasionally still left a gap.  It's genuinely surprising how a few ingredients can enable homemade Thai, Korean and Chinese dishes.  We started making Mango Chicken, Bulgogi and Thai Basil Chicken at home to satisfy the asian cuisine cravings with modest proficiency.

On-Line Learning

The State of Minnesota offered the DEEDS program, subsidizing on-line learning for the past year.  With a surplus of time and interest in a variety of subjects I hammered out 54 courses, ranging from 4-hrs to multiple weeks, in a variety of tech topics.  

Podcasts

One luxury of working from home this past year has been the ability to take an uninterrupted walk over the noon hour, often accompanied with a podcast.  With an increase in sitting time, this activity helps my body remember that it's natural state isn't the seated position.

Started a Book

Like many folks, I've occasionally been drawn to 'write a book', despite a real need for it.  Mid 2020, I had a couple inspiring computer science majors contact me via Reddit for advice, mostly involving 'what is CS' and 'How do I get into CS', but one exchange left me puzzled.  A young man from Ireland, just leaving high school was accepted into university but later rejected as a result of Covid reduction in campus actions.  He asked what he could do to get a head-start in self-study or prepare for the industry in the event he never gets in.  My suggestion was simply; "go to the university bookstore, find the CS textbooks, buy them and begin self-study".  I heavily encouraged going to university, and stressed that I doubt I'd be a professional in the industry had I not done so, but as a plan-B aligning your self-study with the university curriculum would be better than adhoc YouTube, influencer offerings, or code camps.  To my surprise, I quickly found I'm out of touch with how universities teach as of late.  Many no longer have physical textbooks, or virtual ones for that matter, instead they teach via interactive websites with automated grading.  Restricted to university students closed the avenue to my suggestion.  So, over a few days I got a bug to write a book, a collaboration of my CS university teachings in a manner I had wished it was presented to me.  Worse case, after spending some time on it, I'd know how lofty an effort.  One chapter completed'ish, and it was clear it'd be a substantial effort with likely a limited (or non-existent) audience, so onto the back burner it went.

Created a CS Mentoring Website

Still amp'd from a desire to help folks into the industry, a frequent contributor to Reddit posts, there seemed a real need for guidance/mentorship for those interested in CS.  Personally, I'd have never made it into the profession without some highly dedicated and patient teachers and mentors, so with ample free time I thought the timing would be right for assisting however I could.  I was always puzzled when I attended Minnebar (or other conferences) that recommended mentorship but never offered any facilities to connect folks.  So I created a mentorship proof-of-concept website, unpublished, to get a feel for what I thought would be beneficial.  Then, I reached out to local communities (e.g. Twitter) to gauge interest and I found non-existent interest in the subject.  Onto the back-burner it went.

Woodworking

I've always enjoyed woodworking, but mostly focused on 'big' stuff.....decks, sheds, firepits, stairs....but always wanted to get proficient in high-detailed work.  Garage Therapy over the past year allowed me to build my first indoor furniture piece, a variety of small trinkets (spoons, trays), cutting boards, bird feeders as well as a variety of failures destined for firewood.  With quality wood prices skyrocketing, and it becoming a more popular hobby over the year it's likely less expensive to take up cocaine as a recreational activity, but in the meantime I hone my skills on big-box-store cheaper lumber with hope of one day using quality woods.




Cleaned House

Dozens of boxes of donations have recently bid adieu, hopefully finding their way to a someone who could better use them.  Our house, considerably lighter, partly due to thousands of papers being electronically scanned before being recycled.  I'm a self-professed hoarder in some regards, especially with respect to tech information.  Some of the most inspiring training I had early in my career really set the stage for my success in the profession, I've always felt fortunate for such a investments and retained them for reference.  Kinda like old family photos, there is reassurance knowing you have them despite rarely even looking at them.  Now, they virtually sit in a backed up repository never to be lost while freeing cubic yards of space in the office(s).  Similarly, boxes of old family photos were scanned in the same manner and distributed to the family for similar reasons.

Meetups

I've always admired proficient tech speakers and genuinely miss the days of attending colloquiums held by passionate and knowledgeable speakers.  Like 94.7% of people (a statistic I just made up) who would rather face a rabid grizzly bear than speak in front of an audience I figured what time better than to dive into the pool of fear and uncomfort.  Four presentations under my current belt, including ones that I intentionally didn't rehearse to death, an attempt to address my fear of being asked a question I wasn't prepared for.  A patient and understanding audience really makes all the difference, each time being easier than the last.  

In My Humble Opinion

I've had dozens of 'passion projects', software projects you do in your spare time in an effort to provide something useful to the world.  This project, a distributed survey community, combined cloud computing, Android development, security, and a butt-load of interesting technologies into something I thought would be interesting and useful.  To date, this is the last significant project I've worked on, abandoning it after it failed to generate any real interest.  Learned a ton of new tech and knocked off the rust on some old skills but back-burnered it as it didn't appear to have a real track in interest.

Blogging

I've been blogging on-and-off for years now, most recently a solid 2-year weekly contribution here.  I feel I gave it a solid try and accomplished what I originally set out to do, but disappointed in not feeling it's really of value beyond myself.  For the past couple years, I established a queue of 'waiting to publish' articles and published weekly, releasing all unpublished articles in one fatal swoop a few months ago.  Awaiting inspiration to return for another 'go'.