mirror of
				https://github.com/k4yt3x/video2x.git
				synced 2025-10-31 12:50:59 +01:00 
			
		
		
		
	redesigned UI progress display
This commit is contained in:
		
							parent
							
								
									f2943802cb
								
							
						
					
					
						commit
						790bb54598
					
				| @ -85,9 +85,12 @@ class Upscaler: | ||||
|         self.preserve_frames = False | ||||
| 
 | ||||
|         # other internal members and signals | ||||
|         self.stop_signal = False | ||||
|         self.running = False | ||||
|         self.total_frames_upscaled = 0 | ||||
|         self.total_frames = 0 | ||||
|         self.total_videos = 0 | ||||
|         self.total_processed = 0 | ||||
|         self.current_input_video = pathlib.Path() | ||||
| 
 | ||||
|     def create_temp_directories(self): | ||||
|         """create temporary directories | ||||
| @ -347,7 +350,7 @@ class Upscaler: | ||||
|             while self.process_pool: | ||||
| 
 | ||||
|                 # if stop signal received, terminate all processes | ||||
|                 if self.stop_signal is True: | ||||
|                 if self.running is False: | ||||
|                     raise SystemExit | ||||
| 
 | ||||
|                 for process in self.process_pool: | ||||
| @ -386,7 +389,7 @@ class Upscaler: | ||||
|         """ | ||||
| 
 | ||||
|         # external stop signal when called in a thread | ||||
|         self.stop_signal = False | ||||
|         self.running = True | ||||
| 
 | ||||
|         # define process pool to contain processes | ||||
|         self.process_pool = [] | ||||
| @ -396,7 +399,7 @@ class Upscaler: | ||||
|         self._check_arguments() | ||||
| 
 | ||||
|         # define processing queue | ||||
|         processing_queue = queue.Queue() | ||||
|         self.processing_queue = queue.Queue() | ||||
| 
 | ||||
|         # if input is a list of files | ||||
|         if isinstance(self.input, list): | ||||
| @ -407,17 +410,17 @@ class Upscaler: | ||||
| 
 | ||||
|                 if input_path.is_file(): | ||||
|                     output_video = self.output / input_path.name | ||||
|                     processing_queue.put((input_path.absolute(), output_video.absolute())) | ||||
|                     self.processing_queue.put((input_path.absolute(), output_video.absolute())) | ||||
| 
 | ||||
|                 elif input_path.is_dir(): | ||||
|                     for input_video in [f for f in input_path.iterdir() if f.is_file()]: | ||||
|                         output_video = self.output / input_video.name | ||||
|                         processing_queue.put((input_video.absolute(), output_video.absolute())) | ||||
|                         self.processing_queue.put((input_video.absolute(), output_video.absolute())) | ||||
| 
 | ||||
|         # if input specified is single file | ||||
|         elif self.input.is_file(): | ||||
|             Avalon.info(_('Upscaling single video file: {}').format(self.input)) | ||||
|             processing_queue.put((self.input.absolute(), self.output.absolute())) | ||||
|             self.processing_queue.put((self.input.absolute(), self.output.absolute())) | ||||
| 
 | ||||
|         # if input specified is a directory | ||||
|         elif self.input.is_dir(): | ||||
| @ -426,10 +429,13 @@ class Upscaler: | ||||
|             self.output.mkdir(parents=True, exist_ok=True) | ||||
|             for input_video in [f for f in self.input.iterdir() if f.is_file()]: | ||||
|                 output_video = self.output / input_video.name | ||||
|                 processing_queue.put((input_video.absolute(), output_video.absolute())) | ||||
|                 self.processing_queue.put((input_video.absolute(), output_video.absolute())) | ||||
| 
 | ||||
|         while not processing_queue.empty(): | ||||
|             input_video, output_video = processing_queue.get() | ||||
|         # record video count for external calls | ||||
|         self.total_videos = self.processing_queue.qsize() | ||||
| 
 | ||||
|         while not self.processing_queue.empty(): | ||||
|             self.current_input_video, output_video = self.processing_queue.get() | ||||
|             # drivers that have native support for video processing | ||||
|             if self.driver == 'anime4kcpp': | ||||
|                 # append FFmpeg path to the end of PATH | ||||
| @ -442,7 +448,7 @@ class Upscaler: | ||||
|                 driver = DriverWrapperMain(copy.deepcopy(self.driver_settings)) | ||||
| 
 | ||||
|                 # run Anime4KCPP | ||||
|                 self.process_pool.append(driver.upscale(input_video, output_video, self.scale_ratio, self.processes)) | ||||
|                 self.process_pool.append(driver.upscale(self.current_input_video, output_video, self.scale_ratio, self.processes)) | ||||
|                 self._wait() | ||||
|                 Avalon.info(_('Upscaling completed')) | ||||
| 
 | ||||
| @ -454,7 +460,7 @@ class Upscaler: | ||||
|                     fm = Ffmpeg(self.ffmpeg_settings, self.image_format) | ||||
| 
 | ||||
|                     Avalon.info(_('Reading video information')) | ||||
|                     video_info = fm.get_video_info(input_video) | ||||
|                     video_info = fm.get_video_info(self.current_input_video) | ||||
|                     # analyze original video with ffprobe and retrieve framerate | ||||
|                     # width, height = info['streams'][0]['width'], info['streams'][0]['height'] | ||||
| 
 | ||||
| @ -471,7 +477,7 @@ class Upscaler: | ||||
|                         raise StreamNotFoundError('no video stream found') | ||||
| 
 | ||||
|                     # extract frames from video | ||||
|                     self.process_pool.append((fm.extract_frames(input_video, self.extracted_frames))) | ||||
|                     self.process_pool.append((fm.extract_frames(self.current_input_video, self.extracted_frames))) | ||||
|                     self._wait() | ||||
| 
 | ||||
|                     # get average frame rate of video stream | ||||
| @ -512,7 +518,7 @@ class Upscaler: | ||||
| 
 | ||||
|                     # migrate audio tracks and subtitles | ||||
|                     Avalon.info(_('Migrating audio tracks and subtitles to upscaled video')) | ||||
|                     self.process_pool.append(fm.migrate_audio_tracks_subtitles(input_video, output_video, self.upscaled_frames)) | ||||
|                     self.process_pool.append(fm.migrate_audio_tracks_subtitles(self.current_input_video, output_video, self.upscaled_frames)) | ||||
|                     self._wait() | ||||
| 
 | ||||
|                     # destroy temp directories | ||||
| @ -522,3 +528,9 @@ class Upscaler: | ||||
|                     with contextlib.suppress(ValueError): | ||||
|                         self.cleanup_temp_directories() | ||||
|                     raise e | ||||
| 
 | ||||
|             # increment total number of videos processed | ||||
|             self.total_processed += 1 | ||||
| 
 | ||||
|         # signal upscaling completion | ||||
|         self.running = False | ||||
|  | ||||
| @ -219,11 +219,17 @@ class Video2XMainWindow(QMainWindow): | ||||
|         self.scale_ratio_double_spin_box = self.findChild(QDoubleSpinBox, 'scaleRatioDoubleSpinBox') | ||||
|         self.preserve_frames_check_box = self.findChild(QCheckBox, 'preserveFramesCheckBox') | ||||
| 
 | ||||
|         # progress bar and start/stop controls | ||||
|         self.progress_bar = self.findChild(QProgressBar, 'progressBar') | ||||
|         # currently processing | ||||
|         self.currently_processing_label = self.findChild(QLabel, 'currentlyProcessingLabel') | ||||
|         self.current_progress_bar = self.findChild(QProgressBar, 'currentProgressBar') | ||||
|         self.time_elapsed_label = self.findChild(QLabel, 'timeElapsedLabel') | ||||
|         self.time_remaining_label = self.findChild(QLabel, 'timeRemainingLabel') | ||||
|         self.rate_label = self.findChild(QLabel, 'rateLabel') | ||||
|         self.frames_label = self.findChild(QLabel, 'framesLabel') | ||||
| 
 | ||||
|         # overall progress | ||||
|         self.overall_progress_bar = self.findChild(QProgressBar, 'overallProgressBar') | ||||
|         self.overall_progress_label = self.findChild(QLabel, 'overallProgressLabel') | ||||
|         self.start_button = self.findChild(QPushButton, 'startButton') | ||||
|         self.start_button.clicked.connect(self.start) | ||||
|         self.stop_button = self.findChild(QPushButton, 'stopButton') | ||||
| @ -625,38 +631,33 @@ class Video2XMainWindow(QMainWindow): | ||||
|         message_box.exec_() | ||||
| 
 | ||||
|     def start_progress_bar(self, progress_callback): | ||||
|         # wait for progress monitor to come online | ||||
|         while 'progress_monitor' not in self.upscaler.__dict__: | ||||
|             if self.upscaler.stop_signal: | ||||
|                 return | ||||
|             time.sleep(0.1) | ||||
| 
 | ||||
|         # initialize progress bar values | ||||
|         upscale_begin_time = time.time() | ||||
|         progress_callback.emit((0, 0, 0, upscale_begin_time)) | ||||
|         progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, pathlib.Path())) | ||||
| 
 | ||||
|         # keep querying upscaling process and feed information to callback signal | ||||
|         while self.upscaler.progress_monitor.running: | ||||
|             try: | ||||
|                 progress_percentage = int(100 * self.upscaler.total_frames_upscaled / self.upscaler.total_frames) | ||||
|             except ZeroDivisionError: | ||||
|                 progress_percentage = 0 | ||||
|         while self.upscaler.running: | ||||
| 
 | ||||
|             progress_callback.emit((progress_percentage, | ||||
|             progress_callback.emit((upscale_begin_time, | ||||
|                                     self.upscaler.total_frames_upscaled, | ||||
|                                     self.upscaler.total_frames, | ||||
|                                     upscale_begin_time)) | ||||
|                                     self.upscaler.total_processed, | ||||
|                                     self.upscaler.total_videos, | ||||
|                                     self.upscaler.current_input_video)) | ||||
|             time.sleep(1) | ||||
| 
 | ||||
|         # upscale process will stop at 99% | ||||
|         # so it's set to 100 manually when all is done | ||||
|         progress_callback.emit((100, 0, 0, upscale_begin_time)) | ||||
|         progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, pathlib.Path())) | ||||
| 
 | ||||
|     def set_progress(self, progress_information: tuple): | ||||
|         progress_percentage = progress_information[0] | ||||
|         upscale_begin_time = progress_information[0] | ||||
|         total_frames_upscaled = progress_information[1] | ||||
|         total_frames = progress_information[2] | ||||
|         upscale_begin_time = progress_information[3] | ||||
|         total_processed = progress_information[3] | ||||
|         total_videos = progress_information[4] | ||||
|         current_input_video = progress_information[5] | ||||
| 
 | ||||
|         # calculate fields based on frames and time elapsed | ||||
|         time_elapsed = time.time() - upscale_begin_time | ||||
| @ -668,10 +669,29 @@ class Video2XMainWindow(QMainWindow): | ||||
|             time_remaining = 0.0 | ||||
| 
 | ||||
|         # set calculated values in GUI | ||||
|         self.progress_bar.setValue(progress_percentage) | ||||
|         self.current_progress_bar.setMaximum(total_frames) | ||||
|         self.current_progress_bar.setValue(total_frames_upscaled) | ||||
|         self.frames_label.setText('Frames: {}/{}'.format(total_frames_upscaled, total_frames)) | ||||
|         self.time_elapsed_label.setText('Time Elapsed: {}'.format(time.strftime("%H:%M:%S", time.gmtime(time_elapsed)))) | ||||
|         self.time_remaining_label.setText('Time Remaining: {}'.format(time.strftime("%H:%M:%S", time.gmtime(time_remaining)))) | ||||
|         self.rate_label.setText('Rate (FPS): {}'.format(round(rate, 2))) | ||||
|         self.overall_progress_label.setText('Overall Progress: {}/{}'.format(total_processed, total_videos)) | ||||
|         self.overall_progress_bar.setMaximum(total_videos) | ||||
|         self.overall_progress_bar.setValue(total_processed) | ||||
|         self.currently_processing_label.setText('Currently Processing: {}'.format(str(current_input_video.name))) | ||||
| 
 | ||||
|     def reset_progress_display(self): | ||||
|         # reset progress display UI elements | ||||
|         self.current_progress_bar.setMaximum(100) | ||||
|         self.current_progress_bar.setValue(0) | ||||
|         self.frames_label.setText('Frames: {}/{}'.format(0, 0)) | ||||
|         self.time_elapsed_label.setText('Time Elapsed: {}'.format(time.strftime("%H:%M:%S", time.gmtime(0)))) | ||||
|         self.time_remaining_label.setText('Time Remaining: {}'.format(time.strftime("%H:%M:%S", time.gmtime(0)))) | ||||
|         self.rate_label.setText('Rate (FPS): {}'.format(0.0)) | ||||
|         self.overall_progress_label.setText('Overall Progress: {}/{}'.format(0, 0)) | ||||
|         self.overall_progress_bar.setMaximum(100) | ||||
|         self.overall_progress_bar.setValue(0) | ||||
|         self.currently_processing_label.setText('Currently Processing:') | ||||
| 
 | ||||
|     def start(self): | ||||
| 
 | ||||
| @ -736,12 +756,14 @@ class Video2XMainWindow(QMainWindow): | ||||
|         self.threadpool.waitForDone(5) | ||||
|         self.start_button.setEnabled(True) | ||||
|         self.stop_button.setEnabled(False) | ||||
|         self.reset_progress_display() | ||||
| 
 | ||||
|     def upscale_interrupted(self): | ||||
|         self.show_message('Upscale has been interrupted') | ||||
|         self.threadpool.waitForDone(5) | ||||
|         self.start_button.setEnabled(True) | ||||
|         self.stop_button.setEnabled(False) | ||||
|         self.reset_progress_display() | ||||
| 
 | ||||
|     def upscale_successful(self): | ||||
|         # if all threads have finished | ||||
| @ -749,10 +771,11 @@ class Video2XMainWindow(QMainWindow): | ||||
|         self.show_message('Upscale finished successfully, taking {} seconds'.format(round((time.time() - self.begin_time), 5))) | ||||
|         self.start_button.setEnabled(True) | ||||
|         self.stop_button.setEnabled(False) | ||||
|         self.reset_progress_display() | ||||
| 
 | ||||
|     def stop(self): | ||||
|         with contextlib.suppress(AttributeError): | ||||
|             self.upscaler.stop_signal = True | ||||
|             self.upscaler.running = False | ||||
| 
 | ||||
|     def closeEvent(self, event): | ||||
|         # try cleaning up temp directories | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE QtCreatorProject> | ||||
| <!-- Written by QtCreator 4.12.0, 2020-05-07T21:11:12. --> | ||||
| <!-- Written by QtCreator 4.12.0, 2020-05-08T18:14:51. --> | ||||
| <qtcreator> | ||||
|  <data> | ||||
|   <variable>EnvironmentId</variable> | ||||
|  | ||||
| @ -7,7 +7,7 @@ | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>718</width> | ||||
|     <height>668</height> | ||||
|     <height>740</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="acceptDrops"> | ||||
| @ -1276,72 +1276,184 @@ | ||||
|      </widget> | ||||
|     </item> | ||||
|     <item> | ||||
|      <layout class="QVBoxLayout" name="controlsVerticalLayout"> | ||||
|       <item> | ||||
|        <widget class="QProgressBar" name="progressBar"> | ||||
|         <property name="value"> | ||||
|          <number>0</number> | ||||
|         </property> | ||||
|        </widget> | ||||
|       </item> | ||||
|       <item> | ||||
|        <layout class="QHBoxLayout" name="timeControlsHorizontalLayout"> | ||||
|         <item> | ||||
|          <widget class="QLabel" name="timeElapsedLabel"> | ||||
|           <property name="acceptDrops"> | ||||
|            <bool>false</bool> | ||||
|           </property> | ||||
|           <property name="frameShape"> | ||||
|            <enum>QFrame::StyledPanel</enum> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string>Time Elapsed: 00:00:00</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QLabel" name="timeRemainingLabel"> | ||||
|           <property name="frameShape"> | ||||
|            <enum>QFrame::StyledPanel</enum> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string>Time Remaining: 00:00:00</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QLabel" name="rateLabel"> | ||||
|           <property name="frameShape"> | ||||
|            <enum>QFrame::StyledPanel</enum> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string>Rate (FPS): 0.0</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QPushButton" name="startButton"> | ||||
|           <property name="enabled"> | ||||
|            <bool>false</bool> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string>Start</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QPushButton" name="stopButton"> | ||||
|           <property name="enabled"> | ||||
|            <bool>false</bool> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string>Stop</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|      </layout> | ||||
|      <widget class="QGroupBox" name="currentVideoProcessingProgressGroupBox"> | ||||
|       <property name="title"> | ||||
|        <string>Current Video Processing Progress</string> | ||||
|       </property> | ||||
|       <layout class="QVBoxLayout" name="verticalLayout_11"> | ||||
|        <item> | ||||
|         <widget class="QLabel" name="currentlyProcessingLabel"> | ||||
|          <property name="minimumSize"> | ||||
|           <size> | ||||
|            <width>0</width> | ||||
|            <height>20</height> | ||||
|           </size> | ||||
|          </property> | ||||
|          <property name="text"> | ||||
|           <string>Currently Processing:</string> | ||||
|          </property> | ||||
|         </widget> | ||||
|        </item> | ||||
|        <item> | ||||
|         <widget class="QProgressBar" name="currentProgressBar"> | ||||
|          <property name="value"> | ||||
|           <number>0</number> | ||||
|          </property> | ||||
|         </widget> | ||||
|        </item> | ||||
|        <item> | ||||
|         <layout class="QHBoxLayout" name="currentlyProcessingInfoHorizontalLayout"> | ||||
|          <item> | ||||
|           <widget class="QLabel" name="timeElapsedLabel"> | ||||
|            <property name="minimumSize"> | ||||
|             <size> | ||||
|              <width>0</width> | ||||
|              <height>20</height> | ||||
|             </size> | ||||
|            </property> | ||||
|            <property name="acceptDrops"> | ||||
|             <bool>false</bool> | ||||
|            </property> | ||||
|            <property name="frameShape"> | ||||
|             <enum>QFrame::StyledPanel</enum> | ||||
|            </property> | ||||
|            <property name="text"> | ||||
|             <string>Time Elapsed: 00:00:00</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QLabel" name="timeRemainingLabel"> | ||||
|            <property name="minimumSize"> | ||||
|             <size> | ||||
|              <width>0</width> | ||||
|              <height>20</height> | ||||
|             </size> | ||||
|            </property> | ||||
|            <property name="frameShape"> | ||||
|             <enum>QFrame::StyledPanel</enum> | ||||
|            </property> | ||||
|            <property name="text"> | ||||
|             <string>Time Remaining: 00:00:00</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QLabel" name="rateLabel"> | ||||
|            <property name="minimumSize"> | ||||
|             <size> | ||||
|              <width>0</width> | ||||
|              <height>20</height> | ||||
|             </size> | ||||
|            </property> | ||||
|            <property name="frameShape"> | ||||
|             <enum>QFrame::StyledPanel</enum> | ||||
|            </property> | ||||
|            <property name="text"> | ||||
|             <string>Rate (FPS): 0.0</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QLabel" name="framesLabel"> | ||||
|            <property name="frameShape"> | ||||
|             <enum>QFrame::StyledPanel</enum> | ||||
|            </property> | ||||
|            <property name="text"> | ||||
|             <string>Frames: 0/0</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|         </layout> | ||||
|        </item> | ||||
|       </layout> | ||||
|      </widget> | ||||
|     </item> | ||||
|     <item> | ||||
|      <widget class="QGroupBox" name="overallVideoProcessingProgressGroupBox"> | ||||
|       <property name="title"> | ||||
|        <string>Overall Video Processing Progress</string> | ||||
|       </property> | ||||
|       <layout class="QVBoxLayout" name="verticalLayout_13"> | ||||
|        <item> | ||||
|         <widget class="QProgressBar" name="overallProgressBar"> | ||||
|          <property name="value"> | ||||
|           <number>0</number> | ||||
|          </property> | ||||
|         </widget> | ||||
|        </item> | ||||
|        <item> | ||||
|         <layout class="QHBoxLayout" name="overallProcessingHorizontalLayout"> | ||||
|          <item> | ||||
|           <widget class="QLabel" name="overallProgressLabel"> | ||||
|            <property name="minimumSize"> | ||||
|             <size> | ||||
|              <width>0</width> | ||||
|              <height>20</height> | ||||
|             </size> | ||||
|            </property> | ||||
|            <property name="maximumSize"> | ||||
|             <size> | ||||
|              <width>16777215</width> | ||||
|              <height>16777215</height> | ||||
|             </size> | ||||
|            </property> | ||||
|            <property name="frameShape"> | ||||
|             <enum>QFrame::StyledPanel</enum> | ||||
|            </property> | ||||
|            <property name="text"> | ||||
|             <string>Overall Progress: 0/0</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QPushButton" name="startButton"> | ||||
|            <property name="enabled"> | ||||
|             <bool>false</bool> | ||||
|            </property> | ||||
|            <property name="minimumSize"> | ||||
|             <size> | ||||
|              <width>130</width> | ||||
|              <height>0</height> | ||||
|             </size> | ||||
|            </property> | ||||
|            <property name="maximumSize"> | ||||
|             <size> | ||||
|              <width>16777215</width> | ||||
|              <height>16777215</height> | ||||
|             </size> | ||||
|            </property> | ||||
|            <property name="text"> | ||||
|             <string>Start</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QPushButton" name="stopButton"> | ||||
|            <property name="enabled"> | ||||
|             <bool>false</bool> | ||||
|            </property> | ||||
|            <property name="minimumSize"> | ||||
|             <size> | ||||
|              <width>130</width> | ||||
|              <height>0</height> | ||||
|             </size> | ||||
|            </property> | ||||
|            <property name="maximumSize"> | ||||
|             <size> | ||||
|              <width>16777215</width> | ||||
|              <height>16777215</height> | ||||
|             </size> | ||||
|            </property> | ||||
|            <property name="text"> | ||||
|             <string>Stop</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|         </layout> | ||||
|        </item> | ||||
|       </layout> | ||||
|      </widget> | ||||
|     </item> | ||||
|    </layout> | ||||
|   </widget> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user