def METHOD_NAME(self, filename, width, height, extra_enc_args=None):
    fd_r, fd_w = os.pipe()
    cfg = self._get_scene_func()
    if not cfg:
        self.failed.emit("You didn't select any scene to export.")
        return False
    fps = cfg["framerate"]
    duration = cfg["duration"]
    samples = cfg["samples"]
    cmd = [
        # fmt: off
        "ffmpeg", "-r", "%d/%d" % fps,
        "-nostats", "-nostdin",
        "-f", "rawvideo",
        "-video_size", "%dx%d" % (width, height),
        "-pixel_format", "rgba",
        "-i", "pipe:%d" % fd_r
        # fmt: on
    ]
    if extra_enc_args:
        cmd += extra_enc_args
    cmd += ["-y", filename]
    reader = subprocess.Popen(cmd, pass_fds=(fd_r,))
    os.close(fd_r)
    capture_buffer = bytearray(width * height * 4)
    # node.gl context
    ctx = ngl.Context()
    ctx.configure(
        platform=ngl.PLATFORM_AUTO,
        backend=get_backend(cfg["backend"]),
        offscreen=1,
        width=width,
        height=height,
        viewport=get_viewport(width, height, cfg["aspect_ratio"]),
        samples=samples,
        clear_color=cfg["clear_color"],
        capture_buffer=capture_buffer,
    )
    ctx.set_scene_from_string(cfg["scene"])
    if self._time is not None:
        ctx.draw(self._time)
        os.write(fd_w, capture_buffer)
        self.progressed.emit(100)
    else:
        # Draw every frame
        nb_frame = int(duration * fps[0] / fps[1])
        for i in range(nb_frame):
            if self._cancelled:
                break
            time = i * fps[1] / float(fps[0])
            ctx.draw(time)
            os.write(fd_w, capture_buffer)
            self.progressed.emit(i * 100 / nb_frame)
        self.progressed.emit(100)
    os.close(fd_w)
    reader.wait()
    return True