2017-11-02 22:42:30 +00:00
#!/bin/bash
2017-11-02 23:45:12 +00:00
########
# Init Variables
# Available Environment Variables:
# VIDEO_FORMATS_LOCATION: Pass a location to a different json file holding video convert configurations
# VIDEO_LOCATION: Pass a location to a different folder which holds the videos
# VIDEO_FORMATS: Pass all video formats which should trigger the conversion, seperated by ":". Example: .mp4:.wmv
# VIDEO_FFMPEG_PATH: Path to ffmpeg executable
########
########
# Environment variables as a base
########
# Video formats location
if [ -n $VIDEO_FORMATS_LOCATION ]
then
video_formats_location = $VIDEO_FORMATS_LOCATION
fi
# Video location
if [ -n $VIDEO_LOCATION ]
then
video_location = $VIDEO_LOCATION
fi
# All video formats
if [ -n $VIDEO_FORMATS ]
then
2017-11-03 00:06:51 +00:00
video_formats_string = $VIDEO_FORMATS
2017-11-02 23:45:12 +00:00
fi
# ffmpeg executable
if [ -n $VIDEO_FFMPEG_PATH ]
then
video_ffmpeg_path = $VIDEO_FFMPEG_PATH
fi
########
# Passed Options, any passed option will overwrite a previously set environment variable
########
while getopts ":c:p:v:p:h" opt; do
case $opt in
c)
video_formats_location = $OPTARG
; ;
p)
video_location = $OPTARG
; ;
v)
2017-11-03 00:06:51 +00:00
video_formats_string = $OPTARG
2017-11-02 23:45:12 +00:00
; ;
f)
video_ffmpeg_path = $OPTARG
; ;
h)
echo " AVAILABLE OPTIONS:
-c: Video Formats Location. Pass a path with a JSON config file for conversion. Defaults to 'video_formats.json' in current folder.
-p: Video Location. Pass a location to a different folder which holds the videos. Defaults to currents folder.
-v: Video Formats. Pass all video formats which should trigger the conversion, seperated by ':' . Example: .mp4:.wmv
-f: Path to ffmpeg executable. Defaults to 'ffmpeg'
-h: Print this help message.
ENVIRONMENT VARIABLES:
All settings can also be done via environment variables. However, a passed option will overwrite a previously set environment variable.
VIDEO_FORMATS_LOCATION: Pass a location to a different json file holding video convert configurations
VIDEO_LOCATION: Pass a location to a different folder which holds the videos
VIDEO_FORMATS: Pass all video formats which should trigger the conversion, seperated by ' :. Example: .mp4:.wmv
VIDEO_FFMPEG_PATH: Path to ffmpeg executable
Copyright 2017 K. Langenberg
Licensed under GNU GPLv3"
exit 0
; ;
\? )
echo " Invalid option: - $OPTARG . Use -h to print all available options. " >& 2
exit 1
; ;
:)
echo " Option - $OPTARG requires an argument. Use -h to print all available options. " >& 2
exit 1
; ;
esac
done
########
# Defaults
########
# Video Formats Location
if [ -z $video_formats_location ]
then
video_formats_location = $PWD /video_formats.json
fi
# Video Location
if [ -z $video_location ]
then
video_location = $PWD
fi
# Video Formats
2017-11-03 00:06:51 +00:00
if [ -z $video_formats_string ]
2017-11-02 23:45:12 +00:00
then
2017-11-03 00:06:51 +00:00
video_formats_string = '.mp4'
2017-11-02 23:45:12 +00:00
fi
# Default ffmpeg path
if [ -z $video_ffmpeg_path ]
then
video_ffmpeg_path = ffmpeg
fi
########
# Checks
########
2017-11-02 22:42:30 +00:00
# Check if the converterfile exists
2017-11-02 23:45:12 +00:00
if [ ! -f $video_formats_location ]
then
echo " Video Formats .json file ( $video_formats_location ) does not exist! "
exit 1;
fi
# Check if the video folder exists
if [ ! -d $video_location ]
2017-11-02 22:42:30 +00:00
then
2017-11-02 23:45:12 +00:00
echo " Video location folder ( $video_location ) does not exist! "
2017-11-02 22:42:30 +00:00
exit 1;
fi
2017-11-02 23:45:12 +00:00
# Remove end slash in video location
video_location = ${ video_location %/ }
2017-11-02 22:42:30 +00:00
2017-11-02 23:45:12 +00:00
# Loop through our convertfile
2017-11-03 00:06:51 +00:00
video_formats_file = $( <$video_formats_location )
2017-11-02 22:42:30 +00:00
2017-11-02 23:45:12 +00:00
########
2017-11-02 22:42:30 +00:00
# Run every 5 seconds
2017-11-02 23:45:12 +00:00
########
2017-11-02 22:42:30 +00:00
while true; do
2017-11-03 01:17:57 +00:00
# Remove Spaces in filename (because bash doesn't like them and would throw an error)
rename 's/ /_/g' *
2017-11-02 22:42:30 +00:00
# loop through all files
2017-11-02 23:45:12 +00:00
for file in $video_location /*; do
2017-11-02 22:42:30 +00:00
# Check if the current file is a video
2017-11-03 00:06:51 +00:00
file_format = ${ file : -4 }
if [ " ${ video_formats_string / $file_format } " != " $video_formats_string " ]
2017-11-02 22:42:30 +00:00
then
2017-11-03 00:06:51 +00:00
2017-11-02 22:42:30 +00:00
# If it is a videofile, if no "locker" already exists, create one and start converting
if [ ! -f $file .lock ]
then
# Tell the User what we're doing
echo "================"
echo " Found file: $file "
2017-11-03 00:39:38 +00:00
# Get the video width and height
2017-11-03 01:17:57 +00:00
# Hack to get the height even if the audio and video stream are in reverse order
codec_type = $( ffprobe -v quiet -show_streams -print_format json " $file " | jq --raw-output '.streams [0] .codec_type' )
2017-11-03 11:06:47 +00:00
if [ " $codec_type " = "video" ] ; then
2017-11-03 01:17:57 +00:00
video_height = $( ffprobe -v quiet -show_streams -print_format json " $file " | jq '.streams [0] .height' )
else
video_height = $( ffprobe -v quiet -show_streams -print_format json " $file " | jq '.streams [1] .height' )
fi
2017-11-03 11:06:47 +00:00
# Check if the file is a video file
if [ " $codec_type " = "null" ] ; then
echo " $file is not a video file "
else
# Create Lock file
touch $file .lock
# Create the output folder
mkdir $file .out
2017-11-02 22:42:30 +00:00
2017-11-03 11:06:47 +00:00
# Loop through all videoformats and convert them
for row in $( echo " ${ video_formats_file } " | jq -r '.[] | @base64' ) ; do
_jq( ) {
echo ${ row } | base64 --decode | jq -r ${ 1 }
}
2017-11-03 01:17:57 +00:00
2017-11-03 11:06:47 +00:00
# Check if the video is larger or as large as the format we want to convert it to
IFS = ':' read -r -a video_resolutions <<< " $( _jq '.resolution' ) "
2017-11-03 00:39:38 +00:00
2017-11-03 11:06:47 +00:00
# TODO don't ignore aspect ratio, maybe even only input a height in conversion json file, calculate the with based on aspect ration obtained from ffprobe. Setting to however force the aspect ratio
2017-11-03 00:39:38 +00:00
2017-11-03 11:06:47 +00:00
if [ " ${ video_resolutions [1] } " -le " $video_height " ]
2017-11-03 00:39:38 +00:00
then
2017-11-03 11:06:47 +00:00
echo " Converting to $( _jq '.name' ) , Resolution: $( _jq '.resolution' ) , Bitrate: $( _jq '.video_bitrate' ) , Framerate: $( _jq '.framerate' ) "
# Make Framerate optional, don't modify the framerate if it is not set
framerate = ""
if [ " $( _jq '.framerate' ) " != "null" ]
then
framerate = " -r $( _jq '.framerate' ) "
fi
# Convert
$video_ffmpeg_path -i $file -b:v $( _jq '.video_bitrate' ) $framerate -c:v $( _jq '.video_codec' ) -vf scale = $( _jq '.resolution' ) -c:a $( _jq '.audio_codec' ) -b:a $( _jq '.audio_bitrate' ) $file .out/$( basename " $file " " $file_format " ) _$( _jq '.name' ) .$( _jq '.file_ending' ) &
2017-11-03 00:39:38 +00:00
fi
2017-11-03 11:06:47 +00:00
done
2017-11-02 22:42:30 +00:00
2017-11-03 11:06:47 +00:00
# Wait until all formats are created
wait
2017-11-02 22:42:30 +00:00
2017-11-03 11:06:47 +00:00
# Cleanup: Remove the lockfile, move the original to the converted folder.
mv $file $file .out/$( basename " $file " " $file_format " ) _orig" $file_format "
rm $file .lock
touch $file .out/$( basename " $file " " $file_format " ) .done
2017-11-02 22:42:30 +00:00
2017-11-03 11:06:47 +00:00
echo " Finished Converting $file "
2017-11-02 22:42:30 +00:00
2017-11-03 11:06:47 +00:00
fi
2017-11-02 22:42:30 +00:00
echo "================"
fi
fi
done
2017-11-02 23:45:12 +00:00
# Every 5 seconds...
2017-11-02 22:42:30 +00:00
sleep 5s
done