def converter_for_video_project_with_id(
    project_id,
    deeplake_ds_loader,
    lb_api_key,
    group_mapping=None,
    fail_on_error=False,
    fail_on_labelbox_project_export_error=False,
    generate_metadata=True,
    metadata_prefix="lb_meta",
    project_json=None,
) -> Optional[labelbox_video_converter]:
    """
    Creates a converter for Labelbox video project to a Deeplake dataset format based on annotation types.

    Args:
        project_id (str): The unique identifier for the Labelbox project to convert.
        deeplake_ds_loader (callable): A function that creates/loads a Deeplake dataset given a name.
        lb_api_key (str): Labelbox API key for authentication.
        group_mapping (dict, optional): A dictionary mapping annotation kinds (labelbox_kind) to the desired tensor group name (tensor_name). This mapping determines whether annotations of the same kind should be grouped into the same tensor or kept separate.
        fail_on_error (bool, optional): Whether to raise an exception if data validation fails. Defaults to False.
        fail_on_labelbox_project_export_error (bool, optional): Whether to raise an exception if Labelbox project export fails. Defaults to False.
        generate_metadata (bool, optional): Whether to generate metadata tensors. Defaults to True.
        metadata_prefix (str, optional): Prefix for metadata tensors. Defaults to "lb_meta". Will be ignored if generate_metadata is False.
        project_json (Any, optional): Optional project JSON data to use for conversion. If not provided, the function will fetch the project data from Labelbox.


    Returns:
        Optional[labelbox_video_converter]: Returns a labelbox_type_converter if successful, None if no data is found.
        The returned converter can be used to apply Labelbox annotations to a Deeplake dataset.

    Raises:
        Exception: If project data validation fails.

    Example:
        >>> converter = converter_for_video_project_with_id(
        ...     '<project_id>',
        ...     lambda name: deeplake.load(name),
        ...     'your_api_key',
        ...     group_mapping={"raster-segmentation": "mask"}
        ... )
        >>> if converter:
        ...     # Use converter to apply annotations
        ...     ds = converter.dataset_with_applied_annotations()

    Notes:
        - Supports Video ontology from labelbox.
        - The function first validates the project data before setting up converters.
    """
    import labelbox as lb  # type: ignore

    client = lb.Client(api_key=lb_api_key)
    if project_json is None:
        project_json = labelbox_get_project_json_with_id_(
            client, project_id, fail_on_labelbox_project_export_error
        )

    if len(project_json) == 0:
        print("no data")
        return None

    ds_name = project_json[0]["projects"][project_id]["name"]
    wrapped_dataset = dataset_wrapper(deeplake_ds_loader(ds_name))

    if not validate_project_data_(project_json, wrapped_dataset, project_id, "video"):
        if fail_on_error:
            raise Exception("Data validation failed")

    ontology_id = project_json[0]["projects"][project_id]["project_details"][
        "ontology_id"
    ]
    ontology = client.get_ontology(ontology_id)

    converters = {
        "rectangle": bbox_converter_,
        "radio": radio_converter_,
        "checklist": checkbox_converter_,
        "point": point_converter_,
        "line": line_converter_,
        "raster-segmentation": raster_segmentation_converter_,
        "text": text_converter_,
    }

    if generate_metadata:
        tensor_name_generator = lambda name: (
            f"{metadata_prefix}/{name}" if metadata_prefix else name
        )

        metadata_generators = {
            tensor_name_generator("video_name"): {
                "generator": get_video_name_from_video_project_,
                "create_tensor_kwargs": text_tensor_create_kwargs_(),
            },
            tensor_name_generator("id"): {
                "generator": get_data_row_id_from_video_project_,
                "create_tensor_kwargs": text_tensor_create_kwargs_(),
            },
            tensor_name_generator("row_data"): {
                "generator": lambda project, ctx: get_data_row_url_from_video_project_(
                    project, ctx
                ),
                "create_tensor_kwargs": text_tensor_create_kwargs_(),
            },
            tensor_name_generator("label_creator"): {
                "generator": get_label_creator_from_video_project_,
                "create_tensor_kwargs": text_tensor_create_kwargs_(),
            },
            tensor_name_generator("frame_rate"): {
                "generator": get_frame_rate_from_video_project_,
                "create_tensor_kwargs": generic_tensor_create_kwargs_("int32"),
            },
            tensor_name_generator("frame_count"): {
                "generator": get_frame_count_from_video_project_,
                "create_tensor_kwargs": generic_tensor_create_kwargs_("int32"),
            },
            tensor_name_generator("width"): {
                "generator": get_width_from_video_project_,
                "create_tensor_kwargs": generic_tensor_create_kwargs_("int32"),
            },
            tensor_name_generator("height"): {
                "generator": get_height_from_video_project_,
                "create_tensor_kwargs": generic_tensor_create_kwargs_("int32"),
            },
            tensor_name_generator("ontology_id"): {
                "generator": get_ontology_id_from_video_project_,
                "create_tensor_kwargs": text_tensor_create_kwargs_(),
            },
            tensor_name_generator("project_name"): {
                "generator": get_project_name_from_video_project_,
                "create_tensor_kwargs": text_tensor_create_kwargs_(),
            },
            tensor_name_generator("dataset_name"): {
                "generator": get_dataset_name_from_video_project_,
                "create_tensor_kwargs": text_tensor_create_kwargs_(),
            },
            tensor_name_generator("dataset_id"): {
                "generator": get_dataset_id_from_video_project_,
                "create_tensor_kwargs": text_tensor_create_kwargs_(),
            },
            tensor_name_generator("global_key"): {
                "generator": get_global_key_from_video_project_,
                "create_tensor_kwargs": text_tensor_create_kwargs_(),
            },
            tensor_name_generator("frame_number"): {
                "generator": lambda project, ctx: ctx["frame_idx"]
                + 1,  # 1-indexed frame number
                "create_tensor_kwargs": generic_tensor_create_kwargs_("int32"),
            },
            tensor_name_generator("current_frame_name"): {
                "generator": lambda project, ctx: f"{get_video_name_from_video_project_(project, ctx)}_{(ctx['frame_idx'] + 1):06d}",  # 1-indexed frame number
                "create_tensor_kwargs": text_tensor_create_kwargs_(),
            },
        }
    else:
        metadata_generators = None

    return labelbox_video_converter(
        ontology,
        converters,
        project_json,
        project_id,
        wrapped_dataset,
        {"ds": wrapped_dataset, "lb_api_key": lb_api_key},
        metadata_generators=metadata_generators,
        group_mapping=group_mapping,
    )

    Creates a converter for Labelbox video project to a Deeplake dataset format based on annotation types.

    Args:
        project_id (str): The unique identifier for the Labelbox project to convert.
        deeplake_ds_loader (callable): A function that creates/loads a Deeplake dataset given a name.
        lb_api_key (str): Labelbox API key for authentication.
        group_mapping (dict, optional): A dictionary mapping annotation kinds (labelbox_kind) to the desired tensor group name (tensor_name). This mapping determines whether annotations of the same kind should be grouped into the same tensor or kept separate.
        fail_on_error (bool, optional): Whether to raise an exception if data validation fails. Defaults to False.
        fail_on_labelbox_project_export_error (bool, optional): Whether to raise an exception if Labelbox project export fails. Defaults to False.
        generate_metadata (bool, optional): Whether to generate metadata tensors. Defaults to True.
        metadata_prefix (str, optional): Prefix for metadata tensors. Defaults to "lb_meta". Will be ignored if generate_metadata is False.
        project_json (Any, optional): Optional project JSON data to use for conversion. If not provided, the function will fetch the project data from Labelbox.


    Returns:
        Optional[labelbox_video_converter]: Returns a labelbox_type_converter if successful, None if no data is found.
        The returned converter can be used to apply Labelbox annotations to a Deeplake dataset.

    Raises:
        Exception: If project data validation fails.

    Example:
        >>> converter = converter_for_video_project_with_id(
        ...     '<project_id>',
        ...     lambda name: deeplake.load(name),
        ...     'your_api_key',
        ...     group_mapping={"raster-segmentation": "mask"}
        ... )
        >>> if converter:
        ...     # Use converter to apply annotations
        ...     ds = converter.dataset_with_applied_annotations()

    Notes:
        - Supports Video ontology from labelbox.
        - The function first validates the project data before setting up converters.
    
python/deeplake/integrations/labelbox/labelbox_.py