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