Compare commits

..

9 Commits
master ... dev

Author SHA1 Message Date
a557e636ea add settings for preview 2020-12-28 15:44:01 +03:00
099e49e0aa feat: gen preview for ranges 2020-12-27 13:57:47 +03:00
3acbb56f87 v0.2
- add preview mode;
- deps config;
- upscale mode is selected automatically;
- add scale mode support (i.e. without noise reduction);
- refactoring.
2020-12-24 14:02:48 +03:00
bf8b8bae63
Update NOTES.md 2020-11-14 21:13:02 +03:00
423cc310a3
Update NOTES.md 2020-11-14 21:12:03 +03:00
0ccd0d28ea add NOTES.md and my thoughts about VFR 2020-11-14 21:07:57 +03:00
0ad4d4771d feat: auto-range system 2020-11-02 20:54:02 +03:00
ab46134e7b ... 2020-10-28 03:09:35 +03:00
df579e6082 init 2020-10-27 02:25:40 +03:00
17 changed files with 926 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
dependencies
input
output

44
NOTES.md Normal file
View File

@ -0,0 +1,44 @@
# About VFR support:
I can get all information about each frame like this:
`ffprobe -v quiet -show_entries packet -select_streams <stream_index> <videofile>`
And here is a way to take something specific:
`ffprobe -v quiet -show_entries packet=pts_time,duration_time -select_streams <stream_index> <videofile>`
It is possible to concatenate all frames from variable times using ffmpeg concat.
Need to make a file with the following content:
```
ffconcat version 1.0
file './frames_upscaled/000001.png'
duration 0.042000
file './frames_upscaled/000002.png'
duration 0.042000
file './frames_upscaled/000003.png'
duration 0.042000
...
```
I should note that in the case of VFR there is more than just frame time. There are two parameters: pts and dts (and they may not match).
* pts is the presentation time stamp, that is, how the frames should be displayed.
* dts is a decoding time stamp, that is, in what order the frames should be decoded.
And apparently the frames are stored in dts order, which complicates things for me.
Then merge video like this:
```
ffmpeg \
-hide_banner \
-f "concat" \
-safe 0 \
-i "$FrameDurationList" \
-vsync vfr \
-r "42" \
-vcodec "$VideoCodec" \
-preset "$Preset" \
-pix_fmt "$PixelFormat" \
$(auto_bitrate) \
$(auto_x265params) \
"$VideoUpscaled"
```
This is the closest thing I could do (this option gives VFR video at the output, all other attempts continued to create CFR) but this is still a wrong option, since if you decompose it into frames again, you can see that their duration does not match the original video.
In addition, the -r parameter is specified here. In this case, it sets the maximum FPS (not average). I don't understand why it is needed, because all the information about the frame time is already exists in the concat file (!), but if you do not specify it, ffmpeg sets it to 25fps and this is definitely not what I need

174
scripts/common.lib Normal file
View File

@ -0,0 +1,174 @@
#!/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/>.
######## Filesystem ########
readonly DepsDir="$BaseDir/dependencies"
readonly ScriptsDir="$BaseDir/scripts"
readonly SettingsDir="$BaseDir/settings"
readonly OutputDir="$BaseDir/output"
readonly FramesDir="$OutputDir/frames"
readonly AudioDir="$OutputDir/audio"
readonly VideoDir="$OutputDir/video"
readonly SubtitlesDir="$OutputDir/subtitles"
readonly ChaptersDir="$OutputDir/chapters"
readonly AttachmentsDir="$OutputDir/attachments"
readonly ReleaseDir="$OutputDir/release"
readonly PreviewDir="$OutputDir/preview"
readonly FramesUpscaledDir="${FramesDir}_upscaled"
readonly VideoUpscaledDir="${VideoDir}_upscaled"
readonly FormatJson="$OutputDir/format.json"
readonly StreamsJson="$OutputDir/streams.json"
readonly ChaptersJson="$OutputDir/chapters.json"
readonly RangesList="$OutputDir/ranges.list"
readonly DepsConf="$SettingsDir/deps.conf"
readonly Waifu2xConf="$SettingsDir/waifu2x-caffe.conf"
readonly PreviewConf="$SettingsDir/preview.conf"
readonly FfmpegConf="$SettingsDir/ffmpeg.conf"
readonly RangeGenConf="$SettingsDir/range-gen.conf"
######## Return codes ########
SUCCESS=0
OPTION_ERROR=1
PARAMETER_ERROR=2
EXTRACT_AUDIO_ERROR=3
EXTRACT_VIDEO_ERROR=4
EXTRACT_SUBTITLE_ERROR=5
EXTRACT_ATTACHMENT_ERROR=6
UNKNOWN_CODEC_TYPE_ERROR=7
NO_EXTENSION_FOR_CODEC=8
CONVERT_TO_FRAMES_ERROR=9
FILE_READ_ERROR=10
RANGES_LIST_SYNTAX_ERROR=11
SETTINGS_ERROR=12
WAIFU2X_ERROR=13
MERGE_RELEASE_ERROR=14
NO_INFO_ERROR=15
INTERRUPT=16
CREATE_UPSCALED_VIDEO_ERROR=17
######## Functions ########
function clean_line ()
{
printf "\r%$(tput cols)s\r" ""
}
function model_path () # $1: model name
{
echo "$(dirname $(readlink -e $(which waifu2x-caffe-cui)))/models/$1"
}
function framerate ()
{
local StreamCount=$(jq -r '.format.nb_streams' "$FormatJson")
for (( Index=0; Index < StreamCount; Index++ ))
do
if [[ $(jq -r ".streams[$Index].codec_type" "$StreamsJson") == "video" ]]; then
jq -r ".streams[$Index].r_frame_rate" "$StreamsJson"
break
fi
done
}
function png_num () # $1: String
{
echo "$1" | \
sed 's|.png||' | \
sed -r 's|0*([1-9][0-9]*)|\1|'
}
function check_ranges ()
{
local Errors=0
local ParamCount=0
local LineIndex=0
local LastEndFrame=""
while read Line
do
((LineIndex++))
local RangeInfo=($Line)
local ParamCount=${#RangeInfo[@]}
if [[ "$ParamCount" -eq 0 ]]; then
continue
elif [[ "$ParamCount" -eq 2 ]] || [[ "$ParamCount" -eq 3 ]]; then
local StartFrame=$(png_num ${RangeInfo[0]})
local EndFrame=$(png_num ${RangeInfo[1]})
local NoiseLevel=$(png_num ${RangeInfo[2]})
if [[ "$StartFrame" =~ ^[0-9]+$ ]]; then
if [[ -n "$LastEndFrame" ]] && [[ $(($LastEndFrame+1)) != $StartFrame ]]; then
echo "ERR [$LineIndex]: StartFrame ($StartFrame) doesn't follow the previous one ($LastEndFrame)"
((Errors++))
fi
else
echo "ERR [$LineIndex]: StartFrame $StartFrame is not valid integer"
((Errors++))
fi
if [[ "$EndFrame" =~ ^[0-9]+$ ]]; then
LastEndFrame="$EndFrame"
else
LastEndFrame=""
echo "ERR [$LineIndex]: EndFrame $EndFrame is not valid integer"
((Errors++))
fi
if [[ "$NoiseLevel" =~ ^[0-9]+$ ]]; then
if [[ "$NoiseLevel" -lt 0 ]] || [[ "$NoiseLevel" -gt 3 ]]; then
echo "ERR [$LineIndex]: NoiseLevel $NoiseLevel incorrect value (should be in the range 0-3)"
((Errors++))
fi
elif [[ -n "$NoiseLevel" ]]; then
echo "ERR [$LineIndex]: NoiseLevel $NoiseLevel is not valid integer"
((Errors++))
fi
else
echo "ERR [$LineIndex]: $ParamCount parameters received (2 or 3 expected)"
((Errors++))
fi
done < <(cat "$RangesList"; echo) # make bash not skip the last line (if there is no empty line at the end)
if [[ "$Errors" -gt 0 ]]; then
echo "Ranges list syntax: $Errors errors"
fi
return "$Errors"
}
######## Includes ########
source "$DepsConf"
######## Initialization ########
if [[ -n "$Waifu2xCaffeDir" ]]; then
PATH="$PATH:$(readlink -e $Waifu2xCaffeDir)"
fi
if [[ -n "$MkvToolNixDir" ]]; then
PATH="$PATH:$(readlink -e $MkvToolNixDir)"
fi
if [[ -n "$FfmpegDir" ]]; then
PATH="$PATH:$(readlink -e $FfmpegDir)"
fi
if [[ -t 2 ]] && [[ -z "${NO_COLOR-}" ]] && [[ "${TERM-}" != "dumb" ]]; then
DEF='\e[0m'; BLD='\e[1m'; RED='\e[31m'; GRN='\e[32m'; YLW='\e[33m'; WHT='\e[97m'
else
DEF=''; BLD=''; RED=''; GRN=''; YLW=''; WHT=''
fi

109
scripts/extract.sh Normal file
View File

@ -0,0 +1,109 @@
#!/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"
# Disable error checking
# because ffmpeg always throws an error:
# "At least one output file must be specified",
# although it successfully saves attachments.
set +e
ffmpeg -hide_banner -dump_attachment:t "" -i "$InputFile"
set -e
popd
}
function extract_chapters ()
{
# TODO: Convert $ChaptersJson to mkv-compatible format?
echo "DUMMY"
}
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 )
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

22
scripts/frames.sh Normal file
View File

@ -0,0 +1,22 @@
#!/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/>.
InputFile=$(find "$VideoDir" -mindepth 1 -maxdepth 1 -type f | head -n 1)
rm -rf "$FramesDir"; mkdir -p "$FramesDir"
ffmpeg -hide_banner -i "$InputFile" -r "$(framerate)" -f image2 "$FramesDir/%06d.png"

35
scripts/merge.sh Normal file
View File

@ -0,0 +1,35 @@
#!/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/>.
# temporary solution.
# TODO:
# Replace with creating mkv container
# with all resources using mkvmerge
rm -rf "$ReleaseDir"; mkdir -p "$ReleaseDir"
ffmpeg \
-hide_banner \
-i $(find "$VideoUpscaledDir" -type f | head -n 1) \
-i $(find "$AudioDir" -type f | head -n 1) \
-vcodec "copy" \
-acodec "copy" \
"$ReleaseDir/release.mp4"
if [[ $? -ne 0 ]]; then
exit "$MERGE_RELEASE_ERROR"
fi

135
scripts/preview.sh Normal file
View File

@ -0,0 +1,135 @@
#!/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/>.
source "$Waifu2xConf"
source "$PreviewConf"
readonly TmpFramesSrcDir="${PreviewDir}_tmpsrc"
readonly TmpFramesOutDir="${PreviewDir}_tmpout"
if ! [[ -r "$RangesList" ]]; then
echo "Read file error: \"$RangesList\""
exit "$FILE_READ_ERROR"
fi
if ! check_ranges; then
exit "$RANGES_LIST_SYNTAX_ERROR"
fi
rm -rf "$PreviewDir" "$TmpFramesSrcDir" "$TmpFramesOutDir"
mkdir -p "$PreviewDir" "$TmpFramesSrcDir" "$TmpFramesOutDir"
# Prepare frames
CopyList=""
while read Line
do
if [[ -z "$Line" ]]; then
continue
fi
RangeInfo=($Line)
StartFrame=$(png_num ${RangeInfo[0]})
EndFrame=$(png_num ${RangeInfo[1]})
TargetFrame=$((StartFrame + (EndFrame - StartFrame)/2))
CopyList+="$(printf "%06d" $TargetFrame).png " # faster than copying one by one
done < <(cat "$RangesList"; echo) # make bash not skip the last line (if there is no empty line at the end)
pushd "$FramesDir" > /dev/null
cp -f $CopyList "$TmpFramesSrcDir"
popd > /dev/null
if echo "$UseRangeNumbers" | grep -qiF "True"; then
pushd "$TmpFramesSrcDir" > /dev/null
Index=0
while read File
do
((Index+=1))
mv "$File" "$(printf "%06d" $Index).png"
done < <(find "$TmpFramesSrcDir" -type f -name '*.png' -printf '%f\n')
popd > /dev/null
fi
# Upscale (scale)
if echo "$Waifu2xScalePreview" | grep -qiF "True" && [[ "$ScaleRatio" -ne 1 ]]; then
echo "waifu2x scale"
waifu2x-caffe-cui \
--mode "scale" \
--scale_ratio "$ScaleRatio" \
--output_depth "$OutputDepth" \
--tta "$TtaMode" \
--gpu "$GpuNum" \
--process "$Process" \
--crop_size "$CropSize" \
--batch_size "$BatchSize" \
--model_dir "$(model_path $Model)" \
--input_path "$TmpFramesSrcDir" \
--output_path "$TmpFramesOutDir" \
> /dev/null
pushd "$TmpFramesOutDir" > /dev/null
while read Filename
do
NewFilename=$(echo "$Filename" | sed "s|.png|_scale${ScaleRatio}.png|")
mv "$Filename" "$PreviewDir/$NewFilename"
done < <(find "$TmpFramesOutDir" -type f -name '*.png' -printf "%f\n")
popd > /dev/null
fi
# Upscale (noise_scale)
for NoiseLevel in $Waifu2xNoiseScaleList
do
if [[ "$ScaleRatio" -eq 1 ]]; then
UpscaleMode="noise"
else
UpscaleMode="noise_scale"
fi
echo "waifu2x $UpscaleMode $NoiseLevel"
waifu2x-caffe-cui \
--mode "$UpscaleMode" \
--scale_ratio "$ScaleRatio" \
--output_depth "$OutputDepth" \
--noise_level "$NoiseLevel" \
--tta "$TtaMode" \
--gpu "$GpuNum" \
--process "$Process" \
--crop_size "$CropSize" \
--batch_size "$BatchSize" \
--model_dir "$(model_path $Model)" \
--input_path "$TmpFramesSrcDir" \
--output_path "$TmpFramesOutDir" \
> /dev/null
pushd "$TmpFramesOutDir" > /dev/null
while read Filename
do
NewFilename=$(echo "$Filename" | sed "s|.png|_scale${ScaleRatio}_noise${NoiseLevel}.png|")
mv "$Filename" "$PreviewDir/$NewFilename"
done < <(find "$TmpFramesOutDir" -type f -name '*.png' -printf "%f\n")
popd > /dev/null
done
if echo "$ResizePreivew" | grep -qiF "True"; then
echo "scale original"
mogrify -scale $(echo "$ScaleRatio * 100" | bc)% "$TmpFramesSrcDir"/*.png
pushd "$TmpFramesSrcDir" > /dev/null
mv *.png "$PreviewDir"
popd > /dev/null
fi
rm -rf "$TmpFramesSrcDir" "$TmpFramesOutDir"

29
scripts/ranges.sh Normal file
View File

@ -0,0 +1,29 @@
#!/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/>.
# Range list format:
# START_FRAME END_FRAME NOISE_LEVEL
# (separate line for each range)
# (NOISE_LEVEL is optional)
source "$RangeGenConf"
if [[ -n "$NoiseLevel" ]]; then
"$DepsDir/range-gen/range-gen.exe" -j "$Jobs" -n "$NoiseLevel" "$FramesDir" "$RangesList" "$Threshold"
else
"$DepsDir/range-gen/range-gen.exe" -j "$Jobs" "$FramesDir" "$RangesList" "$Threshold"
fi

32
scripts/test.sh Normal file
View File

@ -0,0 +1,32 @@
#!/bin/bash
Symbols=16
function HammingDistance () # $1: Prev, $2: Current
{
local Dist=0
local PrevPart
local CurrentPart
for (( i=1; i<=$Symbols; i++ ))
do
PrevPart=$((16#$(echo "$1" | cut -c "$i")))
CurrentPart=$((16#$(echo "$2" | cut -c "$i")))
Offset=$(echo $((PrevPart-CurrentPart)) | sed 's|-||')
((Dist+=Offset))
done
echo "$Dist"
}
HashList="./hash.list"
PrevHash=$(printf "%0${Symbols}s" "")
:> "$HashList"
find "$FramesDir" -type f -printf "%f\n" | \
while read Image
do
Hash=$(./dependencies/go-perceptualhash/go-perceptualhash.exe --bits 8 --digest -f "$FramesDir/$Image")
Distance=$(HammingDistance "$PrevHash" "$Hash")
PrevHash="$Hash"
echo -e "$Image\t$Hash\t$Distance"
echo -e "$Image\t$Hash\t$Distance" >> "$HashList"
done

169
scripts/upscale.sh Normal file
View File

@ -0,0 +1,169 @@
#!/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/>.
source "$Waifu2xConf"
readonly TmpFramesDir="${FramesDir}_tmp"
readonly RowTemplate="\r%-8s%-8s%-12s%-8s%-8s\n"
function upscale_mode () # $1: ScaleRatio, $2: NoiseLevel
{
local ScaleRatio="$1"
local NoiseLevel="$2"
if [[ "$ScaleRatio" -ne 1 ]] && [[ -n "$NoiseLevel" ]]; then
echo "noise_scale"
return 0
fi
if [[ "$ScaleRatio" -eq 1 ]] && [[ -n "$NoiseLevel" ]]; then
echo "noise"
return 0
fi
if [[ "$ScaleRatio" -ne 1 ]] && [[ -z "$NoiseLevel" ]]; then
echo "scale"
return 0
fi
return 1
}
function upscale_images () # $1: InputDir, $2: OutputDir, $3: ProgressBarPID, $4: ParentPID
{
waifu2x-caffe-cui \
--mode "$UpscaleMode" \
--scale_ratio "$ScaleRatio" \
--output_depth "$OutputDepth" \
--noise_level "$NoiseLevel" \
--tta "$TtaMode" \
--gpu "$GpuNum" \
--process "$Process" \
--crop_size "$CropSize" \
--batch_size "$BatchSize" \
--model_dir "$(model_path $Model)" \
--input_path "$1" \
--output_path "$2" \
> /dev/null
local RT=$?
kill "$3" 2> /dev/null
if [[ "$RT" -ne 0 ]]; then
kill -1 "$4" 2> /dev/null
fi
}
function progress_bar ()
{
local PreviousUpscaledFrame=""
local LastUpscaledFrame=""
local Total=$(png_num $LastOriginalFrame)
while [[ "$LastUpscaledFrame" != "$LastOriginalFrame" ]]
do
LastUpscaledFrame=$(ls "$FramesUpscaledDir" | sort | tail -n 1)
if [[ "$PreviousUpscaledFrame" != "$LastUpscaledFrame" ]]; then
local Done=$(png_num $LastUpscaledFrame)
printf "\r[%3d%%] %d/%d" "$(($Done*100/$Total))" "$Done" "$Total"
PreviousUpscaledFrame="$LastUpscaledFrame"
fi
sleep 1
done
}
if ! [[ -r "$RangesList" ]]; then
echo "Read file error: \"$RangesList\""
exit "$FILE_READ_ERROR"
fi
if ! check_ranges; then
exit "$RANGES_LIST_SYNTAX_ERROR"
fi
rm -rf "$TmpFramesDir"
mkdir -p "$FramesUpscaledDir"
LastOriginalFrame=$(ls "$FramesDir" | sort | tail -n 1)
LastUpscaledFrame=$(ls "$FramesUpscaledDir" | sort | tail -n 1)
if [[ "$LastUpscaledFrame" == "$LastOriginalFrame" ]]; then
echo "WARN: Upscaled frames already exists - skip."
exit "$SUCCESS"
fi
LastUpscaledFrame=$(png_num "$LastUpscaledFrame")
printf "${BLD}$RowTemplate${DEF}" "START" "END" "MODE" "NOISE" "ACTION"
while read Line
do
if [[ -z "$Line" ]]; then
continue
fi
RangeInfo=($Line)
StartFrame=$(png_num ${RangeInfo[0]})
EndFrame=$(png_num ${RangeInfo[1]})
NoiseLevel=$(png_num ${RangeInfo[2]})
UpscaleMode=$(upscale_mode "$ScaleRatio" "$NoiseLevel")
if [[ -z "$NoiseLevel" ]]; then
NoiseLevel="0"
NoiseLevelDisplay="-"
else
NoiseLevelDisplay="$NoiseLevel"
fi
clean_line
if [[ -n "$LastUpscaledFrame" ]] && [[ "$LastUpscaledFrame" -ge "$EndFrame" ]]; then
printf "$RowTemplate" "$StartFrame" "$EndFrame" "$UpscaleMode" "$NoiseLevelDisplay" "SKIP"
continue
fi
if [[ -n "$LastUpscaledFrame" ]] && [[ "$StartFrame" -lt "$LastUpscaledFrame" ]]; then
printf "$RowTemplate" "$StartFrame" "$(($LastUpscaledFrame-1))" "$UpscaleMode" "$NoiseLevelDisplay" "SKIP"
printf "$RowTemplate" "$LastUpscaledFrame" "$EndFrame" "$UpscaleMode" "$NoiseLevelDisplay" "CONTINUE"
# if waifu2x-caffe was interrupted while saving the file, a corrupted file is saved
# so it's better to start by overwriting the last upscaled file
StartFrame="$LastUpscaledFrame"
else
printf "$RowTemplate" "$StartFrame" "$EndFrame" "$UpscaleMode" "$NoiseLevelDisplay"
fi
rm -rf "$TmpFramesDir"
mkdir "$TmpFramesDir"
echo -ne "\rCopying range..."
CopyList=""
for (( i=StartFrame; i <= EndFrame; i++))
do
CopyList+="$(printf "%06d" $i).png "
done
pushd "$FramesDir" > /dev/null
cp $CopyList "$TmpFramesDir"
popd > /dev/null
clean_line
(progress_bar) &
ProgressBarPID=$!
(upscale_images "$TmpFramesDir" "$FramesUpscaledDir" "$ProgressBarPID" "$$") &
Waifu2xPID=$!
trap "kill $ProgressBarPID 2> /dev/null; exit $WAIFU2X_ERROR" HUP
trap "kill $Waifu2xPID $ProgressBarPID 2> /dev/null; echo -e '\nInterrupted'; exit $INTERRUPT" INT
wait 2> /dev/null
rm -rf "$TmpFramesDir"
done < <(cat "$RangesList"; echo) # make bash not skip the last line (if there is no empty line at the end)

73
scripts/video.sh Normal file
View File

@ -0,0 +1,73 @@
#!/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 create_default_conf ()
{
echo "\
VideoCodec=\"libx265\"
Preset=\"slow\"
PixelFormat=\"yuv420p10le\"
ConstantRateFactor=\"16\"
VideoBitrate=\"\"
x265params=\"\"
" > "$FfmpegConf"
}
function auto_x265params ()
{
if [[ -n "$x265params" ]]; then
echo '-x265-params' "$x265params"
fi
}
function auto_bitrate ()
{
if [[ -n "$ConstantRateFactor" ]]; then
echo '-crf' "$ConstantRateFactor"
elif [[ -n "$VideoBitrate" ]]; then
echo '-b:v' "$VideoBitrate"
else
exit "$SETTINGS_ERROR"
fi
}
if ! [[ -e "$FfmpegConf" ]]; then
create_default_conf
fi
source "$FfmpegConf"
rm -rf "$VideoUpscaledDir"; mkdir -p "$VideoUpscaledDir"
VideoUpscaled="$VideoUpscaledDir/video.mp4"
ffmpeg \
-hide_banner \
-f "image2" \
-framerate "$(framerate)" \
-i "$FramesUpscaledDir/%06d.png" \
-r "$(framerate)" \
-vcodec "$VideoCodec" \
-preset "$Preset" \
-pix_fmt "$PixelFormat" \
$(auto_bitrate) \
$(auto_x265params) \
"$VideoUpscaled"
if [[ $? -ne 0 ]]; then
exit "$CREATE_UPSCALED_VIDEO_ERROR"
fi

9
settings/deps.conf Normal file
View File

@ -0,0 +1,9 @@
### Dependencies settings ###
# By default, the script will look for utilities (ffmpeg, waifu2x-caffe-cui, etc) in the $PATH,
# specify directories here if they are not accessible via $PATH.
# You can also specify a relative path, the directory with the "video2d-2x" script is the base directory.
Waifu2xCaffeDir="dependencies/waifu2x-caffe"
MkvToolNixDir="dependencies/mkvtoolnix"
FfmpegDir=""

5
settings/ffmpeg.conf Normal file
View File

@ -0,0 +1,5 @@
VideoCodec="libx265"
Preset="slow"
PixelFormat="yuv420p10le"
ConstantRateFactor="16"
x265params="limit-sao=1:bframes=8:psy-rd=1:aq-mode=3"

7
settings/preview.conf Normal file
View File

@ -0,0 +1,7 @@
### Preview gen settings ###
UseRangeNumbers="True" # (Instead of frame numbers)
ResizePreivew="False" # Resize original frames with ImageMagisk
Waifu2xScalePreview="False" # Generate preview for Waifu2x scale mode
Waifu2xNoiseScaleList="0 1 3" # Preview for Waifu2x noise_scale mode. Specify noise reduction levels in the list.

3
settings/range-gen.conf Normal file
View File

@ -0,0 +1,3 @@
Jobs="$(nproc)"
Threshold="365"
NoiseLevel="1"

View File

@ -0,0 +1,13 @@
### Waifu2x-caffe settings ###
# you can read about each parameter here:
# https://github.com/lltcggie/waifu2x-caffe/blob/master/README-EN.md#command-line-options-common
Process="cudnn"
GpuNum="0"
ScaleRatio="3"
OutputDepth="16"
CropSize="256"
BatchSize="1"
Model="upresnet10"
TtaMode="0"

64
video2d-2x Normal file
View File

@ -0,0 +1,64 @@
#!/bin/bash
# video2d-2x is a command line tool for upscaling videos using waifu2x.
# Copyright (C) 2020 GenZmeY
# mailto: genzmey@gmail.com
#
# 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/>.
set -Eeuo pipefail
readonly ScriptName=$(basename "$0")
readonly ScriptVersion="0.2"
readonly BaseDir=$(dirname $(readlink -e "$0"))
source "$BaseDir/scripts/common.lib"
function show_version ()
{
echo "$ScriptName v$ScriptVersion"
}
function show_help ()
{
echo "$ScriptName - command line tool for upscaling videos using waifu2x"
echo " -e, --extract <FILE> extract all resources from (video) FILE"
echo " -f, --frames convert extracted video to frames"
echo " -r, --ranges generate range list for frames"
echo " -p, --preview generate preview images for each range"
echo " -u, --upscale upscale frames with range settings"
echo " -v, --video generate upscaled video from upscaled frames"
echo " -m, --merge merge upscaled video with all extracted resources"
echo " -V, --version show version"
echo " -h, --help show help"
}
if [[ $# -eq 0 ]]; then show_help; exit 0; fi
case $1 in
-h|--help ) show_help ;;
-V|--version ) show_version ;;
-e|--extract ) shift; source "$ScriptsDir/extract.sh" ;;
-f|--frames ) shift; source "$ScriptsDir/frames.sh" ;;
-r|--ranges ) shift; source "$ScriptsDir/ranges.sh" ;;
-p|--preview ) shift; source "$ScriptsDir/preview.sh" ;;
-u|--upscale ) shift; source "$ScriptsDir/upscale.sh" ;;
-v|--video ) shift; source "$ScriptsDir/video.sh" ;;
-m|--merge ) shift; source "$ScriptsDir/merge.sh" ;;
-t|--test ) shift; source "$ScriptsDir/test.sh" ;;
* ) echo "Command not recognized: $1" ; exit "$OPTION_ERROR";;
esac
exit "$SUCCESS"