https://sppas.org/

SPPAS 4.16

Module sppas.src.videodata

Class sppasBufferVideoWriter

Description

Write a video and/or a set of images into files.

There are 2 main solutions to write the result (video+images):

  1. video
  1. folder with images

Constructor

Create a new instance.

def __init__(self):
    """Create a new instance.

    """
    self._video_writer = None
    self._video = False
    self._folder = False
    self._fps = 25.0
    self._video_ext = annots.video_extension
    self._image_ext = annots.image_extension

Public functions

get_video_extension

Return the extension for video files.

def get_video_extension(self):
    """Return the extension for video files."""
    return self._video_ext
set_video_extension

Set the extension of video files.

Parameters
  • ext
def set_video_extension(self, ext):
    """Set the extension of video files."""
    ext = str(ext)
    if ext.startswith('.') is False:
        ext = '.' + ext
    if ext not in video_extensions:
        raise sppasExtensionWriteError(ext)
    self._video_ext = ext
get_image_extension

Return the extension for image files.

def get_image_extension(self):
    """Return the extension for image files."""
    return self._image_ext
set_image_extension

Set the extension of image files.

Parameters
  • ext
def set_image_extension(self, ext):
    """Set the extension of image files."""
    ext = str(ext)
    if ext.startswith('.') is False:
        ext = '.' + ext
    if ext not in image_extensions:
        raise sppasExtensionWriteError(ext)
    self._image_ext = ext
get_fps

Return the defined fps value to write video files (float).

def get_fps(self):
    """Return the defined fps value to write video files (float)."""
    return self._fps
set_fps

Fix the framerate of the output video.

Parameters

  • value: (float) Number of frames per seconds

Raises

NegativeValueError, IntervalRangeError

def set_fps(self, value):
    """Fix the framerate of the output video.

        :param value: (float) Number of frames per seconds
        :raise: NegativeValueError, IntervalRangeError

        """
    w = sppasVideoWriter()
    w.set_fps(value)
    self._fps = value
get_video_output

Return True if images will be saved into a video, as it.

def get_video_output(self):
    """Return True if images will be saved into a video, as it."""
    return self._video
get_folder_output

Return True if results will be saved in a folder of image files.

def get_folder_output(self):
    """Return True if results will be saved in a folder of image files."""
    return self._folder
set_video_output

Set true to enable the output of the video.

Parameters
  • value
def set_video_output(self, value):
    """Set true to enable the output of the video."""
    self._video = bool(value)
set_folder_output

Set true to enable the output of the folder of images.

Parameters
  • value
def set_folder_output(self, value):
    """Set true to enable the output of the folder of images."""
    self._folder = bool(value)
is_opened

Return True of the video writer opened a video stream.

def is_opened(self):
    """Return True of the video writer opened a video stream."""
    return self._video_writer is not None
close

Close the sppasVideoWriter().

It has to be invoked when writing buffers is finished in order to

release the video writer.

def close(self):
    """Close the sppasVideoWriter().

        It has to be invoked when writing buffers is finished in order to
        release the video writer.

        """
    if self._video_writer is not None:
        self._video_writer.close()
        self._video_writer = None
write

Save the result into file(s) depending on the options.

The out_name is a base name, its extension is ignored and replaced by

the one(s) defined in this class.

Parameters

  • video_buffer: (sppasCoordsVideoBuffer) The images and results to write
  • out_name: (str) The output name for the folder and/or the video
  • opt_pattern: (str) Un-used

Returns

  • list of newly created file names
def write(self, video_buffer, out_name, opt_pattern=''):
    """Save the result into file(s) depending on the options.

        The out_name is a base name, its extension is ignored and replaced by
        the one(s) defined in this class.

        :param video_buffer: (sppasCoordsVideoBuffer) The images and results to write
        :param out_name: (str) The output name for the folder and/or the video
        :param opt_pattern: (str) Un-used
        :return: list of newly created file names

        """
    new_files = list()
    fn, _ = os.path.splitext(out_name)
    out_name = fn
    if self._video is True:
        new_video_files = self.write_video(video_buffer, out_name, opt_pattern)
        if len(new_video_files) > 1:
            logging.info('{:d} video files created'.format(len(new_video_files)))
        new_files.extend(new_video_files)
    if self._folder is True:
        new_image_files = self.write_folder(video_buffer, out_name, opt_pattern)
        if len(new_image_files) > 1:
            logging.info('{:d} image files created'.format(len(new_image_files)))
    return new_files
write_video

Save the result in video format.

Parameters

  • video_buffer: (sppasImage) The image to write
  • out_name: (str) The filename of the output video file
  • pattern: (str) Pattern to add to video filename

Returns

  • list of newly created video file names
def write_video(self, video_buffer, out_name, pattern):
    """Save the result in video format.

        :param video_buffer: (sppasImage) The image to write
        :param out_name: (str) The filename of the output video file
        :param pattern: (str) Pattern to add to video filename
        :return: list of newly created video file names

        """
    new_files = list()
    iter_images = video_buffer.__iter__()
    for i in range(video_buffer.__len__()):
        image = next(iter_images)
        if self._video_writer is None:
            self._video_writer, fn = self.create_video_writer(out_name, image, pattern)
            new_files.append(fn)
        self._video_writer.write(image)
    return new_files
write_folder

Save the result in image format into a folder.

Parameters

  • video_buffer: (sppasImage) The image to write
  • out_name: (str) The folder name of the output image files
  • pattern: (str) Pattern to add to folder name(s)
def write_folder(self, video_buffer, out_name, pattern=''):
    """Save the result in image format into a folder.

        :param video_buffer: (sppasImage) The image to write
        :param out_name: (str) The folder name of the output image files
        :param pattern: (str) Pattern to add to folder name(s)

        """
    new_files = list()
    folder_name = '{:s}{:s}'.format(out_name, pattern)
    if os.path.exists(folder_name) is False:
        os.mkdir(folder_name)
    begin_idx, end_idx = video_buffer.get_buffer_range()
    folder = os.path.join(folder_name, '{:06d}'.format(begin_idx))
    if os.path.exists(folder) is True:
        shutil.rmtree(folder)
    os.mkdir(folder)
    iter_images = video_buffer.__iter__()
    for i in range(video_buffer.__len__()):
        image = next(iter_images)
        img_name = self._image_name(begin_idx + i) + self._image_ext
        image.write(os.path.join(folder, img_name))
        new_files.append(os.path.join(folder, img_name))
    return new_files
create_video_writer

Create a sppasVideoWriter().

Raises

PermissionError

Parameters
  • out_name
  • image
  • pattern
def create_video_writer(self, out_name, image, pattern=''):
    """Create a sppasVideoWriter().

        :raise: PermissionError

        """
    w, h = image.size()
    filename = '{:s}{:s}'.format(out_name, pattern) + self._video_ext
    logging.debug('Create a video writer {:s}. Size {:d}, {:d}'.format(filename, w, h))
    if os.path.exists(filename) is True:
        logging.warning('A file with name {:s} is already existing.'.format(filename))
        trash_filename = sppasTrash().put_file_into(filename)
        logging.info('The file was moved into the Trash of SPPAS with name: {:s}'.format(trash_filename))
    try:
        writer = sppasVideoWriter()
        writer.set_size(w, h)
        writer.set_fps(self._fps)
        writer.set_aspect('extend')
        writer.open(filename)
        logging.debug(' ... Video writer opened successfully for {}'.format(filename))
    except Exception as e:
        logging.error('OpenCV failed to open the VideoWriter for file {}: {}'.format(filename, str(e)))
        return None
    return (writer, filename)

Private functions

_image_name

Return an image name from its index.

Parameters
  • idx
@staticmethod
def _image_name(idx):
    """Return an image name from its index."""
    return 'img_{:06d}'.format(idx)