diff --git anon-upload-template.php anon-upload-template.php
index 68be0b8..949d4b9 100644
--- anon-upload-template.php
+++ anon-upload-template.php
@@ -61,6 +61,7 @@ function anon_upload_css() {
 
 	.video-upload p {
 		margin: 16px 0;
+		overflow: auto;
 	}
 
 	.video-upload h3 {
@@ -214,6 +215,9 @@ if ( !empty($_REQUEST['error']) ) {
 		case 13:
 			$message = "Error: please leave the first field empty. (It helps us know you're not a spammer.)";
 			break;
+		case 14:
+			$message = "Error: please enter a valid WordPress.org username for the producer, or leave the field empty.";
+			break;
 	}
 	$message = '<div class="error"><p>' . $message . '</p></div>';
 } elseif ( !empty($_REQUEST['success']) ) {
@@ -314,8 +318,8 @@ if ( !empty($_REQUEST['error']) ) {
 	</div>
 
 	<p>
-		<label for="wptv_video_producer"><?php esc_html_e( 'Video producer' ); ?></label>
-		<input type="text" id="wptv_video_producer" name="wptv_video_producer" value="" />
+		<label for="wptv_producer_username"><?php esc_html_e( 'Producer WordPress.org Username' ); ?></label>
+		<input type="text" id="wptv_producer_username" name="wptv_producer_username" value="" />
 	</p>
 	<p>
 		<label for="wptv_speakers"><?php esc_html_e( 'Speakers' ); ?></label>
diff --git functions.php functions.php
index 9f6d785..7007f48 100644
--- functions.php
+++ functions.php
@@ -28,7 +28,7 @@ class WordPressTV_Theme {
 		add_action( 'init', array( $this, 'improve_search' ) );
 		add_action( 'publish_post', array( $this, 'publish_post' ), 10, 1 );
 		add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
-		add_action( 'save_post', array( $this, 'save_meta_box_fields' ), 10, 2);
+		add_action( 'save_post', array( $this, 'save_meta_box_fields' ), 10, 2 );
 		add_action( 'wp_footer', array( $this, 'videopress_flash_params' ) );
 		add_action( 'transition_post_status', array( $this, 'transition_post_status' ), 10, 2 );
 
@@ -78,6 +78,15 @@ class WordPressTV_Theme {
 			'rewrite'  => array( 'slug' => 'producer' ),
 		) );
 
+		register_taxonomy( 'producer-username', array( 'post' ), array(
+			'label'    => __( 'Producer Username', 'wptv' ),
+			'template' => __( 'Producer: %l.', 'wptv' ),
+			'helps'    => __( 'Separate producer usernames with commas.', 'wptv' ),
+			'sort'     => true,
+			'args'     => array( 'orderby' => 'term_order' ),
+			'rewrite'  => array( 'slug' => 'producer-username' ),
+		) );
+
 		register_taxonomy( 'speakers', array( 'post' ), array(
 			'label'    => __( 'Speakers', 'wptv' ),
 			'template' => __( 'Speakers: %l.', 'wptv' ),
@@ -154,7 +163,10 @@ class WordPressTV_Theme {
 	 * Register meta boxes
 	 */
 	function add_meta_boxes() {
-		add_meta_box( 'video-info', 'Video Info', array( $this, 'render_video_info_metabox' ), 'post', 'normal', 'high' );
+		add_meta_box( 'video-info', 'Video Info', array(
+				$this,
+				'render_video_info_metabox'
+			), 'post', 'normal', 'high' );
 	}
 
 	/**
@@ -170,10 +182,10 @@ class WordPressTV_Theme {
 
 		<p>
 			<label for="wptv-slides-url">Slides URL</label>
-			<input type="text" class="widefat" id="wptv-slides-url" name="_wptv_slides_url" value="<?php echo esc_url( $slides_url ); ?>" />
+			<input type="text" class="widefat" id="wptv-slides-url" name="_wptv_slides_url"
+			       value="<?php echo esc_url( $slides_url ); ?>"/>
 		</p>
-
-		<?php
+	<?php
 	}
 
 	/**
@@ -226,6 +238,7 @@ class WordPressTV_Theme {
 		 *
 		 * Maybe look at ways to do the sorting in PHP, or just use Elasticsearch instead.
 		 */
+
 		return;
 
 		if ( ! $query->is_main_query() || ! $query->is_search ) {
@@ -405,14 +418,15 @@ class WordPressTV_Theme {
 			<?php if ( $comment->comment_type != 'pingback' ) : ?>
 
 				<small class="commentmetadata">
-					<a href="#comment-<?php comment_ID() ?>" title=""><?php printf( __( '%1$s at %2$s', 'wptv' ), get_comment_date(), get_comment_time() ); ?></a>
+					<a href="#comment-<?php comment_ID() ?>"
+					   title=""><?php printf( __( '%1$s at %2$s', 'wptv' ), get_comment_date(), get_comment_time() ); ?></a>
 					<?php
-						edit_comment_link( __( 'edit', 'wptv' ), '&nbsp;&nbsp;', '' );
-						echo comment_reply_link( array(
-							'depth'     => $depth,
-							'max_depth' => $args['max_depth'],
-							'before'    => ' | ',
-						) );
+					edit_comment_link( __( 'edit', 'wptv' ), '&nbsp;&nbsp;', '' );
+					echo comment_reply_link( array(
+						'depth'     => $depth,
+						'max_depth' => $args['max_depth'],
+						'before'    => ' | ',
+					) );
 					?>
 				</small>
 
@@ -514,7 +528,7 @@ class WordPressTV_Theme {
 		foreach ( $matches[1] as $key => $code ) {
 			$code   = '[vodpod ' . $code . ']';
 			$vodpod = apply_filters( 'the_content', $code );
-			$id     = trim( str_replace( '</div>','', preg_replace( '/.*key\=([^&]+)&.*/', '$1', $vodpod ) ) );
+			$id     = trim( str_replace( '</div>', '', preg_replace( '/.*key\=([^&]+)&.*/', '$1', $vodpod ) ) );
 
 			$image = $this->get_vodpod_thumbnails( $code );
 			$video = $vodpod;
@@ -548,7 +562,7 @@ class WordPressTV_Theme {
 		foreach ( $matches[1] as $key => $code ) {
 			preg_match( '/([0-9A-Za-z]+)/i', $code, $m );
 			$guid = $m[1];
-			$ret = video_image_url_by_guid( $guid, 'fmt_dvd' );
+			$ret  = video_image_url_by_guid( $guid, 'fmt_dvd' );
 		}
 
 		preg_match_all( '|\[wporg-screencast (.+?)]|ie', $post->post_content, $matches );
@@ -745,16 +759,17 @@ class WordCampTV_Walker_Nav_Menu extends Walker {
 		<div>
 			<h3>
 				<?php echo apply_filters( 'the_title', $item->title ); ?>
-				<a href="<?php echo esc_url( $item->url ); ?>" class="view-more"><?php esc_html_e( 'More &rarr;' ); ?></a>
+				<a href="<?php echo esc_url( $item->url ); ?>"
+				   class="view-more"><?php esc_html_e( 'More &rarr;' ); ?></a>
 			</h3>
 			<ul class="video-list four-col">
 				<?php while ( $query->have_posts() ) : $query->the_post(); ?>
-				<li>
-					<a href="<?php the_permalink(); ?>">
-						<span class="video-thumbnail"><?php $wptv->the_video_image( 50, null, false ); ?></span>
-						<span class="video-title"><?php the_title(); ?></span>
-					</a>
-				</li>
+					<li>
+						<a href="<?php the_permalink(); ?>">
+							<span class="video-thumbnail"><?php $wptv->the_video_image( 50, null, false ); ?></span>
+							<span class="video-title"><?php the_title(); ?></span>
+						</a>
+					</li>
 				<?php endwhile; ?>
 			</ul>
 		</div>
@@ -776,6 +791,7 @@ function wptv_enqueue_scripts() {
 		wp_enqueue_script( 'comment-reply' );
 	}
 }
+
 add_action( 'wp_enqueue_scripts', 'wptv_enqueue_scripts' );
 
 /**
@@ -810,6 +826,7 @@ function wptv_wp_title( $title, $sep ) {
 
 	return $title;
 }
+
 add_filter( 'wp_title', 'wptv_wp_title', 10, 2 );
 
 /**
@@ -828,4 +845,29 @@ function wptv_excerpt_slides( $excerpt ) {
 
 	return $excerpt;
 }
+
 add_filter( 'get_the_excerpt', 'wptv_excerpt_slides' );
+
+/**
+ * Checks if the given username exists on WordPress.org
+ *
+ * grav-redirect.php will redirect to a Gravatar image URL. If the WordPress.org username exists, the `d` parameter
+ * will be 'retro', and if it doesn't it'll be 'mm'.
+ *
+ * @param string $username
+ *
+ * @return bool
+ */
+function wporg_username_exists( $username ) {
+	$username_exists = false;
+	$validator_url   = add_query_arg( 'user', $username, 'https://wordpress.org/grav-redirect.php' );
+	$response        = wp_remote_retrieve_headers( wp_remote_get( $validator_url, array( 'redirection' => 0 ) ) );
+
+	if ( array_key_exists( 'location', $response ) ) {
+		if ( false === strpos( $response['location'], 'd=mm' ) ) {
+			$username_exists = true;
+		}
+	}
+
+	return $username_exists;
+}
diff --git plugins/wordpresstv-anon-upload/anon-upload.php plugins/wordpresstv-anon-upload/anon-upload.php
index 18bca59..92390e0 100644
--- plugins/wordpresstv-anon-upload/anon-upload.php
+++ plugins/wordpresstv-anon-upload/anon-upload.php
@@ -47,7 +47,7 @@ class WPTV_Anon_Upload {
 	function validate() {
 		$text_fields = array(
 			'wptv_video_title',
-			'wptv_video_producer',
+			'wptv_producer_username',
 			'wptv_speakers',
 			'wptv_event',
 			'wptv_slides_url'
@@ -62,6 +62,10 @@ class WPTV_Anon_Upload {
 			return $this->error( 13 );
 		}
 
+		if ( empty( $_POST['wptv_producer_username'] ) || ! wporg_username_exists( $_POST['wptv_producer_username'] ) ) {
+			return $this->error( 14 );
+		}
+
 		if ( ! is_user_logged_in() ) {
 			if ( empty( $_POST['wptv_uploaded_by'] ) ) {
 				return $this->error( 10 );
@@ -269,14 +273,14 @@ class WPTV_Anon_Upload {
 			$anon_author_email = $this->sanitize_text( $_posted['wptv_email'] );
 		}
 
-		$video_title    = $this->sanitize_text( $_posted['wptv_video_title'] );
-		$video_producer = $this->sanitize_text( $_posted['wptv_video_producer'] );
-		$speakers       = $this->sanitize_text( $_posted['wptv_speakers'] );
-		$event          = $this->sanitize_text( $_posted['wptv_event'] );
-		$description    = $this->sanitize_text( $_posted['wptv_video_description'], false );
-		$language       = $this->sanitize_text( $_posted['wptv_language'] );
-		$slides         = $this->sanitize_text( $_posted['wptv_slides_url'] );
-		$ip             = $_SERVER['REMOTE_ADDR'];
+		$video_title       = $this->sanitize_text( $_posted['wptv_video_title'] );
+		$producer_username = $this->sanitize_text( $_posted['wptv_producer_username'] );
+		$speakers          = $this->sanitize_text( $_posted['wptv_speakers'] );
+		$event             = $this->sanitize_text( $_posted['wptv_event'] );
+		$description       = $this->sanitize_text( $_posted['wptv_video_description'], false );
+		$language          = $this->sanitize_text( $_posted['wptv_language'] );
+		$slides            = $this->sanitize_text( $_posted['wptv_slides_url'] );
+		$ip                = $_SERVER['REMOTE_ADDR'];
 
 		$categories = '';
 		if ( ! empty( $_posted['post_category'] ) && is_array( $_posted['post_category'] ) ) {
@@ -289,18 +293,18 @@ class WPTV_Anon_Upload {
 		}
 
 		$post_meta = array(
-			'attachment_id'   => $attachment_id,
-			'submitted_by'    => $anon_author,
-			'submitted_email' => $anon_author_email,
-			'title'           => $video_title,
-			'producer'        => $video_producer,
-			'speakers'        => $speakers,
-			'event'           => $event,
-			'language'        => $language,
-			'categories'      => $categories,
-			'description'     => $description,
-			'slides'          => $slides,
-			'ip'              => $ip,
+			'attachment_id'     => $attachment_id,
+			'submitted_by'      => $anon_author,
+			'submitted_email'   => $anon_author_email,
+			'title'             => $video_title,
+			'producer_username' => $producer_username,
+			'speakers'          => $speakers,
+			'event'             => $event,
+			'language'          => $language,
+			'categories'        => $categories,
+			'description'       => $description,
+			'slides'            => $slides,
+			'ip'                => $ip,
 		);
 
 		$post_meta['video_guid'] = $video_data->guid;
@@ -335,9 +339,12 @@ class WPTV_Anon_Upload {
 		$embed_args['blog_id'] = get_current_blog_id();
 		$embed_args['post_id'] = $meta['attachment_id'];
 
-		// Add slides index to meta (necessary for posts that were uploaded before the field was added)
-		if ( ! array_key_exists( 'slides', $meta ) ) {
-			$meta['slides'] = '';
+		// Add missing indexes to $meta (necessary for posts that were uploaded before the fields were added)
+		$new_fields = array( 'slides', 'producer_username' );
+		foreach ( $new_fields as $field ) {
+			if ( ! array_key_exists( $field, $meta ) ) {
+				$meta[ $field ] = '';
+			}
 		}
 
 		?>
@@ -471,10 +478,11 @@ class WPTV_Anon_Upload {
 					</div>
 
 					<div class="row">
-						<p class="label">Producer:</p>
+						<p class="label">Producer WordPress.org Username:</p>
+
 						<p class="data">
-							<input type="text" value="<?php echo esc_attr( $meta['producer'] ); ?>"/>
-							<a class="button-secondary anon-approve" href="#new-tag-producer">Approve</a>
+							<input type="text" value="<?php echo esc_attr( $meta['producer_username'] ); ?>"/>
+							<a class="button-secondary anon-approve" href="#new-tag-producer-username">Approve</a>
 						</p>
 					</div>
 
diff --git sidebar-single.php sidebar-single.php
index 84a2fe6..deb288d 100644
--- sidebar-single.php
+++ sidebar-single.php
@@ -81,5 +81,41 @@
 						printf( '<a href="%s">Subtitle this video &rarr;</a>', esc_url( add_query_arg( 'video', $video->post_id, home_url( 'subtitle/' ) ) ) );
 					}
 				}
+
+			/*
+			 * Credit video producer with link to their WordPress.org profile
+			 *
+			 * In most cases we'll either have the producer name, or the username, but not both.
+			 */
+			$producer_username = get_the_terms( get_the_ID(), 'producer-username' );
+			$producer_name = get_the_terms( get_the_ID(), 'producer' );
 			?>
+
+			<?php if ( $producer_name || $producer_username ) : ?>
+				<h5>Producer</h5>
+
+				<div class="video-producer">
+					<?php if ( $producer_username && $producer_name ) : ?>
+						<?php $producer_username = $producer_username[0]->name; ?>
+						<a href="<?php echo esc_url( 'https://profiles.wordpress.org/' . rawurlencode( $producer_username ) ); ?>">
+							<?php echo esc_html( $producer_name[0]->name ); ?>
+						</a>
+
+					<?php elseif ( $producer_username ) : ?>
+
+						<?php $producer_username = $producer_username[0]->name; ?>
+						<a href="<?php echo esc_url( 'https://profiles.wordpress.org/' . rawurlencode( $producer_username ) ); ?>">
+							<?php echo esc_html( $producer_username ); ?>
+						</a>
+
+					<?php else : ?>
+
+						<a href="<?php echo esc_url( get_term_link( $producer_name[0] ) ); ?>">
+							<?php echo esc_html( $producer_name[0]->name ); ?>
+						</a>
+
+					<?php endif; ?>
+				</div>
+			<?php endif; ?>
+
 </div><!-- .secondary-content -->
