Compare commits

..

3 Commits

Author SHA1 Message Date
Frédéric Tronel
556d88d73a mkvinfo command is now mandatory. 2023-12-18 16:11:46 +01:00
Frédéric Tronel
af52c80a8e Positioning inside files using lseek is made uniformly. 2023-12-18 16:11:05 +01:00
Frédéric Tronel
04d23ca1b2 The langage used by commands cannot be set using locales module. 2023-12-18 16:09:48 +01:00

View File

@@ -1,14 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse import argparse
import locale
import re import re
from sys import exit from sys import exit
from datetime import datetime,timedelta,time from datetime import datetime,timedelta,time
import coloredlogs, logging import coloredlogs, logging
from functools import cmp_to_key from functools import cmp_to_key
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
from os import read, write, lseek, pipe, set_inheritable, memfd_create, SEEK_SET, close, unlink from os import read, write, lseek, pipe, set_inheritable, memfd_create, SEEK_SET, close, unlink, fstat, ftruncate
import os.path import os.path
from io import BytesIO, TextIOWrapper from io import BytesIO, TextIOWrapper
import json import json
@@ -29,7 +28,7 @@ def checkRequiredTools():
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
allOptionalTools = True allOptionalTools = True
paths = {} paths = {}
required = ['ffmpeg', 'ffprobe', 'mkvmerge'] required = ['ffmpeg', 'ffprobe', 'mkvmerge', 'mkvinfo']
optional = ['mkvextract', 'vobsubocr','tesseract'] optional = ['mkvextract', 'vobsubocr','tesseract']
for tool in required: for tool in required:
path = which(tool) path = which(tool)
@@ -191,7 +190,7 @@ def getFormat(ffprobe, inputFile):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
infd = inputFile.fileno() infd = inputFile.fileno()
inputFile.seek(0,0) lseek(infd, 0, SEEK_SET)
set_inheritable(infd, True) set_inheritable(infd, True)
with Popen([ffprobe, '-loglevel', 'quiet', '-show_format', '-of', 'json', '-i', '/proc/self/fd/%d' % infd], stdout=PIPE, close_fds=False) as ffprobe: with Popen([ffprobe, '-loglevel', 'quiet', '-show_format', '-of', 'json', '-i', '/proc/self/fd/%d' % infd], stdout=PIPE, close_fds=False) as ffprobe:
out, _ = ffprobe.communicate() out, _ = ffprobe.communicate()
@@ -207,7 +206,7 @@ def getStreams(ffprobe, inputFile):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
infd = inputFile.fileno() infd = inputFile.fileno()
inputFile.seek(0,0) lseek(infd, 0, SEEK_SET)
set_inheritable(infd, True) set_inheritable(infd, True)
with Popen([ffprobe, '-loglevel', 'quiet', '-show_streams', '-of', 'json', '-i', '/proc/self/fd/%d' % infd], stdout=PIPE, close_fds=False) as ffprobe: with Popen([ffprobe, '-loglevel', 'quiet', '-show_streams', '-of', 'json', '-i', '/proc/self/fd/%d' % infd], stdout=PIPE, close_fds=False) as ffprobe:
out, _ = ffprobe.communicate() out, _ = ffprobe.communicate()
@@ -484,10 +483,10 @@ def extractMKVPart(mkvmerge, inputFile, outputFile, begin, end):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
logger.info('Extract video between I-frames at %s and %s' % (begin,end)) logger.info('Extract video between I-frames at %s and %s' % (begin,end))
inputFile.seek(0,0)
outputFile.seek(0,0)
infd = inputFile.fileno() infd = inputFile.fileno()
outfd = outputFile.fileno() outfd = outputFile.fileno()
lseek(infd, 0, SEEK_SET)
lseek(outfd, 0, SEEK_SET)
set_inheritable(infd, True) set_inheritable(infd, True)
set_inheritable(outfd, True) set_inheritable(outfd, True)
warnings = [] warnings = []
@@ -519,8 +518,9 @@ def extractMKVPart(mkvmerge, inputFile, outputFile, begin, end):
def extractPictures(ffmpeg, inputFile, begin, nbFrames, width=640, height=480): def extractPictures(ffmpeg, inputFile, begin, nbFrames, width=640, height=480):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
inputFile.seek(0,0)
infd = inputFile.fileno() infd = inputFile.fileno()
lseek(infd, 0, SEEK_SET)
outfd = memfd_create('pictures', flags=0) outfd = memfd_create('pictures', flags=0)
set_inheritable(outfd, True) set_inheritable(outfd, True)
# PPM header # PPM header
@@ -550,9 +550,9 @@ def extractPictures(ffmpeg, inputFile, begin, nbFrames, width=640, height=480):
def extractSound(ffmpeg, inputFile, begin, outputFileName, packetDuration, subChannel=0, nbPackets=0, sampleRate=48000, nbChannels=2): def extractSound(ffmpeg, inputFile, begin, outputFileName, packetDuration, subChannel=0, nbPackets=0, sampleRate=48000, nbChannels=2):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
inputFile.seek(0,0)
outfd = memfd_create(outputFileName, flags=0) outfd = memfd_create(outputFileName, flags=0)
infd = inputFile.fileno() infd = inputFile.fileno()
lseek(infd, 0, SEEK_SET)
set_inheritable(infd, True) set_inheritable(infd, True)
set_inheritable(outfd, True) set_inheritable(outfd, True)
sound = bytes() sound = bytes()
@@ -848,8 +848,6 @@ def extractSubTitleTrack(mkvmerge, inputFileName, index, lang):
def main(): def main():
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
coloredlogs.install() coloredlogs.install()
# Fix the language used by tools to print their messages to make the script independant of environment.
locale.setlocale(locale.LC_ALL, 'C')
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input", dest='inputFile', type=str, required=True, help="Input file to process (can be .ts, .mp4 or .mkv).") parser.add_argument("-i", "--input", dest='inputFile', type=str, required=True, help="Input file to process (can be .ts, .mp4 or .mkv).")
parser.add_argument("-o", "--output", dest='outputFile', type=str, required=True, help="Output MKV file to produce.") parser.add_argument("-o", "--output", dest='outputFile', type=str, required=True, help="Output MKV file to produce.")