Index: src/wp-includes/theme.php
===================================================================
--- src/wp-includes/theme.php	(revision 39232)
+++ src/wp-includes/theme.php	(working copy)
@@ -1400,7 +1400,7 @@
  * @return bool True if a custom header is set. False if not.
  */
 function has_custom_header() {
-	if ( has_header_image() || ( is_front_page() && has_header_video() ) ) {
+	if ( has_header_image() || ( has_header_video() && is_header_video_active() ) ) {
 		return true;
 	}
 
@@ -1408,6 +1408,36 @@
 }
 
 /**
+ * Checks whether the custom header video is eligible to show on the current page.
+ *
+ * @since 4.7.0
+ *
+ * @return bool True if the custom header video should be shown. False if not.
+ */
+function is_header_video_active() {
+	if ( ! get_theme_support( 'custom-header', 'video' ) ) {
+		return false;
+	}
+
+	$video_active_cb = get_theme_support( 'custom-header', 'video-active-callback' );
+
+	if ( empty( $video_active_cb ) || ! is_callable( $video_active_cb ) ) {
+		$show_video = true;
+	} else {
+		$show_video = call_user_func( $video_active_cb );
+	}
+
+	/**
+	 * Modify whether the custom header video is eligible to show on the current page.
+	 *
+	 * @since 4.7.0
+	 *
+	 * @param bool $show_video Whether the custom header video should be shown. Defaults to the value of the theme setting for the `custom-header`'s `video-active-callback`. If no callback is set, the default value is that of `is_front_page()`.
+	 */
+	return apply_filters( 'is_header_video_active', $show_video );
+}
+
+/**
  * Retrieve the markup for a custom header.
  *
  * The container div will always be returned in the Customizer preview.
@@ -1442,7 +1472,7 @@
 
 	echo $custom_header;
 
-	if ( is_front_page() && ( has_header_video() || is_customize_preview() ) ) {
+	if ( is_header_video_active() && ( has_header_video() || is_customize_preview() ) ) {
 		wp_enqueue_script( 'wp-custom-header' );
 		wp_localize_script( 'wp-custom-header', '_wpCustomHeaderSettings', get_header_video_settings() );
 	}
@@ -2058,6 +2088,7 @@
 				'admin-head-callback' => '',
 				'admin-preview-callback' => '',
 				'video' => false,
+				'video-active-callback' => 'is_front_page',
 			);
 
 			$jit = isset( $args[0]['__jit'] );
Index: tests/phpunit/tests/theme/support.php
===================================================================
--- tests/phpunit/tests/theme/support.php	(revision 39232)
+++ tests/phpunit/tests/theme/support.php	(working copy)
@@ -191,4 +191,136 @@
 		$this->assertEmpty( get_registered_nav_menus() );
 		$this->assertFalse( current_theme_supports( 'menus' ) );
 	}
+
+	/**
+	 * @ticket 38738
+	 */
+	function test_video_header_callback_front_page_from_front_page() {
+		// Back up theme features global to avoid poisoning later tests.
+		global $_wp_theme_features;
+		$_wp_theme_features_backup = $_wp_theme_features;
+
+		add_theme_support( 'custom-header', array(
+			'video' => true,
+			'__jit' => true, // Force refresh.
+		) );
+
+		$this->go_to( home_url() );
+
+		$result = is_header_video_active();
+
+		// Restore theme features global to initial state.
+		$_wp_theme_features = $_wp_theme_features_backup;
+
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @ticket 38738
+	 */
+	function test_video_header_callback_front_page_from_elsewhere() {
+		// Back up theme features global to avoid poisoning later tests.
+		global $_wp_theme_features;
+		$_wp_theme_features_backup = $_wp_theme_features;
+
+		add_theme_support( 'custom-header', array(
+			'video' => true,
+			'__jit' => true, // Force refresh.
+		) );
+
+		$p = self::factory()->post->create( array(
+			'post_status' => 'publish',
+		) );
+
+		$this->go_to( get_permalink( $p ) );
+
+		$result = is_header_video_active();
+
+		// Restore theme features global to initial state.
+		$_wp_theme_features = $_wp_theme_features_backup;
+
+		$this->assertFalse( $result );
+	}
+
+	/**
+	 * @ticket 38738
+	 */
+	function test_video_header_callback_globally_from_front_page() {
+		// Back up theme features global to avoid poisoning later tests.
+		global $_wp_theme_features;
+		$_wp_theme_features_backup = $_wp_theme_features;
+
+		add_theme_support( 'custom-header', array(
+			'video' => true,
+			'video-active-callback' => '__return_true',
+			'__jit' => true, // Force refresh.
+		) );
+
+		$this->go_to( home_url() );
+
+		$result = is_header_video_active();
+
+		// Restore theme features global to initial state.
+		$_wp_theme_features = $_wp_theme_features_backup;
+
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @ticket 38738
+	 */
+	function test_video_header_callback_globally_from_elsewhere() {
+		// Back up theme features global to avoid poisoning later tests.
+		global $_wp_theme_features;
+		$_wp_theme_features_backup = $_wp_theme_features;
+
+		add_theme_support( 'custom-header', array(
+			'video' => true,
+			'video-active-callback' => '__return_true',
+			'__jit' => true, // Force refresh.
+		) );
+
+		$p = self::factory()->post->create( array(
+			'post_status' => 'publish',
+		) );
+
+		$this->go_to( get_permalink( $p ) );
+
+		$result = is_header_video_active();
+
+		// Restore theme features global to initial state.
+		$_wp_theme_features = $_wp_theme_features_backup;
+
+		$this->assertTrue( $result );
+	}
+
+	/**
+	 * @ticket 38738
+	 */
+	function test_video_header_callback_globally_with_negative_filter() {
+		// Back up theme features global to avoid poisoning later tests.
+		global $_wp_theme_features;
+		$_wp_theme_features_backup = $_wp_theme_features;
+
+		add_theme_support( 'custom-header', array(
+			'video' => true,
+			'video-active-callback' => '__return_true',
+			'__jit' => true, // Force refresh.
+		) );
+
+		$p = self::factory()->post->create( array(
+			'post_status' => 'publish',
+		) );
+
+		$this->go_to( get_permalink( $p ) );
+
+		add_filter( 'is_header_video_active', '__return_false' );
+		$result = is_header_video_active();
+		remove_filter( 'is_header_video_active', '__return_false' );
+
+		// Restore theme features global to initial state.
+		$_wp_theme_features = $_wp_theme_features_backup;
+
+		$this->assertFalse( $result );
+	}
 }
