#!/bin/bash -x # usage: change-length.sh 1.007 input.mp4 output.mp4 [0] [--fast] set -euo pipefail RATIO=$1; IN_FILE=$2; OUT_FILE=$3; IS_MAC=${4-"0"}; MODE=${5-"--slow"}; BITRATE=$(ffmpeg -i "$IN_FILE" 2>&1 | grep bitrate | awk -F", " '{print $3}' | sed 's/bitrate: //' | sed 's/ //' | sed 's/b\/s//' || echo ""); echo ratio set to "$RATIO" INV_RATIO=$(python -c "print(1/$RATIO)"); FILTER=""; OPTS=(); AUDIO_FILTER="[0:a]atempo=$(echo "$INV_RATIO")[a]"; HAS_AUDIO=$( (ffprobe "$IN_FILE" || echo "") 2>&1 | grep Stream | grep --count Audio | tail -n 1); HAS_VIDEO=$(ffprobe "$IN_FILE" 2>&1 | grep Stream | grep --count Video || echo "0"); slow () { echo " "; echo " "; echo " "; echo " "; echo "USING SLOW MODE. If you want only video, use --fast"; echo " "; echo " "; echo " "; echo " "; echo " "; echo " "; echo " "; echo "Checking streams within the file..."; if [ "$HAS_AUDIO" -ge 0 ]; then FILTER=$AUDIO_FILTER; OPTS+=(-map "[a]"); fi; if [ "$HAS_VIDEO" -ge 0 ]; then FILTER="$FILTER;[0:v]setpts=$RATIO*PTS,hwupload[v]"; OPTS+=(-map "[v]"); fi; echo "running with filter $FILTER"; if [ "$IS_MAC" -eq 1 ]; then ffmpeg -hwaccel videotoolbox -i "$IN_FILE" -b:v $BITRATE -filter_complex "$FILTER" "${OPTS[@]}" -c:v h264_videotoolbox "$OUT_FILE"; else ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -vaapi_device /dev/dri/renderD128 -i "$IN_FILE" -b:v $BITRATE -filter_complex "$FILTER" "${OPTS[@]}" -c:v h264_vaapi "$OUT_FILE"; fi; } fast (){ if [ "$HAS_AUDIO" -ge 0 ]; then TEMP_VIDEO="$(dirname $IN_FILE)/.temp.$(random).video.$(basename "$IN_FILE")"; ffmpeg -itsscale "$RATIO" -i "$IN_FILE" -c copy -an "$TEMP_VIDEO"; TEMP_AUDIO="$(dirname $IN_FILE)/.temp.$(random).audio.$(basename "$IN_FILE")"; ffmpeg -i "$IN_FILE" -filter_complex "$AUDIO_FILTER" -vn -map "[a]" "$TEMP_AUDIO"; ffmpeg -i "$TEMP_VIDEO" -i "$TEMP_AUDIO" -c:v copy -c:a copy "$OUT_FILE"; rm -f "$TEMP_AUDIO" "$TEMP_VIDEO"; else ffmpeg -itsscale "$RATIO" -i "$IN_FILE" -c copy -an "$OUT_FILE"; fi; } if [ "$MODE" = "--fast" ]; then fast; else slow fi;