def frame_generator_(
    video_path: str, header: Optional[dict[str, Any]] = None, retries: int = 5
) -> Generator[Tuple[int, np.ndarray], None, None]:
    """
    Generate frames from a video file.

    Parameters:
    video_path (str): Path to the video file
    header (dict, optional): Optional request header for authorization

    Yields:
    tuple: (frame_number, frame_data)
        - frame_number (int): The sequential number of the frame
        - frame_data (numpy.ndarray): The frame image data
    """

    def get_video_container(current_retries):
        import av

        try:
            return av.open(video_path, options=header)
        except Exception as e:
            if current_retries > 0:
                print(f"Failed opening video: {e}. Retrying...")
                return get_video_container(current_retries - 1)
            else:
                raise e

    try:
        container = get_video_container(retries)
        print(f"Start generating frames from {video_path}")
        frame_num = 0
        for frame in container.decode(video=0):
            yield frame_num, frame.to_ndarray(format="rgb24")
            frame_num += 1
    except Exception as e:
        print(f"Failed generating frames: {e}")

    Generate frames from a video file.

    Parameters:
    video_path (str): Path to the video file
    header (dict, optional): Optional request header for authorization

    Yields:
    tuple: (frame_number, frame_data)
        - frame_number (int): The sequential number of the frame
        - frame_data (numpy.ndarray): The frame image data
    
python/deeplake/integrations/labelbox/labelbox_utils.py