10 Commits
4.1.0 ... 4.2.0

Author SHA1 Message Date
k4yt3x
676e70f088 updated drivers tooltips 2020-05-17 16:15:38 -04:00
k4yt3x
f57b5e9d04 bumped GUI version number 2020-05-17 16:15:26 -04:00
k4yt3x
f48e23a890 ignore FileNotFoundError while clearing cache 2020-05-17 15:50:05 -04:00
k4yt3x
826b4e9829 renamed stream copy checkbox 2020-05-17 15:48:21 -04:00
k4yt3x
c56be51e21 updated output path generation logic, organized lines 2020-05-17 15:48:06 -04:00
k4yt3x
d2b3175ccd changed default output codec to yuv420p for wider compatibility, added frame interpolation comment 2020-05-17 15:47:33 -04:00
k4yt3x
a98d1c7277 added stopping confirmation 2020-05-17 10:51:17 -04:00
k4yt3x
e107ddc96e updated translations 2020-05-17 10:13:43 -04:00
k4yt3x
289f5441eb added FFmpeg frame interpolation option 2020-05-17 09:57:07 -04:00
k4yt3x
179bd6afc8 updated GUI 2.1.0 screenshot 2020-05-16 08:01:11 -04:00
10 changed files with 412 additions and 279 deletions

View File

@@ -86,7 +86,7 @@ The list is sorted from new to old.
### Video2X GUI ### Video2X GUI
![GUI Preview](https://user-images.githubusercontent.com/21986859/81662226-cacb1480-942c-11ea-831f-2f0827f9cd11.png)\ ![GUI Preview](https://user-images.githubusercontent.com/21986859/82119295-bc526500-976c-11ea-9ea8-53264689023e.png)\
*Video2X GUI Screenshot* *Video2X GUI Screenshot*
### Video2X CLI ### Video2X CLI

View File

@@ -5,8 +5,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"POT-Creation-Date: 2020-05-12 04:27-0400\n" "POT-Creation-Date: 2020-05-17 10:10-0400\n"
"PO-Revision-Date: 2020-05-12 04:29-0400\n" "PO-Revision-Date: 2020-05-17 10:13-0400\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"Language: zh_CN\n" "Language: zh_CN\n"
@@ -21,276 +21,280 @@ msgstr ""
msgid "Upscaling Progress" msgid "Upscaling Progress"
msgstr "放大进度" msgstr "放大进度"
#: upscaler.py:106 #: upscaler.py:109
msgid "Specified or default cache directory is a file/link" msgid "Specified or default cache directory is a file/link"
msgstr "指定或默认的缓存目录是文件/链接" msgstr "指定或默认的缓存目录是文件/链接"
#: upscaler.py:112 #: upscaler.py:115
msgid "Creating cache directory {}" msgid "Creating cache directory {}"
msgstr "创建缓存目录 {}" msgstr "创建缓存目录 {}"
#: upscaler.py:115 #: upscaler.py:118
msgid "Unable to create {}" msgid "Unable to create {}"
msgstr "无法创建 {}" msgstr "无法创建 {}"
#: upscaler.py:120 #: upscaler.py:123
msgid "Extracted frames are being saved to: {}" msgid "Extracted frames are being saved to: {}"
msgstr "提取的帧将被保存到:{}" msgstr "提取的帧将被保存到:{}"
#: upscaler.py:122 #: upscaler.py:125
msgid "Upscaled frames are being saved to: {}" msgid "Upscaled frames are being saved to: {}"
msgstr "已放大的帧将被保存到:{}" msgstr "已放大的帧将被保存到:{}"
#: upscaler.py:132 #: upscaler.py:135
msgid "Cleaning up cache directory: {}" msgid "Cleaning up cache directory: {}"
msgstr "清理缓存目录:{}" msgstr "清理缓存目录:{}"
#: upscaler.py:135 #: upscaler.py:138
msgid "Unable to delete: {}" msgid "Unable to delete: {}"
msgstr "无法删除:{}" msgstr "无法删除:{}"
#: upscaler.py:141 upscaler.py:156 upscaler.py:167 #: upscaler.py:144 upscaler.py:159 upscaler.py:170
msgid "Input and output path type mismatch" msgid "Input and output path type mismatch"
msgstr "输入和输出路径类型不匹配" msgstr "输入和输出路径类型不匹配"
#: upscaler.py:142 #: upscaler.py:145
msgid "Input is multiple files but output is not directory" msgid "Input is multiple files but output is not directory"
msgstr "输入是多个文件,但输出不是目录" msgstr "输入是多个文件,但输出不是目录"
#: upscaler.py:146 #: upscaler.py:149
msgid "Input path {} is neither a file nor a directory" msgid "Input path {} is neither a file nor a directory"
msgstr "输入路径 {} 既不是文件也不是目录" msgstr "输入路径 {} 既不是文件也不是目录"
#: upscaler.py:150 upscaler.py:172 #: upscaler.py:153 upscaler.py:175
msgid "Input directory and output directory cannot be the same" msgid "Input directory and output directory cannot be the same"
msgstr "输入目录和输出目录不能相同" msgstr "输入目录和输出目录不能相同"
#: upscaler.py:157 #: upscaler.py:160
msgid "Input is single file but output is directory" msgid "Input is single file but output is directory"
msgstr "所选的输入路径是单个文件,但输出路径是目录" msgstr "所选的输入路径是单个文件,但输出路径是目录"
#: upscaler.py:160 #: upscaler.py:163
msgid "No suffix found in output file path" msgid "No suffix found in output file path"
msgstr "在输出文件路径中未找到后缀" msgstr "在输出文件路径中未找到后缀"
#: upscaler.py:161 #: upscaler.py:164
msgid "Suffix must be specified" msgid "Suffix must be specified"
msgstr "必须指定文件后缀" msgstr "必须指定文件后缀"
#: upscaler.py:168 #: upscaler.py:171
msgid "Input is directory but output is existing single file" msgid "Input is directory but output is existing single file"
msgstr "输入是目录,但输出是现有的单个文件" msgstr "输入是目录,但输出是现有的单个文件"
#: upscaler.py:177 #: upscaler.py:180
msgid "Input path is neither a file nor a directory" msgid "Input path is neither a file nor a directory"
msgstr "输入路径既不是文件也不是目录" msgstr "输入路径既不是文件也不是目录"
#: upscaler.py:186 #: upscaler.py:189
msgid "FFmpeg or FFprobe cannot be found under the specified path" msgid "FFmpeg or FFprobe cannot be found under the specified path"
msgstr "在指定的路径下找不到 FFmpeg 或 FFprobe" msgstr "在指定的路径下找不到 FFmpeg 或 FFprobe"
#: upscaler.py:187 upscaler.py:197 #: upscaler.py:190 upscaler.py:200
msgid "Please check the configuration file settings" msgid "Please check the configuration file settings"
msgstr "请检查配置文件设置" msgstr "请检查配置文件设置"
#: upscaler.py:196 #: upscaler.py:199
msgid "Specified driver executable directory doesn't exist" msgid "Specified driver executable directory doesn't exist"
msgstr "指定驱动的可执行文件不存在" msgstr "指定驱动的可执行文件不存在"
#: upscaler.py:223 #: upscaler.py:226
msgid "Failed to parse driver argument: {}" msgid "Failed to parse driver argument: {}"
msgstr "解析驱动程序参数失败:{}" msgstr "解析驱动程序参数失败:{}"
#: upscaler.py:248 #: upscaler.py:258
msgid "Anime4KCPP doesn't yet support GIF processing"
msgstr "Anime4KCPP 尚不支持GIF处理"
#: upscaler.py:263
msgid "Unrecognized driver: {}" msgid "Unrecognized driver: {}"
msgstr "无法识别的驱动名称:{}" msgstr "无法识别的驱动名称:{}"
#: upscaler.py:303 #: upscaler.py:298
msgid "Starting progress monitor" msgid "Starting progress monitor"
msgstr "启动进度监视器" msgstr "启动进度监视器"
#: upscaler.py:308 #: upscaler.py:303
msgid "Starting upscaled image cleaner" msgid "Starting upscaled image cleaner"
msgstr "启动已放大图像清理程序" msgstr "启动已放大图像清理程序"
#: upscaler.py:317 upscaler.py:334 #: upscaler.py:312 upscaler.py:329
msgid "Killing progress monitor" msgid "Killing progress monitor"
msgstr "终结进度监视器" msgstr "终结进度监视器"
#: upscaler.py:320 upscaler.py:337 #: upscaler.py:315 upscaler.py:332
msgid "Killing upscaled image cleaner" msgid "Killing upscaled image cleaner"
msgstr "终结已放大图像清理程序" msgstr "终结已放大图像清理程序"
#: upscaler.py:341 #: upscaler.py:336
msgid "Terminating all processes" msgid "Terminating all processes"
msgstr "正在终止所有进程" msgstr "正在终止所有进程"
#: upscaler.py:348 #: upscaler.py:343
msgid "Main process waiting for subprocesses to exit" msgid "Main process waiting for subprocesses to exit"
msgstr "主进程开始等待子进程结束" msgstr "主进程开始等待子进程结束"
#: upscaler.py:367 upscaler.py:371 #: upscaler.py:362 upscaler.py:366
msgid "Subprocess {} exited with code {}" msgid "Subprocess {} exited with code {}"
msgstr "子进程 {} 结束,返回码 {}" msgstr "子进程 {} 结束,返回码 {}"
#: upscaler.py:377 #: upscaler.py:372
msgid "Stop signal received" msgid "Stop signal received"
msgstr "收到停止信号" msgstr "收到停止信号"
#: upscaler.py:382 #: upscaler.py:377
msgid "Subprocess execution ran into an error" msgid "Subprocess execution ran into an error"
msgstr "子进程执行遇到错误" msgstr "子进程执行遇到错误"
#: upscaler.py:430 #: upscaler.py:425
msgid "Upscaling single file: {}" msgid "Upscaling single file: {}"
msgstr "放大单个文件:{}" msgstr "放大单个文件:{}"
#: upscaler.py:466 #: upscaler.py:461
msgid "Starting to upscale image" msgid "Starting to upscale image"
msgstr "开始放大图像" msgstr "开始放大图像"
#: upscaler.py:469 upscaler.py:487 upscaler.py:545 #: upscaler.py:464 upscaler.py:526
msgid "Upscaling completed" msgid "Upscaling completed"
msgstr "放大完成" msgstr "放大完成"
#: upscaler.py:482 #: upscaler.py:478
msgid "Starting to upscale video with Anime4KCPP"
msgstr "开始用 Anime4KCPP 放大视频"
#: upscaler.py:496
msgid "Reading video information" msgid "Reading video information"
msgstr "读取视频信息" msgstr "读取视频信息"
#: upscaler.py:510 #: upscaler.py:492
msgid "Aborting: No video stream found" msgid "Aborting: No video stream found"
msgstr "程序中止:文件中未找到视频流" msgstr "程序中止:文件中未找到视频流"
#: upscaler.py:531 #: upscaler.py:497
msgid "Unsupported pixel format: {}"
msgstr "不支持的像素格式:{}"
#: upscaler.py:534
msgid "Framerate: {}" msgid "Framerate: {}"
msgstr "帧率:{}" msgstr "帧率:{}"
#: upscaler.py:543 #: upscaler.py:514
msgid "Unsupported pixel format: {}"
msgstr "不支持的像素格式:{}"
#: upscaler.py:524
msgid "Starting to upscale extracted frames" msgid "Starting to upscale extracted frames"
msgstr "开始对提取的帧进行放大" msgstr "开始对提取的帧进行放大"
#: upscaler.py:550 #: upscaler.py:531
msgid "File {} ({}) neither an image of a video" msgid "File {} ({}) neither an image of a video"
msgstr "文件 {} {} 既不是图片也不是视频" msgstr "文件 {} {} 既不是图片也不是视频"
#: upscaler.py:551 #: upscaler.py:532
msgid "Skipping this file" msgid "Skipping this file"
msgstr "将跳过此文件" msgstr "将跳过此文件"
#: upscaler.py:561 #: upscaler.py:542
msgid "Converting extracted frames into GIF image" msgid "Converting extracted frames into GIF image"
msgstr "正在将提取的帧转换为 GIF" msgstr "正在将提取的帧转换为 GIF"
#: upscaler.py:565 upscaler.py:574 #: upscaler.py:546 upscaler.py:555
msgid "Conversion completed" msgid "Conversion completed"
msgstr "转换已完成" msgstr "转换已完成"
#: upscaler.py:570 #: upscaler.py:551
msgid "Converting extracted frames into video" msgid "Converting extracted frames into video"
msgstr "正在将提取的帧转换为视频" msgstr "正在将提取的帧转换为视频"
#: upscaler.py:578 #: upscaler.py:559
msgid "Migrating audio, subtitles and other streams to upscaled video" msgid "Migrating audio, subtitles and other streams to upscaled video"
msgstr "正在将音频、字幕和其他流迁移到放大后的视频" msgstr "正在将音频、字幕和其他流迁移到放大后的视频"
#: upscaler.py:587 #: upscaler.py:569
msgid "Failed to migrate streams" msgid "Failed to migrate streams"
msgstr "迁移流失败" msgstr "迁移流失败"
#: upscaler.py:588 #: upscaler.py:570
msgid "Trying to output video without additional streams" msgid "Trying to output video without additional streams"
msgstr "正在尝试输出不含其他流的视频" msgstr "正在尝试输出不含其他流的视频"
#: upscaler.py:599 #: upscaler.py:586
msgid "Output video file exists, aborting" msgid "Output video file exists"
msgstr "输出目标文件已存在,取消输出" msgstr "输出目标文件已存在"
#: upscaler.py:603 #: upscaler.py:590
msgid "Created temporary directory to contain file"
msgstr "为文件创建了临时目录"
#: upscaler.py:593
msgid "Writing intermediate file to: {}" msgid "Writing intermediate file to: {}"
msgstr "正在将中间视频文件写入至:{}" msgstr "正在将中间视频文件写入至:{}"
#: video2x.py:84 #: video2x.py:85
msgid "" msgid ""
"Video2X Version: {}\n" "Video2X CLI Version: {}\n"
"Upscaler Version: {}\n"
"Author: K4YT3X\n" "Author: K4YT3X\n"
"License: GNU GPL v3\n" "License: GNU GPL v3\n"
"Github Page: https://github.com/k4yt3x/video2x\n" "Github Page: https://github.com/k4yt3x/video2x\n"
"Contact: k4yt3x@k4yt3x.com" "Contact: k4yt3x@k4yt3x.com"
msgstr "" msgstr ""
"Video2X 版本: {}\n" "Video2X 版本: {}\n"
"放大组件版本:{}\n"
"作者: K4YT3X\n" "作者: K4YT3X\n"
"开源许可: GNU GPL v3\n" "开源许可: GNU GPL v3\n"
"GitHub 主页https://github.com/k4yt3x/video2x\n" "GitHub 主页https://github.com/k4yt3x/video2x\n"
"联系方式k4yt3x@k4yt3x.com" "联系方式k4yt3x@k4yt3x.com"
#: video2x.py:106 #: video2x.py:108
msgid "Video2X Options" msgid "Video2X Options"
msgstr "Video2X 选项" msgstr "Video2X 选项"
#: video2x.py:107 #: video2x.py:109
msgid "show this help message and exit" msgid "show this help message and exit"
msgstr "显示此帮助消息并退出" msgstr "显示此帮助消息并退出"
#: video2x.py:108 #: video2x.py:110
msgid "source video file/directory" msgid "source video file/directory"
msgstr "源视频文件/目录" msgstr "源视频文件/目录"
#: video2x.py:109 #: video2x.py:111
msgid "output video file/directory" msgid "output video file/directory"
msgstr "输出视频文件/目录" msgstr "输出视频文件/目录"
#: video2x.py:110 #: video2x.py:112
msgid "video2x config file path" msgid "video2x config file path"
msgstr "video2x 配置文件路径" msgstr "video2x 配置文件路径"
#: video2x.py:112 #: video2x.py:114
msgid "display version, lawful information and exit" msgid "display version, lawful information and exit"
msgstr "显示版本和法律信息并退出" msgstr "显示版本和法律信息并退出"
#: video2x.py:115 #: video2x.py:117
msgid "Upscaling Options" msgid "Upscaling Options"
msgstr "视频放大选项" msgstr "视频放大选项"
#: video2x.py:116 #: video2x.py:118
msgid "upscaling driver" msgid "upscaling driver"
msgstr "视频放大驱动" msgstr "视频放大驱动"
#: video2x.py:117 #: video2x.py:119
msgid "scaling ratio" msgid "scaling ratio"
msgstr "缩放比" msgstr "缩放比"
#: video2x.py:118 #: video2x.py:120
msgid "number of processes to use for upscaling" msgid "number of processes to use for upscaling"
msgstr "并发进程数" msgstr "并发进程数"
#: video2x.py:119 #: video2x.py:121
msgid "preserve extracted and upscaled frames" msgid "preserve extracted and upscaled frames"
msgstr "保留提取的和放大的帧" msgstr "保留提取的和放大的帧"
#: video2x.py:159 #: video2x.py:161
msgid "This file cannot be imported" msgid "This file cannot be imported"
msgstr "此文件无法被当作模块导入" msgstr "此文件无法被当作模块导入"
#: video2x.py:234 #: video2x.py:236
msgid "Program completed, taking {} seconds" msgid "Program completed, taking {} seconds"
msgstr "程序执行完毕,总计花费 {} 秒" msgstr "程序执行完毕,总计花费 {} 秒"
#: video2x.py:237 #: video2x.py:239
msgid "An exception has occurred" msgid "An exception has occurred"
msgstr "发生了异常" msgstr "发生了异常"
#~ msgid "Anime4KCPP doesn't yet support GIF processing"
#~ msgstr "Anime4KCPP 尚不支持GIF处理"
#~ msgid "Starting to upscale video with Anime4KCPP"
#~ msgstr "开始用 Anime4KCPP 放大视频"
#~ msgid "output video width" #~ msgid "output video width"
#~ msgstr "输出视频宽度" #~ msgstr "输出视频宽度"

View File

@@ -4,7 +4,7 @@
Name: Video2X Upscaler Name: Video2X Upscaler
Author: K4YT3X Author: K4YT3X
Date Created: December 10, 2018 Date Created: December 10, 2018
Last Modified: May 16, 2020 Last Modified: May 17, 2020
Description: This file contains the Upscaler class. Each Description: This file contains the Upscaler class. Each
instance of the Upscaler class is an upscaler on an image or instance of the Upscaler class is an upscaler on an image or
@@ -134,7 +134,9 @@ class Upscaler:
# therefore, plain print is used # therefore, plain print is used
print(_('Cleaning up cache directory: {}').format(directory)) print(_('Cleaning up cache directory: {}').format(directory))
shutil.rmtree(directory) shutil.rmtree(directory)
except (OSError, FileNotFoundError): except FileNotFoundError:
pass
except OSError:
print(_('Unable to delete: {}').format(directory)) print(_('Unable to delete: {}').format(directory))
traceback.print_exc() traceback.print_exc()

View File

@@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2020-05-12 04:27-0400\n" "POT-Creation-Date: 2020-05-17 10:10-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -19,268 +19,265 @@ msgstr ""
msgid "Upscaling Progress" msgid "Upscaling Progress"
msgstr "" msgstr ""
#: upscaler.py:106 #: upscaler.py:109
msgid "Specified or default cache directory is a file/link" msgid "Specified or default cache directory is a file/link"
msgstr "" msgstr ""
#: upscaler.py:112 #: upscaler.py:115
msgid "Creating cache directory {}" msgid "Creating cache directory {}"
msgstr "" msgstr ""
#: upscaler.py:115 #: upscaler.py:118
msgid "Unable to create {}" msgid "Unable to create {}"
msgstr "" msgstr ""
#: upscaler.py:120 #: upscaler.py:123
msgid "Extracted frames are being saved to: {}" msgid "Extracted frames are being saved to: {}"
msgstr "" msgstr ""
#: upscaler.py:122 #: upscaler.py:125
msgid "Upscaled frames are being saved to: {}" msgid "Upscaled frames are being saved to: {}"
msgstr "" msgstr ""
#: upscaler.py:132 #: upscaler.py:135
msgid "Cleaning up cache directory: {}" msgid "Cleaning up cache directory: {}"
msgstr "" msgstr ""
#: upscaler.py:135 #: upscaler.py:138
msgid "Unable to delete: {}" msgid "Unable to delete: {}"
msgstr "" msgstr ""
#: upscaler.py:141 upscaler.py:156 upscaler.py:167 #: upscaler.py:144 upscaler.py:159 upscaler.py:170
msgid "Input and output path type mismatch" msgid "Input and output path type mismatch"
msgstr "" msgstr ""
#: upscaler.py:142 #: upscaler.py:145
msgid "Input is multiple files but output is not directory" msgid "Input is multiple files but output is not directory"
msgstr "" msgstr ""
#: upscaler.py:146 #: upscaler.py:149
msgid "Input path {} is neither a file nor a directory" msgid "Input path {} is neither a file nor a directory"
msgstr "" msgstr ""
#: upscaler.py:150 upscaler.py:172 #: upscaler.py:153 upscaler.py:175
msgid "Input directory and output directory cannot be the same" msgid "Input directory and output directory cannot be the same"
msgstr "" msgstr ""
#: upscaler.py:157 #: upscaler.py:160
msgid "Input is single file but output is directory" msgid "Input is single file but output is directory"
msgstr "" msgstr ""
#: upscaler.py:160 #: upscaler.py:163
msgid "No suffix found in output file path" msgid "No suffix found in output file path"
msgstr "" msgstr ""
#: upscaler.py:161 #: upscaler.py:164
msgid "Suffix must be specified" msgid "Suffix must be specified"
msgstr "" msgstr ""
#: upscaler.py:168 #: upscaler.py:171
msgid "Input is directory but output is existing single file" msgid "Input is directory but output is existing single file"
msgstr "" msgstr ""
#: upscaler.py:177 #: upscaler.py:180
msgid "Input path is neither a file nor a directory" msgid "Input path is neither a file nor a directory"
msgstr "" msgstr ""
#: upscaler.py:186 #: upscaler.py:189
msgid "FFmpeg or FFprobe cannot be found under the specified path" msgid "FFmpeg or FFprobe cannot be found under the specified path"
msgstr "" msgstr ""
#: upscaler.py:187 upscaler.py:197 #: upscaler.py:190 upscaler.py:200
msgid "Please check the configuration file settings" msgid "Please check the configuration file settings"
msgstr "" msgstr ""
#: upscaler.py:196 #: upscaler.py:199
msgid "Specified driver executable directory doesn't exist" msgid "Specified driver executable directory doesn't exist"
msgstr "" msgstr ""
#: upscaler.py:223 #: upscaler.py:226
msgid "Failed to parse driver argument: {}" msgid "Failed to parse driver argument: {}"
msgstr "" msgstr ""
#: upscaler.py:248 #: upscaler.py:258
msgid "Anime4KCPP doesn't yet support GIF processing"
msgstr ""
#: upscaler.py:263
msgid "Unrecognized driver: {}" msgid "Unrecognized driver: {}"
msgstr "" msgstr ""
#: upscaler.py:303 #: upscaler.py:298
msgid "Starting progress monitor" msgid "Starting progress monitor"
msgstr "" msgstr ""
#: upscaler.py:308 #: upscaler.py:303
msgid "Starting upscaled image cleaner" msgid "Starting upscaled image cleaner"
msgstr "" msgstr ""
#: upscaler.py:317 upscaler.py:334 #: upscaler.py:312 upscaler.py:329
msgid "Killing progress monitor" msgid "Killing progress monitor"
msgstr "" msgstr ""
#: upscaler.py:320 upscaler.py:337 #: upscaler.py:315 upscaler.py:332
msgid "Killing upscaled image cleaner" msgid "Killing upscaled image cleaner"
msgstr "" msgstr ""
#: upscaler.py:341 #: upscaler.py:336
msgid "Terminating all processes" msgid "Terminating all processes"
msgstr "" msgstr ""
#: upscaler.py:348 #: upscaler.py:343
msgid "Main process waiting for subprocesses to exit" msgid "Main process waiting for subprocesses to exit"
msgstr "" msgstr ""
#: upscaler.py:367 upscaler.py:371 #: upscaler.py:362 upscaler.py:366
msgid "Subprocess {} exited with code {}" msgid "Subprocess {} exited with code {}"
msgstr "" msgstr ""
#: upscaler.py:377 #: upscaler.py:372
msgid "Stop signal received" msgid "Stop signal received"
msgstr "" msgstr ""
#: upscaler.py:382 #: upscaler.py:377
msgid "Subprocess execution ran into an error" msgid "Subprocess execution ran into an error"
msgstr "" msgstr ""
#: upscaler.py:430 #: upscaler.py:425
msgid "Upscaling single file: {}" msgid "Upscaling single file: {}"
msgstr "" msgstr ""
#: upscaler.py:466 #: upscaler.py:461
msgid "Starting to upscale image" msgid "Starting to upscale image"
msgstr "" msgstr ""
#: upscaler.py:469 upscaler.py:487 upscaler.py:545 #: upscaler.py:464 upscaler.py:526
msgid "Upscaling completed" msgid "Upscaling completed"
msgstr "" msgstr ""
#: upscaler.py:482 #: upscaler.py:478
msgid "Starting to upscale video with Anime4KCPP"
msgstr ""
#: upscaler.py:496
msgid "Reading video information" msgid "Reading video information"
msgstr "" msgstr ""
#: upscaler.py:510 #: upscaler.py:492
msgid "Aborting: No video stream found" msgid "Aborting: No video stream found"
msgstr "" msgstr ""
#: upscaler.py:531 #: upscaler.py:497
msgid "Unsupported pixel format: {}"
msgstr ""
#: upscaler.py:534
msgid "Framerate: {}" msgid "Framerate: {}"
msgstr "" msgstr ""
#: upscaler.py:543 #: upscaler.py:514
msgid "Unsupported pixel format: {}"
msgstr ""
#: upscaler.py:524
msgid "Starting to upscale extracted frames" msgid "Starting to upscale extracted frames"
msgstr "" msgstr ""
#: upscaler.py:550 #: upscaler.py:531
msgid "File {} ({}) neither an image of a video" msgid "File {} ({}) neither an image of a video"
msgstr "" msgstr ""
#: upscaler.py:551 #: upscaler.py:532
msgid "Skipping this file" msgid "Skipping this file"
msgstr "" msgstr ""
#: upscaler.py:561 #: upscaler.py:542
msgid "Converting extracted frames into GIF image" msgid "Converting extracted frames into GIF image"
msgstr "" msgstr ""
#: upscaler.py:565 upscaler.py:574 #: upscaler.py:546 upscaler.py:555
msgid "Conversion completed" msgid "Conversion completed"
msgstr "" msgstr ""
#: upscaler.py:570 #: upscaler.py:551
msgid "Converting extracted frames into video" msgid "Converting extracted frames into video"
msgstr "" msgstr ""
#: upscaler.py:578 #: upscaler.py:559
msgid "Migrating audio, subtitles and other streams to upscaled video" msgid "Migrating audio, subtitles and other streams to upscaled video"
msgstr "" msgstr ""
#: upscaler.py:587 #: upscaler.py:569
msgid "Failed to migrate streams" msgid "Failed to migrate streams"
msgstr "" msgstr ""
#: upscaler.py:588 #: upscaler.py:570
msgid "Trying to output video without additional streams" msgid "Trying to output video without additional streams"
msgstr "" msgstr ""
#: upscaler.py:599 #: upscaler.py:586
msgid "Output video file exists, aborting" msgid "Output video file exists"
msgstr "" msgstr ""
#: upscaler.py:603 #: upscaler.py:590
msgid "Created temporary directory to contain file"
msgstr ""
#: upscaler.py:593
msgid "Writing intermediate file to: {}" msgid "Writing intermediate file to: {}"
msgstr "" msgstr ""
#: video2x.py:84 #: video2x.py:85
msgid "" msgid ""
"Video2X Version: {}\n" "Video2X CLI Version: {}\n"
"Upscaler Version: {}\n"
"Author: K4YT3X\n" "Author: K4YT3X\n"
"License: GNU GPL v3\n" "License: GNU GPL v3\n"
"Github Page: https://github.com/k4yt3x/video2x\n" "Github Page: https://github.com/k4yt3x/video2x\n"
"Contact: k4yt3x@k4yt3x.com" "Contact: k4yt3x@k4yt3x.com"
msgstr "" msgstr ""
#: video2x.py:106 #: video2x.py:108
msgid "Video2X Options" msgid "Video2X Options"
msgstr "" msgstr ""
#: video2x.py:107 #: video2x.py:109
msgid "show this help message and exit" msgid "show this help message and exit"
msgstr "" msgstr ""
#: video2x.py:108 #: video2x.py:110
msgid "source video file/directory" msgid "source video file/directory"
msgstr "" msgstr ""
#: video2x.py:109 #: video2x.py:111
msgid "output video file/directory" msgid "output video file/directory"
msgstr "" msgstr ""
#: video2x.py:110 #: video2x.py:112
msgid "video2x config file path" msgid "video2x config file path"
msgstr "" msgstr ""
#: video2x.py:112 #: video2x.py:114
msgid "display version, lawful information and exit" msgid "display version, lawful information and exit"
msgstr "" msgstr ""
#: video2x.py:115 #: video2x.py:117
msgid "Upscaling Options" msgid "Upscaling Options"
msgstr "" msgstr ""
#: video2x.py:116 #: video2x.py:118
msgid "upscaling driver" msgid "upscaling driver"
msgstr "" msgstr ""
#: video2x.py:117 #: video2x.py:119
msgid "scaling ratio" msgid "scaling ratio"
msgstr "" msgstr ""
#: video2x.py:118 #: video2x.py:120
msgid "number of processes to use for upscaling" msgid "number of processes to use for upscaling"
msgstr "" msgstr ""
#: video2x.py:119 #: video2x.py:121
msgid "preserve extracted and upscaled frames" msgid "preserve extracted and upscaled frames"
msgstr "" msgstr ""
#: video2x.py:159 #: video2x.py:161
msgid "This file cannot be imported" msgid "This file cannot be imported"
msgstr "" msgstr ""
#: video2x.py:234 #: video2x.py:236
msgid "Program completed, taking {} seconds" msgid "Program completed, taking {} seconds"
msgstr "" msgstr ""
#: video2x.py:237 #: video2x.py:239
msgid "An exception has occurred" msgid "An exception has occurred"
msgstr "" msgstr ""

View File

@@ -1,7 +1,7 @@
# Name: Video2X Configuration File # Name: Video2X Configuration File
# Creator: K4YT3X # Creator: K4YT3X
# Date Created: October 23, 2018 # Date Created: October 23, 2018
# Last Modified: May 14, 2020 # Last Modified: May 17, 2020
# Values here are the default values. Change the value here to # Values here are the default values. Change the value here to
# save the default value permanently. # save the default value permanently.
# Items commented out are parameters irrelevant to this context # Items commented out are parameters irrelevant to this context
@@ -119,7 +119,7 @@ ffmpeg:
'-f': image2 # force image2 format '-f': image2 # force image2 format
output_options: output_options:
'-vcodec': libx264 # video codec '-vcodec': libx264 # video codec
'-pix_fmt': 'yuv444p10le' # overwrite default pixel format '-pix_fmt': 'yuv420p' # overwrite default pixel format
'-crf': 17 # H.264 Constant Rate Factor '-crf': 17 # H.264 Constant Rate Factor
'-b:v': null # target average bitrate '-b:v': null # target average bitrate
'-vf': 'pad=ceil(iw/2)*2:ceil(ih/2)*2' # ensure output is divisible by 2, recommended for libx264 '-vf': 'pad=ceil(iw/2)*2:ceil(ih/2)*2' # ensure output is divisible by 2, recommended for libx264
@@ -138,6 +138,7 @@ ffmpeg:
- '1:d?' # copy data streams - '1:d?' # copy data streams
- '1:t?' # copy fonts - '1:t?' # copy fonts
'-c': copy # copy codec for all streams '-c': copy # copy codec for all streams
# '-vf': 'minterpolate=''fps=60''' # minterpolate frame interpolation
'-map_metadata': 0 # copy known metadata tags '-map_metadata': 0 # copy known metadata tags
# '-movflags': 'use_metadata_tags' # copy custom/arbitrary metadata tags # '-movflags': 'use_metadata_tags' # copy custom/arbitrary metadata tags
'-pix_fmt': null '-pix_fmt': null

View File

@@ -4,7 +4,7 @@
Creator: Video2X GUI Creator: Video2X GUI
Author: K4YT3X Author: K4YT3X
Date Created: May 5, 2020 Date Created: May 5, 2020
Last Modified: May 15, 2020 Last Modified: May 17, 2020
""" """
# local imports # local imports
@@ -29,9 +29,8 @@ from PyQt5 import QtGui, uic
from PyQt5.QtCore import * from PyQt5.QtCore import *
from PyQt5.QtWidgets import * from PyQt5.QtWidgets import *
import magic import magic
# QObject, pyqtSlot, pyqtSignal, QRunnable, QThreadPool, QAbstractTableModel, Qt
GUI_VERSION = '2.1.0' GUI_VERSION = '2.3.0'
LEGAL_INFO = f'''Video2X GUI Version: {GUI_VERSION}\\ LEGAL_INFO = f'''Video2X GUI Version: {GUI_VERSION}\\
Upscaler Version: {UPSCALER_VERSION}\\ Upscaler Version: {UPSCALER_VERSION}\\
@@ -374,9 +373,12 @@ class Video2XMainWindow(QMainWindow):
self.ffmpeg_migrate_streams_output_options_mapping_data_check_box_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsOutputOptionsMappingDataCheckBox') self.ffmpeg_migrate_streams_output_options_mapping_data_check_box_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsOutputOptionsMappingDataCheckBox')
self.ffmpeg_migrate_streams_output_options_mapping_font_check_box_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsOutputOptionsMappingFontCheckBox') self.ffmpeg_migrate_streams_output_options_mapping_font_check_box_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsOutputOptionsMappingFontCheckBox')
self.ffmpeg_migrate_streams_output_options_pixel_format_line_edit = self.findChild(QLineEdit, 'ffmpegMigrateStreamsOutputOptionsPixelFormatLineEdit') self.ffmpeg_migrate_streams_output_options_pixel_format_line_edit = self.findChild(QLineEdit, 'ffmpegMigrateStreamsOutputOptionsPixelFormatLineEdit')
self.ffmpeg_migrate_streams_output_options_copy_codec_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsOutputOptionsCopyCodecCheckBox') self.ffmpeg_migrate_streams_output_options_frame_interpolation_spin_box = self.findChild(QSpinBox, 'ffmpegMigrateStreamsOutputOptionsFrameInterpolationSpinBox')
self.ffmpeg_migrate_streams_output_options_copy_known_metadata_tags_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsOutputOptionsOtherCopyKnownMetadataTagsCheckBox') self.ffmpeg_migrate_streams_output_options_frame_interpolation_spin_box.valueChanged.connect(self.mutually_exclude_frame_interpolation_stream_copy)
self.ffmpeg_migrate_streams_output_options_copy_arbitrary_metadata_tags_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsOutputOptionsOtherCopyArbitraryMetadataTagsCheckBox') self.ffmpeg_migrate_streams_output_options_frame_interpolation_spin_box.textChanged.connect(self.mutually_exclude_frame_interpolation_stream_copy)
self.ffmpeg_migrate_streams_output_options_copy_streams_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsOutputOptionsCopyStreamsCheckBox')
self.ffmpeg_migrate_streams_output_options_copy_known_metadata_tags_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsOutputOptionsCopyKnownMetadataTagsCheckBox')
self.ffmpeg_migrate_streams_output_options_copy_arbitrary_metadata_tags_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsOutputOptionsCopyArbitraryMetadataTagsCheckBox')
self.ffmpeg_migrate_streams_hardware_acceleration_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsHardwareAccelerationCheckBox') self.ffmpeg_migrate_streams_hardware_acceleration_check_box = self.findChild(QCheckBox, 'ffmpegMigrateStreamsHardwareAccelerationCheckBox')
# Gifski settings # Gifski settings
@@ -396,48 +398,6 @@ class Video2XMainWindow(QMainWindow):
# load configurations after GUI initialization # load configurations after GUI initialization
self.load_configurations() self.load_configurations()
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
input_paths = [pathlib.Path(u.toLocalFile()) for u in event.mimeData().urls()]
for path in input_paths:
if (path.is_file() or path.is_dir()) and not self.input_table_path_exists(path):
self.input_table_data.append(path)
self.update_input_table()
self.update_output_path()
def enable_line_edit_file_drop(self, line_edit: QLineEdit):
line_edit.dragEnterEvent = self.dragEnterEvent
line_edit.dropEvent = lambda event: line_edit.setText(str(pathlib.Path(event.mimeData().urls()[0].toLocalFile()).absolute()))
def show_ffprobe_output(self, event):
input_paths = [pathlib.Path(u.toLocalFile()) for u in event.mimeData().urls()]
if not input_paths[0].is_file():
return
ffmpeg_object = Ffmpeg(self.ffmpeg_settings)
file_info_json = ffmpeg_object.probe_file_info(input_paths[0])
self.ffprobe_plain_text_edit.setPlainText(json.dumps(file_info_json, indent=2))
@staticmethod
def read_config(config_file: pathlib.Path) -> dict:
""" read video2x configurations from config file
Arguments:
config_file {pathlib.Path} -- video2x configuration file pathlib.Path
Returns:
dict -- dictionary of video2x configuration
"""
with open(config_file, 'r') as config:
return yaml.load(config, Loader=yaml.FullLoader)
def load_configurations(self): def load_configurations(self):
# get config file path from line edit # get config file path from line edit
@@ -691,8 +651,18 @@ class Video2XMainWindow(QMainWindow):
self.config['ffmpeg']['migrate_streams']['output_options']['-pix_fmt'] = self.ffmpeg_migrate_streams_output_options_pixel_format_line_edit.text() self.config['ffmpeg']['migrate_streams']['output_options']['-pix_fmt'] = self.ffmpeg_migrate_streams_output_options_pixel_format_line_edit.text()
if (fps := self.ffmpeg_migrate_streams_output_options_frame_interpolation_spin_box.value()) > 0:
if ('-vf' in self.config['ffmpeg']['migrate_streams']['output_options'] and
len(self.config['ffmpeg']['migrate_streams']['output_options']['-vf']) > 0 and
'minterpolate=' not in self.config['ffmpeg']['migrate_streams']['output_options']['-vf']):
self.config['ffmpeg']['migrate_streams']['output_options']['-vf'] += f',minterpolate=\'fps={fps}\''
else:
self.config['ffmpeg']['migrate_streams']['output_options']['-vf'] = f'minterpolate=\'fps={fps}\''
else:
self.config['ffmpeg']['migrate_streams']['output_options'].pop('-vf', None)
# copy source codec # copy source codec
if self.ffmpeg_migrate_streams_output_options_copy_codec_check_box.isChecked(): if self.ffmpeg_migrate_streams_output_options_copy_streams_check_box.isChecked():
self.config['ffmpeg']['migrate_streams']['output_options']['-c'] = 'copy' self.config['ffmpeg']['migrate_streams']['output_options']['-c'] = 'copy'
else: else:
self.config['ffmpeg']['migrate_streams']['output_options'].pop('-c', None) self.config['ffmpeg']['migrate_streams']['output_options'].pop('-c', None)
@@ -728,6 +698,56 @@ class Video2XMainWindow(QMainWindow):
self.config['gifski']['once'] = self.gifski_once_check_box.isChecked() self.config['gifski']['once'] = self.gifski_once_check_box.isChecked()
self.config['gifski']['quiet'] = self.gifski_quiet_check_box.isChecked() self.config['gifski']['quiet'] = self.gifski_quiet_check_box.isChecked()
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
input_paths = [pathlib.Path(u.toLocalFile()) for u in event.mimeData().urls()]
for path in input_paths:
if (path.is_file() or path.is_dir()) and not self.input_table_path_exists(path):
self.input_table_data.append(path)
self.update_output_path()
self.update_input_table()
def enable_line_edit_file_drop(self, line_edit: QLineEdit):
line_edit.dragEnterEvent = self.dragEnterEvent
line_edit.dropEvent = lambda event: line_edit.setText(str(pathlib.Path(event.mimeData().urls()[0].toLocalFile()).absolute()))
def show_ffprobe_output(self, event):
input_paths = [pathlib.Path(u.toLocalFile()) for u in event.mimeData().urls()]
if not input_paths[0].is_file():
return
ffmpeg_object = Ffmpeg(self.ffmpeg_settings)
file_info_json = ffmpeg_object.probe_file_info(input_paths[0])
self.ffprobe_plain_text_edit.setPlainText(json.dumps(file_info_json, indent=2))
@staticmethod
def read_config(config_file: pathlib.Path) -> dict:
""" read video2x configurations from config file
Arguments:
config_file {pathlib.Path} -- video2x configuration file pathlib.Path
Returns:
dict -- dictionary of video2x configuration
"""
with open(config_file, 'r') as config:
return yaml.load(config, Loader=yaml.FullLoader)
def mutually_exclude_frame_interpolation_stream_copy(self):
if self.ffmpeg_migrate_streams_output_options_frame_interpolation_spin_box.value() > 0:
self.ffmpeg_migrate_streams_output_options_copy_streams_check_box.setChecked(False)
self.ffmpeg_migrate_streams_output_options_copy_streams_check_box.setDisabled(True)
else:
self.ffmpeg_migrate_streams_output_options_copy_streams_check_box.setChecked(True)
self.ffmpeg_migrate_streams_output_options_copy_streams_check_box.setDisabled(False)
def update_gui_for_driver(self): def update_gui_for_driver(self):
current_driver = AVAILABLE_DRIVERS[self.driver_combo_box.currentText()] current_driver = AVAILABLE_DRIVERS[self.driver_combo_box.currentText()]
@@ -764,13 +784,16 @@ class Video2XMainWindow(QMainWindow):
for item in items_to_delete: for item in items_to_delete:
self.input_table_data.remove(item) self.input_table_data.remove(item)
self.update_output_path()
self.update_input_table() self.update_input_table()
def input_table_clear_all(self): def input_table_clear_all(self):
self.input_table_data = [] self.input_table_data = []
self.update_output_path()
self.update_input_table() self.update_input_table()
def input_table_path_exists(self, input_path): def input_table_path_exists(self, input_path: pathlib.Path) -> bool:
for path in self.input_table_data: for path in self.input_table_data:
# not using Path.samefile since file may not exist # not using Path.samefile since file may not exist
if str(path.absolute()) == str(input_path.absolute()): if str(path.absolute()) == str(input_path.absolute()):
@@ -790,58 +813,67 @@ class Video2XMainWindow(QMainWindow):
return pathlib.Path(folder_selected) return pathlib.Path(folder_selected)
def update_output_path(self): def update_output_path(self):
# if there is more than one input # if input list is empty
if len(self.input_table_data) != 1: # clear output path
return if len(self.input_table_data) == 0:
self.output_line_edit.setText('')
input_path = self.input_table_data[0] # if there are multiple output files
# give up if input path doesn't exist or isn't a file or a directory # use cwd/output directory for output
if not input_path.exists() or not (input_path.is_file() or input_path.is_dir()): elif len(self.input_table_data) > 1:
return self.output_line_edit.setText(str((pathlib.Path.cwd() / 'output').absolute()))
if input_path.is_file(): # if there's only one input file
# generate output file/directory name automatically
elif len(self.input_table_data) == 1:
input_path = self.input_table_data[0]
# give up if input path doesn't exist or isn't a file or a directory
if not input_path.exists() or not (input_path.is_file() or input_path.is_dir()):
return
# generate suffix automatically
input_file_mime_type = magic.from_file(str(input_path.absolute()), mime=True)
input_file_type = input_file_mime_type.split('/')[0]
input_file_subtype = input_file_mime_type.split('/')[1]
# if input file is an image
if input_file_type == 'image':
# if file is a gif, use .gif
if input_file_subtype == 'gif':
suffix = '.gif'
# otherwise, use .png by default for all images
else:
suffix = '.png'
# if input is video, use .mp4 as output by default
elif input_file_type == 'video':
suffix = '.mp4'
# if failed to detect file type
# use input file's suffix
else:
suffix = input_path.suffix
output_path = input_path.parent / f'{input_path.stem}_output{suffix}'
elif input_path.is_dir():
output_path = input_path.parent / f'{input_path.stem}_output'
# try up to 1000 times
output_path_id = 0
while output_path.exists() and output_path_id <= 1000:
if input_path.is_file(): if input_path.is_file():
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_path_id}{suffix}')
elif input_path.is_dir():
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_path_id}')
output_path_id += 1
if not output_path.exists(): # generate suffix automatically
self.output_line_edit.setText(str(output_path.absolute())) input_file_mime_type = magic.from_file(str(input_path.absolute()), mime=True)
input_file_type = input_file_mime_type.split('/')[0]
input_file_subtype = input_file_mime_type.split('/')[1]
# if input file is an image
if input_file_type == 'image':
# if file is a gif, use .gif
if input_file_subtype == 'gif':
suffix = '.gif'
# otherwise, use .png by default for all images
else:
suffix = '.png'
# if input is video, use .mp4 as output by default
elif input_file_type == 'video':
suffix = '.mp4'
# if failed to detect file type
# use input file's suffix
else:
suffix = input_path.suffix
output_path = input_path.parent / f'{input_path.stem}_output{suffix}'
elif input_path.is_dir():
output_path = input_path.parent / f'{input_path.stem}_output'
# try up to 1000 times
output_path_id = 0
while output_path.exists() and output_path_id <= 1000:
if input_path.is_file():
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_path_id}{suffix}')
elif input_path.is_dir():
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_path_id}')
output_path_id += 1
if not output_path.exists():
self.output_line_edit.setText(str(output_path.absolute()))
def select_input_file(self): def select_input_file(self):
if ((input_file := self.select_file('Select Input File')) is None or if ((input_file := self.select_file('Select Input File')) is None or
@@ -880,7 +912,7 @@ class Video2XMainWindow(QMainWindow):
self.config_line_edit.setText(str(config_file.absolute())) self.config_line_edit.setText(str(config_file.absolute()))
self.load_configurations() self.load_configurations()
def select_driver_binary_path(self, driver_line_edit): def select_driver_binary_path(self, driver_line_edit: QLineEdit):
if (driver_binary_path := self.select_file('Select Driver Binary File')) is None: if (driver_binary_path := self.select_file('Select Driver Binary File')) is None:
return return
driver_line_edit.setText(str(driver_binary_path.absolute())) driver_line_edit.setText(str(driver_binary_path.absolute()))
@@ -922,7 +954,7 @@ You can [submit an issue on GitHub](https://github.com/k4yt3x/video2x/issues/new
message_box.setText(error_message.format(exception, urllib.parse.quote(str(exception)))) message_box.setText(error_message.format(exception, urllib.parse.quote(str(exception))))
message_box.exec_() message_box.exec_()
def progress_monitor(self, progress_callback): def progress_monitor(self, progress_callback: pyqtSignal):
# initialize progress bar values # initialize progress bar values
upscale_begin_time = time.time() upscale_begin_time = time.time()
@@ -1093,13 +1125,39 @@ You can [submit an issue on GitHub](https://github.com/k4yt3x/video2x/issues/new
self.reset_progress_display() self.reset_progress_display()
def stop(self): def stop(self):
with contextlib.suppress(AttributeError):
self.upscaler.running = False
def closeEvent(self, event): try:
# if upscaler is running, ask the user for confirmation
if self.upscaler.running is True:
confirmation = QMessageBox.question(self,
'Stopping Confirmation',
'Are you sure you want to want to stop the upscaling process?',
QMessageBox.Yes,
QMessageBox.No)
# if the user indeed wants to stop processing
if confirmation == QMessageBox.Yes:
with contextlib.suppress(AttributeError):
self.upscaler.running = False
return True
# if the user doesn't want ot stop processing
else:
return False
# if the upscaler is not running
else:
return True
# if an AttributeError happens
# that means the upscaler object haven't been created yet
except AttributeError:
return True
def closeEvent(self, event: QtGui.QCloseEvent):
# try cleaning up temp directories # try cleaning up temp directories
self.stop() if self.stop():
event.accept() event.accept()
else:
event.ignore()
# this file shouldn't be imported # this file shouldn't be imported

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.12.0, 2020-05-14T22:33:50. --> <!-- Written by QtCreator 4.12.0, 2020-05-17T16:15:14. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

View File

@@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>671</width> <width>673</width>
<height>802</height> <height>802</height>
</rect> </rect>
</property> </property>
@@ -270,7 +270,57 @@
<item> <item>
<widget class="QComboBox" name="driverComboBox"> <widget class="QComboBox" name="driverComboBox">
<property name="toolTip"> <property name="toolTip">
<string>Driver to use for upscaling. Waifu2x Caffe is only for Nvidia GPUs.</string> <string>&lt;p style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Driver to use for
upscaling. &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Waifu2X Caffe&lt;/span&gt;
&lt;ul&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span
style=&quot;font-size: 8pt; font-weight: 600;&quot;&gt;requires Nvidia GPU and CUDA/cuDNN&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Caffe
implementation of waifu2x which is classic and stable&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Lots of models
available&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Waifu2X Converter
CPP&lt;/span&gt;
&lt;ul&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;CPP
implementation of waifu2x&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Uses OpenCL
and OpenCV for graphical processing&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Waifu2X NCNN
Vulkan&lt;/span&gt;
&lt;ul&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;NCNN
implementation of waifu2x&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Uses Vulkan
API for graphical processing&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;SRMD NCNN
Vulkan&lt;/span&gt;
&lt;ul&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;NCNN
implementation of SRMD&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Uses Vulkan
API for graphical processing&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Anime4KCPP&lt;/span&gt;
&lt;ul&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;CPP
implementation of Anime4K&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Very fast but
low quality&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;-qt-block-indent: 0; text-indent: 0px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-size: 8pt;&quot;&gt;Multithreading
is preferred&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</string>
</property> </property>
<item> <item>
<property name="text"> <property name="text">
@@ -1933,7 +1983,7 @@
<item> <item>
<widget class="QCheckBox" name="ffmpegAssembleVideoOutputOptionsEnsureDivisibleCheckBox"> <widget class="QCheckBox" name="ffmpegAssembleVideoOutputOptionsEnsureDivisibleCheckBox">
<property name="text"> <property name="text">
<string>Ensure output width and height are divisible by 2</string> <string>Ensure output width and height are divisible by 2 (-vf: &quot;pad=ceil(iw/2)*2:ceil(ih/2)*2&quot;)</string>
</property> </property>
<property name="checked"> <property name="checked">
<bool>true</bool> <bool>true</bool>
@@ -2070,9 +2120,9 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_32"> <layout class="QVBoxLayout" name="verticalLayout_32">
<item> <item>
<layout class="QHBoxLayout" name="ffmpegMigrateStreamsOutputOptionsOtherPixelFormatHorizontalLayout"> <layout class="QHBoxLayout" name="ffmpegMigrateStreamsOutputOptionsPixelFormatHorizontalLayout">
<item> <item>
<widget class="QLabel" name="ffmpegMigrateStreamsOutputOptionsOtherPixelFormatLabel"> <widget class="QLabel" name="ffmpegMigrateStreamsOutputOptionsPixelFormatLabel">
<property name="text"> <property name="text">
<string>Pixel Format (-pix_fmt)</string> <string>Pixel Format (-pix_fmt)</string>
</property> </property>
@@ -2084,9 +2134,30 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="ffmpegMigrateStreamsOutputOptionsCopyCodecCheckBox"> <layout class="QHBoxLayout" name="ffmpegMigrateStreamsOutputOptionsFrameInterpolationHorizontalLayout">
<item>
<widget class="QLabel" name="ffmpegMigrateStreamsOutputOptionsFrameInterpolationLabel">
<property name="text">
<string>Frame Interpolation (-filter &quot;minterpolate='fps=n'&quot;)</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="ffmpegMigrateStreamsOutputOptionsFrameInterpolationSpinBox">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="ffmpegMigrateStreamsOutputOptionsCopyStreamsCheckBox">
<property name="toolTip">
<string>Copy streams without re-encoding</string>
</property>
<property name="text"> <property name="text">
<string>Copy codec</string> <string>Copy streams (-c copy)</string>
</property> </property>
<property name="checked"> <property name="checked">
<bool>true</bool> <bool>true</bool>
@@ -2094,9 +2165,9 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="ffmpegMigrateStreamsOutputOptionsOtherCopyKnownMetadataTagsCheckBox"> <widget class="QCheckBox" name="ffmpegMigrateStreamsOutputOptionsCopyKnownMetadataTagsCheckBox">
<property name="text"> <property name="text">
<string>Copy known metadata tags</string> <string>Copy known metadata tags (-map_metadata 0)</string>
</property> </property>
<property name="checked"> <property name="checked">
<bool>true</bool> <bool>true</bool>
@@ -2104,9 +2175,9 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="ffmpegMigrateStreamsOutputOptionsOtherCopyArbitraryMetadataTagsCheckBox"> <widget class="QCheckBox" name="ffmpegMigrateStreamsOutputOptionsCopyArbitraryMetadataTagsCheckBox">
<property name="text"> <property name="text">
<string>Copy arbitrary metadata tags</string> <string>Copy arbitrary metadata tags (-movflags use_metadata_tags)</string>
</property> </property>
<property name="checked"> <property name="checked">
<bool>true</bool> <bool>true</bool>
@@ -2114,7 +2185,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="ffmpegMigrateStreamsOutputOptionsOtherVerticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@@ -2511,7 +2582,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>671</width> <width>673</width>
<height>21</height> <height>21</height>
</rect> </rect>
</property> </property>