Index: wp-includes/class-wp-customize-manager.php
===================================================================
--- wp-includes/class-wp-customize-manager.php	(revision 38613)
+++ wp-includes/class-wp-customize-manager.php	(working copy)
@@ -2162,18 +2162,31 @@
 		/* Custom Header */
 
 		$this->add_section( 'header_image', array(
-			'title'          => __( 'Header Image' ),
+			'title'          => __( 'Site Header' ),
 			'theme_supports' => 'custom-header',
 			'priority'       => 60,
 		) );
 
+		$video_width = absint( get_theme_support( 'custom-header', 'video-width' ) );
+		$video_height = absint( get_theme_support( 'custom-header', 'video-height' ) );
+
+		$this->add_setting( 'header_video' );
+
+		$this->add_control( new WP_Customize_Media_Control( $this, 'header_video', array(
+			'default'        => get_theme_support( 'custom-header', 'default-video' ),
+			'mime_type'       => 'video',
+			'label'           => __( 'Header Video' ),
+			'description'     => sprintf( __( 'Displayed in place of the header image when provided. Keep the bitrate and filesize as low as possible for best results. Your theme recommends %s for video.' ),
+				sprintf( '<strong>%s &times; %s</strong>', $video_width, $video_height  )),
+			'section'         => 'header_image',
+		) ) );
+
 		$this->add_setting( new WP_Customize_Filter_Setting( $this, 'header_image', array(
 			'default'        => get_theme_support( 'custom-header', 'default-image' ),
 			'theme_supports' => 'custom-header',
 		) ) );
 
 		$this->add_setting( new WP_Customize_Header_Image_Setting( $this, 'header_image_data', array(
-			// 'default'        => get_theme_support( 'custom-header', 'default-image' ),
 			'theme_supports' => 'custom-header',
 		) ) );
 
Index: wp-includes/theme.php
===================================================================
--- wp-includes/theme.php	(revision 38613)
+++ wp-includes/theme.php	(working copy)
@@ -1264,6 +1264,9 @@
 		'thumbnail_url' => '',
 		'width'         => get_theme_support( 'custom-header', 'width' ),
 		'height'        => get_theme_support( 'custom-header', 'height' ),
+		'video_url'		  => get_header_video(),
+		'video_width'   => get_theme_support( 'custom-header', 'video-width' ),
+		'video_height'  => get_theme_support( 'custom-header', 'video-height' ),
 	);
 	return (object) wp_parse_args( $data, $default );
 }
@@ -1311,6 +1314,132 @@
 }
 
 /**
+ * Check whether a header video is set or not.
+ *
+ * @since 4.7.0
+ *
+ * @see get_header_video()
+ *
+ * @return bool Whether a header video is set or not.
+ */
+function has_header_video() {
+	return (bool) get_header_video();
+}
+
+/* Retrieve header video for custom header.
+*
+* @since 4.7.0
+*
+* @return string|false
+*/
+function get_header_video() {
+	$url = get_theme_mod( 'header_video' );
+
+	if ( 'remove-header' == $url )
+		return false;
+
+	if ( $url ) {
+		// We have an attachment ID, need the full URL
+		$url = wp_get_attachment_url( $url );
+	} else {
+		// Fallback to the theme's default video
+		$url = get_theme_support( 'custom-header', 'default-video' );
+	}
+
+	return esc_url_raw( set_url_scheme( $url ) );
+}
+
+/**
+ * Create video tag markup for a custom header video.
+ *
+ * @since 4.7.0
+ *
+ * @param array $attr Optional. Additional attributes for the image tag. Can be used
+ *                              to override the default attributes. Default empty.
+ * @return string HTML image element markup or empty string on failure.
+ */
+function get_header_video_tag( $attr = array() ) {
+	$header = get_custom_header();
+
+	if ( empty( $header->video_url ) ) {
+		return '';
+	}
+
+	$width = absint( $header->width );
+	$height = absint( $header->height );
+
+	$attr = wp_parse_args(
+		$attr,
+		array(
+			'src' => $header->video_url,
+			'autoplay' => true,
+			'loop' => true,
+			'muted' => true,
+		)
+	);
+
+	$attr = array_map( 'esc_attr', $attr );
+	$html = '<video';
+
+	foreach ( $attr as $name => $value ) {
+		$html .= ' ' . $name . '="' . $value . '"';
+	}
+
+	$html .= '></video>';
+
+	/**
+	 * Filters the markup of header videos.
+	 *
+	 * @since 4.7.0
+	 *
+	 * @param string $html   The HTML image tag markup being filtered.
+	 * @param object $header The custom header object returned by 'get_custom_header()'.
+	 * @param array  $attr   Array of the attributes for the image tag.
+	 */
+	return apply_filters( 'get_header_video_tag', $html, $header, $attr );
+}
+
+/**
+ * Display the video markup for a custom header video.
+ *
+ * @since 4.7.0
+ *
+ * @param array $attr Optional. Attributes for the image markup. Default empty.
+ */
+function the_header_video_tag( $attr = array() ) {
+	echo get_header_video_tag( $attr );
+}
+
+/**
+ * Display header video URL.
+ *
+ * @since 4.7.0
+ */
+function header_video() {
+	$video = get_header_video();
+	if ( $video ) {
+		echo esc_url( $video );
+	}
+}
+
+/**
+ * Determines if a image or video tag should be returned.
+ *
+ * @since 4.7.0
+ */
+function get_header_tag() {
+	$header = get_custom_header();
+
+	if ( $header->video_url ) {
+		return get_header_video_tag();
+	} else if ( $header->url ) {
+		return get_header_image_tag();
+	}
+
+	return '';
+}
+
+/**
  * Retrieve background image for custom background.
  *
  * @since 3.0.0
@@ -1623,6 +1752,9 @@
 				'wp-head-callback' => '',
 				'admin-head-callback' => '',
 				'admin-preview-callback' => '',
+				'default-video' => '',
+				'video-height' => 0,
+				'video-width' => 0,
 			);
 
 			$jit = isset( $args[0]['__jit'] );
@@ -1672,6 +1804,21 @@
 			if ( $jit && ! empty( $args[0]['default-image'] ) )
 				$args[0]['random-default'] = false;
 
+			if ( defined( 'HEADER_VIDEO_WIDTH' ) )
+				$args[0]['video-width'] = (int) HEADER_VIDEO_WIDTH;
+			elseif ( isset( $args[0]['video-width'] ) )
+				define( 'HEADER_VIDEO_WIDTH', (int) $args[0]['video-width'] );
+
+			if ( defined( 'HEADER_VIDEO_HEIGHT' ) )
+				$args[0]['video-height'] = (int) HEADER_VIDEO_HEIGHT;
+			elseif ( isset( $args[0]['video-height'] ) )
+				define( 'HEADER_VIDEO_HEIGHT', (int) $args[0]['video-height'] );
+
+			if ( defined( 'HEADER_VIDEO' ) )
+				$args[0]['default-video'] = HEADER_VIDEO;
+			elseif ( isset( $args[0]['default-video'] ) )
+				define( 'HEADER_VIDEO', $args[0]['default-video'] );
+
 			// If headers are supported, and we still don't have a defined width or height,
 			// we have implicit flex sizes.
 			if ( $jit ) {
@@ -2082,7 +2229,7 @@
 		return;
 	}
 
-	require_once ABSPATH . WPINC . '/class-wp-customize-manager.php'; 
+	require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
 	$GLOBALS['wp_customize'] = new WP_Customize_Manager();
 }
 
