示例#1
0
def get_offset(beatmap, start_index, end_index, replay_info, endtime, fps=60):
    replay_event = replay_info.play_data
    if endtime == -1:
        endtime = 5000
    else:
        endtime = 0
    start_time = replay_event[start_index][3]
    diffcalculator = DiffCalculator(beatmap.diff)
    timepreempt = diffcalculator.ar()

    # same as skip() code
    hitobjectindex = search_time(start_time, beatmap.hitobjects)
    to_time = min(beatmap.hitobjects[hitobjectindex]["time"] - timepreempt,
                  start_time)
    osr_index = search_osrindex(to_time, replay_event)
    old = osr_index
    # simulate video draw code
    curtime = replay_event[osr_index][Replays.TIMES]
    interval = 1000 / fps
    while osr_index < start_index:
        curtime += interval
        tt, _ = nearer(curtime, replay_info, osr_index)
        osr_index += tt
    osr_index = max(0, osr_index - 1)

    offset = replay_event[osr_index][Replays.TIMES]
    endtime += replay_event[end_index][Replays.TIMES] + 100
    logger.debug("\n\nOFFSET: %s", offset)
    return offset, endtime
示例#2
0
def search_osrindex(to_time, replays):
    # pass_counter = 0
    cur_index = 0
    while cur_index <= len(replays) - 1 and replays[cur_index +
                                                    1][3] < to_time:
        cur_index += 1

    logger.debug("cur_index %d", cur_index)
    return cur_index
示例#3
0
def audioprc(my_info, beatmap, offset, endtime, mods, settings):
    nc = Mod.Nightcore in mods
    addmisssound = not (Mod.Relax in mods or Mod.Autopilot in mods)

    skin_path = settings.skin_path
    default_skinpath = settings.default_path
    beatmap_path = settings.beatmap
    audio_name = beatmap.general["AudioFilename"]

    ccc = time.time()

    try:
        audio_name = get_actual_audio_filename(audio_name, beatmap_path)
        song = Audio2p(*read(os.path.join(beatmap_path, audio_name),
                             settings,
                             volume=settings.settings["Song volume"] / 100,
                             speed=settings.timeframe / 1000,
                             changepitch=nc))
    except FileNotFoundError:
        raise AudioNotFound()
    song.rate /= settings.timeframe / 1000
    song.audio = apply_offset(song, settings.settings["Song delay"])

    filenames = getfilenames(beatmap,
                             settings.settings["Ignore beatmap hitsounds"])
    setuphitsound(filenames, beatmap_path, skin_path, default_skinpath,
                  settings)

    if not addmisssound:
        Hitsound.miss = Audio2p(1, np.zeros((0, 2), dtype=np.float32))

    hitsoundm = HitsoundManager(beatmap)

    logger.debug("Done loading: %f", time.time() - ccc)

    for x in range(len(my_info)):

        hitsoundm.updatetimingpoint(my_info, x, song)
        hitsoundm.addhitsound(my_info, x, song)
        hitsoundm.addslidersound(my_info, x, song)
        hitsoundm.addspinnerhitsound(my_info, x, song)
        hitsoundm.addcombobreak(my_info, x, song)
        hitsoundm.addsectionsound(my_info, x, song)

    out = getoffset(offset, endtime, song)

    write(settings.temp + 'audio.mp3',
          round(song.rate * settings.timeframe / 1000), out)
示例#4
0
    def __init__(self, filename, settings, scale=1, delimiter="", rotate=0):
        self.settings = settings
        self.filename = filename
        self.scale = scale
        self.delimiter = delimiter
        self.frames = []
        self.rotate = rotate
        self.n_frame = 0
        self.unanimate = False
        self.imgfrom = None

        self.load(defaultpath=False)
        if self.unanimate and self.imgfrom == ImageFrom.BLANK:
            logger.debug("Loading default path YImagesss: %s", filename)
            self.frames = []
            self.load(defaultpath=True)
示例#5
0
    def joinvideo(self):
        if self.data["Process"] >= 1:
            for i in range(self.data["Process"]):
                logger.debug(self.drawers[i].is_alive())
                logger.debug(self.writers[i].is_alive())
                self.drawers[i].join()
                logger.debug(f"Joined drawers {i}")

                self.writers[i].join(
                )  # temporary fixm might cause some infinite loop
                logger.debug(f"Joined writers {i}")

                conn1, conn2 = self.pipes[i]
                conn1.close()
                conn2.close()
                logger.debug(f"Closed conn {i}")

        self.drawers, self.writers, self.pipes = None, None, None
示例#6
0
def checkmain(beatmap, replay_info, settings, tests=False):
    osr_index = 0
    replay_event = replay_info.play_data

    diffmod(replay_info, beatmap.diff)

    hitobjectchecker = HitObjectChecker(beatmap, settings, replay_info, tests)

    break_index = 0
    breakperiod = beatmap.breakperiods[break_index]
    in_break = int(replay_event[osr_index][Replays.TIMES]) in range(
        breakperiod["Start"], breakperiod["End"])

    logger.debug("Start check")
    while osr_index < len(replay_event) - 3:
        k1, k2, m1, m2 = keys(replay_event[osr_index][Replays.KEYS_PRESSED])
        if not in_break:
            f_k1, f_k2, f_m1, f_m2 = keys(
                replay_event[osr_index + 1][Replays.KEYS_PRESSED])
        else:
            f_k1, f_k2, f_m1, f_m2 = False, False, False, False

        new_k1, new_k2 = f_k1 and not k1, f_k2 and not k2
        new_m1, new_m2 = f_m1 and not m1, f_m2 and not m2
        new_click = [new_k1, new_k2, new_m1, new_m2]

        hitobjectchecker.checkcursor(replay_event, new_click, osr_index + 1,
                                     in_break, breakperiod)

        osr_index += 1

        breakperiod = beatmap.breakperiods[break_index]
        next_break = replay_event[osr_index][
            Replays.TIMES] > breakperiod["End"]
        if next_break:
            break_index = min(break_index + 1, len(beatmap.breakperiods) - 1)
            breakperiod = beatmap.breakperiods[break_index]
        in_break = int(replay_event[osr_index][Replays.TIMES]) in range(
            breakperiod["Start"], breakperiod["End"])

    logger.debug("check done")
    logger.log(1, "RETURN %r", hitobjectchecker.info[-1])
    return hitobjectchecker.info
示例#7
0
def search_updateindex(idd, resultinfo, component, to_time):
    if idd == -1:
        return len(resultinfo) - 1
    cur_index = 0
    while cur_index <= len(resultinfo) - 1 and resultinfo[cur_index].id != idd:
        cur_index += 1
    # cur_index = max(0, cur_index - 1)
    if cur_index == 0:
        return 0
    info = resultinfo[max(0, cur_index - 1)]
    component.scorecounter.set_score(resultinfo[cur_index].time, info.score,
                                     info.showscore)
    component.accuracy.set_acc(info.accuracy)
    component.combocounter.set_combo(info.combo)
    component.scorebar.set_hp(info.hp)
    component.scoreboard.setsetscore(info.score, info.combo)

    component.key1.set_freeze(resultinfo[cur_index].time, info.clicks[0])
    component.key2.set_freeze(resultinfo[cur_index].time, info.clicks[1])
    component.mouse1.set_freeze(resultinfo[cur_index].time, info.clicks[2])
    component.mouse2.set_freeze(resultinfo[cur_index].time, info.clicks[3])
    urindex = cur_index
    diff = 0
    while diff < 5000:
        urindex -= 1
        if urindex <= -1:
            break
        diff = info.time - resultinfo[urindex].time
    while urindex < cur_index:
        if type(
                resultinfo[urindex].more
        ).__name__ == "Circle" and resultinfo[urindex].hitresult is not None:
            if resultinfo[urindex].hitresult > 0:
                component.urbar.add_bar(resultinfo[urindex].more.deltat,
                                        resultinfo[urindex].hitresult)
                component.urbar.movearrow()
        urindex += 1

    logger.debug("done")
    return cur_index
示例#8
0
	def __init__(self, scale, settings):
		self.score_images = []
		scoreprefix = "-"
		score_x = scoreprefix + "x"
		score_percent = scoreprefix + "percent"
		score_dot = scoreprefix + "dot"
		for x in range(10):
			self.score_images.append(YImage(scoreprefix + str(x), settings, scale, prefix="ScorePrefix"))

		self.score_percent = YImage(score_percent, settings, scale, prefix="ScorePrefix")
		logger.debug(scale)
		# fierymod_v8_realest_ver[1] has very big score_percent.png but it doesn't show up in real osu
		# after some testing, if the image is >= 570px then it won't show up
		if self.score_percent.orig_cols >= int(570 * scale):
			self.score_percent.img = Image.new("RGBA", (self.score_percent.orig_cols, self.score_percent.orig_rows))

		self.score_dot = YImage(score_dot, settings, scale, prefix="ScorePrefix")

		self.score_x = YImage(score_x, settings, scale, prefix="ScorePrefix")

		self.combo_images = []
		for x in range(10):
			self.combo_images.append(YImage(scoreprefix + str(x), settings, scale, prefix="ComboPrefix"))
		self.combo_x = YImage(score_x, settings, scale, prefix="ComboPrefix")
示例#9
0
def write(shared, conn, filename, settings, iii):
	asdfasdf = time.time()

	logger.debug("{}\n".format(filename))
	logger.debug("Start write")

	if settings.codec.lower() in videoextensions:
		raise FourccIsNotExtension()

	buf = np.zeros((settings.height * settings.width * 3), dtype=np.uint8)
	writer = getwriter(filename, settings, buf)

	np_img = np.frombuffer(shared, dtype=np.uint8)
	np_img = np_img.reshape((settings.height, settings.width, 4))
	buf = buf.reshape((settings.height, settings.width, 3))

	timer = 0

	timer2 = 0
	timer3 = 0
	a = 0
	framecount = 1
	logger.debug("start writing: %f", time.time() - asdfasdf)

	startwringtime = time.time()

	if iii:
		filewriter = open(os.path.join(settings.temp, "speed.txt"), "w")

	while a != 10:

		asdf = time.time()
		a = conn.recv()
		timer2 += time.time() - asdf

		if a == 1:
			asdf = time.time()
			cv2.cvtColor(np_img, cv2.COLOR_BGRA2RGB, dst=buf)
			conn.send(0)
			timer3 += time.time() - asdf

			asdf = time.time()

			if not settings.settings["Use FFmpeg video writer"]:
				writer.write(buf)
			else:
				writer.write()

			timer += time.time() - asdf

			framecount += 1
			if iii and framecount % 200:
				deltatime = max(1, timer)
				filewriter.seek(0)
				# logger.log(1, "Writing progress {}, {}, {}, {}".format(framecount, deltatime, filename, startwringtime))
				filewriter.write("{}\n{}\n{}\n{}".format(framecount, deltatime, filename, startwringtime))
				filewriter.truncate()

	if iii:
		filewriter.write("done")
		filewriter.close()

	logger.debug("Release write")
	writer.release()

	logger.debug("End write")

	logger.debug("\nWriting done {}".format(filename))
	logger.debug("Writing time: {}".format(timer))
	logger.debug("Total time: {}".format(time.time() - asdfasdf))
	logger.debug("Waiting time: {}".format(timer2))
	logger.debug("Changing value time: {}".format(timer3))
示例#10
0
	def __init__(self, settings, diff, mod_combination, ur=None, bg=None, loadranking=True):
		skin = settings.skin_ini
		self.loadranking = loadranking
		check = DiffCalculator(diff)
		hd = Mod.Hidden in mod_combination
		fl = Mod.Flashlight in mod_combination
		if settings.settings["Automatic cursor size"]:
			circlescale = 4/diff["CircleSize"]
			settings.settings["Cursor size"] *= circlescale
		if ur is None:
			ur = [0, 0, 0]
		if bg is None:
			bg = [0, 0, ""]

		logger.debug('start preparing cursor')
		self.cursor, default = prepare_cursor(settings.scale * settings.settings["Cursor size"], settings)
		logger.debug('start preparing cursormiddle')
		self.cursormiddle, self.continuous = prepare_cursormiddle(settings.scale * settings.settings["Cursor size"], settings, default)
		logger.debug('start preparing cursortrail')
		self.cursor_trail = prepare_cursortrail(settings.scale * settings.settings["Cursor size"], self.continuous, settings)

		logger.debug('start preparing scoreentry')
		self.scoreentry = prepare_scoreentry(settings.scale, skin.colours["InputOverlayText"], settings)
		self.inputoverlayBG = prepare_inputoverlaybg(settings.scale, settings)
		self.key = prepare_inputoverlay(settings.scale, [255, 220, 20], 2, settings)
		self.mouse = prepare_inputoverlay(settings.scale, [220, 0, 220], 1, settings)

		logger.debug('start preparing scorenumber')
		self.scorenumbers = ScoreNumbers(settings.scale, settings)
		self.hitcirclenumber = prepare_hitcirclenumber(diff, settings.playfieldscale, settings)

		logger.debug('start preparing accuracy')
		self.accuracy = prepare_accuracy(self.scorenumbers)
		self.combocounter = prepare_combo(self.scorenumbers, settings)
		self.hitresult = prepare_hitresults(settings.scale, diff, settings)
		self.spinbonus = prepare_spinbonus(self.scorenumbers)
		self.scorecounter = prepare_scorecounter(self.scorenumbers)

		self.playinggrade = prepare_playinggrade(settings.scale * 0.75, settings)

		self.urbar = prepare_bar(settings.scale * settings.settings["Score meter size"], check.scorewindow)

		self.fpmanager = prepare_fpmanager(settings.playfieldscale, settings)

		logger.debug('start preparing circle')
		self.circle = prepare_circle(diff, settings.playfieldscale, settings, hd)
		self.slider = prepare_slider(diff, settings.playfieldscale, settings)
		self.spinner = prepare_spinner(settings.playfieldscale, settings)

		logger.debug('start preparing background')
		self.bg = prepare_background(os.path.join(settings.beatmap, bg[2]), settings)

		logger.debug('start preparing sections')
		self.sections = prepare_sections(settings.scale, settings)
		self.scorebarbg = prepare_scorebarbg(settings.scale, self.bg, settings)
		self.scorebar = prepare_scorebar(settings.scale, settings)
		self.arrowwarning = prepare_arrowwarning(settings.scale, settings)

		logger.debug('start preparing scoreboard')
		self.scoreboardscore = prepare_scoreboardscore(settings.scale, settings)
		self.scoreboard = prepare_scoreboard(settings.scale, settings)
		self.scoreboardeffect = prepare_scoreboardeffect(settings.scale)

		self.modicons = prepare_modicons(settings.scale, settings)
		if loadranking:
			self.rankingpanel = prepare_rankingpanel(settings.scale, self.bg, settings)
			self.rankinghitresults = prepare_rankinghitresults(settings.scale, settings)
			self.rankingscore = prepare_rankingscorecounter(self.scorenumbers)
			self.rankinggrades = prepare_rankinggrade(settings.scale, settings)
			self.rankingtitle = prepare_rankingtitle(settings.scale, settings)
			self.rankingcombo = prepare_rankingcombo(settings.scale * 1.05, settings)
			self.rankingaccuracy = prepare_rankingaccuracy(settings.scale * 1.05, settings)
			self.menuback = prepare_menuback(settings.scale, settings)
			self.rankingreplay = prepare_rankingreplay(settings.scale, settings)
			self.rankinggraph = prepare_rankinggraph(settings.scale, settings)
			logger.debug("start preparing ur ranking")
			self.rankingur = prepare_rankingur(settings, ur)
			self.rankinggraph.extend(self.rankingur)

		self.flashlight = prepare_flashlight(settings, fl)
		self.urarrow = prepare_urarrow(settings)
		logger.debug('start preparing done')
示例#11
0
def draw(shared, conn, beatmap, replay_info, resultinfo, videotime, settings,
         showranking):
    asdfasdf = time.time()

    logger.log(1, "CALL {}, {}".format(videotime, showranking))
    logger.debug("process start")

    ur = getunstablerate(resultinfo)
    frames = PreparedFrames(settings,
                            beatmap.diff,
                            replay_info.mod_combination,
                            ur=ur,
                            bg=beatmap.bg,
                            loadranking=showranking)

    drawer = Drawer(shared, beatmap, frames, replay_info, resultinfo,
                    videotime, settings)

    logger.log(1, "PROCESS {}, {}".format(videotime, drawer))

    logger.debug("setup done")
    logger.debug("Starting draw")
    timer = 0
    timer2 = 0
    timer3 = 0
    while drawer.frame_info.osr_index < videotime[1]:
        status = drawer.render_draw()
        asdf = time.time()
        if status:
            conn.send(1)
            timer3 += time.time() - asdf

            asdf = time.time()
            i = conn.recv()
            timer2 += time.time() - asdf

    if showranking:
        for x in range(int(5 * settings.fps)):
            drawer.draw_rankingpanel()
            conn.send(1)
            i = conn.recv()

    conn.send(10)
    logger.debug("End draw: %f", time.time() - asdfasdf)
    logger.debug("\nprocess done {}, {}".format(videotime, drawer))
    logger.debug("Drawing time: {}".format(timer))
    logger.debug("Total time: {}".format(time.time() - asdfasdf))
    logger.debug("Waiting time: {}".format(timer2))
    logger.debug("Changing value time: {}".format(timer3))
示例#12
0
	def __init__(self, frames, fonts):
		super().__init__(frames[0])
		self.nwidth = self.w()
		scale = frames[1]
		self.overlap = int(fonts["HitCircleOverlap"]*scale)
		logger.debug("%s %s %s", self.overlap, fonts["HitCircleOverlap"], scale)
示例#13
0
def setupglobals(data,
                 gameplaydata,
                 mod_combination,
                 settings,
                 ppsettings=None,
                 strainsettings=None):
    skin_path = data["Skin path"]
    beatmap_path = data["Beatmap path"]
    output_path = data.get("Output path", "output.avi")
    ffmpeg = data.get("ffmpeg path", "ffmpeg")
    default_path = os.path.join(settings.path, "res/default/")
    fps = data.get("FPS", 60)
    width = data.get("Width", 1920)
    height = data.get("Height", 1080)
    osupath = data.get("osu! path", None)
    #
    # if skin_path[-1] != "/" and skin_path[-1] != "\\":
    # 	skin_path += "/"
    #
    # if beatmap_path[-1] != "/" and beatmap_path[-1] != "\\":
    # 	beatmap_path += "/"
    #
    # if osupath[-1] != "/" and osupath[-1] != "\\":
    # 	osupath += "/"

    time_frame = 1000

    if Mod.DoubleTime in mod_combination or Mod.Nightcore in mod_combination:
        time_frame *= 1.5
    if Mod.HalfTime in mod_combination:
        time_frame *= 0.75
    logger.debug(time_frame)

    playfield_scale, playfield_width, playfield_height, scale, move_right, move_down = get_screensize(
        width, height)
    settings.width, settings.height, settings.scale = width, height, scale
    settings.playfieldscale, settings.playfieldwidth, settings.playfieldheight = playfield_scale, playfield_width, playfield_height
    settings.fps, settings.timeframe = fps, time_frame
    settings.moveright, settings.movedown = move_right, move_down

    settings.output = output_path
    settings.ffmpeg = ffmpeg
    settings.beatmap = beatmap_path
    settings.osu = osupath

    skin = Skin(skin_path, default_path)
    # defaultskin = Skin(default_path, default_path)

    settings.skin_path = skin_path
    settings.default_path = default_path
    settings.skin_ini = skin
    settings.default_skin_ini = skin

    # gameplaydata["Enable PP counter"] = gameplaydata.get("Enable PP counter", False)
    # gameplaydata["Song delay"] = gameplaydata.get("Song delay", 0)
    # gameplaydata["Show mods icon"] = gameplaydata.get("Show mods icon", True)
    # gameplaydata["Custom mods"] = gameplaydata.get("Custom mods", "")
    # gameplaydata["Use FFmpeg video writer"] = gameplaydata.get("Use FFmpeg video writer", False)
    # gameplaydata["FFmpeg codec"] = gameplaydata.get("Use FFmpeg video writer", False)
    # gameplaydata["Use FFmpeg video writer"] = gameplaydata.get("Use FFmpeg video writer", False)

    for setting in defaultsettings:
        if setting not in gameplaydata:
            gameplaydata[setting] = defaultsettings[setting]

    settings.settings = gameplaydata

    if ppsettings is not None:
        settings.ppsettings = ppsettings
    if strainsettings is not None:
        settings.strainsettings = strainsettings
示例#14
0
def prepare_circle(diff, scale, settings, hd):
    # prepare every single frame before entering the big loop, this will save us a ton of time since we don't need
    # to overlap number, circle overlay and approach circle every single time.

    opacity_interval, time_preempt, fade_in = calculate_ar(
        diff["ApproachRate"], settings)

    cs = (54.4 - 4.48 * diff["CircleSize"]) * scale
    radius_scale = cs * overlay_scale * 2 / default_size

    circle, c_overlay, slider, s_overlay = load(settings)
    if not hd:
        approach_frames = prepare_approach(radius_scale, time_preempt,
                                           settings)

    fadeout = [[], []]  # circle, slider
    circle_frames = []  # [color][number][alpha]
    slidercircle_frames = []  # [color][number][alpha]
    alphas = []

    for c in range(1, settings.skin_ini.colours["ComboNumber"] + 1):
        color = settings.skin_ini.colours["Combo" + str(c)]

        orig_circle = overlayhitcircle(c_overlay, circle, color, radius_scale)

        if not hd:
            fadeout[0].append(prepare_fadeout(orig_circle, settings))
        else:
            fadeout[0].append([Image.new("RGBA", (1, 1))])

        orig_slider = overlayhitcircle(s_overlay, slider, color, radius_scale)

        if not hd:
            fadeout[1].append(prepare_fadeout(orig_slider, settings))
        else:
            fadeout[1].append([Image.new("RGBA", (1, 1))])

        alpha = 0  # alpha for fadein
        circle_frames.append([])
        slidercircle_frames.append([])
        if not hd:

            # we also overlay approach circle to circle to avoid multiple add_to_frame call
            for i in range(len(approach_frames)):
                approach_circle = imageproc.add_color(approach_frames[i],
                                                      color)
                approach_slider = approach_circle.copy()

                circle_frames[-1].append(
                    overlayapproach(orig_circle, approach_circle, alpha))
                slidercircle_frames[-1].append(
                    overlayapproach(orig_slider, approach_slider, alpha))

                alphas.append(alpha)
                alpha = min(100, alpha + opacity_interval)
            # for late tapping
            slidercircle_frames[-1].append(orig_slider)
            circle_frames[-1].append(orig_circle)
            alphas.append(alpha)

        else:
            # source: https://github.com/ppy/osu/blob/4cb57f8205edf5ed7b7da076325ba76ec9cc3039/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs#L23
            interval = settings.timeframe / settings.fps
            fade_in = time_preempt * 0.4
            fade_in_interval = 100 * interval / fade_in

            ii = fade_in_interval

            fade_out = time_preempt * 0.3
            fade_out_interval = 100 * interval / fade_out

            #interval = 1 if not interval else interval
            for i in np.arange(time_preempt, 0, -interval):
                if alpha != 0:
                    circle_frames[-1].append(newalpha(orig_circle,
                                                      alpha / 100))
                    slidercircle_frames[-1].append(
                        newalpha(orig_slider, alpha / 100))
                else:
                    circle_frames[-1].append(Image.new("RGBA", (1, 1)))
                    slidercircle_frames[-1].append(Image.new("RGBA", (1, 1)))

                if alpha == 100:
                    ii = -fade_out_interval

                alphas.append(alpha)
                alpha = max(0, min(100, alpha + ii))

        logger.debug("done")

    return slidercircle_frames, circle_frames, fadeout, alphas
示例#15
0
from osr2mp4 import logger
from osr2mp4cv import getaudiocodec

a = getaudiocodec()

codec = {}
for x in a:
    codec[x.decode("utf-8")] = a[x].decode("utf-8")

for x in codec:
    logger.debug(f"{x}: {codec[x]}")
示例#16
0
def create_frame(settings, beatmap, replay_info, resultinfo, videotime, showranking):
	logger.debug('entering preparedframes')

	if settings.process >= 1:
		shared_array = []
		shared_pipe = []
		drawers = []
		writers = []

		start_index, end_index = videotime

		osr_interval = int((end_index - start_index) / settings.process)
		start = start_index

		my_file = open(os.path.join(settings.temp, "listvideo.txt"), "w")
		for i in range(settings.process):

			if i == settings.process - 1:
				end = end_index
			else:
				end = start + osr_interval

			shared = RawArray(ctypes.c_uint8, settings.height * settings.width * 4)
			conn1, conn2 = Pipe()

			# extract container
			_, file_extension = os.path.splitext(settings.output)
			f = "output" + str(i) + file_extension

			vid = (start, end)

			drawer = Process(target=draw_frame, args=(
				shared, conn1, beatmap, replay_info, resultinfo, vid, settings, showranking and i == settings.process-1))

			writer = Process(target=write_frame, args=(shared, conn2, settings.temp + f, settings, i == settings.process-1))

			shared_array.append(shared)
			shared_pipe.append((conn1, conn2))
			drawers.append(drawer)
			writers.append(writer)

			my_file.write("file '{}'\n".format(f))
			logger.debug("Starting process")

			drawer.start()
			logger.debug("Start drawer {}".format(i))
			writer.start()
			logger.debug("Start writer {}".format(i))

			start += osr_interval
		my_file.close()

		return drawers, writers, shared_pipe, shared_array

	else:
		from osr2mp4.VideoProcess.AFrames import PreparedFrames
		from osr2mp4.CheckSystem.mathhelper import getunstablerate
		import numpy as np

		logger.debug("process start")

		ur = getunstablerate(resultinfo)
		frames = PreparedFrames(settings, beatmap.diff, replay_info.mod_combination, ur=ur, bg=beatmap.bg, loadranking=showranking)

		shared = RawArray(ctypes.c_uint8, settings.height * settings.width * 4)
		drawer = Drawer(shared, beatmap, frames, replay_info, resultinfo, videotime, settings)

		_, file_extension = os.path.splitext(settings.output)
		f = os.path.join(settings.temp, "outputf" + file_extension)

		buf = np.zeros((settings.height * settings.width * 3), dtype=np.uint8)
		writer = getwriter(f, settings, buf)
		buf = buf.reshape((settings.height, settings.width, 3))

		logger.debug("setup done")
		framecount = 0
		startwritetime = time.time()
		while drawer.frame_info.osr_index < videotime[1]:
			status = drawer.render_draw()

			if status:
				cv2.cvtColor(drawer.np_img, cv2.COLOR_BGRA2RGB, dst=buf)

				if not settings.settings["Use FFmpeg video writer"]:
					writer.write(buf)
				else:
					writer.write()

				framecount += 1
				if framecount % 100 == 0:
					filewriter = open(os.path.join(settings.temp, "speed.txt"), "w")
					deltatime = time.time() - startwritetime
					filewriter.write("{}\n{}\n{}\n{}".format(framecount, deltatime, f, startwritetime))
					filewriter.close()

					update_progress(framecount, deltatime, videotime)

		if showranking:
			for x in range(int(5 * settings.fps)):
				drawer.draw_rankingpanel()
				cv2.cvtColor(drawer.np_img, cv2.COLOR_BGRA2RGB, dst=buf)
				if not settings.settings["Use FFmpeg video writer"]:
					writer.write(buf)
				else:
					writer.write()
		writer.release()
		logger.debug("\nprocess done")

		return None, None, None, None