123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- #!/usr/bin/env bash
- set -euo pipefail # bash strict mode
- echo "
- _ _ ______________ ________________ __
- | | | | ___| ___ \ \/ |_ _| ___\ \ / /
- | | | | |__ | |_/ / . . | | | | |_ \ V /
- | |/\| | __|| ___ \ |\/| | | | | _| \ /
- \ /\ / |___| |_/ / | | |_| |_| | | |
- \/ \/\____/\____/\_| |_/\___/\_| \_/
- VERSION: 1.5 CREATED: 1/1/2021 BY: ANON
- Use "'"-h"'" for help
- "
- # I would highly reccomend placing this script in /home/username/scripts
- # and adding the following to your .bashrc (without the # of course)
- #
- # alias webmify='~/scripts/webmify.sh'
- #
- # Change this option to where you store your converted webms. if you leave it blank, it will output converted webms to the same directory as this script
- # You must have a / at the end of the path, eg. "home/use/Videos/"
- default_path="/mnt/melchior-3/Videos/created_webms/"
- # Option flags, in case the user wants to skip the prompts
- while getopts i:o:n:f:r:s:e:m:a:k:hy flag
- do
- case "${flag}" in
- i) input=${OPTARG} ;;
- o) output=${OPTARG} ;;
- n) filename=${OPTARG} ;;
- f) fps=${OPTARG} ;;
- r) resolution=${OPTARG} ;;
- s) beginning=${OPTARG} ;;
- e) end=${OPTARG} ;;
- m) max_size=${OPTARG} ;;
- a) audio_set=${OPTARG} ;;
- k) keyframe=${OPTARG} ;;
- h) help="true" ;;
- y) skip="true" ;;
- esac
- done
- if [ -z "$help" ]
- then
- if ([ -z "$max_size" ] && [ -z "$audio_set" ]) || (! [ -z "$max_size" ] && ! [ -z "$audio_set" ])
- then
- true
- else
- echo "Error! if -a is specified, -m must also be specified, and vice versa!"
- exit
- fi
- #getting the input file, if one wasn't specified when running the script
- if [ -z "$input" ]
- then
- read -r -p "Path to input file: " input_file
- input_file="$input_file"
- else
- input_file="$input"
- fi
- echo
- #get the source video information
- default_resolution=$(ffprobe -i $input_file -v quiet -show_entries stream=height -hide_banner -of default=noprint_wrappers=1:nokey=1)
- default_length=$(ffprobe -i $input_file -v quiet -show_entries format=duration -hide_banner -of default=noprint_wrappers=1:nokey=1)
- #split up the full path to extract just the filename, sans extension
- xpath=${input_file%/*}
- xbase=${input_file##*/}
- xfext=${xbase##*.}
- xpref=${xbase%.*}
- #determine max file size
- if ! [ -z "$max_size" ]
- then
- max_file_size=$max_size
- if [ $audioset == "y" ]
- then
- audioset="-c:a libvorbis "
- else
- audioset="-an "
- fi
- else
- #ask the user for target filesize based on 4chan limits
- #they are slightly below to limit to account for ffmpeg using average bitrates and usually being slightly over-size
- read -r -p "Posting to WSG/GIF (audio and higher filesize)? [y/N]
- Or type 'c' for a custom value " response
- case "$response" in
- [yY][eE][sS]|[yY])
- max_file_size=4950
- audioset="-c:a libvorbis "
- ;;
- [cC])
- read -r -p "Enter max filesize in bytes: " max_file_size
- read -r -p "Would you like audio? " response
- case "$response" in
- [yY][eE][sS]|[yY])
- audioset="-c:a libvorbis "
- ;;
- *)
- audioset="-an "
- ;;
- esac
- ;;
- *)
- max_file_size=2950
- audioset="-an "
- ;;
- esac
- echo
- fi
- #determine output location
- if ! [ -z "$output" ]
- then
- output_filename=$output$xpref.gif
- else
- # Ask the user for the output path, or use default if not provided
- if [ -z "$skip" ]
- then
- echo Please enter the destination path.
- echo Example: '$HOME/Videos/'
- echo Leave Blank: Default path "($default_path)"
- read -r -p "Destination path: " path
- fi
- if [ -z "$path" ]
- then
- path=$default_path
- else
- true
- fi
- if [ -z "$skip" ]
- then
- echo Please enter the output filename.
- echo Example: 'My_Movie'
- echo Leave Blank: Default filename "($xpref)"
- read -r -p "output filename: " filename
- fi
- if [ -z "$filename" ]
- then
- filename=$xpref
- else
- true
- fi
- output_filename=$path$filename.webm
- echo
- fi
- if [ ! -d $path ]; then
- mkdir -p $path;
- fi
- #determine the output framerate
- if [ -z $fps ]
- then
- if [ -z "$skip" ]
- then
- echo Please enter webm framerate '(fps)'.
- echo Example: 30
- echo Leave Blank: Source video framerate
- read -r -p "Framerate: " fps
- echo
- fi
- if [ -z $fps ]; then fps=$default_fps; fi;
- elif [ $fps == "d" ]
- then
- fps=$default_fps
- fi
- #determine the keyframe interval
- if [ -z $keyframe ]
- then
- if [ -z "$skip" ]
- then
- echo Please enter keyframe interval in frames.
- echo "If you don't know what this means it's best to leave it blank."
- echo Example: 30
- echo Leave Blank: Source keyframe interval.
- read -r -p "Keyframe interval: " keyframe
- echo
- fi
- if ! [ -z $keyframe ]
- then
- keyframe=" -g $keyframe "
- fi
- fi
- #determine the output resolution
- if [ -z $resolution ]
- then
- if [ -z "$skip" ]
- then
- echo Please enter webm vertical render resolution.
- echo Example: 720
- echo Leave Blank: Source video resolution.
- read -r -p "Resolution: " resolution
- echo
- fi
- if [ -z $resolution ]; then resolution=$default_resolution; fi;
- elif [ $resolution == "d" ]
- then
- resolution=$default_resolution
- fi
- #determine where to start the clip
- if ! [ -z "$beginning" ]
- then
- start=$beginning
- else
- if [ -z "$skip" ]
- then
- #ask the user where the encode should start (in seconds offset from the beginning of the source)
- echo Please enter webm rendering offset in SECONDS.
- echo Example: 31
- echo Leave Blank: Start of source video.
- read -r -p "Offset: " start
- echo
- fi
- fi
- if ! [ -z "$start" ] && ! [ "$start" == "0" ]
- then
- startset="-ss $start "
- else
- start="Start of video"
- fi
- #determine where to end the clip
- if ! [ -z "$end" ]
- then
- [[ "$end" == "end" ]] && length=$default_length || true
- length=$end
- else
- if [ -z "$skip" ]
- then
- #ask the user where the encode should end (in seconds offset from the beginning of the source)
- echo Please enter webm rendering length in SECONDS.
- echo Example: 15
- echo Leave Blank: Entire source video.
- read -r -p "Length: " length
- echo
- fi
- fi
- #determine the target bitrate
- #the calculation for this is: (8 [number of bits in a byte] * maximum file sile [in kilobytes]) / total legnth
- #ffmpeg caluclates bitrate in kilobits per second, hence the converion from kilobytes to kilobits
- if ! [ -z "$length" ] && ! [ "$length" == "end" ]
- then
- lengthset="-t $length "
- bitrate=$(echo "8*$max_file_size/$length" | bc)'K'
- else
- length=$default_length
- bitrate=$(echo "8*$max_file_size/$length" | bc)'K'
- length="End of Video"
- fi
- #tell the user what we've just done, and ask them if these settings are ok
- echo "Creating webm with the following settings:
- Resolution: $resolution
- Framerate: $fps
- Start at: $start
- End at: $length
- Bitrate: $bitrate
- Output to: $output_filename
- "
- # i totally nabbed this from github
- # https://github.com/fearside/ProgressBar/blob/master/progressbar.sh
- function ProgressBar {
- # Process data
- let _progress=(${1}*100/${2}*100)/100
- let _done=(${_progress}*4)/10
- let _left=40-$_done
- # Build progressbar string lengths
- _done=$(printf "%${_done}s")
- _left=$(printf "%${_left}s")
- # 1.2 Build progressbar strings and print the ProgressBar line
- # 1.2.1 Output example:
- # 1.2.1.1 Progress : [########################################] 100%
- printf "\rProgress : [${_done// /#}${_left// /-}] ${_progress}%%"
- }
- function DoTheThing {
- #two-pass encoding for best quality and to limit filesize to the desired limit
- ProgressBar 10 100
- ffmpeg -i $input_file $startset$lengthset-c:v libvpx -b:v $bitrate $audioset$keyframe-sn -threads 0 -hide_banner -loglevel error -f webm -pass 1 -y null
- ProgressBar 50 100
- ffmpeg -i $input_file $startset$lengthset-c:v libvpx -b:v $bitrate -vf fps=$fps,scale=-1:$resolution $audioset$keyframe -sn -threads 0 -hide_banner -loglevel error -pass 2 -y "$output_filename"
- ProgressBar 75 100
- sleep 0.1
- ProgressBar 100 100
- sleep 0.1
- echo "
- All done!
- ⣿⡇⣿⣿⣿⠛⠁⣴⣿⡿⠿⠧⠹⠿⠘⣿⣿⣿⡇⢸⡻⣿⣿⣿⣿⣿⣿⣿
- ⢹⡇⣿⣿⣿⠄⣞⣯⣷⣾⣿⣿⣧⡹⡆⡀⠉⢹⡌⠐⢿⣿⣿⣿⡞⣿⣿⣿
- ⣾⡇⣿⣿⡇⣾⣿⣿⣿⣿⣿⣿⣿⣿⣄⢻⣦⡀⠁⢸⡌⠻⣿⣿⣿⡽⣿⣿
- ⡇⣿⠹⣿⡇⡟⠛⣉⠁⠉⠉⠻⡿⣿⣿⣿⣿⣿⣦⣄⡉⠂⠈⠙⢿⣿⣝⣿
- ⠤⢿⡄⠹⣧⣷⣸⡇⠄⠄⠲⢰⣌⣾⣿⣿⣿⣿⣿⣿⣶⣤⣤⡀⠄⠈⠻⢮
- ⠄⢸⣧⠄⢘⢻⣿⡇⢀⣀⠄⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠄⢀
- ⠄⠈⣿⡆⢸⣿⣿⣿⣬⣭⣴⣿⣿⣿⣿⣿⣿⣿⣯⠝⠛⠛⠙⢿⡿⠃⠄⢸
- ⠄⠄⢿⣿⡀⣿⣿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⡾⠁⢠⡇⢀
- ⠄⠄⢸⣿⡇⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣏⣫⣻⡟⢀⠄⣿⣷⣾
- ⠄⠄⢸⣿⡇⠄⠈⠙⠿⣿⣿⣿⣮⣿⣿⣿⣿⣿⣿⣿⣿⡿⢠⠊⢀⡇⣿⣿
- ⠒⠤⠄⣿⡇⢀⡲⠄⠄⠈⠙⠻⢿⣿⣿⠿⠿⠟⠛⠋⠁⣰⠇⠄⢸⣿⣿⣿
- ⠄⠄⠄⣿⡇⢬⡻⡇⡄⠄⠄⠄⡰⢖⠔⠉⠄⠄⠄⠄⣼⠏⠄⠄⢸⣿⣿⣿
- ⠄⠄⠄⣿⡇⠄⠙⢌⢷⣆⡀⡾⡣⠃⠄⠄⠄⠄⠄⣼⡟⠄⠄⠄⠄⢿⣿⣿
- You can find the finished file at: $output_filename
- "
- }
- read -r -p "Start the conversion? [Y/n]: " continue
- echo
- case "$continue" in
- [yY][eE][sS]|[yY])
- DoTheThing
- ;;
- *)
- exit
- ;;
- esac
- #Thanks for using my script! <3
- #Below is the help text
- else
- cat <<EOF
- NAME
- webmify - convert a video file into a webm using ffmpeg
- SYNOPSIS
- webmify [OPTIONS]
- webmify
- DESCRIPTION
- Designed to get the best quality WEBM for psoting on 4chan. Options for various board file sizes and audio restrcitions.
- Convert a single INPUT file to an OUTPUT directory. The output file will use the same name as the source.
- Arguments are optional. If no arguments are specified, the user is prompted for conversion settings.
- I highly reccomend placing this script in $HOME/Scripts and creating an alias
- alias wbm='$HOME/Scripts/webmify.sh"
- OPTIONS
- -i
- INPUT file.
- -o
- OUTPUT directory. Cannot be a filename.
- Must end in /
- -n
- Output FILENAME. Should not comtain spaces.
- -f
- Desired output FRAMERATE in frames per second
- -r
- Desired output vertical RESOLUTION.
- Example: 720 for 720p
- -s
- Time to START the encode, in seconds from the beginning of the video.
- This will trim off N number of seconds from the beginning of the video.
- -e
- When the output file should END, in seconds from the beginning of the video.
- Cannot be longer than the source length.
- -m
- Specify the MAX FILE SIZE in bytes.
- Because of how FFMPEG works, this should be a little under the actual desired file size.
- Example: 4900 for ~5MB
- If -m is specified, -a MUST ALSO e specified.
- -a
- Specify if the output should have AUDIO or not.
- 'y' for audio, anything else for no audio.
- If -a is specified, -m MUST ALSO e specified.
- -y
- Will skip all user prompts. If a certain value is not specified, the default will be used.
- User is still prompted for INPUT file, and for which 4chan board to post on (determines MAX FILE SIZE/AUDIO).
- AUTHOR
- Just a guy trying to make some webms
- COPYRIGHT
- You can use this shit however you want. I give you permission.
- The above copyright notice, this permission notice and the word "NIGGER" shall be included in all copies or substantial portions of the Software.
- SEE ALSO
- GIFY (probably in the same folder as this script)
- EOF
- fi
|