Skip to content

Instantly share code, notes, and snippets.

@meodai
Last active January 8, 2025 13:38
Show Gist options
  • Save meodai/826bacf5fc58ba57546b81849796b1d4 to your computer and use it in GitHub Desktop.
Save meodai/826bacf5fc58ba57546b81849796b1d4 to your computer and use it in GitHub Desktop.
video
#!/usr/bin/env fish
function show_spinner
set -l pid $argv[1]
set -l text $argv[2]
set -l spinner_chars "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
set -l i 1
while kill -0 $pid 2>/dev/null
printf "\r%s %s " (string sub -s $i -l 1 $spinner_chars) $text
set i (math "$i + 1")
if test $i -gt (string length $spinner_chars)
set i 1
end
sleep 0.1
end
printf "\r%s Done! \n" $text
end
function create_slitscan
set -l input_video $argv[1]
set -l output_image $argv[2]
set -l direction $argv[3] # "vertical" or "horizontal"
set -l slice_position $argv[4] # 0-100 percentage
set -l slice_thickness $argv[5] # pixels
set -l temp_dir (mktemp -d)
# Extract frames and get video info
echo "Extracting frames..."
ffmpeg -i $input_video -vf fps=30 $temp_dir/frame_%d.png -hide_banner -loglevel error
# Create directory for slices
mkdir -p $temp_dir/slices
# Get dimensions of a frame
set -l dimensions (magick identify -format "%wx%h" $temp_dir/frame_1.png)
set -l width (string split "x" $dimensions)[1]
set -l height (string split "x" $dimensions)[2]
# Calculate slice position based on percentage
set -l slice_x 0
set -l slice_y 0
if test "$direction" = "vertical"
set slice_x (math "floor($width * $slice_position / 100)")
else
set slice_y (math "floor($height * $slice_position / 100)")
end
# Extract slice from each frame and add frame number to filename
echo "Processing frames..."
set frame_num 1
begin
for frame in $temp_dir/frame_*.png
# Create the crop geometry string first
set -l crop_geometry
if test "$direction" = "vertical"
set crop_geometry "$slice_thickness"x"$height"+"$slice_x"+0
else
set crop_geometry "$width"x"$slice_thickness"+0+"$slice_y"
end
# Extract slice
magick "$frame" -crop "$crop_geometry" "$temp_dir/slices/slice_"(printf "%06d.png" $frame_num)
set frame_num (math $frame_num + 1)
end
end &
set -l process_pid $last_pid
show_spinner $process_pid "Processing frames"
# Combine all slices based on direction
echo "Combining slices..."
begin
if test "$direction" = "vertical"
# Arrange slices horizontally
magick "$temp_dir/slices/slice_"*.png +append "$output_image"
else
# Stack slices vertically
magick "$temp_dir/slices/slice_"*.png -append "$output_image"
end
end &
set -l combine_pid $last_pid
show_spinner $combine_pid "Combining slices"
# Clean up temporary files
rm -rf $temp_dir
echo "✨ Slitscan created successfully: $output_image"
end
# Check if correct number of arguments provided
if test (count $argv) -ne 5
echo "Usage: "(status filename)" <input_video> <output_image> <direction> <slice_position> <slice_thickness>"
echo " direction: vertical or horizontal"
echo " slice_position: 0-100 (percentage from left/top)"
echo " slice_thickness: pixels"
echo ""
echo "Example:"
echo " "(status filename)" input.mp4 output.png vertical 50 1"
exit 1
end
# Check if required commands exist
for cmd in ffmpeg magick
if not command -v $cmd >/dev/null
echo "Error: Required command '$cmd' not found"
echo "Please install ffmpeg and imagemagick"
exit 1
end
end
create_slitscan $argv[1] $argv[2] $argv[3] $argv[4] $argv[5]
@meodai
Copy link
Author

meodai commented Jan 8, 2025

video-slitscan(1)

NAME

video-slitscan - create time-slice compositions from video files

SYNOPSIS

video-slitscan input_video output_image direction slice_position slice_thickness

DESCRIPTION

Creates artistic time-slice compositions by extracting slices from video frames and combining them into a single image. Each slice represents a moment in time, arranged sequentially.

OPTIONS

  • input_video: Source video file (MP4, WebM, or other ffmpeg-supported format)
  • output_image: Destination image file (PNG recommended)
  • direction: Either 'vertical' or 'horizontal' slice orientation
  • slice_position: Position of slice (0-100, as percentage from left/top)
  • slice_thickness: Width/height of slice in pixels

EXAMPLES

Extract 1px vertical slices from center of frame:

video-slitscan input.mp4 output.png vertical 50 1

Create horizontal time-slices from top third:

video-slitscan input.mp4 output.png horizontal 33 2

DEPENDENCIES

Requires ffmpeg and ImageMagick

NOTES

Performance depends on video length and slice thickness. Temporary files are automatically cleaned up after processing.

./video_slitscan.fish input.mp4 output.png vertical 50 1
./video_slitscan.fish input.mp4 output.png horizontal 50 1

@EIIisD
Copy link

EIIisD commented Jan 8, 2025

wicked

@EIIisD
Copy link

EIIisD commented Jan 8, 2025

what did you use for the screencaps?

@meodai
Copy link
Author

meodai commented Jan 8, 2025

@EIIisD just the native OSX feature. (Cmd + Shift + 5)

@meodai
Copy link
Author

meodai commented Jan 8, 2025

@EIIisD it might be possible to use hardware acceleration for all this...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment