ssif.smap-to-ssif tool
Posted: Wed Nov 08, 2023 1:50 am
Hey.
Just in case anyone else would have also a need for this.
Below is a little Python script that generates the *.ssif files from the *.m2ts files using the *.ssif.smap files:
There's not much error handling, but it should at least fail noticeable in case of an error (albeit in some cases just by having an exception not caught) and care is taken that no existing files are modified.
HTH,
Jemima
Just in case anyone else would have also a need for this.
Below is a little Python script that generates the *.ssif files from the *.m2ts files using the *.ssif.smap files:
Code: Select all
#!/usr/bin/python3
import sys
import os
import argparse
import re
smap_file_header = "# SSIF MAP FILE v1\n"
default_maximum_read_size = 1024**2
def main():
#parse command arguments
parser = argparse.ArgumentParser(allow_abbrev=False)
parser.add_argument("smap_files", type=str, nargs="+", help="The SMAP-files for which – using the M2TS-files listed therein – the SSIF-files shall be generated in the working directory.", metavar="FILENAME")
args = parser.parse_args()
#process SMAP-file operands
for smap_filename in args.smap_files:
with open(smap_filename, mode="rt") as smap_file:
#check SMAP-file header
line = smap_file.readline( len(smap_file_header) )
if line != smap_file_header:
print(f"Error: `{smap_filename}` is not a valid `*.smap`-file.", file=sys.stderr)
sys.exit(os.EX_DATAERR)
#determine SMAP-file name
ssif_filename = re.sub(r"\.ssif\.smap$", ".ssif", smap_filename)
if ssif_filename == smap_filename:
ssif_filename += ".ssif"
#create SSIF-file
with open(ssif_filename, mode="xb") as ssif_file:
#process lines of the SMAP-file
for line in smap_file:
#remove trailing newline (that is: the Line Feed (LF) control character)
if line[-1] == "\n":
line = line[:-1]
#ignore empty and comment lines
if re.fullmatch(r"[ \t]*(?:#.*)?", line):
continue
#parse record
m = re.fullmatch(r"(?P<filename>.*) (?P<offset>[0-9a-fA-F]+) (?P<length>[0-9a-fA-F]+)", line)
m2ts_filename = m["filename"]
offset = int(m["offset"], 16) * 2048
length = int(m["length"], 16) * 2048
#append range to SSIF-file
with open(m2ts_filename, mode="rb") as m2ts_file:
m2ts_file.seek(offset)
while length > 0:
#determine read size
if length > default_maximum_read_size:
read_size = default_maximum_read_size
else:
read_size = length
#read from the M2TS-file
buffer = m2ts_file.read(read_size)
buffer_size = len(buffer)
length -= buffer_size
#check for a premature end of the file
if (buffer_size == 0) and (length != 0):
print(f"Error: Couldn not read {length} bytes from `{m2ts_filename}`.", file=sys.stderr)
sys.exit(os.EX_DATAERR)
#write buffer
ssif_file.write(buffer)
sys.exit(os.EX_OK)
if __name__ == "__main__":
main()
#This program is free software: you can redistribute it and/or modify it under
#the terms of the GNU General Public License as published by the Free Software
#Foundation, either version 3 of the License, or (at your option) any later
#version.
#This program is distributed in the hope that it will be useful, but WITHOUT ANY
#WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
#PARTICULAR PURPOSE.
#See the GNU General Public License for more details.
#You should have received a copy of the GNU General Public License along with
#this program. If not, see <https://www.gnu.org/licenses/>.
HTH,
Jemima