Skip to content

Instantly share code, notes, and snippets.

@bczhc
Created April 21, 2022 13:26
Show Gist options
  • Save bczhc/391e319077403a8ae9bc0b458958e88c to your computer and use it in GitHub Desktop.
Save bczhc/391e319077403a8ae9bc0b458958e88c to your computer and use it in GitHub Desktop.
视频调速

Usage: speed-up-video <src> <dest> <factor> <framerate>

#!/bin/bash
set -e
function print_help() {
self_name="$(basename "$0")"
echo "Usage: $self_name <src> <dest> <factor> <framerate>"
}
# if argument count is not 3, print help
if [ "$#" -ne 4 ]; then
print_help
exit 1
fi
# loop through arguments, if '-h' or '--help' presented, print help
for arg in "$@"; do
if [ "$arg" == "-h" ] || [ "$arg" == "--help" ]; then
print_help
exit 0
fi
done
src="$1"
dest="$2"
factor="$3"
framerate="$4"
factor="$(echo "scale=10; $factor" | bc 2>&1)"
if echo "$factor" | grep 'Runtime\ error' >/dev/null ||
echo "$factor" | grep 'syntax error' >/dev/null; then
echo "Invalid factor: $factor"
exit 1
fi
# if factor <= 0, print error
if (($(echo "$factor < 0" | bc -l))); then
echo "Error: factor must be a positive number"
exit 1
fi
pts_multiplier="$(echo "scale=10; 1/$factor" | bc 2>&1)"
if echo "$pts_multiplier" | grep 'Runtime error' >/dev/null; then
echo "Invalid factor: $factor"
exit 1
fi
if (($(echo "$factor <= 2" | bc -l))); then
filter_complex="[0:v]setpts=$pts_multiplier*PTS[ov]; [0:a]atempo=${factor}[oa]"
else
log2="$(echo "scale=10; l($factor)/l(2)" | bc -l)"
log_int_part="$(echo "scale=0; $log2 / 1" | bc)"
remain_multiplier="$(echo "scale=10; $factor / 2^$log_int_part" | bc)"
atempo_filter="[0:a]"
for ((i = 0; i < log_int_part; ++i)); do
if [ "$i" == 0 ]; then
atempo_filter="${atempo_filter}atempo=2[oa$i]; "
else
atempo_filter="${atempo_filter}[oa$((i - 1))]atempo=2[oa$i]; "
fi
done
atempo_filter="${atempo_filter}[oa$((i - 1))]atempo=${remain_multiplier}[oa]"
filter_complex="[0:v]setpts=$pts_multiplier*PTS[ov]; $atempo_filter"
fi
echo "used filter: $filter_complex"
ffmpeg -i "$src" \
-filter_complex "$filter_complex" \
-map '[ov]' -map '[oa]' \
-b:a 0 -b:v 0 -c:v h264_nvenc -r "$framerate" \
"$dest"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment