126 lines
3.8 KiB
Bash
126 lines
3.8 KiB
Bash
#!/bin/bash
|
|
|
|
# This file is part of video2d-2x.
|
|
#
|
|
# video2d-2x is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
function extension_by_codec () # $1: Codec
|
|
{
|
|
local Ext=""
|
|
for Mux in muxer demuxer
|
|
do
|
|
# Where is my json?!
|
|
Ext=$(
|
|
ffprobe -v quiet -h $Mux="$1" | \
|
|
grep 'Common extensions:' | \
|
|
sed -r 's|^.+: ([^,\.]+).+|\1|')
|
|
if [[ -n "$Ext" ]]; then
|
|
echo "$Ext"
|
|
break
|
|
fi
|
|
done
|
|
}
|
|
|
|
function extract_attachments ()
|
|
{
|
|
pushd "$AttachmentsDir"
|
|
|
|
ffmpeg -hide_banner -dump_attachment:t "" -i "$InputFile"
|
|
|
|
# There is no error checking,
|
|
# because ffmpeg always throws an error:
|
|
# "At least one output file must be specified",
|
|
# although it successfully saves attachments.
|
|
|
|
popd
|
|
}
|
|
|
|
function extract_chapters ()
|
|
{
|
|
# TODO: Convert $ChaptersJson to mkv-compatible format?
|
|
echo "DUMMY"
|
|
}
|
|
|
|
function extract_framedurations () # $1: stream index
|
|
{
|
|
local FileIndex=0
|
|
echo "ffconcat version 1.0" > "$FrameDurationList"
|
|
while read Line
|
|
do
|
|
if echo "$Line" | grep -qF 'pts_time='; then
|
|
((FileIndex++))
|
|
printf "file \'./$(basename $FramesUpscaledDir)/%06d.png\'\n" "$FileIndex" >> "$FrameDurationList"
|
|
echo "inpoint $(echo "$Line" | grep -Po '\d+\.\d+')" >> "$FrameDurationList"
|
|
elif echo "$Line" | grep -qF 'duration_time='; then
|
|
echo "duration $(echo "$Line" | grep -Po '\d+\.\d+')" >> "$FrameDurationList"
|
|
fi
|
|
done < <(ffprobe -v quiet -show_entries packet=pts_time,duration_time -select_streams "$Index" "$InputFile")
|
|
}
|
|
|
|
if [[ -z "$1" ]]; then
|
|
echo "You must specify the video file"
|
|
exit "$PARAMETER_ERROR"
|
|
else
|
|
InputFile=$(readlink -e "$1")
|
|
fi
|
|
|
|
if ! [[ -r "$InputFile" ]]; then
|
|
echo "Read file error: \"$InputFile\""
|
|
exit "$FILE_READ_ERROR"
|
|
fi
|
|
|
|
rm -rf "$AudioDir"; mkdir -p "$AudioDir"
|
|
rm -rf "$VideoDir"; mkdir -p "$VideoDir"
|
|
rm -rf "$SubtitlesDir"; mkdir -p "$SubtitlesDir"
|
|
rm -rf "$ChaptersDir"; mkdir -p "$ChaptersDir"
|
|
rm -rf "$AttachmentsDir"; mkdir -p "$AttachmentsDir"
|
|
|
|
ffprobe -v quiet -print_format json -show_streams "$InputFile" > "$StreamsJson"
|
|
ffprobe -v quiet -print_format json -show_format "$InputFile" > "$FormatJson"
|
|
ffprobe -v quiet -print_format json -show_chapters "$InputFile" > "$ChaptersJson"
|
|
|
|
StreamCount=$(jq -r '.format.nb_streams' "$FormatJson")
|
|
|
|
for (( Index=0; Index < StreamCount; Index++ ))
|
|
do
|
|
Type=$(jq -r ".streams[$Index].codec_type" "$StreamsJson")
|
|
Codec=$(jq -r ".streams[$Index].codec_name" "$StreamsJson")
|
|
Extension=$(extension_by_codec "$Codec")
|
|
|
|
if [[ -z "$Extension" ]]; then
|
|
echo "No extension for codec \"$Codec\""
|
|
exit "$NO_EXTENSION_FOR_CODEC"
|
|
fi
|
|
|
|
case "$Type" in
|
|
video )
|
|
extract_framedurations "$Index"
|
|
ffmpeg -hide_banner -i "$InputFile" -map "0:$Index" -c:v copy "$VideoDir/$Index.$Extension"
|
|
if [[ "$?" != 0 ]]; then exit "$EXTRACT_AUDIO_ERROR"; fi ;;
|
|
audio )
|
|
ffmpeg -hide_banner -i "$InputFile" -map "0:$Index" -c:a copy "$AudioDir/$Index.$Extension"
|
|
if [[ "$?" != 0 ]]; then exit "$EXTRACT_VIDEO_ERROR"; fi ;;
|
|
subtitle )
|
|
ffmpeg -hide_banner -i "$InputFile" -map "0:$Index" "$SubtitlesDir/$Index.$Extension"
|
|
if [[ "$?" != 0 ]]; then exit "$EXTRACT_SUBTITLE_ERROR"; fi ;;
|
|
attachment )
|
|
continue ;;
|
|
* )
|
|
echo "Unknown codec type: \"$Type\""
|
|
exit "$UNKNOWN_CODEC_TYPE_ERROR" ;;
|
|
esac
|
|
done
|
|
|
|
extract_attachments
|