191 lines
6.2 KiB
Python
Executable File
191 lines
6.2 KiB
Python
Executable File
"""
|
|
Convert Image sequence to Mp4 Format
|
|
Uses ffmpeg.exe
|
|
Documentation : https://www.ffmpeg.org/ffmpeg.html
|
|
|
|
Ref to Ruby version here
|
|
//[Project]/tools/script/video/
|
|
"""
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
import time
|
|
import getopt
|
|
import subprocess
|
|
|
|
# LD_Keep
|
|
ff_profile = "ld"
|
|
crf_setting = "25"
|
|
|
|
TOOLS_BIN = "{}\\Bin".format(os.environ.get('RS_TOOLSROOT'))
|
|
FFMPEG_BIN = "{}\\video\\ffmpeg.exe".format(TOOLS_BIN)
|
|
|
|
|
|
def ffmpeg(input_file, output_file, *command_order, **command_parameters):
|
|
"""
|
|
Converts a video or set of images into another video format
|
|
|
|
This command accepts all the flags that the command line version does as
|
|
keyword arguements. Please refer to the ffmpeg documentation to learn
|
|
what arguments this command accepts.
|
|
|
|
When using keyword arguments the positioning of the arguments is not saved
|
|
and will be randomly placed. If you need to
|
|
|
|
Keyword values can't be used more than once in python, so if you need to use
|
|
the same flag with different values concecutively, pass the values inside a list
|
|
|
|
e.i.
|
|
|
|
ffmpeg -i stereo.wav -map 0:0 -map 0:0 -map_channel 0.0.0:0.0 -map_channel 0.0.1:0.1 -y out.ogg
|
|
|
|
If you need a specific order and multiple values then you would write it as
|
|
|
|
ffmpeg('stereo.wav', 'out.ogg',
|
|
'map', 'map', 'map_channel', 'map_channel',
|
|
map=['0:0,0:0'], map_channel=['0.0.0:0.0','0.0.1:0.1'])
|
|
|
|
Arguments:
|
|
|
|
in_file: string or list[string, string, etc.]; path(s) to the image sequence(s) or video file(s) to convert.
|
|
out_file: string; path where you want the new mp4 file to be saved out
|
|
*command_order: list[string, string, etc.]; the order you want the flags the ffmpeg command to be in
|
|
|
|
Keyword Arguments:
|
|
|
|
Any flag that the ffmpeg.exe is accepted as a keyword arguement. If the flag is meant to be used multiple times
|
|
then simply add the multiple values as a list to the keyword arguement.
|
|
|
|
Returns:
|
|
|
|
None
|
|
"""
|
|
command_order = list(command_order)
|
|
|
|
#Remove output flags if they are in command_parameters
|
|
command_parameters.pop("o", None)
|
|
command_parameters.pop("y", None)
|
|
|
|
#Put the input value(s) into the command_parameters dictionary
|
|
command_parameters["i"] = input_file
|
|
|
|
#Convert all command_parameter value to lists if they are not lists already
|
|
for each_flag, each_value in command_parameters.iteritems():
|
|
|
|
if not isinstance(each_value, list):
|
|
command_parameters[each_flag] = [each_value]
|
|
|
|
if each_flag not in command_order:
|
|
command_order.append(each_flag)
|
|
|
|
#Add the i flag into the command order if it isn't there already
|
|
if "i" not in command_order:
|
|
#Insert "i" to the front of the list
|
|
for each in command_parameters["i"]:
|
|
command_order[0:0] = ["i"]
|
|
|
|
#Build format string
|
|
command_format = []
|
|
for each in command_order:
|
|
index = 0
|
|
each = each.strip()
|
|
while "{%s[%d]}" % (each, index) in command_format:
|
|
index += 1
|
|
command_format.append("-%s {%s[%d]} " % (each, each, index))
|
|
command_format = "".join(command_format)
|
|
|
|
#Build the command
|
|
command = command_format.format(**command_parameters)
|
|
command = r'{} {} -y {}'.format(FFMPEG_BIN, command, os.path.abspath(output_file))
|
|
|
|
#Run command
|
|
return subprocess.check_call(command, shell=True)
|
|
|
|
|
|
def convertToMp4(in_file, out_file=None):
|
|
"""
|
|
Converts a given image sequence or video into a mp4 format video
|
|
|
|
Arguments:
|
|
|
|
in_file: string; path to the image sequence or video file to convert.
|
|
out_file: string; path where you want the new mp4 file to be saved out
|
|
|
|
Returns:
|
|
|
|
None
|
|
"""
|
|
flag_order = ['i', 'r', 'vf', 'pix_fmt', 'ar', 'f', 'vcodec', 'strict', 'acodec', 'vpre' , 'crf']
|
|
|
|
#If an image sequence is passed, put the rate flag upfront to lower the byte rate
|
|
if re.search('%0[0-9]+d', in_file):
|
|
flag_order[0:0] = "r"
|
|
|
|
#Resolve output file
|
|
if not out_file:
|
|
out_file = re.sub('-%0[0-9]+d', '', in_file)
|
|
out_file = setExtension(out_file)
|
|
|
|
return ffmpeg(in_file, out_file,
|
|
r=[30,30], vf="scale=960:520", pix_fmt="yuv420p", ar=44100, f="mp4", vcodec="libx264",
|
|
strict="experimental", acodec="aac", vpre=ff_profile, crf=crf_setting,
|
|
*flag_order)
|
|
|
|
|
|
def setExtension(filePath, extension='mp4'):
|
|
"""
|
|
changes the extension of the given file to .mp4
|
|
|
|
Arguments
|
|
filePath: string ; path of the file that you want to change the extension of
|
|
|
|
extension: string ; extension that you want to use, the default extension is mp4
|
|
|
|
Return
|
|
string ; file path with updated extension
|
|
"""
|
|
root = os.path.splitext(filePath)[0]
|
|
return '{root}.{extension}'.format(root=root, extension=extension)
|
|
|
|
|
|
def main(argv):
|
|
"""
|
|
Converts files to mp4g
|
|
"""
|
|
inputfile = ''
|
|
outputfile = ''
|
|
|
|
#Get arguments
|
|
try:
|
|
opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="])
|
|
except getopt.GetoptError:
|
|
print 'sequenceToMp4.py -i <inputfile> -o <outputfile>'
|
|
sys.exit(2)
|
|
|
|
for opt, arg in opts:
|
|
if opt == '-h':
|
|
print 'sequenceToMp4.py -i <inputfile> -o <outputfile>'
|
|
sys.exit()
|
|
elif opt in ("-i", "--ifile"):
|
|
inputfile = arg
|
|
elif opt in ("-o", "--ofile"):
|
|
outputfile = arg
|
|
|
|
#Check if there is a number after the - in the file name
|
|
numbers_in_input_file = re.search("(?<=-)[0-9]+", inputfile)
|
|
if numbers_in_input_file:
|
|
#Get the number as string
|
|
number_string = numbers_in_input_file.group()
|
|
#Get the string length, which also equals the amount of numbers in the number
|
|
amount_of_numbers = len(number_string)
|
|
#Make the number formatting equal the correct length
|
|
number_formatting ='%0{}d'.format(amount_of_numbers)
|
|
|
|
inputfile = inputfile.replace(number_string, number_formatting)
|
|
outputfile = setExtension(inputfile.replace("-{}".format(number_formatting), ''))
|
|
|
|
convertToMp4(inputfile, outputfile)
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv[1:]) |