#!/bin/bash
INPUT_FILE_GIVEN="${1:-"none"}"
[[ "${INPUT_FILE_GIVEN}" == "none" ]]  &&  { >&2 echo "Missing param 1: \${INPUT_FILE}";  exit 91; }
INPUT_FILE="$(readlink -f "${INPUT_FILE_GIVEN}")"
OUTPUT_FILE_DEFAULT="$(dirname "${INPUT_FILE}")"

PARAM_MAX_HEIGHT_DEFAULT=1200
PARAM_MAX_HEIGHT="${2:-"${PARAM_MAX_HEIGHT_DEFAULT}"}"
PARAM_X265_PRESET=slow
PARAM_X265_CRF=28  # default is 28
PARAM_READ_RATE=0.1  # calibrated for 1080p, per device, so that the device isn't constantly too hot

OUTPUT_FILE="$(readlink -f "${3:-"${OUTPUT_FILE_DEFAULT}"}")"
if [[ "${OUTPUT_FILE}" == "${OUTPUT_FILE_DEFAULT}" ]] || [ -d "${OUTPUT_FILE}" ]; then
  OUTPUT_FILE="${OUTPUT_FILE}/$(basename "${INPUT_FILE}")"
  OUTPUT_FILE="${OUTPUT_FILE%.*}.mp4"
fi


ac_stop_cont() {
  local PID_TRG="$1"
  local PWR_PATH
  for d in "/sys/class/power_supply/"*; do [[ "$(cat "${d}/type")" == "Mains" ]] && { PWR_PATH="${d}/online"; break; }; done
  [[ -z "${PWR_PATH}" ]] && { >&2 echo "[ac_stop_cont] No power supply status file found"; return 81; }
  local STATE_PREV STATE_CUR
  STATE_PREV=$(<"${PWR_PATH}")
  while kill -0 "${PID_TRG}" 2>/dev/null; do  # no signal is sent, just check whether process exists
    STATE_CUR=$(<"${PWR_PATH}")
    if [[ "${STATE_CUR}" != "${STATE_PREV}" ]]; then
      if [[ "${STATE_CUR}" -eq 0 ]]
        then  kill -STOP "${PID_TRG}";  >&2 echo "[ac_stop_cont] SIGSTOP process ${PID_TRG}"
        else  kill -CONT "${PID_TRG}";  >&2 echo "[ac_stop_cont] SIGCONT process ${PID_TRG}"
      fi
      STATE_PREV="${STATE_CUR}"
    fi
    sleep 3s
  done
}


HEIGHT_CUR=$(ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=s=x:p=0 "${INPUT_FILE}")
[ ${HEIGHT_CUR} -gt ${PARAM_MAX_HEIGHT} ]  &&  SCALE="-vf scale=-2:${PARAM_MAX_HEIGHT}"
AUDIO_CODEC_CUR=$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "${INPUT_FILE}")
AUDIO_TASK="aac -b:a 192k -ac 2";  [[ " aac mp3 ac3 alac eac3 " == *" ${AUDIO_CODEC_CUR} "* ]] && AUDIO_TASK="copy"

mkdir -p "$(dirname "${OUTPUT_FILE}")"

trap 'kill -SIGINT ${PID_FFMPEG}' INT
  </dev/null  nice --adjustment=19 ionice --class=3  ffmpeg  -hide_banner -loglevel error -stats  -xerror \
   -readrate ${PARAM_READ_RATE}  -i "${INPUT_FILE}"  -map 0:a -map 0:v -map -v -map V \
   -c:v libx265 -x265-params log-level=warning -preset "${PARAM_X265_PRESET}" -crf "${PARAM_X265_CRF}" ${SCALE} \
   -c:a ${AUDIO_TASK}  -map 0:s:m:codec:text? -c:s mov_text  -map_metadata 0 \
   "${OUTPUT_FILE}"  &
PID_FFMPEG=$!

ac_stop_cont "${PID_FFMPEG}" & ;  PID_MONITOR=$!
wait "${PID_FFMPEG}" ;  FFMPEG_EXITCODE=$?
kill "${PID_MONITOR}" 2>/dev/null


if [[ ${FFMPEG_EXITCODE} -ne 0 ]]; then   # cleanup partially-made output if ffmpeg unsuccessful
  >&2  echo "ERROR: FFMPEG abnormal exit (code ${FFMPEG_EXITCODE},  SIGINT=255)"
  rm -f "${OUTPUT_FILE}";  rmdir -p --ignore-fail-on-non-empty "$(dirname "${OUTPUT_FILE}")"
fi

exit ${FFMPEG_EXITCODE}
