Ejemplo n.º 1
0
def array2avi(A, fname, fps=25, codec='rawvideo', codec_params='', width=800,
              makelog=False):

    if A.ndim == 3:
        fmt = 'gray'
    elif A.ndim == 4:
        if A.shape[3] == 3:
            fmt = 'rgb8'
        elif A.shape[3] == 4:
            fmt = 'argb'
        else:
            raise Exception('Invalid input 4th dimension - should'
                            ' be rgb or argb')
    else:
        raise Exception('Invalid number of input dimensions (should be'
                        ' [frame,row,col] or [frame,row,col,(a)rgb]')

    A = rescale_8bit(A)

    nframes, h, w = A.shape[:3]
    aspect = float(h) / w
    width = 2 * int(width / 2.)
    height = 2 * int((width / 2.) * aspect)

    cmd = ['ffmpeg', '-y',

           '-f', 'rawvideo',
           '-pix_fmt', fmt,
           '-r', '%d' % fps,
           '-s', '%ix%i' % (w, h),
           '-i', 'pipe:0',

           '-vcodec', codec,
           # '-b:v', '%ik' %kbitrate,
           '-s', '%ix%i' % (width, height),
           fname]

    if makelog:
        logfile = open(fname + '.log', 'w')
    else:
        logfile = open(devnull, 'w')

    proc = sp.Popen(cmd, shell=False, stdin=sp.PIPE, stdout=logfile,
                    stderr=logfile)

    wbh = Waitbar(title='Writing %s' % fname, showETA=True)
    for ii, frame in enumerate(A):
        proc.stdin.write(frame.tostring())
        wbh.update((ii + 1.) / nframes)

    proc.stdin.close()
    proc.terminate()
    logfile.close()
Ejemplo n.º 2
0
    def save(self, fname, codec='rawvideo', fps=None, width=800,
             makelog=False):

        if not np.all(self.hasplayed):
            raise Exception(
                "All frames need to have been displayed at "
                "least once before writing")
        if fps is None:
            fps = self.framerate

        # make sure we start with the first frame
        self.rewind()

        # need to disconnect the first draw callback, since we'll be
        # doing draws. otherwise, we'll end up starting the animation.
        if self.animator._first_draw_id is not None:
            self.animator._fig.canvas.mpl_disconnect(
                self.animator._first_draw_id)
            reconnect_first_draw = True
        else:
            reconnect_first_draw = False

        # input pixel dimensions
        w, h = self.fig.canvas.get_width_height()
        nframes = self.data.shape[0]

        # make sure that output width and height are divisible by 2
        # (some codecs don't like odd dimensions)
        figsize = self.fig.get_size_inches()
        aspect = figsize[1] / figsize[0]
        width = 2 * int(width / 2.)
        height = 2 * int((width / 2.) * aspect)

        # spawn an ffmpeg process - we're going to pipe the frames
        # directly to ffmpeg as raw bytes

        cmd = [
                # global options
               'ffmpeg', '-y',
               '-loglevel', 'verbose',

               # input options
               '-f', 'rawvideo',
               '-pix_fmt', 'bgr24',
               '-r', '%d' % fps,
               '-s', '%ix%i' % (w, h),
               '-i', 'pipe:0',

               # output options
               '-vcodec', codec,
               '-an',
               '-pix_fmt', 'rgb24', # NB: need to reverse channel order!
               '-s', '%ix%i' % (width, height),
               fname
               ]

        # print ' '.join(cmd)

        if makelog:
            logfile = open(fname + '.log', 'w')
        else:
            logfile = open(devnull, 'w')

        proc = sp.Popen(cmd, shell=False, stdin=sp.PIPE,
                        stdout=logfile, stderr=logfile)

        # Render each frame, save it to the stdin of the spawned process
        wbh = Waitbar(title='Writing %s' % fname, showETA=True)
        for ii, data in enumerate(self.animator.new_saved_frame_seq()):
            self.animator._draw_next_frame(data, blit=True)
            # self.animator._fig.savefig(proc.stdin,format='png')
            proc.stdin.write(self.animator._fig.canvas.tostring_rgb())
            wbh.update((ii + 1.) / nframes)

        logfile.close()

        if reconnect_first_draw:
            drawid = self.animator._fig.canvas.mpl_connect(
                'draw_event', self.animator._start)
            self.animator._first_draw_id = drawid