def METHOD_NAME(cfg: SceneCfg, fast=True, segment_time=2.0, constrained_timeranges=False):
    """
    Parallel media playback, flipping between the two sources.
    The fast version makes sure the textures continue to be updated even though
    they are not displayed. On the other hand, the slow version will update the
    textures only when needed to be displayed, causing potential seek in the
    underlying media, and thus undesired delays.
    """
    m1 = ngl.Media(cfg.medias[0].filename, label="media #1")
    m2 = ngl.Media(cfg.medias[0].filename, label="media #2")
    t1 = ngl.Texture2D(data_src=m1, label="texture #1")
    t2 = ngl.Texture2D(data_src=m2, label="texture #2")
    render1 = ngl.RenderTexture(t1)
    render2 = ngl.RenderTexture(t2)
    text_settings = {
        "box_corner": (-1, 1 - 0.2, 0),
        "box_height": (0, 0.2, 0),
        "aspect_ratio": cfg.aspect_ratio,
    }
    render1 = ngl.Group(children=(render1, ngl.Text("media #1", **text_settings)))
    render2 = ngl.Group(children=(render2, ngl.Text("media #2", **text_settings)))
    rf1 = ngl.TimeRangeFilter(render1)
    rf2 = ngl.TimeRangeFilter(render2)
    if constrained_timeranges:
        rf1.set_prefetch_time(segment_time / 3.0)
        rf2.set_prefetch_time(segment_time / 3.0)
        rf1.set_max_idle_time(segment_time / 2.0)
        rf2.set_max_idle_time(segment_time / 2.0)
    t = 0
    rr1 = []
    rr2 = []
    while t < cfg.duration:
        rr1.append(ngl.TimeRangeModeCont(t))
        rr1.append(ngl.TimeRangeModeNoop(t + segment_time))
        rr2.append(ngl.TimeRangeModeNoop(t))
        rr2.append(ngl.TimeRangeModeCont(t + segment_time))
        t += 2 * segment_time
    rf1.add_ranges(*rr1)
    rf2.add_ranges(*rr2)
    g = ngl.Group()
    g.add_children(rf1, rf2)
    if fast:
        g.add_children(t1, t2)
    return g