code: def add_text_with_timestamps(
      parser_builder: builders.BaseParserBuilder,
      preprocessor_builder: builders.PreprocessorBuilder,
      tokenizer: tokenizers.TextTokenizer,
      input_feature_name: str = "caption/string",
      input_timestamp_start_name: str = "caption/timestamp/start",
      input_timestamp_end_name: str = "caption/timestamp/end",
      input_duration_name: str = "video/duration",
      output_raw_timestamp_name: str = "timestamp",
      output_raw_duration_name: str = "duration",
      max_events: int = 50,
      vocabulary_size: int = 32128,
      num_bins: int = 100,
      output_raw_string_name: str = builders.TEXT_FEATURE_NAME,
      output_feature_name: str = builders.TEXT_INDICES_FEATURE_NAME,
      prepend_bos: bool = True,
      append_eos: bool = True,
      keep_raw_string: bool = False,
      max_num_tokens: Optional[int] = 128,
      abs_time_token: bool = False,
      time_format: str = "se",
      order: str = "ld",
      notime: bool = False,
      asr_input: bool = True,
      max_num_input_words: int = 512,
      asr_raw_string_name: str = "ASR/string",
      asr_timestamp_name: str = "ASR/timestamps",
      corrupt: float = 0.0,
      span_len: float = 3.0,
      tmp_only: bool = False,
      asr_notime: bool = False,
      t: int = 1000000,
  ):
      """Prepares data for Vid2Seq model.
  
      Args:
        parser_builder: DMVR Parser builder.
        preprocessor_builder: DMVR Preprocessor builder.
        tokenizer: Text tokenizer.
        input_feature_name: Field name for the captions.
        input_timestamp_start_name: Field name for the start timestamps.
        input_timestamp_end_name: Field name for the end timestamps.
        input_duration_name: Field name for video duration.
        output_raw_timestamp_name: Output key for the timestamps.
        output_raw_duration_name: Output key for the duration.
        max_events: Maximum number of events to consider.
        vocabulary_size: Number of tokens of the text tokenizer.
        num_bins: Number of quantization bins for time tokens.
        output_raw_string_name: Output key for the captions.
        output_feature_name: Output key for the caption tokens.
        prepend_bos: Whether to put BOS at the start of the sequences.
        append_eos: Whether to add EOS at the end of the sequences.
        keep_raw_string: Whether to keep raw string in batch.
        max_num_tokens: Maximum number of tokens for sequences.
        abs_time_token: Whether to use absolute (vs relative) time tokens.
        time_format: st for start-end or cd for center-duration.
        order: ld for time tokens first, dl for text tokens first.
        notime: Whether to use time tokens.
        asr_input: Whether to use ASR as input.
        max_num_input_words: Maximum number of tokens in ASR input.
        asr_raw_string_name: Field name for input ASR text.
        asr_timestamp_name: Field name for input ASR timestamps.
        corrupt: Ratio of corruption for T5-style corrupted sequence.
        span_len: Average length of corrupted spans for T5-style corrupted sequence.
        tmp_only: Localization only mode.
        asr_notime: Whether to use time tokens for ASR input.
        t: FPS * 1000000
  
      Returns:
        Nothing, modifies DMVR builder inplace.
      """
  
      # Parse text indices.
      if isinstance(
          parser_builder, builders.SequenceExampleParserBuilder
      ):
          parser_builder.parse_feature(
              feature_name=input_feature_name,
              feature_type=tf.io.VarLenFeature(dtype=tf.string),
              output_name=output_raw_string_name,
              is_context=True,
          )
      elif isinstance(parser_builder, builders.ExampleParserBuilder):
          parser_builder.parse_feature(
              feature_name=input_feature_name,
              feature_type=tf.io.VarLenFeature(dtype=tf.string),
              output_name=output_raw_string_name,
          )
  
      # Parser builder for timestamps and video duration.
      parser_builder.parse_feature(
          feature_name=input_timestamp_start_name,
          feature_type=tf.io.VarLenFeature(dtype=tf.int64),
          output_name=output_raw_timestamp_name + "_start",
          is_context=True,
      )
      parser_builder.parse_feature(
          feature_name=input_timestamp_end_name,
          feature_type=tf.io.VarLenFeature(dtype=tf.int64),
          output_name=output_raw_timestamp_name + "_end",
          is_context=True,
      )
      parser_builder.parse_feature(
          feature_name=input_duration_name,
          feature_type=tf.io.VarLenFeature(dtype=tf.int64),
          output_name=output_raw_duration_name,
          is_context=True,
      )
  
      # Tokenize the text captions individually.
      preprocessor_builder.add_fn(
          fn=lambda x: processors.tokenize(  # pylint: disable=g-long-lambda
              x,
              tokenizer,
              output_raw_string_name,
              output_feature_name,
              prepend_bos,
              append_eos,
              max_num_tokens,
              keep_raw_string,
          ),
          fn_name=f"{output_feature_name}_tokenization",
      )
  
      if asr_input:
          # Parse ASR text indices.
          if isinstance(
              parser_builder, builders.SequenceExampleParserBuilder
          ):
              parser_builder.parse_feature(
                  feature_name=asr_raw_string_name,
                  feature_type=tf.io.VarLenFeature(dtype=tf.string),
                  output_name="asr_string",
                  is_context=True,
              )
          elif isinstance(
              parser_builder, builders.ExampleParserBuilder
          ):
              parser_builder.parse_feature(
                  feature_name=asr_raw_string_name,
                  feature_type=tf.io.VarLenFeature(dtype=tf.string),
                  output_name="asr_string",
              )
  
          # Parser builder for ASR timestamps.
          parser_builder.parse_feature(
              feature_name=asr_timestamp_name + "/start",
              feature_type=tf.io.VarLenFeature(dtype=tf.int64),
              output_name="asr_start",
              is_context=True,
          )
          parser_builder.parse_feature(
              feature_name=asr_timestamp_name + "/end",
              feature_type=tf.io.VarLenFeature(dtype=tf.int64),
              output_name="asr_end",
              is_context=True,
          )
  
          # Tokenize the ASR sentences individually.
          preprocessor_builder.add_fn(
              fn=lambda x: processors.tokenize(  # pylint: disable=g-long-lambda
                  x,
                  tokenizer,
                  "asr_string",
                  "asr_indices",
                  prepend_bos,
                  append_eos,
                  max_num_input_words,
                  False,
              ),
              fn_name="asr_indices_tokenization",
          )
  
      def add_timestamp(batch):
          # Tokenize timestamp and add these tokens to each caption.
  
          # Load batch.
          duration = batch[output_raw_duration_name]
          start = batch[output_raw_timestamp_name + "_start"]
          end = batch[output_raw_timestamp_name + "_end"]
          caption_tokens = batch[output_feature_name]
  
          # Truncate events.
          start = start[:max_events]
          end = end[:max_events]
          caption_tokens = caption_tokens[:max_events]
  
          # Tokenize timestamps.
          timestamp_token = timestampify(
              start=start,
              end=end,
              duration=duration,
              abs_time_token=abs_time_token,
              num_bins=num_bins,
              vocabulary_size=vocabulary_size,
              time_format=time_format,
              t=t,
          )
  
          # Merge caption and time tokens.
          if (not notime) and (not tmp_only):
              seq = merge_cap_time_tokens(
                  caption_tokens, timestamp_token, order
              )
          elif notime:  # only consider caption tokens
              seq = caption_tokens
          elif tmp_only:  # only consider time tokens
              seq = timestamp_token
              seq -= 32126
  
          # Prepare timestamp for ASR.
          if asr_input:
              asr_start = batch["asr_start"]
              asr_end = batch["asr_end"]
              asr_tokens = batch["asr_indices"]
              asr_stamp_token = timestampify(
                  start=asr_start,
                  end=asr_end,
                  duration=duration,
                  abs_time_token=abs_time_token,
                  num_bins=num_bins,
                  vocabulary_size=vocabulary_size,
                  time_format=time_format,
              )
              if asr_notime:
                  batch["asr_indices"] = asr_tokens
              else:
                  batch["asr_indices"] = merge_cap_time_tokens(
                      asr_tokens, asr_stamp_token, order
                  )
  
              del batch["asr_start"]
              del batch["asr_end"]
  
          batch[output_feature_name] = seq  # [n_events, max_num_words]
  
          # Pad caption, start, end, split to max_events for data collation.
          if keep_raw_string:  # eval
              n_events = tf.shape(input=start)[0]
              padding_pattern = [
                  [0, tf.maximum(0, max_events - n_events)],
              ]
              if "split" in batch:
                  batch["split"] = tf.pad(
                      tensor=batch["split"],
                      paddings=padding_pattern,
                      constant_values=-1,
                  )
              batch[output_raw_string_name] = tf.pad(
                  tensor=batch[output_raw_string_name],
                  paddings=padding_pattern,
                  constant_values="",
              )
              batch[output_raw_timestamp_name + "_start"] = tf.pad(
                  tensor=start,
                  paddings=padding_pattern,
                  constant_values=-1,
              )
              batch[output_raw_timestamp_name + "_end"] = tf.pad(
                  tensor=end,
                  paddings=padding_pattern,
                  constant_values=-1,
              )
          else:
              del batch[output_raw_timestamp_name + "_start"]
              del batch[output_raw_timestamp_name + "_end"]
  
          return batch
  
      # Add timestamp tokens.
      preprocessor_builder.add_fn(
          fn=add_timestamp, fn_name=f"{output_feature_name}_timify"
      )
  
      # Reshape to concatenate all the dense captions.
      preprocessor_builder.add_fn(
          fn=lambda x: tf.reshape(x, [-1]),
          feature_name=output_feature_name,
          fn_name=f"{output_feature_name}_reshape",
      )
  
      # Get the boolean mask and remove padded tokens for each caption.
      preprocessor_builder.add_fn(
          fn=lambda x: tf.boolean_mask(x, tf.not_equal(x, 0)),
          feature_name=output_feature_name,
          fn_name=f"{output_feature_name}_unpad",
      )
  
      # Get the boolean mask and remove EOS tokens for each caption.
      preprocessor_builder.add_fn(
          fn=lambda x: tf.boolean_mask(x, tf.not_equal(x, 1)),
          feature_name=output_feature_name,
          fn_name=f"{output_feature_name}_uneos",
      )
  
      def corruption(batch):
          tokens = batch[output_feature_name]
          x = single_example_denoise(
              tokens=tokens,
              vocabulary_size=vocabulary_size,
              noise_density=corrupt,
              noise_mask_fn=functools.partial(
                  random_spans_noise_mask,
                  mean_noise_span_length=span_len,
              ),
              inputs_fn=noise_span_to_unique_sentinel,
              targets_fn=nonnoise_span_to_unique_sentinel,
          )
          # no BOS in encoder and no EOS anywhere here
          batch[
              output_feature_name + "_corrupt_outputs"
          ] = processors.sample_or_pad_non_sorted_sequence(
              tf.concat([[0], x["outputs"][: max_num_tokens - 1]], 0),
              max_num_tokens,
              pad_value=0,
              random=False,
          )  # max_num_tokens
          batch[
              output_feature_name + "_corrupt_inputs"
          ] = processors.sample_or_pad_non_sorted_sequence(
              x["inputs"][: max_num_tokens - 1],
              max_num_tokens - 1,
              pad_value=0,
              random=False,
          )  # max_num_tokens - 1
          return batch
  
      preprocessor_builder.add_fn(
          fn=corruption, fn_name=f"{output_feature_name}_corrupt"
      )
  
      # Readd BOS=PAD and EOS token, truncate+pad for the full sequence.
      preprocessor_builder.add_fn(
          fn=lambda x: processors.sample_or_pad_non_sorted_sequence(  # pylint: disable=g-long-lambda
              tf.concat([[0], x, [1]], 0),
              max_num_tokens,
              pad_value=0,
              random=False,
          ),
          feature_name=output_feature_name,
          fn_name=f"{output_feature_name}_repad",
      )
  
      if asr_input:
          # Reshape to concatenate all the dense captions
          preprocessor_builder.add_fn(
              fn=lambda x: tf.reshape(x, [-1]),
              feature_name="asr_indices",
              fn_name="asr_indices_reshape",
          )
  
          # Get the boolean mask and remove padded tokens for each caption
          preprocessor_builder.add_fn(
              fn=lambda x: tf.boolean_mask(x, tf.not_equal(x, 0)),
              feature_name="asr_indices",
              fn_name="asr_indices_unpad",
          )
  
          # Get the boolean mask and remove EOS tokens for each caption
          preprocessor_builder.add_fn(
              fn=lambda x: tf.boolean_mask(x, tf.not_equal(x, 1)),
              feature_name="asr_indices",
              fn_name="asr_indices_uneos",
          )
  
          # Readd BOS=PAD and EOS token, truncate+pad for the full sequence
          preprocessor_builder.add_fn(
              fn=lambda x: processors.sample_or_pad_non_sorted_sequence(  # pylint: disable=g-long-lambda
                  tf.concat([x, [1]], 0),
                  max_num_input_words,
                  pad_value=0,
                  random=False,
              ),
              feature_name="asr_indices",
              fn_name="asr_indices_repad",
          )
  
imports: import functools
  from typing import Any, Mapping, Optional, Union
  from dmvr import builders
  from dmvr import processors
  from dmvr import tokenizers
  import gin
  from t5.data.preprocessors import DenoiseInputsFn
  from t5.data.preprocessors import DenoiseNoiseMaskFn
  from t5.data.preprocessors import DenoiseTargetsFn
  from t5.data.preprocessors import random_spans_noise_mask
  import tensorflow
label_desc: Use image node_id 7 for calling a global function with example usage: add_text_with_timestamps(parser_builder, preprocessor_builder, tokenizer, input_feature_name, input_timestamp_start_name, input_timestamp_end_name, input_duration_name, output_raw_timestamp_name, output_raw_duration_name, max_events, vocabulary_size, num_bins, output_raw_string_name, output_feature_name, prepend_bos, append_eos, keep_raw_string, max_num_tokens, abs_time_token, time_format, order, notime, asr_input, max_num_input_words, asr_raw_string_name, asr_timestamp_name, corrupt, span_len, tmp_only, asr_notime, t) and returns: batch, batch