Advertisement
Guest User

SnowcrashVideo

a guest
Feb 13th, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 6.28 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. exec 5> debug_snowvid.txt; BASH_XTRACEFD="5"; PS4='$LINENO: '; set -x # debugging
  4. die() { echo "$*" >&2;  exit 2; } # Call a usage function from here as well.
  5.  
  6. while getopts edcs:b:m:r:i:o: opt
  7. do
  8.     case $opt in
  9.         e) CASE_E=1;; # for encoding
  10.         d) CASE_D=1;; # for decoding
  11.  
  12.         c) COLOR=1;; # color mode
  13.         s) SCALE="$OPTARG";; # either 1, 2, 3, 4, 6
  14.         b) BLOCK="$OPTARG";; # either 4, 8, 16
  15.         m) MEGAS="$OPTARG";; # 0=perfect, 1=SDR_low, 2=HDR_low, 3=SDR_hi, 4=HDR_hi
  16.         r) RATE="$OPTARG";; # either 24, 30, 48, 60
  17.  
  18.         i) INPUT="$OPTARG";; # input file
  19.         o) OUTPUT="$OPTARG";; # output file
  20.     esac
  21. done
  22.  
  23. #matrix[scale,megas]
  24. declare -A matrix # for 1, 2, 3, 4
  25. matrix[1,1]=10; matrix[1,2]=0; matrix[1,3]=15; matrix[1,4]=0;
  26. matrix[2,1]=50; matrix[2,2]=65; matrix[2,3]=75; matrix[2,4]=95;
  27. matrix[3,1]=80; matrix[3,2]=100; matrix[3,3]=120; matrix[3,4]=150;
  28. matrix[4,1]=160; matrix[4,2]=200; matrix[4,3]=240; matrix[4,4]=300;
  29. declare -A two_k # for 6
  30. two_k[1,1]=350; two_k[1,2]=440; two_k[1,3]=530; two_k[1,4]=660;
  31. two_k[2,1]=450; two_k[2,2]=560; two_k[2,3]=680; two_k[2,4]=850;
  32.  
  33. if [ $((CASE_E+CASE_D)) -eq 0 ]; then
  34.     die "Error: need a function flag"
  35. elif [ $((CASE_E+CASE_D)) -eq 2 ]; then
  36.     die "Error: Multiple function flags were given"
  37. fi
  38. shopt -s extglob
  39. if [ ${CASE_E} -eq 1 ]; then
  40.     if [[ ${SCALE} != @(1|2|3|4|6) ]]; then
  41.         die "Error: scale is not 1, 2, 3, 4 or 6"
  42.     elif [[ ${BLOCK} != @(4|8|16) ]]; then
  43.         die "Error: block is not 4, 8 or 16"
  44.     elif [[ ( ${SCALE} == @(1|3) ) && ( ${BLOCK} == 16 ) ]]; then
  45.         die "Error; scale is odd while block is 16"
  46.     elif [[ ${RATE} != @(24|30|48|60) ]]; then
  47.         die "Error: rate is not either 24, 30, 48 or 60"
  48.     elif [ -z "${INPUT}" ]; then
  49.         die "Error: Image file path not given"
  50.     elif [ ! -r "${INPUT}" ]; then
  51.         die "Error: Image file path '${INPUT}' is not readable"
  52.     elif [ -z "${OUTPUT}" ]; then
  53.         die "Error: Output file path not given"
  54.     elif [ ! -r "$(dirname "${OUTPUT}")" ]; then
  55.         die "Error: Output file path '${OUTPUT}' does not exist"
  56.     fi
  57.     mkdir vidtmp
  58.     WIDTH=$((640*SCALE/BLOCK)); HEIGHT=$((360*SCALE/BLOCK)) # set dimensions
  59.     FILE_SIZE=$(stat -c %s "${INPUT}") # check file size
  60.     if [ ${COLOR} -eq 1 ]; then
  61.         AREA=$((WIDTH*HEIGHT*3/8)); TONE="rgb"
  62.     else
  63.         AREA=$((WIDTH*HEIGHT/8)); TONE="gray"
  64.         # do not spell it as grey
  65.     fi
  66.     FILE_SIZE=$(((FILE_SIZE+AREA-1)/AREA*AREA)); # create new file size
  67.     cp "${INPUT}" vidtmp/tmp0; truncate -s "${FILE_SIZE}" vidtmp/tmp0 # copy and padding
  68.     split -b${AREA} -a6 --numeric-suffixes=1 vidtmp/tmp0 vidtmp/ # splitting file
  69.     # -b splits by number of bytes, -a adds number by digit count
  70.     for file in vidtmp/+([0-9]); do # for each fragment
  71.         convert -depth 1 -size "${WIDTH}"x"${HEIGHT}" "${TONE}":"${file}" "${file}".bmp # binary to bmp
  72.         convert -scale "${BLOCK}"00% "${file}".bmp "${file}".png # bmp to png
  73.         # do not use -resize as it will blur the iamge, use -scale instead
  74.     done
  75.     if [ "${MEGAS}" -eq 0 ]; then # perfect video
  76.         ffmpeg -framerate "${RATE}" -i vidtmp/%06d.png -c:v libx264 -preset veryslow -crf 0 "${OUTPUT}"
  77.     elif [ "${SCALE}" -ne 6 ]; then # bitrate video for non-2k
  78.         BRATE="${matrix[${SCALE},${MEGAS}]}"00
  79.         ffmpeg -framerate "${RATE}" -i vidtmp/%06d.png -c:v libx264 -bf 2 -minrate "${BRATE}" -maxrate "${BRATE}" "${OUTPUT}"
  80.     elif [ "${SCALE}" -eq 6 ]; then # bitrate video for 2k
  81.         MINRATE="${two_k[1,${MEGAS}]}"00; MAXRATE="${two_k[2,${MEGAS}]}"00
  82.         ffmpeg -framerate "${RATE}" -i vidtmp/%06d.png -c:v libx264 -bf 2 -minrate "${MINRATE}" -maxrate "${MAXRATE}" "${OUTPUT}"
  83.     fi; # rm vidtmp
  84.  
  85. elif [ ${CASE_D} -eq 1 ]; then
  86.     if [ -z "${INPUT}" ]; then
  87.         die "Error: Image file path not given"
  88.     elif [ ! -r "${INPUT}" ]; then
  89.         die "Error: Image file path '${INPUT}' is not readable"
  90.     elif [ -z "${OUTPUT}" ]; then
  91.         die "Error: Output file path not given"
  92.     elif [ ! -r "$(dirname "${OUTPUT}")" ]; then
  93.         die "Error: Output file path '${OUTPUT}' does not exist"
  94.     fi
  95.     mkdir vidtmp
  96.     RESOLUTION=$(ffmpeg -i hi.mp4 2>&1 | grep -Eo '[0-9]{3,4}x[0-9]{3,4}') # e.g. 640x360
  97.     LWIDTH="${RESOLUTION%%x*}"; LHEIGHT="${RESOLUTION##*x}" # full resoluton
  98.     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
  99.     if [ ${COLOR} -eq 1 ]; then TONE="rgb"; else TONE="gray"; fi # one-liner???
  100.     ffmpeg -i "${INPUT}" -r "${RATE}" vidtmp/%06d.png # video to png
  101.     convert vidtmp/000001.png vidtmp/testing.bmp # generate testing bmp
  102.     convert -depth 1 vidtmp/testing.bmp "${TONE}":vidtmp/binaries # generate testing binary file
  103.     dimension() { WIDTH=$((LWIDTH/BLOCK)); HEIGHT=$((LHEIGHT/BLOCK)); }
  104.     counter() { # <== Functiion works, and creates a variable called numtmp
  105.         echo "$1"; old_char=""; numtmp=0; combo=0
  106.         for (( i=1; "${i}" <= "${#1}"; i++ )); do
  107.             new_char=$(echo "$1" | cut -c"${i}")
  108.             if [ "${new_char}" = "${old_char}" ]; then # repeating character
  109.                 ((numtmp++)) # add count to length of repeated characters
  110.             else # non-repeating character
  111.                 if [ "${combo}" -eq 0 ] || [ "${numtmp}" -lt "${combo}" ]; then
  112.                     combo="${numtmp}"
  113.                 fi
  114.             numtmp=1; old_char="${new_char}"
  115.             fi
  116.         done
  117.         if [ "${combo}" -eq 0 ] || [ "${numtmp}" -lt "${combo}" ]; then
  118.             combo="${numtmp}"
  119.         fi
  120.     echo "${combo}";}
  121.     if [ ${COLOR} -eq 1 ]; then
  122.         counter $(base64 vidtmp/binaries | tr -d "\n" | cut -c1-"$((LWIDTH/2))") # 2 pixels per character <==
  123.         BLOCK=$((combo*2));
  124.     else
  125.         counter $(xxd -p vidtmp/binaries | tr -d "\n" | cut -c1-"$((LWIDTH/4))") # 4 pixels per character <==
  126.         BLOCK=$((combo*4));
  127.     fi; dimension; for file in vidtmp/+([0-9]).png; do TMPNAME="${file%%.png}"
  128.         convert -scale "${WIDTH}"x"${HEIGHT}" "${file}" "${TMPNAME}".bmp # png to bmp
  129.         convert -depth 1 "${TMPNAME}".bmp "${TONE}":"${TMPNAME}" # bmp to binary
  130.     done; cat vidtmp/+([0-9]) > "${OUTPUT}"; rm vidtmp # combining split pieces
  131. fi; exit
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement