folders
This commit is contained in:
124
remove-text.sh
Normal file
124
remove-text.sh
Normal file
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# remove_text.sh — conceal on-screen text in a rectangular area for a chosen time window.
|
||||
# Requires: ffmpeg (with delogo filter)
|
||||
|
||||
show_help() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
remove_text.sh -i INPUT -o OUTPUT --x X --y Y --w W --h H [--start SEC] [--end SEC] [--feather PX] [--preview] [--dry-run]
|
||||
|
||||
Params:
|
||||
-i, --input Input video file
|
||||
-o, --output Output video file
|
||||
--x Left coordinate of the box (pixels)
|
||||
--y Top coordinate of the box (pixels)
|
||||
--w Box width (pixels)
|
||||
--h Box height (pixels)
|
||||
--start Start time in seconds (e.g. 12 or 12.5). If omitted, applies from t=0.
|
||||
--end End time in seconds (exclusive). If omitted, applies to end of video.
|
||||
--feather Feather thickness for delogo (default: 8). Higher = softer edge.
|
||||
--preview Instead of removing, draw a red box to help align the area.
|
||||
--dry-run Print the ffmpeg command but don't execute it.
|
||||
-h, --help Show this help
|
||||
|
||||
Examples:
|
||||
Preview the area (draws box only):
|
||||
remove_text.sh -i in.mp4 -o preview.mp4 --x 120 --y 940 --w 680 --h 60 --start 12.5 --end 28.3 --preview
|
||||
|
||||
Remove text in that area/time range:
|
||||
remove_text.sh -i in.mp4 -o out.mp4 --x 120 --y 940 --w 680 --h 60 --start 12.5 --end 28.3
|
||||
EOF
|
||||
}
|
||||
|
||||
# ---- defaults ----
|
||||
INPUT=""
|
||||
OUTPUT=""
|
||||
X=""
|
||||
Y=""
|
||||
W=""
|
||||
H=""
|
||||
START=""
|
||||
END=""
|
||||
FEATHER="8"
|
||||
PREVIEW="0"
|
||||
DRYRUN="0"
|
||||
|
||||
# ---- parse args ----
|
||||
if [[ $# -eq 0 ]]; then show_help; exit 1; fi
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-i|--input) INPUT="${2:-}"; shift 2;;
|
||||
-o|--output) OUTPUT="${2:-}"; shift 2;;
|
||||
--x) X="${2:-}"; shift 2;;
|
||||
--y) Y="${2:-}"; shift 2;;
|
||||
--w) W="${2:-}"; shift 2;;
|
||||
--h) H="${2:-}"; shift 2;;
|
||||
--start) START="${2:-}"; shift 2;;
|
||||
--end) END="${2:-}"; shift 2;;
|
||||
--feather) FEATHER="${2:-}"; shift 2;;
|
||||
--preview) PREVIEW="1"; shift;;
|
||||
--dry-run) DRYRUN="1"; shift;;
|
||||
-h|--help) show_help; exit 0;;
|
||||
*) echo "Unknown argument: $1"; echo; show_help; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ---- validation ----
|
||||
if [[ -z "$INPUT" || -z "$OUTPUT" || -z "$X" || -z "$Y" || -z "$W" || -z "$H" ]]; then
|
||||
echo "Error: Missing required arguments."; echo
|
||||
show_help; exit 1
|
||||
fi
|
||||
|
||||
if ! command -v ffmpeg >/dev/null 2>&1; then
|
||||
echo "Error: ffmpeg not found in PATH."; exit 1
|
||||
fi
|
||||
|
||||
# Build enable expression based on start/end
|
||||
ENABLE_EXPR=""
|
||||
if [[ -n "$START" && -n "$END" ]]; then
|
||||
ENABLE_EXPR="between(t\,${START}\,${END})"
|
||||
elif [[ -n "$START" ]]; then
|
||||
ENABLE_EXPR="gte(t\,${START})"
|
||||
elif [[ -n "$END" ]]; then
|
||||
ENABLE_EXPR="lte(t\,${END})"
|
||||
else
|
||||
ENABLE_EXPR="" # apply for whole video
|
||||
fi
|
||||
|
||||
# Build filter chain
|
||||
if [[ "$PREVIEW" == "1" ]]; then
|
||||
if [[ -n "$ENABLE_EXPR" ]]; then
|
||||
VFILTER="drawbox=x=${X}:y=${Y}:w=${W}:h=${H}:color=red@0.5:thickness=2:enable='${ENABLE_EXPR}'"
|
||||
else
|
||||
VFILTER="drawbox=x=${X}:y=${Y}:w=${W}:h=${H}:color=red@0.5:thickness=2"
|
||||
fi
|
||||
else
|
||||
# delogo: x, y, w, h, t = feather thickness; show=0 (no outline)
|
||||
# delogo: x, y, w, h, band = feather thickness; show=0 (no outline)
|
||||
if [[ -n "$ENABLE_EXPR" ]]; then
|
||||
VFILTER="delogo=x=${X}:y=${Y}:w=${W}:h=${H}:show=0:enable='${ENABLE_EXPR}'"
|
||||
else
|
||||
VFILTER="delogo=x=${X}:y=${Y}:w=${W}:h=${H}:show=0"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# Assemble ffmpeg command
|
||||
# -c:v libx264 -crf 18: quality/size balance; adjust as needed
|
||||
# -preset medium: speed/efficiency tradeoff
|
||||
# -c:a copy: keep original audio
|
||||
CMD=(ffmpeg -hide_banner -y -i "$INPUT" -vf "$VFILTER" -c:v libx264 -crf 18 -preset medium -c:a copy "$OUTPUT")
|
||||
|
||||
echo "Running:"
|
||||
printf ' %q' "${CMD[@]}"; echo
|
||||
|
||||
if [[ "$DRYRUN" == "1" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
"${CMD[@]}"
|
||||
|
||||
echo "Done: $OUTPUT"
|
||||
Reference in New Issue
Block a user