Skip to content

Instantly share code, notes, and snippets.

@chand1012
Created October 21, 2025 16:42
Show Gist options
  • Select an option

  • Save chand1012/e855d88b25166db1da3d85cc80bc6367 to your computer and use it in GitHub Desktop.

Select an option

Save chand1012/e855d88b25166db1da3d85cc80bc6367 to your computer and use it in GitHub Desktop.
Use FFMPEG for some tasks from a docker container. Mostly so I could do some media file operations directly from UnRAID.
# extract-frames.sh
#!/usr/bin/env bash
# Purpose: Extract a frame every 2 seconds from a video using Dockerized ffmpeg,
# saving frames to a directory named <basename>_frames in the host CWD.
set -euo pipefail
IMAGE="${FFMPEG_IMAGE:-jrottenberg/ffmpeg:latest}"
if [[ $# -ne 1 ]]; then
echo "usage: $0 <input-video-file>" >&2
exit 1
fi
INPUT_PATH="$1"
if [[ ! -f "$INPUT_PATH" ]]; then
echo "file not found: $INPUT_PATH" >&2
exit 1
fi
IN_DIR="$(cd "$(dirname "$INPUT_PATH")" && pwd)"
IN_BASE="$(basename "$INPUT_PATH")"
OUT_DIR="$(pwd)/${IN_BASE%.*}_frames"
mkdir -p "$OUT_DIR"
# Pull ffmpeg image if missing
if ! docker image inspect "$IMAGE" >/dev/null 2>&1; then
docker pull "$IMAGE" >/dev/null
fi
# Extract a frame every 2 seconds (fps=1/2)
docker run --rm \
-v "$IN_DIR":/in:ro \
-v "$OUT_DIR":/out \
"$IMAGE" \
-hide_banner -y -threads 8 \
-i "/in/$IN_BASE" \
-vf fps=1/2 "/out/frame_%04d.jpg"
# owner can't be root since we'll need to be able to read the file from n8n
# change it to 1000:1000
chown -R 1000:1000 "$OUT_DIR"
echo "$OUT_DIR"
# strip-audio.sh
#!/usr/bin/env bash
# Purpose: Use the ffmpeg Docker image to extract audio from a video as 128 kbps MP3 (max 8 threads),
# saving the output to the host's current working directory with .mp3 extension.
set -euo pipefail
IMAGE="${FFMPEG_IMAGE:-jrottenberg/ffmpeg:latest}"
if ! command -v docker >/dev/null 2>&1; then
echo "docker not found" >&2
exit 1
fi
if [[ $# -ne 1 ]]; then
echo "usage: $0 <input-video-file>" >&2
exit 1
fi
INPUT_PATH="$1"
if [[ ! -f "$INPUT_PATH" ]]; then
echo "file not found: $INPUT_PATH" >&2
exit 1
fi
# Resolve absolute paths
IN_DIR="$(cd "$(dirname "$INPUT_PATH")" && pwd)"
IN_BASE="$(basename "$INPUT_PATH")"
# Output goes to the host's current working directory
OUT_DIR="$(pwd)"
BASE_NO_EXT="${IN_BASE%.*}"
OUT_FILE="$BASE_NO_EXT.mp3"
# Prevent accidental overwrite; change -n to -y if you prefer overwrite
OVERWRITE_FLAG="-y"
# Pull image if missing
if ! docker image inspect "$IMAGE" >/dev/null 2>&1; then
docker pull "$IMAGE" >/dev/null
fi
# Run ffmpeg in container:
# - Mount input readonly at /in
# - Mount host CWD at /out
# - Use up to 8 threads, strip video, encode libmp3lame at 128k
docker run --rm \
-v "$IN_DIR":/in:ro \
-v "$OUT_DIR":/out \
"$IMAGE" \
-hide_banner $OVERWRITE_FLAG -threads 8 \
-i "/in/$IN_BASE" \
-vn -acodec libmp3lame -b:a 128k \
"/out/$OUT_FILE"
# owner can't be root since we'll need to be able to read the file from n8n
# change it to 1000:1000
chown 1000:1000 "$OUT_DIR/$OUT_FILE"
echo "$OUT_DIR/$OUT_FILE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment