Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- exec 5> debug_snowvid.txt; BASH_XTRACEFD="5"; PS4='$LINENO: '; set -x # debugging
- die() { echo "$*" >&2; exit 2; } # Call a usage function from here as well.
- while getopts edcs:b:m:r:i:o: opt
- do
- case $opt in
- e) CASE_E=1;; # for encoding
- d) CASE_D=1;; # for decoding
- c) COLOR=1;; # color mode
- s) SCALE="$OPTARG";; # either 1, 2, 3, 4, 6
- b) BLOCK="$OPTARG";; # either 4, 8, 16
- m) MEGAS="$OPTARG";; # 0=perfect, 1=SDR_low, 2=HDR_low, 3=SDR_hi, 4=HDR_hi
- r) RATE="$OPTARG";; # either 24, 30, 48, 60
- i) INPUT="$OPTARG";; # input file
- o) OUTPUT="$OPTARG";; # output file
- esac
- done
- #matrix[scale,megas]
- declare -A matrix # for 1, 2, 3, 4
- matrix[1,1]=10; matrix[1,2]=0; matrix[1,3]=15; matrix[1,4]=0;
- matrix[2,1]=50; matrix[2,2]=65; matrix[2,3]=75; matrix[2,4]=95;
- matrix[3,1]=80; matrix[3,2]=100; matrix[3,3]=120; matrix[3,4]=150;
- matrix[4,1]=160; matrix[4,2]=200; matrix[4,3]=240; matrix[4,4]=300;
- declare -A two_k # for 6
- two_k[1,1]=350; two_k[1,2]=440; two_k[1,3]=530; two_k[1,4]=660;
- two_k[2,1]=450; two_k[2,2]=560; two_k[2,3]=680; two_k[2,4]=850;
- if [ $((CASE_E+CASE_D)) -eq 0 ]; then
- die "Error: need a function flag"
- elif [ $((CASE_E+CASE_D)) -eq 2 ]; then
- die "Error: Multiple function flags were given"
- fi
- shopt -s extglob
- if [ ${CASE_E} -eq 1 ]; then
- if [[ ${SCALE} != @(1|2|3|4|6) ]]; then
- die "Error: scale is not 1, 2, 3, 4 or 6"
- elif [[ ${BLOCK} != @(4|8|16) ]]; then
- die "Error: block is not 4, 8 or 16"
- elif [[ ( ${SCALE} == @(1|3) ) && ( ${BLOCK} == 16 ) ]]; then
- die "Error; scale is odd while block is 16"
- elif [[ ${RATE} != @(24|30|48|60) ]]; then
- die "Error: rate is not either 24, 30, 48 or 60"
- elif [ -z "${INPUT}" ]; then
- die "Error: Image file path not given"
- elif [ ! -r "${INPUT}" ]; then
- die "Error: Image file path '${INPUT}' is not readable"
- elif [ -z "${OUTPUT}" ]; then
- die "Error: Output file path not given"
- elif [ ! -r "$(dirname "${OUTPUT}")" ]; then
- die "Error: Output file path '${OUTPUT}' does not exist"
- fi
- mkdir vidtmp
- WIDTH=$((640*SCALE/BLOCK)); HEIGHT=$((360*SCALE/BLOCK)) # set dimensions
- FILE_SIZE=$(stat -c %s "${INPUT}") # check file size
- if [ ${COLOR} -eq 1 ]; then
- AREA=$((WIDTH*HEIGHT*3/8)); TONE="rgb"
- else
- AREA=$((WIDTH*HEIGHT/8)); TONE="gray"
- # do not spell it as grey
- fi
- FILE_SIZE=$(((FILE_SIZE+AREA-1)/AREA*AREA)); # create new file size
- cp "${INPUT}" vidtmp/tmp0; truncate -s "${FILE_SIZE}" vidtmp/tmp0 # copy and padding
- split -b${AREA} -a6 --numeric-suffixes=1 vidtmp/tmp0 vidtmp/ # splitting file
- # -b splits by number of bytes, -a adds number by digit count
- for file in vidtmp/+([0-9]); do # for each fragment
- convert -depth 1 -size "${WIDTH}"x"${HEIGHT}" "${TONE}":"${file}" "${file}".bmp # binary to bmp
- convert -scale "${BLOCK}"00% "${file}".bmp "${file}".png # bmp to png
- # do not use -resize as it will blur the iamge, use -scale instead
- done
- if [ "${MEGAS}" -eq 0 ]; then # perfect video
- ffmpeg -framerate "${RATE}" -i vidtmp/%06d.png -c:v libx264 -preset veryslow -crf 0 "${OUTPUT}"
- elif [ "${SCALE}" -ne 6 ]; then # bitrate video for non-2k
- BRATE="${matrix[${SCALE},${MEGAS}]}"00
- ffmpeg -framerate "${RATE}" -i vidtmp/%06d.png -c:v libx264 -bf 2 -minrate "${BRATE}" -maxrate "${BRATE}" "${OUTPUT}"
- elif [ "${SCALE}" -eq 6 ]; then # bitrate video for 2k
- MINRATE="${two_k[1,${MEGAS}]}"00; MAXRATE="${two_k[2,${MEGAS}]}"00
- ffmpeg -framerate "${RATE}" -i vidtmp/%06d.png -c:v libx264 -bf 2 -minrate "${MINRATE}" -maxrate "${MAXRATE}" "${OUTPUT}"
- fi; # rm vidtmp
- elif [ ${CASE_D} -eq 1 ]; then
- if [ -z "${INPUT}" ]; then
- die "Error: Image file path not given"
- elif [ ! -r "${INPUT}" ]; then
- die "Error: Image file path '${INPUT}' is not readable"
- elif [ -z "${OUTPUT}" ]; then
- die "Error: Output file path not given"
- elif [ ! -r "$(dirname "${OUTPUT}")" ]; then
- die "Error: Output file path '${OUTPUT}' does not exist"
- fi
- mkdir vidtmp
- RESOLUTION=$(ffmpeg -i hi.mp4 2>&1 | grep -Eo '[0-9]{3,4}x[0-9]{3,4}') # e.g. 640x360
- LWIDTH="${RESOLUTION%%x*}"; LHEIGHT="${RESOLUTION##*x}" # full resoluton
- RATE=$(ffmpeg -i hi.mp4 2>&1 | grep -Eo '[0-9]{2}(\.[0-9]+)? fps' | grep -Eo '[0-9]{2}(\.[0-9]+)?') # e.g. 29.97
- if [ ${COLOR} -eq 1 ]; then TONE="rgb"; else TONE="gray"; fi # one-liner???
- ffmpeg -i "${INPUT}" -r "${RATE}" vidtmp/%06d.png # video to png
- convert vidtmp/000001.png vidtmp/testing.bmp # generate testing bmp
- convert -depth 1 vidtmp/testing.bmp "${TONE}":vidtmp/binaries # generate testing binary file
- dimension() { WIDTH=$((LWIDTH/BLOCK)); HEIGHT=$((LHEIGHT/BLOCK)); }
- counter() { # <== Functiion works, and creates a variable called numtmp
- echo "$1"; old_char=""; numtmp=0; combo=0
- for (( i=1; "${i}" <= "${#1}"; i++ )); do
- new_char=$(echo "$1" | cut -c"${i}")
- if [ "${new_char}" = "${old_char}" ]; then # repeating character
- ((numtmp++)) # add count to length of repeated characters
- else # non-repeating character
- if [ "${combo}" -eq 0 ] || [ "${numtmp}" -lt "${combo}" ]; then
- combo="${numtmp}"
- fi
- numtmp=1; old_char="${new_char}"
- fi
- done
- if [ "${combo}" -eq 0 ] || [ "${numtmp}" -lt "${combo}" ]; then
- combo="${numtmp}"
- fi
- echo "${combo}";}
- if [ ${COLOR} -eq 1 ]; then
- counter $(base64 vidtmp/binaries | tr -d "\n" | cut -c1-"$((LWIDTH/2))") # 2 pixels per character <==
- BLOCK=$((combo*2));
- else
- counter $(xxd -p vidtmp/binaries | tr -d "\n" | cut -c1-"$((LWIDTH/4))") # 4 pixels per character <==
- BLOCK=$((combo*4));
- fi; dimension; for file in vidtmp/+([0-9]).png; do TMPNAME="${file%%.png}"
- convert -scale "${WIDTH}"x"${HEIGHT}" "${file}" "${TMPNAME}".bmp # png to bmp
- convert -depth 1 "${TMPNAME}".bmp "${TONE}":"${TMPNAME}" # bmp to binary
- done; cat vidtmp/+([0-9]) > "${OUTPUT}"; rm vidtmp # combining split pieces
- fi; exit
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement