2013-03-03 00:01:20 +01:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
## TODO: audio quality. Copy if AAC or OGG <320k.
|
|
|
|
## TODO: crop options.
|
|
|
|
## TODO: handle srt encoding.
|
|
|
|
|
|
|
|
if [ -z "$(command -v ffmpeg)" ]; then
|
|
|
|
echo "ffmpeg required."
|
|
|
|
exit
|
|
|
|
fi
|
|
|
|
|
|
|
|
_printhelp()
|
|
|
|
{
|
|
|
|
cat <<EOF
|
2013-03-03 11:19:50 +01:00
|
|
|
Usage: ${1##*/} [OPTIONS] FILES|FOLDERS
|
2013-03-03 00:01:20 +01:00
|
|
|
|
|
|
|
Transcode FILES or files found in FOLDERS to .mkv with x264 and ogg. Output
|
|
|
|
files are the same as the original, with time appended. You can customize
|
|
|
|
encoding with the TC_* variables.
|
|
|
|
|
2013-07-14 13:27:25 +02:00
|
|
|
-c: Copy streams (no reencoding).
|
2013-09-21 18:09:18 +02:00
|
|
|
-f: Remove source when done.
|
2013-05-03 23:44:53 +02:00
|
|
|
-h: Display this help.
|
2013-05-14 16:38:27 +02:00
|
|
|
-o OPT: Additional options.
|
2013-05-03 23:44:53 +02:00
|
|
|
-s: Sample of 5 minutes.
|
|
|
|
-S MIN: Sample of MIN minutes.
|
2013-05-14 16:38:27 +02:00
|
|
|
-t: Remove all "title" metadata.
|
2013-05-05 10:19:01 +02:00
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
2013-05-14 16:38:27 +02:00
|
|
|
* Exchange stream 1 an 2 by first removing them, then reading them in the
|
2013-05-05 10:19:01 +02:00
|
|
|
desired order.
|
|
|
|
|
|
|
|
${1##*/} -o '-map -0:1 -map -0:2 -map 0:2 -map 0:1' input.mkv
|
|
|
|
|
|
|
|
* Change audio stream 1 title and remove audio stream 2 title:
|
|
|
|
|
|
|
|
${1##*/} -o '-metadata:s:a:0 title="FR: OGG Stereo" -metadata:s:a:1 title=' input.mkv
|
|
|
|
|
2013-03-03 00:01:20 +01:00
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
TC_SAMPLE=""
|
2013-05-05 10:19:01 +02:00
|
|
|
TC_USER_OPT=""
|
2013-07-14 13:27:25 +02:00
|
|
|
TC_REMOVE_TITLE=false
|
|
|
|
TC_VIDEO_CODEC="libx264"
|
|
|
|
TC_AUDIO_CODEC="libvorbis"
|
2013-08-04 11:29:35 +02:00
|
|
|
TC_VIDEO_OPT="-preset slow -crf 20"
|
|
|
|
|
|
|
|
## What to do if file exists:
|
|
|
|
# -y overwrite
|
|
|
|
# -n do not overwrite.
|
|
|
|
TC_OVERWRITE="-n"
|
2013-09-21 18:09:18 +02:00
|
|
|
OPT_OVERWRITE=false
|
2013-08-04 11:29:35 +02:00
|
|
|
|
|
|
|
## WARNING: we mix down audio to 2 channels with '-ac 2'. This greatly reduce
|
|
|
|
## file size and avoid any confusion for playback, which is often the case when
|
|
|
|
## converting DTS to any other format because DTS has embedded channel
|
|
|
|
## description which is not available in other formats.
|
|
|
|
TC_AUDIO_OPT="-b:a 192k -ac 2"
|
2013-03-03 00:01:20 +01:00
|
|
|
|
2013-07-14 13:27:25 +02:00
|
|
|
while getopts ":cfho:sS:t" opt; do
|
2013-03-03 00:01:20 +01:00
|
|
|
case $opt in
|
2013-07-14 13:27:25 +02:00
|
|
|
c)
|
|
|
|
TC_VIDEO_OPT=""
|
|
|
|
TC_AUDIO_OPT=""
|
|
|
|
TC_VIDEO_CODEC="copy"
|
|
|
|
TC_AUDIO_CODEC="copy" ;;
|
2013-03-03 00:01:20 +01:00
|
|
|
f)
|
2013-09-21 18:09:18 +02:00
|
|
|
TC_OVERWRITE="-y"
|
|
|
|
OPT_OVERWRITE=true;;
|
2013-03-03 00:01:20 +01:00
|
|
|
h)
|
|
|
|
_printhelp "$0"
|
2013-07-14 13:27:25 +02:00
|
|
|
exit 1 ;;
|
2013-05-05 10:19:01 +02:00
|
|
|
o)
|
2013-07-14 13:27:25 +02:00
|
|
|
TC_USER_OPT="$OPTARG" ;;
|
2013-03-03 00:01:20 +01:00
|
|
|
s)
|
2013-07-14 13:27:25 +02:00
|
|
|
TC_SAMPLE="-ss 60 -t 360" ;;
|
2013-05-03 23:44:53 +02:00
|
|
|
S)
|
2013-07-14 13:27:25 +02:00
|
|
|
TC_SAMPLE="-ss 60 -t $((60*$OPTARG))" ;;
|
2013-05-14 16:38:27 +02:00
|
|
|
t)
|
2013-07-14 13:27:25 +02:00
|
|
|
TC_REMOVE_TITLE=true ;;
|
2013-03-03 00:01:20 +01:00
|
|
|
?)
|
|
|
|
_printhelp "$0"
|
2013-07-14 13:27:25 +02:00
|
|
|
exit 1 ;;
|
2013-03-03 00:01:20 +01:00
|
|
|
:)
|
|
|
|
echo "Missing argument."
|
2013-03-03 11:19:50 +01:00
|
|
|
_printhelp "$0"
|
2013-07-14 13:27:25 +02:00
|
|
|
exit 1 ;;
|
2013-03-03 00:01:20 +01:00
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
shift $(($OPTIND - 1))
|
|
|
|
|
|
|
|
|
|
|
|
if [ $# -eq 0 ]; then
|
2013-05-05 20:57:20 +02:00
|
|
|
_printhelp "$0"
|
2013-03-03 00:01:20 +01:00
|
|
|
exit
|
|
|
|
fi
|
|
|
|
|
|
|
|
## Zsh compatibility. We need it otherwise word splitting of parameter like
|
|
|
|
## TC_SAMPLE will not work.
|
|
|
|
STATUS="$(set -o | grep 'shwordsplit' | awk '{print $2}')"
|
|
|
|
[ "$STATUS" = "off" ] && set -o shwordsplit
|
|
|
|
|
|
|
|
_tc_transcode()
|
|
|
|
{
|
2013-05-05 20:57:20 +02:00
|
|
|
cat<<EOF
|
|
|
|
================================================================================
|
2013-05-14 16:38:27 +02:00
|
|
|
User options: ${TC_USER_OPT:-None}
|
|
|
|
Sample: ${TC_SAMPLE:-No}
|
|
|
|
Clear 'Title': $TC_REMOVE_TITLE
|
2013-05-05 20:57:20 +02:00
|
|
|
================================================================================
|
|
|
|
EOF
|
|
|
|
|
2013-05-14 16:38:27 +02:00
|
|
|
STREAM_TITLE=""
|
2013-07-14 13:27:25 +02:00
|
|
|
if $TC_REMOVE_TITLE; then
|
2013-05-14 16:38:27 +02:00
|
|
|
STREAM_NUM=$(ffmpeg -i "$1" 2>&1 | grep -c 'Stream')
|
|
|
|
for i in $(seq 0 $STREAM_NUM); do
|
|
|
|
STREAM_TITLE="${STREAM_TITLE}-metadata:s:$i title= "
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
2013-09-21 18:09:18 +02:00
|
|
|
OUTPUT="${1%.*}-$(date '+%F-%H%M%S').mkv"
|
2013-07-14 13:27:25 +02:00
|
|
|
ffmpeg $TC_OVERWRITE -i "$1" \
|
|
|
|
-c:v $TC_VIDEO_CODEC $TC_VIDEO_OPT \
|
|
|
|
-c:a $TC_AUDIO_CODEC $TC_AUDIO_OPT \
|
2013-03-03 00:01:20 +01:00
|
|
|
-c:s copy \
|
2013-05-14 16:38:27 +02:00
|
|
|
-map 0 $STREAM_TITLE \
|
2013-09-21 18:09:18 +02:00
|
|
|
$TC_SAMPLE $TC_USER_OPT "$OUTPUT"
|
|
|
|
|
|
|
|
if $OPT_OVERWRITE; then
|
|
|
|
rm -f "$1"
|
|
|
|
mv -f "$OUTPUT" "${1%.*}.mkv"
|
|
|
|
fi
|
2013-03-03 00:01:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for i in "$@"; do
|
|
|
|
|
|
|
|
## Argument is a folder. We search for all video files in there.
|
|
|
|
if [ -d "$i" ]; then
|
|
|
|
|
|
|
|
## TODO: provide max-depth as option.
|
|
|
|
while read -r j; do
|
|
|
|
_tc_transcode $j
|
|
|
|
done <<EOF
|
|
|
|
$(find "$i" \( \
|
|
|
|
-iname '*.mkv' -o \
|
|
|
|
-iname '*.mp4' -o \
|
|
|
|
-iname '*.avi' -o \
|
|
|
|
-iname '*.webm' -o \
|
|
|
|
-iname '*.flv' -o \
|
|
|
|
-iname '*.wmv' -o \
|
|
|
|
-iname '*.mpg' \) )
|
|
|
|
EOF
|
|
|
|
|
|
|
|
else
|
2013-05-05 10:19:01 +02:00
|
|
|
## Argument is a regular file.
|
2013-03-03 00:01:20 +01:00
|
|
|
_tc_transcode "$i"
|
|
|
|
fi
|
|
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
## Restore Zsh previous options. This will not turn off shwordsplit if it
|
|
|
|
## was on before calling the function.
|
|
|
|
[ "$STATUS" = "off" ] && set +o shwordsplit
|