Files
2025-09-29 00:52:08 +02:00

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:])