Example #1
0
    def open_mencoder(self):
        self.mencoder_started = True

        info = pg_video_info(self.file, intolerant=True)

        self.width = info['width']
        self.height = info['height']

        self.fps = info['fps']
        self.length = info['length']

        check('float|int', self.length)
        check('float|int', self.fps)
        self.info('length: %r' % self.length)
        self.info('fps: %r' % self.fps)
        self.approx_frames = int(math.ceil(self.length * self.fps))

        # TODO: reading non-RGB streams not supported
        self.info('Reading %dx%d @ %.3f fps '
                  ' (length %ss, approx %d frames), from %s.' %
                  (self.width, self.height, self.fps, self.length,
                   self.approx_frames, friendly_path(self.config.file)))

        self.shape = (self.height, self.width, 3)
        self.dtype = 'uint8'

        pixel_format = "rgb24"

        self.temp_dir = tempfile.mkdtemp(prefix='procgraph_fifo_dir')
        self.fifo_name = os.path.join(self.temp_dir, 'mencoder_fifo')
        os.mkfifo(self.fifo_name)
        args = [
            self.programs['mencoder'], self.file, '-ovc', 'raw', '-rawvideo',
            'w=%d:h=%d:format=%s' % (self.width, self.height, pixel_format),
            '-of', 'rawvideo', '-vf', 'format=rgb24', '-nosound', '-o',
            self.fifo_name
        ]

        self.tmp_stdout = tempfile.TemporaryFile()
        self.tmp_stderr = tempfile.TemporaryFile()

        if self.config.quiet:
            self.process = subprocess.Popen(
                args,
                stdout=self.tmp_stdout.fileno(),
                stderr=self.tmp_stderr.fileno())
        else:
            self.process = subprocess.Popen(args)

        self.delta = 1.0 / self.fps

        if not self.timestamps:
            msg = ('No timestamps found; using delta = %.2f (%.2f fps).' %
                   (self.delta, self.fps))
            self.info(msg)

        self.stream = open(self.fifo_name, 'r')
Example #2
0
    def open_mencoder(self):
        self.mencoder_started = True

        info = pg_video_info(self.file, intolerant=True)

        self.width = info['width']
        self.height = info['height']

        self.fps = info['fps']
        self.length = info['length']

        check('float|int', self.length)
        check('float|int', self.fps)
        self.info('length: %r' % self.length)
        self.info('fps: %r' % self.fps)
        self.approx_frames = int(math.ceil(self.length * self.fps))

        # TODO: reading non-RGB streams not supported
        self.info('Reading %dx%d @ %.3f fps '
                  ' (length %ss, approx %d frames), from %s.' %
                  (self.width, self.height, self.fps, self.length,
                   self.approx_frames, friendly_path(self.config.file)))

        self.shape = (self.height, self.width, 3)
        self.dtype = 'uint8'

        pixel_format = "rgb24"

        self.temp_dir = tempfile.mkdtemp(prefix='procgraph_fifo_dir')
        self.fifo_name = os.path.join(self.temp_dir, 'mencoder_fifo')
        os.mkfifo(self.fifo_name)
        args = [
            self.programs['mencoder'], self.file, '-ovc', 'raw', '-rawvideo',
            'w=%d:h=%d:format=%s' % (self.width, self.height, pixel_format),
            '-of', 'rawvideo', '-vf', 'format=rgb24', '-nosound', '-o',
            self.fifo_name
        ]

        self.tmp_stdout = tempfile.TemporaryFile()
        self.tmp_stderr = tempfile.TemporaryFile()

        if self.config.quiet:
            self.process = subprocess.Popen(args,
                                            stdout=self.tmp_stdout.fileno(),
                                            stderr=self.tmp_stderr.fileno())
        else:
            self.process = subprocess.Popen(args)

        self.delta = 1.0 / self.fps

        if not self.timestamps:
            msg = ('No timestamps found; using delta = %.2f (%.2f fps).' %
                   (self.delta, self.fps))
            self.info(msg)

        self.stream = open(self.fifo_name, 'r')
Example #3
0
 def print_stats(self):
     percentage = 100.0 * self.num_frames_read / self.approx_frames
     # this assumes constant fps
     seconds = self.num_frames_read * self.delta
     seconds_total = self.approx_frames * self.delta
     self.info('%6d/%d frames, %.1f/%.1f sec (%4.1f%%) of %s' % 
               (self.num_frames_read, self.approx_frames,
                seconds, seconds_total,
                percentage,
                friendly_path(self.file)))
Example #4
0
 def print_stats(self):
     if self.approx_frames != 0:
         percentage = 100.0 * self.num_frames_read / self.approx_frames
     else:
         percentage = 0
     # this assumes constant fps
     seconds = self.num_frames_read * self.delta
     seconds_total = self.approx_frames * self.delta
     self.info('%6d/%d frames, %.1f/%.1f sec (%4.1f%%) of %s' %
               (self.num_frames_read, self.approx_frames, seconds,
                seconds_total, percentage, friendly_path(self.file)))
Example #5
0
    def finish(self):
        if self.process is None:
            msg = 'Finish() before starting to encode.'
            self.error(msg)
            raise Exception(msg)
            return

        timestamp = self.first_frame_timestamp
        metadata = self._get_metadata()
        container = self.config.container
        vcodec = self.config.vcodec
        vcodec_params = self.config.vcodec_params

        self.info('Transcoding %s' % friendly_path(self.filename))
        pg_video_convert(self.tmp_filename,
                         self.filename,
                         container=container,
                         vcodec=vcodec,
                         vcodec_params=vcodec_params,
                         timestamp=timestamp,
                         metadata=metadata)

        #         if False:  # XXX
        if os.path.exists(self.tmp_filename):
            os.unlink(self.tmp_filename)

        if True:
            T = self.first_frame_timestamp
            os.utime(self.filename, (T, T))

        self.info('Finished %s' % friendly_path(self.filename))

        # TODO: skip mp4
        if self.config.crop:
            base, ext = os.path.splitext(self.filename)
            cropped = '%s-crop%s' % (base, ext)
            video_crop(self.filename, cropped)
            os.rename(cropped, self.filename)
Example #6
0
    def finish(self):
        if self.process is None:
            msg = 'Finish() before starting to encode.'
            self.error(msg)
            raise Exception(msg)
            return
        
        timestamp = self.first_frame_timestamp 
        metadata = self._get_metadata()
        container = self.config.container
        vcodec = self.config.vcodec
        vcodec_params = self.config.vcodec_params
        
        self.info('Transcoding %s' % friendly_path(self.filename))
        pg_video_convert(self.tmp_filename,
                         self.filename,
                         container=container,
                         vcodec=vcodec,
                         vcodec_params=vcodec_params,
                         timestamp=timestamp,
                         metadata=metadata)

#         if False:  # XXX
        if os.path.exists(self.tmp_filename):
            os.unlink(self.tmp_filename)

        if True:
            T = self.first_frame_timestamp
            os.utime(self.filename, (T, T))

        self.info('Finished %s' % friendly_path(self.filename))

        # TODO: skip mp4
        if self.config.crop:
            base, ext = os.path.splitext(self.filename)
            cropped = '%s-crop%s' % (base, ext)
            video_crop(self.filename, cropped)
            os.rename(cropped, self.filename)
Example #7
0
def get_info_for_file(v, index_filename, convert_to_mov=False):
    """ 
        v: video
        index_filename: used to create relative paths
        
    """
    if convert_to_mov:
        v_mov = os.path.splitext(v)[0] + '.mov'
        if not os.path.exists(v_mov):
            print('Creating Final Cut friendly file:\n<- %s\n-> %s' % 
                  (friendly_path(v), friendly_path(v_mov)))
            pg_video_convert(v, v_mov,
                             vcodec='prores',
                             vcodec_params={'profile': 3})
        T = os.path.getmtime(v)
        os.utime(v_mov, (T, T))
    else:
        v_mov = v
        # convert_to_mov_prores(v, v_mov, profile=2, quiet=False)
    
    #         v_mp4 = os.path.splitext(v)[0] + '.mp4'
    #         if not os.path.exists(v_mp4):
    #             recode_to_mp4(v, v_mp4)
    
       
    rel_filename = os.path.relpath(v_mov, os.path.dirname(index_filename))
    id_video = os.path.splitext(os.path.basename(v))[0]
    id_format = id_video + '_format'
    
    info = pg_video_info(v)
    
    info['filename'] = rel_filename
    info['id_video'] = id_video
    info['id_format'] = id_format
    info['filename_abs'] = v_mov
    
    return info
Example #8
0
def create_event_for_fcpx(dirname, pattern, event_filename=None, event_name=None):
    """ Creates an index Event for final cut pro X """
    if event_filename is None:
        event_filename = os.path.join(dirname, 'event.fcpxml')

    if event_name is None:
        event_name = os.path.basename(dirname) + '-event' 
                
    filenames = list(locate_files(dirname, pattern))
    videos = [get_info_for_file(f, event_filename) for f in filenames]
        
    xml_index = fcpx_get_xml_event(videos, event_name)

    with open(event_filename, 'w') as f:
        f.write(xml_index.strip())

    print('written %s' % friendly_path(event_filename))
Example #9
0
    def try_initialization(self):
        # If we don't have at least two frames, continue
        if len(self.buffer) < 2:
            return

        # Get height and width from first image
        first_image = self.buffer[0][1]

        self.shape = first_image.shape
        self.height = self.shape[0]
        self.width = self.shape[1]

        if self.height > 8192 or self.width > 8192:
            msg = 'Mencoder cannot support movies this big (%sx%s)'
            msg = msg % (self.height, self.width)
            raise Exception(msg)
        self.ndim = len(self.shape)

        # Format for mencoder's rawvideo "format" option
        if self.ndim == 2:
            format = 'y8'  # @ReservedAssignment
        else:
            if self.shape[2] == 3:
                format = 'rgb24'  # @ReservedAssignment
            elif self.shape[2] == 4:
                # Note: did not try this yet
                format = 'rgba'  # @ReservedAssignment
                msg = 'I detected that you are trying to write a transparent'
                msg += 'video. This does not work well yet (and besides,'
                msg += 'it is not supported in many applications, like '
                msg += 'Keynote). Anyway, the plan is to use mencoder '
                msg += 'to write a .AVI with codec "png". This will fail '
                msg += 'for now, but perhaps in the future it will be '
                msg += '.better'
                self.error(msg)

        # guess the fps if we are not given the config
        if self.config.fps is None:
            delta = self.buffer[-1][0] - self.buffer[0][0]

            if delta == 0:
                timestamps = [x[0] for x in self.buffer]
                self.debug('Got 0 delta: timestamps: %s' % timestamps)
                fps = 0
            else:
                fps = (len(self.buffer) - 1) / delta

            # Check for very wrong results
            if not (3 < fps < 60):
                self.error('Detected fps is %.2f; this seems strange to me,'
                           ' so I will use the safe choice fps = %.2f.' %
                           (fps, self.config.fps_safe))
                fps = self.config.fps_safe
        else:
            fps = self.config.fps

        # adapt the bitrate to the size of the image
        vbitrate0 = self.config.firstpass_bitrate
        shape0 = (640, 480)

        n1 = self.width * self.height
        n0 = shape0[0] * shape0[1]
        vbitrate = vbitrate0 * n1 / n0

        self.info('Estimated bitrate %r' % vbitrate)

        max_bitrate = 90 * 1000 * 1000
        if vbitrate > max_bitrate:

            vbitrate = max_bitrate
            self.info('Estimated bitrate too high, capping at %s' % vbitrate)

        self.filename = expand(self.config.file)
        if os.path.exists(self.filename):
            self.info('Removing previous version of %s.' %
                      friendly_path(self.filename))
            os.unlink(self.filename)

        self.tmp_filename = '%s-active.avi' % self.filename

        make_sure_dir_exists(self.filename)

        self.info('Writing %dx%d %s video stream at %.3f fps to %r.' %
                  (self.width, self.height, format, fps,
                   friendly_path(self.filename)))

        if format == 'rgba':
            ovc = ['-ovc', 'lavc', '-lavcopts', 'vcodec=png']
        else:
            ovc = [
                '-ovc', 'lavc', '-lavcopts',
                'vcodec=%s:vbitrate=%d' % ('mpeg4', vbitrate)
            ]

        out = ['-o', self.tmp_filename]
        args = [
            self.programs['mencoder'], '/dev/stdin', '-demuxer', 'rawvideo',
            '-rawvideo',
            'w=%d:h=%d:fps=%f:format=%s' %
            (self.width, self.height, fps, format)
        ] + ovc + out

        # '-v', "0", # verbosity level (1 prints stats \r)

        # self.debug('$ %s' % " ".join(args))
        # Note: mp4 encoding is currently broken in mencoder :-(
        #       so we have to use ffmpeg as a second step.
        # These would be the options to add:
        # '-of', 'lavf', '-lavfopts', 'format=mp4'

        self.tmp_stdout = tempfile.TemporaryFile()
        self.tmp_stderr = tempfile.TemporaryFile()

        quiet = self.config.quiet
        if quiet:
            # XXX /dev/null not portable
            #            self.debug('stderr: %s' % self.tmp_stderr)
            #            self.debug('stdout: %s' % self.tmp_stdout)
            # TODO: write error
            self.process = subprocess.Popen(args,
                                            preexec_fn=ignore_sigint,
                                            stdin=subprocess.PIPE,
                                            stdout=self.tmp_stdout.fileno(),
                                            stderr=self.tmp_stderr.fileno())
        else:
            self.process = subprocess.Popen(args=args, stdin=subprocess.PIPE)

        if self.config.timestamps:
            self.timestamps_filename = self.filename + '.timestamps'
            self.timestamps_file = open(self.timestamps_filename, 'w')
Example #10
0
    def try_initialization(self):
        # If we don't have at least two frames, continue
        if len(self.buffer) < 2:
            return

        # Get height and width from first image
        first_image = self.buffer[0][1]

        self.shape = first_image.shape
        self.height = self.shape[0]
        self.width = self.shape[1]

        if self.height > 8192 or self.width > 8192:
            msg = 'Mencoder cannot support movies this big (%sx%s)'
            msg = msg % (self.height, self.width)
            raise Exception(msg)
        self.ndim = len(self.shape)

        # Format for mencoder's rawvideo "format" option
        if self.ndim == 2:
            format = 'y8'  # @ReservedAssignment
        else:
            if self.shape[2] == 3:
                format = 'rgb24'  # @ReservedAssignment
            elif self.shape[2] == 4:
                # Note: did not try this yet
                format = 'rgba'  # @ReservedAssignment
                msg = 'I detected that you are trying to write a transparent'
                msg += 'video. This does not work well yet (and besides,'
                msg += 'it is not supported in many applications, like '
                msg += 'Keynote). Anyway, the plan is to use mencoder '
                msg += 'to write a .AVI with codec "png". This will fail '
                msg += 'for now, but perhaps in the future it will be '
                msg += '.better'
                self.error(msg)

        # guess the fps if we are not given the config
        if self.config.fps is None:
            delta = self.buffer[-1][0] - self.buffer[0][0]

            if delta == 0:
                timestamps = [x[0] for x in self.buffer]
                self.debug('Got 0 delta: timestamps: %s' % timestamps)
                fps = 0
            else:
                fps = (len(self.buffer) - 1) / delta

            # Check for very wrong results
            if not (3 < fps < 60):
                self.error('Detected fps is %.2f; this seems strange to me,'
                           ' so I will use the safe choice fps = %.2f.' % 
                           (fps, self.config.fps_safe))
                fps = self.config.fps_safe
        else:
            fps = self.config.fps

        # adapt the bitrate to the size of the image
        vbitrate0 = self.config.firstpass_bitrate
        shape0 = (640, 480)

        n1 = self.width * self.height
        n0 = shape0[0] * shape0[1]
        vbitrate = vbitrate0 * n1 / n0
        
        self.info('Estimated bitrate %r' % vbitrate)
        
        max_bitrate = 90*1000*1000
        if vbitrate > max_bitrate:
            
            vbitrate = max_bitrate
            self.info('Estimated bitrate too high, capping at %s' % vbitrate)
            

        self.filename = expand(self.config.file)
        if os.path.exists(self.filename):
            self.info('Removing previous version of %s.' % 
                      friendly_path(self.filename))
            os.unlink(self.filename)

        

        self.tmp_filename = '%s-active.avi' % self.filename
        
        make_sure_dir_exists(self.filename)

        self.info('Writing %dx%d %s video stream at %.3f fps to %r.' % 
                  (self.width, self.height, format, fps,
                   friendly_path(self.filename)))

        if format == 'rgba':
            ovc = ['-ovc', 'lavc', '-lavcopts', 'vcodec=png']
        else:
            ovc = ['-ovc', 'lavc', '-lavcopts',
                  'vcodec=%s:vbitrate=%d' % ('mpeg4', vbitrate)]

        out = ['-o', self.tmp_filename]
        args = [
                self.programs['mencoder'],
                '/dev/stdin',
                '-demuxer', 'rawvideo',
                '-rawvideo', 'w=%d:h=%d:fps=%f:format=%s' % 
                (self.width, self.height, fps, format)
        ] + ovc + out

                # '-v', "0", # verbosity level (1 prints stats \r)

        # self.debug('$ %s' % " ".join(args))
        # Note: mp4 encoding is currently broken in mencoder :-(
        #       so we have to use ffmpeg as a second step.
        # These would be the options to add:
        # '-of', 'lavf', '-lavfopts', 'format=mp4'

        self.tmp_stdout = tempfile.TemporaryFile()
        self.tmp_stderr = tempfile.TemporaryFile()

        quiet = self.config.quiet
        if quiet:
            # XXX /dev/null not portable
#            self.debug('stderr: %s' % self.tmp_stderr)
#            self.debug('stdout: %s' % self.tmp_stdout)
            # TODO: write error
            self.process = subprocess.Popen(args,
                                            preexec_fn=ignore_sigint,
                stdin=subprocess.PIPE, stdout=self.tmp_stdout.fileno(),
                                       stderr=self.tmp_stderr.fileno())
        else:
            self.process = subprocess.Popen(args=args,
                                            stdin=subprocess.PIPE)

        if self.config.timestamps:
            self.timestamps_filename = self.filename + '.timestamps'
            self.timestamps_file = open(self.timestamps_filename, 'w')