code: def replace_with_background(
      video_path: str,
      output_path: Optional[str] = None,
      background_path: Optional[str] = None,
      source_offset: float = 0.0,
      background_offset: float = 0.0,
      source_percentage: float = 0.5,
      transition: Optional[af.TransitionConfig] = None,
      metadata: Optional[List[Dict[str, Any]]] = None,
  ) -> str:
      """
      Replaces the beginning and end of the source video with the background video, keeping the
      total duration of the output video equal to the original duration of the source video
  
      @param video_path: the path to the video to be augmented
  
      @param output_path: the path in which the resulting video will be stored. If not
          passed in, the original video file will be overwritten
  
      @param background_path: the path to the video in which to insert the main video.
          If set to None, the main video will play in the middle of a silent video with
          black frames
  
      @param source_offset: the starting point where the background video transitions to
          the source video. Prior to this point, the source video is replaced with the
          background video. A value of 0 means all background is at the beginning. A value
          of 1 means all background is at the end of the video
  
      @param background_offset: the starting point from which the background video starts
          to play, as a proportion of the background video duration (i.e. this factor is
          multiplied by the background video duration to determine the start point)
  
      @param source_percentage: the percentage of the source video that remains unreplaced
          by the background video. The source percentage plus source offset should be less
          than 1. If it is greater, the output video duration will be longer than the source.
          If the background video is not long enough to get the desired source percentage,
          it will be looped
  
      @param transition: optional transition configuration to apply between the clips
  
      @param metadata: if set to be a list, metadata about the function execution including
          its name, the source & dest duration, fps, etc. will be appended to the inputted
          list. If set to None, no metadata will be appended or returned
  
      @returns: the path to the augmented video
      """
      assert (
          0.0 <= source_offset <= 1.0
      ), "Source offset factor must be a value in the range [0.0, 1.0]"
  
      assert (
          0.0 <= background_offset <= 1.0
      ), "Background offset factor must be a value in the range [0.0, 1.0]"
  
      assert (
          0.0 <= source_percentage <= 1.0
      ), "Source percentage must be a value in the range [0.0, 1.0]"
  
      func_kwargs = helpers.get_func_kwargs(
          metadata, locals(), video_path
      )
      local_path = utils.pathmgr.get_local_path(video_path)
      utils.validate_video_path(local_path)
  
      video_info = helpers.get_video_info(video_path)
      video_duration = float(video_info["duration"])
      width, height = video_info["width"], video_info["height"]
  
      video_paths = []
      with tempfile.TemporaryDirectory() as tmpdir:
          tmp_video_path = os.path.join(tmpdir, "in.mp4")
          resized_bg_path = os.path.join(tmpdir, "bg.mp4")
  
          # create bg video
          if background_path is None:
              helpers.create_color_video(
                  resized_bg_path, video_duration, height, width
              )
          else:
              resize(background_path, resized_bg_path, height, width)
              helpers.add_silent_audio(resized_bg_path)
  
          bg_video_info = helpers.get_video_info(resized_bg_path)
          bg_video_duration = float(bg_video_info["duration"])
          src_video_path_index = 1
  
          final_bg_len = video_duration * (1 - source_percentage)
          # if desired bg video too short, loop bg video
          num_loops_needed = math.ceil(final_bg_len / bg_video_duration)
          if num_loops_needed > 1:
              loop(resized_bg_path, num_loops=num_loops_needed)
  
          first_bg_segment_len = source_offset * final_bg_len
          last_bg_segment_len = final_bg_len - first_bg_segment_len
          # calculate bg start and end times of bg in output video
          bg_start = background_offset * bg_video_duration
          src_start = first_bg_segment_len
          src_length = source_percentage * video_duration
          src_end = src_start + src_length
  
          # add pre src background segment
          if source_offset > 0:
              before_path = os.path.join(tmpdir, "before.mp4")
              trim(
                  resized_bg_path,
                  before_path,
                  start=bg_start,
                  end=bg_start + first_bg_segment_len,
              )
              video_paths.append(before_path)
              src_video_path_index = 1
          else:
              src_video_path_index = 0
  
          # trim source to length satisfying source_percentage
          helpers.add_silent_audio(video_path, tmp_video_path)
          trimmed_src_path = os.path.join(tmpdir, "trim_src.mp4")
          trim(
              tmp_video_path,
              trimmed_src_path,
              start=src_start,
              end=src_end,
          )
          video_paths.append(trimmed_src_path)
  
          # add post src background segment
          if source_offset < 1:
              after_path = os.path.join(tmpdir, "after.mp4")
              trim(
                  resized_bg_path,
                  after_path,
                  start=bg_start + src_start,
                  end=bg_start + src_start + last_bg_segment_len,
              )
              video_paths.append(after_path)
  
          concat(
              video_paths,
              output_path or video_path,
              src_video_path_index,
              transition=transition,
          )
  
      if metadata is not None:
          helpers.get_metadata(
              metadata=metadata,
              function_name="replace_with_background",
              starting_background_duration=first_bg_segment_len,
              source_duration=src_length,
              ending_background_duration=last_bg_segment_len,
              **func_kwargs,
          )
  
      return output_path or video_path
  
imports: import functools
  import math
  import os
  import shutil
  import tempfile
  from typing import Any, Callable, Dict, List, Optional, Tuple, Union
  import numpy
  from augly import audio, image, utils
  from augly.audio import utils
  from augly.video import helpers, utils
  from augly.video.augmenters import cv2, ffmpeg
label_desc: Use image node_id 21 for calling a global function with example usage: replace_with_background(video_path, output_path, background_path, source_offset, background_offset, source_percentage, transition, metadata) and returns: unknown