added audio, subtitles, data, and attachments copying

This commit is contained in:
k4yt3x 2022-02-17 03:51:55 +00:00
parent ef1a8f3e41
commit 9f73e75f17
5 changed files with 45 additions and 35 deletions

View File

@ -19,7 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
Name: Video Decoder Name: Video Decoder
Author: K4YT3X Author: K4YT3X
Date Created: June 17, 2021 Date Created: June 17, 2021
Last Modified: February 12, 2022 Last Modified: February 16, 2022
""" """
# built-in imports # built-in imports
@ -59,7 +59,7 @@ class VideoDecoder(threading.Thread):
processing_queue: queue.Queue, processing_queue: queue.Queue,
processing_settings: tuple, processing_settings: tuple,
ignore_max_image_pixels=True, ignore_max_image_pixels=True,
): ) -> None:
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.running = False self.running = False
self.input_path = input_path self.input_path = input_path
@ -91,7 +91,7 @@ class VideoDecoder(threading.Thread):
# stderr=subprocess.DEVNULL, # stderr=subprocess.DEVNULL,
) )
def run(self): def run(self) -> None:
self.running = True self.running = True
# the index of the frame # the index of the frame
@ -164,5 +164,5 @@ class VideoDecoder(threading.Thread):
self.running = False self.running = False
return super().run() return super().run()
def stop(self): def stop(self) -> None:
self.running = False self.running = False

View File

@ -19,7 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
Name: Video Encoder Name: Video Encoder
Author: K4YT3X Author: K4YT3X
Date Created: June 17, 2021 Date Created: June 17, 2021
Last Modified: June 30, 2021 Last Modified: February 16, 2022
""" """
# built-in imports # built-in imports
@ -61,7 +61,11 @@ class VideoEncoder(threading.Thread):
total_frames: int, total_frames: int,
processed_frames: multiprocessing.managers.ListProxy, processed_frames: multiprocessing.managers.ListProxy,
processed: multiprocessing.sharedctypes.Synchronized, processed: multiprocessing.sharedctypes.Synchronized,
): copy_audio: bool = True,
copy_subtitle: bool = True,
copy_data: bool = False,
copy_attachments: bool = False,
) -> None:
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.running = False self.running = False
self.input_path = input_path self.input_path = input_path
@ -82,31 +86,31 @@ class VideoEncoder(threading.Thread):
r=frame_rate, r=frame_rate,
) )
# map additional streams from original file # copy additional streams from original file
""" # https://ffmpeg.org/ffmpeg.html#Stream-specifiers-1
additional_streams = [ additional_streams = [
# self.original["v?"], # self.original["1:v?"],
self.original["a?"], self.original["a?"] if copy_audio is True else None,
self.original["s?"], self.original["s?"] if copy_subtitle is True else None,
self.original["d?"], self.original["d?"] if copy_data is True else None,
self.original["t?"], self.original["t?"] if copy_attachments is True else None,
] ]
"""
# run FFmpeg and produce final output # run FFmpeg and produce final output
self.encoder = subprocess.Popen( self.encoder = subprocess.Popen(
ffmpeg.compile( ffmpeg.compile(
ffmpeg.output( ffmpeg.output(
frames, frames,
*[s for s in additional_streams if s is not None],
str(self.output_path), str(self.output_path),
pix_fmt="yuv420p", pix_fmt="yuv420p",
vcodec="libx264", vcodec="libx264",
acodec="copy", # acodec="copy",
r=frame_rate, r=frame_rate,
crf=17, crf=17,
vsync="1", vsync="1",
# map_metadata=1, map_metadata=1,
# metadata="comment=Upscaled with Video2X", metadata="comment=Processed with Video2X",
) )
.global_args("-hide_banner") .global_args("-hide_banner")
.global_args("-nostats") .global_args("-nostats")
@ -123,7 +127,7 @@ class VideoEncoder(threading.Thread):
# stderr=subprocess.DEVNULL, # stderr=subprocess.DEVNULL,
) )
def run(self): def run(self) -> None:
self.running = True self.running = True
frame_index = 0 frame_index = 0
while self.running and frame_index < self.total_frames: while self.running and frame_index < self.total_frames:
@ -165,5 +169,5 @@ class VideoEncoder(threading.Thread):
self.running = False self.running = False
return super().run() return super().run()
def stop(self): def stop(self) -> None:
self.running = False self.running = False

View File

@ -19,7 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
Name: Interpolator Name: Interpolator
Author: K4YT3X Author: K4YT3X
Date Created: May 27, 2021 Date Created: May 27, 2021
Last Modified: February 2, 2022 Last Modified: February 16, 2022
""" """
# local imports # local imports
@ -46,7 +46,7 @@ class Interpolator(multiprocessing.Process):
self, self,
processing_queue: multiprocessing.Queue, processing_queue: multiprocessing.Queue,
processed_frames: multiprocessing.managers.ListProxy, processed_frames: multiprocessing.managers.ListProxy,
): ) -> None:
multiprocessing.Process.__init__(self) multiprocessing.Process.__init__(self)
self.running = False self.running = False
self.processing_queue = processing_queue self.processing_queue = processing_queue
@ -54,7 +54,7 @@ class Interpolator(multiprocessing.Process):
signal.signal(signal.SIGTERM, self._stop) signal.signal(signal.SIGTERM, self._stop)
def run(self): def run(self) -> None:
self.running = True self.running = True
logger.info(f"Interpolator process {self.name} initiating") logger.info(f"Interpolator process {self.name} initiating")
processor_objects = {} processor_objects = {}
@ -116,5 +116,5 @@ class Interpolator(multiprocessing.Process):
self.running = False self.running = False
return super().run() return super().run()
def _stop(self, _signal_number, _frame): def _stop(self, _signal_number, _frame) -> None:
self.running = False self.running = False

View File

@ -19,7 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
Name: Upscaler Name: Upscaler
Author: K4YT3X Author: K4YT3X
Date Created: May 27, 2021 Date Created: May 27, 2021
Last Modified: August 17, 2021 Last Modified: February 16, 2022
""" """
# local imports # local imports
@ -56,7 +56,7 @@ class Upscaler(multiprocessing.Process):
self, self,
processing_queue: multiprocessing.Queue, processing_queue: multiprocessing.Queue,
processed_frames: multiprocessing.managers.ListProxy, processed_frames: multiprocessing.managers.ListProxy,
): ) -> None:
multiprocessing.Process.__init__(self) multiprocessing.Process.__init__(self)
self.running = False self.running = False
self.processing_queue = processing_queue self.processing_queue = processing_queue
@ -64,7 +64,7 @@ class Upscaler(multiprocessing.Process):
signal.signal(signal.SIGTERM, self._stop) signal.signal(signal.SIGTERM, self._stop)
def run(self): def run(self) -> None:
self.running = True self.running = True
logger.opt(colors=True).info( logger.opt(colors=True).info(
f"Upscaler process <blue>{self.name}</blue> initiating" f"Upscaler process <blue>{self.name}</blue> initiating"
@ -193,5 +193,5 @@ class Upscaler(multiprocessing.Process):
self.running = False self.running = False
return super().run() return super().run()
def _stop(self, _signal_number, _frame): def _stop(self, _signal_number, _frame) -> None:
self.running = False self.running = False

View File

@ -26,8 +26,8 @@ __ __ _ _ ___ __ __
Name: Video2X Name: Video2X
Creator: K4YT3X Creator: K4YT3X
Date Created: Feb 24, 2018 Date Created: February 24, 2018
Last Modified: February 15, 2022 Last Modified: February 16, 2022
Editor: BrianPetkovsek Editor: BrianPetkovsek
Last Modified: June 17, 2019 Last Modified: June 17, 2019
@ -122,10 +122,10 @@ class Video2X:
- interpolate: perform motion interpolation on a file - interpolate: perform motion interpolation on a file
""" """
def __init__(self): def __init__(self) -> None:
self.version = __version__ self.version = __version__
def _get_video_info(self, path: pathlib.Path): def _get_video_info(self, path: pathlib.Path) -> tuple:
""" """
get video file information with FFmpeg get video file information with FFmpeg
@ -167,7 +167,7 @@ class Video2X:
mode: str, mode: str,
processes: int, processes: int,
processing_settings: tuple, processing_settings: tuple,
): ) -> None:
# record original STDOUT and STDERR for restoration # record original STDOUT and STDERR for restoration
original_stdout = sys.stdout original_stdout = sys.stdout
@ -453,7 +453,10 @@ def parse_arguments() -> argparse.Namespace:
"-t", "-t",
"--threshold", "--threshold",
type=float, type=float,
help="skip if the percent difference between two adjacent frames is below this value; set to 0 to process all frames", help=(
"skip if the percent difference between two adjacent frames is below this"
" value; set to 0 to process all frames"
),
default=0, default=0,
) )
@ -478,14 +481,17 @@ def parse_arguments() -> argparse.Namespace:
"-t", "-t",
"--threshold", "--threshold",
type=float, type=float,
help="skip if the percent difference between two adjacent frames exceeds this value; set to 100 to interpolate all frames", help=(
"skip if the percent difference between two adjacent frames exceeds this"
" value; set to 100 to interpolate all frames"
),
default=10, default=10,
) )
return parser.parse_args() return parser.parse_args()
def main(): def main() -> None:
""" """
command line direct invocation command line direct invocation
program entry point program entry point