Пример #1
0
class TSConverter(PostprocessorInterface):
    def __init__(self):
        self.fs_client = FileSystemClient()
        self.logger = logging.getLogger(
            'stepic_studio.postprocessing.TSConverter')

    def process(self, path: str, filename: str) -> (str, str):
        new_filename = os.path.splitext(filename)[
            0] + MP4_EXTENSION  # change file extension from .TS to .mp4

        source_file = os.path.join(path, filename)
        target_file = os.path.join(path, new_filename)

        reencode_command = settings.FFMPEG_PATH + ' ' + \
                           settings.CAMERA_REENCODE_TEMPLATE.format(source_file, target_file)

        result, _ = self.fs_client.execute_command(reencode_command)

        if result.status is ExecutionStatus.SUCCESS:
            self.logger.info(
                'Successfully start converting TS to mp4 (FFMPEG command: %s)',
                reencode_command)
        else:
            self.logger.error('Converting failed: %s; FFMPEG command: %s',
                              result.message, reencode_command)
        return path, new_filename
Пример #2
0
def convert_mkv_to_mp4(path: str, filename: str):
    new_filename = os.path.splitext(
        filename)[0] + MP4_EXTENSION  # change file extension from .mkv to .mp4
    source_file = os.path.join(path, filename)
    target_file = os.path.join(path, new_filename)
    fs_client = FileSystemClient()

    if not os.path.isfile(source_file):
        logger.error('Converting mkv to mp4 failed; file %s doesn\'t exist',
                     source_file)
        return

    reencode_command = settings.FFMPEG_PATH + ' ' + \
                       settings.TABLET_REENCODE_TEMPLATE.format(source_file, target_file)

    result, _ = fs_client.execute_command(reencode_command)

    if result.status is ExecutionStatus.SUCCESS:
        logger.info(
            'Successfully start converting mkv to mp4 (FFMPEG command: %s)',
            reencode_command)
    else:
        logger.error('Converting mkv to mp4 failed: %s; FFMPEG command: %s',
                     result.message, reencode_command)
Пример #3
0
class ServerCameraRecorder(PostprocessableRecorder):
    def __init__(self):
        super().__init__()
        self.__fs_client = FileSystemClient()
        self.__command = FFMPEGcommand
        self.__process = None
        self.__logger = logging.getLogger(
            'stepic_studio.video_recorders.camera_recorder')
        self.last_processed_path = None
        self.last_processed_file = None
        self._load_postprocessing_pipe(settings.SERVER_POSTPROCESSING_PIPE)

    def start_recording(self, path: str,
                        filename: str) -> InternalOperationResult:
        if self.is_active():
            self.__logger.error(
                'Can\'t start FFMPEG for file %s: camera is acctually recording (process with PID %s)',
                os.path.join(path, filename), self.__process.pid)
            return InternalOperationResult(ExecutionStatus.FATAL_ERROR,
                                           'Camera is actually recording')

        local_command = self.__command + os.path.join(path, filename)
        result, self.__process = self.__fs_client.execute_command(
            local_command, stdin=subprocess.PIPE)

        if result.status is ExecutionStatus.SUCCESS:
            self.__logger.info(
                'Successfully start camera recording (FFMPEG PID: %s; FFMPEG command: %s)',
                self.__process.pid, local_command)
            self.last_processed_file = filename
            self.last_processed_path = path
        else:
            self.__logger.error(
                'Camera recording start failed: %s; FFMPEG command: %s',
                result.message, local_command)

        return result

    def stop_recording(self) -> InternalOperationResult:
        if not self.is_active():
            if self.__process is None:
                pid = None
            else:
                pid = self.__process.pid
                self.__process = None
            self.__logger.warning(
                'Camera isn\'t active: can\'t stop non existing FFMPEG process '
                '(try to stop process with PID %s)', pid)
            return InternalOperationResult(
                ExecutionStatus.SUCCESS,
                'Camera isn\'t active: can\'t stop non existing FFMPEG process'
            )

        result = self.__fs_client.send_quit_signal(self.__process)

        # try to kill ffmpeg process (sending of quit signal may have no effect)
        TaskManager().run_with_delay(FileSystemClient.kill_process,
                                     [self.__process.pid],
                                     delay=KILL_DELAY)

        if result.status is ExecutionStatus.SUCCESS:
            self.__logger.info(
                'Successfully stop camera recording (FFMPEG PID: %s)',
                self.__process.pid)
            self.__process = None
            self._apply_pipe(self.last_processed_path,
                             self.last_processed_file)
            return result
        else:
            self.__logger.error(
                'Problems while stop camera recording (FFMPEG PID: %s) : %s',
                self.__process.pid, result.message)
            return result

    def is_active(self) -> bool:
        return self.__process is not None and self.__process.poll() is None