code: def _video_speech_collate_fn(batch, pad_id):
      """collate batch of video sig, video len, tokens, tokens len
      Args:
          batch (Optional[FloatTensor], Optional[LongTensor], LongTensor,
                 LongTensor):  A tuple of tuples of signal, signal lengths,
                 encoded tokens, and encoded tokens length.  This collate func
                 assumes the signals are 4d torch tensors (Time, Height, Width, Channels).
      """
      packed_batch = list(zip(*batch))
  
      if len(packed_batch) == 5:
          _, video_lengths, _, tokens_lengths, sample_ids = packed_batch
      elif len(packed_batch) == 4:
          sample_ids = None
          _, video_lengths, _, tokens_lengths = packed_batch
      else:
          raise ValueError("Expects 4 or 5 tensors in the batch!")
  
      # Max Video Len
      max_video_len = 0
      has_video = video_lengths[0] is not None
      if has_video:
          max_video_len = max(video_lengths).item()
  
      # Max Token Len
      max_tokens_len = max(tokens_lengths).item()
  
      video_signal, tokens = [], []
      for b in batch:
          if len(b) == 5:
              video_sig, video_sig_len, tokens_i, tokens_i_len, _ = b
          else:
              video_sig, video_sig_len, tokens_i, tokens_i_len = b
  
          # Pad and Append Video
          if has_video:
              video_sig_len = video_sig_len.item()
              if video_sig_len < max_video_len:
                  pad = (
                      0,
                      0,
                      0,
                      0,
                      0,
                      0,
                      0,
                      max_video_len - video_sig_len,
                  )
                  video_sig = torch.nn.functional.pad(video_sig, pad)
              video_signal.append(video_sig)
  
          # Pad and Append Token
          tokens_i_len = tokens_i_len.item()
          if tokens_i_len < max_tokens_len:
              pad = (0, max_tokens_len - tokens_i_len)
              tokens_i = torch.nn.functional.pad(
                  tokens_i, pad, value=pad_id
              )
          tokens.append(tokens_i)
  
      # Stack Video
      if has_video:
          video_signal = torch.stack(video_signal)
          video_lengths = torch.stack(video_lengths)
      else:
          video_signal, video_lengths = None, None
  
      # Stack Text
      tokens = torch.stack(tokens)
      tokens_lengths = torch.stack(tokens_lengths)
  
      # Return
      if sample_ids is None:
          return video_signal, video_lengths, tokens, tokens_lengths
      else:
          sample_ids = torch.tensor(sample_ids, dtype=torch.int32)
          return (
              video_signal,
              video_lengths,
              tokens,
              tokens_lengths,
              sample_ids,
          )
  
imports: import os
  from typing import Callable, Dict, Iterable, List, Optional, Tuple, Union
  import torch
  import webdataset
  from nemo.collections.asr.data.audio_to_text import cache_datastore_manifests, expand_sharded_filepaths
  from nemo.collections.asr.parts.utils.audio_utils import ChannelSelectorType
  from nemo.collections.common import tokenizers
  from nemo.collections.common.parts.preprocessing import collections, parsers
  from nemo.collections.multimodal.speech_cv.parts.preprocessing.features import VideoFeaturizer
  from nemo.core.classes import Dataset, IterableDataset
  from nemo.core.neural_types import *
  from nemo.utils import logging
label_desc: Use image node_id 1 for calling a global function with example usage: _video_speech_collate_fn(batch, pad_id) and returns: video_signal,  video_lengths,  tokens,  tokens_lengths, video_signal,  video_lengths,  tokens,  tokens_lengths,  sample_ids