docs: def run(self, output_path, device_config=None, bitrate=350 << 3 << 10,
              sink=None):
          '''
          Run webcam pipeline and optionally record the video to the specified
          output file path.
  
          __NB__ The output file container is determined based on the extension
          of the output file path.  Supported containers are `avi` and `mp4`.  In
          either case, the video is encoded in MPEG4 format.
  
          Arguments
          ---------
  
           - `output_path`: Output file path.
           - `device_config`:
             * Configuration dictionary or a `pandas.Series` in the format of a
               row of a frame returned by `caps.get_device_configs()`.
             * If not provided, the GStreamer `autovideosrc` is used.
           - `bitrate`: Target encode bit rate in bits/second (default=350kB/s)
          '''
          # Create GStreamer pipeline
          self.pipeline = Gst.Pipeline()
  
          # Create bus to get events from GStreamer pipeline
          self.bus = self.pipeline.get_bus()
          self.bus.add_signal_watch()
          self.bus.connect('message::error', self.on_error)
  
          # This is needed to make the video output in our DrawingArea:
          self.bus.enable_sync_message_emission()
  
          # Create GStreamer elements
          if device_config is None:
              self.src = Gst.ElementFactory.make('autovideosrc', 'source')
          else:
              self.src = get_video_source()
              device_key = get_video_device_key()
              self.src.set_property(device_key, device_config['device'])
          if sink is None:
              self.sink = Gst.ElementFactory.make('autovideosink', 'sink')
          else:
              self.sink = sink
          self.sink.set_property('sync', False)
  
          self.filter_ = Gst.ElementFactory.make('capsfilter', 'filter')
          tee = Gst.ElementFactory.make('tee', None)
  
          sink_queue = Gst.ElementFactory.make('queue', None)
          capture_queue = Gst.ElementFactory.make('queue', None)
          encoder = Gst.ElementFactory.make('avenc_mpeg4', None)
          encoder.set_property('bitrate', bitrate)
          encoder.set_property('bitrate-tolerance', 500 << 10)
          if path(output_path).ext.lower() == '.mp4':
              muxer = Gst.ElementFactory.make('mp4mux', None)
          elif path(output_path).ext.lower() == '.avi':
              muxer = Gst.ElementFactory.make('avimux', None)
          else:
              raise ValueError('Unsupported output file type: %s' %
                               path(output_path).ext)
          filesink = Gst.ElementFactory.make('filesink', None)
          filesink.set_property('location', output_path)
  
          videorate = Gst.ElementFactory.make('videorate', None)
          filter1 = Gst.ElementFactory.make('capsfilter', None)
          filter1.set_property('caps',
                               Gst.Caps('video/x-raw,framerate={framerate_numerator}/{framerate_denominator}'
                                        .format(**device_config)))
  
          caps = Gst.Caps(get_caps_str(device_config))
          self.filter_.set_property('caps', caps)
  
          src_elements = (self.src, self.filter_, videorate, filter1, tee)
          sink_elements = (sink_queue, self.sink)
          capture_elements = (capture_queue, encoder, muxer, filesink)
  
          # Add elements to the pipeline
          for d in src_elements + sink_elements + capture_elements:
              self.pipeline.add(d)
  
          for elements in (src_elements, sink_elements, capture_elements):
              for i, j in zip(elements[:-1], elements[1:]):
                  i.link(j)
  
          tee.link(sink_elements[0])
          tee.link(capture_elements[0])
  
  
          self.output_path = output_path
          self.tee = tee
          self.muxer = muxer
          self.src_elements = src_elements
          self.sink_elements = sink_elements
          self.capture_elements = capture_elements
  
          self.pipeline.set_state(Gst.State.PLAYING)
          self._alive = True