Advertisement
gdunc

Alternative method to create contact sheet

Dec 27th, 2020 (edited)
1,882
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/root/powershell/pwsh
  2. # Change the above if your pwsh resides elsewhere in Linux
  3. <#
  4.   caps.ps1 -file <file> [-burn]
  5.  
  6. Requires: ffmpeg/ffprobe in the system path otherwise edit in the full path to them.
  7.           PowerShell 7+ (Any lesser version and it will just exit)
  8.           It uses the following fonts at lines 65, 68, & 70 - change those lines to use another font:
  9.           Windows font: C:\Windows\fonts\arial.ttf
  10.           Linux font:   /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
  11.           MacOs font:   /System/Library/Fonts/Arial.ttf
  12.  
  13. *** NOTE: ONLY tested with:
  14.           Windows 10 Pro x64
  15.           DietPi v 6.33.3 (Raspbian GNU/Linux 10 (buster), Linux 5.4.79-v7l+ )
  16.           Ubuntu 18.04.5 LTS (WSL)
  17.           PowerShell 7.1.0 (Windows/Linux)
  18.           ffmpeg version 2020-12-06-git-2aab42bc40-full_build-www.gyan.dev (Windows)
  19.           ffmpeg version 4.1.6-1~deb10u1+rpt1 (RasPi - DietPi v6.33.3 - Raspbian GNU/Linux 10 (buster), Linux 5.4.79-v7l+ )
  20.  
  21. Where: file  = full path to the video file
  22.        -burn = [optional] burn in timecodes
  23.  
  24. *** NOTE: Burning timecodes will not work unless ffmpeg has been compiled with the following option:
  25.             --enable-libfreetype
  26.  
  27.           If you don't know then enter the following command and search for 'drawtext' in the output:
  28.             ffmpeg -filters
  29.  
  30.   Generates the contact sheet faster than CTBRec internal method and [optionally] burns in the timecode
  31.   Extreme example: Video 3840x2160, 17.6GB, 2h54m (Ryzen5 3600)
  32.   CTBRec internal:    15 mins 16 secs
  33.   Powershell script:  44 secs
  34. #>
  35.  
  36.  
  37. # Parse command line parameters
  38. param (
  39.   [Parameter(Mandatory=$true)][string]$file,
  40.   [switch]$burn
  41. )
  42.  
  43. function ContactSheet ($infile) {
  44.   $tmpdir = ([System.IO.Path]::GetTempPath() + '~' + ([System.IO.Path]::GetRandomFileName())).Split('.')[0]
  45.   New-Item -Path "$($tmpdir)" -ItemType Directory | Out-Null
  46.   $duration = $(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -i "$($infile)")
  47.   for ($i = 1; $i -lt 57; $i++) {
  48.     $interval = [int](($i-0.5) * $duration/56)    # calculate position of each frame capture
  49.     [string]$ttext = ([timespan]::fromseconds($interval).tostring()).Replace(':', '\:')  # seconds to xx:xx:xx
  50.  
  51.     if ($burn) {                                  # skip to calculated position and grab next key frame
  52.       $ffcmd = "ffmpeg -v quiet -y -skip_frame nokey -ss $interval -i `"$file`" -vf scale=-1:720,select=`"eq(pict_type\,I)`",drawtext=`"text='$ttext':fontcolor=white:fontsize=48:box=1:boxcolor=black@0.5:boxborderw=5:x=(w-text_w)/2:y=(h-text_h-10):fontfile=$ffont`" -vframes 1 `"$tmpdir/image$(([string]$i).PadLeft(2, '0')).png`""
  53.     } else {
  54.       $ffcmd = "ffmpeg -v quiet -y -skip_frame nokey -ss $interval -i `"$file`" -vf select=`"eq(pict_type\,I)`" -vframes 1 `"$tmpdir/image$(([string]$i).PadLeft(2, '0')).png`""
  55.     }
  56.     Invoke-Expression $ffcmd
  57.   }
  58.   $ffcmd = "ffmpeg -v quiet -y -i $tmpdir/image%02d.png -vf `"scale=317:-1,tile=8x7:color=0x333333:margin=2:padding=2,scale=2560:-1`" -qscale:v 3 `"./$(([System.IO.FileInfo]$infile).BaseName).jpg`""
  59.   Invoke-Expression $ffcmd                         # create contact sheet from images -> file.jpg
  60.   Remove-Item -Path "$($tmpdir)" -Recurse -Force   # remove images
  61. }
  62.  
  63. if ($PSVersionTable.PSVersion.Major -ge 7) {       # Check for PS 7+
  64.   if ($IsWindows) {
  65.     $ffont = "C\\:/Windows/fonts/arial.ttf"        # ffmpeg font syntax changes depending on compilation/version, this works with the version I tested it with
  66.   } else {
  67.     if ($IsLinux) {
  68.       $ffont = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
  69.     } else {
  70.       $ffont = "/System/Library/Fonts/Arial.ttf"   # assume MacOS - change this if necessary, I haven't got access to a Mac
  71.     }
  72.   }
  73. } else {
  74.   exit
  75. }
  76.  
  77. Push-Location "$(Split-Path $file -Parent)"
  78. ContactSheet "$(Split-Path $file -Leaf)"
  79. Pop-Location
  80.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement