fixed issue #77 incorrect output video format

This commit is contained in:
k4yt3x 2019-05-06 16:25:10 -04:00
parent a7d41cafdf
commit 146044505b
2 changed files with 101 additions and 32 deletions

View File

@ -4,7 +4,7 @@
Name: FFMPEG Class Name: FFMPEG Class
Author: K4YT3X Author: K4YT3X
Date Created: Feb 24, 2018 Date Created: Feb 24, 2018
Last Modified: April 28, 2019 Last Modified: May 4, 2019
Description: This class handles all FFMPEG related Description: This class handles all FFMPEG related
operations. operations.
@ -77,12 +77,18 @@ class Ffmpeg:
extracted_frames {string} -- video output directory extracted_frames {string} -- video output directory
""" """
execute = [ execute = [
self.ffmpeg_binary, self.ffmpeg_binary
]
execute.extend(self._read_configuration(phase='video_to_frames'))
execute.extend([
'-i', '-i',
input_video, input_video,
f'{extracted_frames}\\extracted_%0d.{self.image_format}' f'{extracted_frames}\\extracted_%0d.{self.image_format}'
] ])
self._execute(execute=execute, phase='video_to_frames')
self._execute(execute)
def convert_video(self, framerate, resolution, upscaled_frames): def convert_video(self, framerate, resolution, upscaled_frames):
"""Converts images into videos """Converts images into videos
@ -100,12 +106,30 @@ class Ffmpeg:
'-r', '-r',
str(framerate), str(framerate),
'-s', '-s',
resolution, resolution
'-i',
f'{upscaled_frames}\\extracted_%d.{self.image_format}',
f'{upscaled_frames}\\no_audio.mp4'
] ]
self._execute(execute=execute, phase='frames_to_video')
# read FFmpeg input options
execute.extend(self._read_configuration(phase='frames_to_video', section='input_options'))
# append input frames path into command
execute.extend([
'-i',
f'{upscaled_frames}\\extracted_%d.{self.image_format}'
])
# read FFmpeg output options
execute.extend(self._read_configuration(phase='frames_to_video', section='output_options'))
# read other options
execute.extend(self._read_configuration(phase='frames_to_video'))
# specify output file location
execute.extend([
f'{upscaled_frames}\\no_audio.mp4'
])
self._execute(execute)
def migrate_audio_tracks_subtitles(self, input_video, output_video, upscaled_frames): def migrate_audio_tracks_subtitles(self, input_video, output_video, upscaled_frames):
""" Migrates audio tracks and subtitles from input video to output video """ Migrates audio tracks and subtitles from input video to output video
@ -120,28 +144,69 @@ class Ffmpeg:
'-i', '-i',
f'{upscaled_frames}\\no_audio.mp4', f'{upscaled_frames}\\no_audio.mp4',
'-i', '-i',
input_video, input_video
output_video
] ]
self._execute(execute=execute, phase='migrating_tracks')
def _execute(self, execute, phase): execute.extend(self._read_configuration(phase='frames_to_video', section='output_options'))
for key in self.ffmpeg_settings[phase].keys(): execute.extend([
output_video
])
value = self.ffmpeg_settings[phase][key] execute.extend(self._read_configuration(phase='migrating_tracks'))
self._execute(execute)
def _read_configuration(self, phase, section=None):
""" read configuration from JSON
Read the configurations (arguments) from the JSON
configuration file and append them to the end of the
FFmpeg command.
Arguments:
execute {list} -- list of arguments to be executed
phase {str} -- phase of operation
"""
configuration = []
# if section is specified, read configurations or keys
# from only that section
if section:
source = self.ffmpeg_settings[phase][section].keys()
else:
source = self.ffmpeg_settings[phase].keys()
for key in source:
if section:
value = self.ffmpeg_settings[phase][section][key]
else:
value = self.ffmpeg_settings[phase][key]
# null or None means that leave this option out (keep default) # null or None means that leave this option out (keep default)
if value is None or value is False: if value is None or value is False or isinstance(value, list) or isinstance(value, dict):
continue continue
else: else:
execute.append(key) configuration.append(key)
# true means key is an option # true means key is an option
if value is True: if value is True:
continue continue
execute.append(str(value)) configuration.append(str(value))
return configuration
def _execute(self, execute):
""" execute command
Arguments:
execute {list} -- list of arguments to be executed
Returns:
int -- execution return code
"""
Avalon.debug_info(f'Executing: {execute}') Avalon.debug_info(f'Executing: {execute}')
return subprocess.run(execute, shell=True, check=True).returncode return subprocess.run(execute, shell=True, check=True).returncode

View File

@ -47,23 +47,27 @@
"-y": true "-y": true
}, },
"frames_to_video": { "frames_to_video": {
"-qscale:v": null, "input_options":{
"-qscale:a": null, "-qscale:v": null,
"-f": "image2", "-qscale:a": null,
"-vcodec": "libx264", "-f": "image2"
"-crf": 17, },
"-b:v": null, "output_options":{
"-pix_fmt": "yuv420p", "-vcodec": "libx264",
"-hwaccel": "auto", "-crf": 17,
"-b:v": null,
"-pix_fmt": "yuv420p"
},
"-y": true "-y": true
}, },
"migrating_tracks": { "migrating_tracks": {
"-map": "0:v:0?", "output_options":{
"-map": "1?", "-map": "0:v:0?",
"-c": "copy", "-map": "1?",
"-map": "-1:v?", "-c": "copy",
"-pix_fmt": "yuv420p", "-map": "-1:v?",
"-hwaccel": "auto", "-pix_fmt": "yuv420p"
},
"-y": true "-y": true
} }
}, },