Index: wp-includes/theme.php
===================================================================
--- wp-includes/theme.php	(revision 38713)
+++ wp-includes/theme.php	(working copy)
@@ -1264,6 +1264,7 @@
 		'thumbnail_url' => '',
 		'width'         => get_theme_support( 'custom-header', 'width' ),
 		'height'        => get_theme_support( 'custom-header', 'height' ),
+		'video'         => get_theme_support( 'custom-header', 'video' ),
 	);
 	return (object) wp_parse_args( $data, $default );
 }
@@ -1311,6 +1312,138 @@
 }
 
 /**
+ * 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 );
+	}
+
+	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();
+	$video = get_header_video();
+	$image = get_header_image();
+
+	if ( empty( $video ) ) {
+		return '';
+	}
+
+	$width = absint( $header->width );
+	$height = absint( $header->height );
+
+	$attr = wp_parse_args(
+		$attr,
+		array(
+			'src' => get_header_video(),
+			'width' => $width,
+			'height' => $height,
+			'controls' => '',
+			'autoplay' => '',
+			'loop' => '',
+			'muted' => '',
+		)
+	);
+
+	// Use the header image as poster attribute.
+	if ( ! empty( $image ) ) {
+		$attr['poster'] = $header->url;
+	}
+
+	$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 the_header_video() {
+	$video = get_header_video();
+	if ( $video ) {
+		echo esc_url( $video );
+	}
+}
+
+/**
+ * Display the video and image markup for a custom header.
+ *
+ * @since 4.7.0
+ */
+function the_custom_header() {
+	$video = get_header_video();
+	$image = get_header_image();
+
+	if ( ! empty( $video ) ) {
+		the_header_video_tag();
+	} elseif ( ! empty( $image ) ) {
+		the_header_image_tag();
+	}
+}
+
+/**
  * Retrieve background image for custom background.
  *
  * @since 3.0.0
@@ -1623,6 +1756,7 @@
 				'wp-head-callback' => '',
 				'admin-head-callback' => '',
 				'admin-preview-callback' => '',
+				'video' => false,
 			);
 
 			$jit = isset( $args[0]['__jit'] );
@@ -2082,7 +2216,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();
 }
 
