Handling custom parsing and importing with Feeds
I finally got everything to work with some code voodoo and changing parsers. One thing that I didn't add to the original question above as an edit was the fact that using the common syndication parser, my custom items that I added to the source feed were never available. I then switched to using the SimplePie parser, and was able to extend that functionality to do what I need.

According to the Feeds module documentation for developers and this blog post, you can do some custom parsing by overriding the parseExtensions() method of FeedsSimplePieParser class. First, you have to declare the class with hook_feeds_plugins():

/**
 * Implementation of hook_feeds_plugins().
 */
function mymodule_feeds_plugins() {
  $info = array();

  $info['MyModuleFeedsParser'] = array(
    'name' =&gt; 'Custom Parser',
    'description' =&gt; 'Custom parser for my video import.',
    'handler' =&gt; array(
      'parent' =&gt; 'FeedsSimplePieParser',
      'class' =&gt; 'MyModuleFeedsParser',
      'file' =&gt; 'MyModuleFeedsParser.inc',
      'path' =&gt; drupal_get_path('module', 'mymodule') . '/plugins/feeds/',
    ),
  );
  return $info;
}


You also want to implement hook_enable to clear caches.

/**
 * Implementation of hook_enable.
 */
function mymodule_enable() {
  //clear the cache to display in Feeds as available plugin.
  cache_clear_all('plugins:feeds:plugins', 'cache');
}


Next you create the class.

/**
 * Custom Feeds parser class used to parse custom info from source site video feed.
 */

class MyModuleFeedsParser extends FeedsSimplePieParser {
  /**
   * Add the extra mapping sources provided by this parser.
   */
  public function getMappingSources() {
    return parent::getMappingSources() + array(
      'source-nid' =&gt; array(
        'name' =&gt; t('Video NID - SimplePie'),
        'description' =&gt; t('.'),
      ),
      'channel-map' =&gt; array(
        'name' =&gt; t('Channel Map - SimplePie'),
        'description' =&gt; t('Target Channel tid - SimplePie.'),
      ),
    );
  }

  /**
   * Parse the extra mapping sources provided by this parser.
   */
  protected function parseExtensions(&amp;$item, $simplepie_item) {
    if ($value = $simplepie_item-&gt;get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'source-nid')) {
      $item['source-nid'] = $value[0]['data'];
    }
    if ($value = $simplepie_item-&gt;get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel-map')) {
      $item['channel-map'] = $value[0]['data'];
    }
    // Filter out non-Tags terms.
    $categories = $simplepie_item-&gt;get_categories();
    // Cycle through the categories and delete any items
    // in feed item that aren't tags. The array id values
    // are synchronized between $categories and $item['tags'].
    foreach($categories as $id =&gt; $category) {
      if (!strstr($category-&gt;scheme, '/tag/')) {
        unset($item['tags'][$id]);
      }
    }
  }
}


This code does a few things:


getMappingSources() creates a couple sources that are available for mapping. You set these in your importer settings for your processor.
Gets the source-nid value from the feed source and add it to the item.
Gets the channel-map value from the feed source and add it to the item.
Filters out the non-tags terms from the categories (aka taxonomy terms). The scheme value is the URL to the taxonomy term (e.g. mysite.com/tag/tag-term), so I use that to identify non-tag terms and unset them.


Finally, I have to create the values for the video field and the Channel vocabulary. This is done with some custom callbacks defined in hook_feeds_node_processor_targets_alter().

/**
 * Implements hook_feeds_node_processor_targets_alter().
 */
function mymodule_feeds_node_processor_targets_alter(&amp;$targets, $entity_type, $bundle_name) {
  $targets['field_source_url'] = array(
    'name' =&gt; 'Source Video URL',
    'description' =&gt; 'The URL of the source video',
    'callback' =&gt; 'mymodule_feeds_set_source_url',
  );

  $targets['channel'] = array(
    'name' =&gt; 'Target Channel',
    'description' =&gt; 'The target video channel',
    'callback' =&gt; 'mymodule_feeds_set_channel_target',
  );
}


And the callbacks themselves:

/**
 * Custom callback to set the video source URL in field_video.
 *
 * @param $node - The node object being built.
 * @param $target - The target field.
 * @param $value - The field value from the feed.
 */
function mymodule_feeds_set_source_url(&amp;$node, $target, $value) {
  $source_url = variable_get('emvideo_source_domain', '') . '/node/' . $value;
  $node-&gt;field_video[0]['embed'] = $source_url;
}

/**
 * Custom callback to set the target vocabulary term.
 *
 * @param $node - The node object being built.
 * @param $target - The target field.
 * @param $value - The field value from the feed.
 */
function mymodule_feeds_set_channel_target(&amp;$node, $target, $value) {
  $term = taxonomy_get_term($value);
  $node-&gt;taxonomy[(int)$value] = $term;
}


You then define these as targets in your Processor mapping (to coincide with the Source values above), and you're good to go.