wp_video_shortcode() – Function | Developer.WordPress.org
Builds the Video shortcode output.
Description
This implements the functionality of the Video Shortcode for displaying WordPress mp4s in a post.
Parameters
$attrarrayrequiredAttributes of the shortcode.
srcstringURL to the source of the video file. Default empty.
heightintHeight of the video embed in pixels. Default 360.
widthintWidth of the video embed in pixels. Default $content_width or 640.
posterstringThe
'poster'attribute for the<video>element. Default empty.loopstringThe
'loop'attribute for the<video>element. Default empty.autoplaystringThe
'autoplay'attribute for the<video>element. Default empty.mutedstringThe
'muted'attribute for the<video>element. Default false.preloadstringThe
'preload'attribute for the<video>element.
Default'metadata'.classstringThe
'class'attribute for the<video>element.
Default'wp-video-shortcode'.
$contentstringrequiredShortcode content.
Return
string|void HTML content to display video.Source
function wp_video_shortcode( $attr, $content = '' ) {
global $content_width;
$post_id = get_post() ? get_the_ID() : 0;
static $instance = 0;
++$instance;
/**
* Filters the default video shortcode output.
*
* If the filtered output isn't empty, it will be used instead of generating
* the default video template.
*
* @since 3.6.0
*
* @see wp_video_shortcode()
*
* @param string $html Empty variable to be replaced with shortcode markup.
* @param array $attr Attributes of the shortcode. See wp_video_shortcode().
* @param string $content Video shortcode content.
* @param int $instance Unique numeric ID of this video shortcode instance.
*/
$override = apply_filters( 'wp_video_shortcode_override', '', $attr, $content, $instance );
if ( '' !== $override ) {
return $override;
}
$video = null;
$default_types = wp_get_video_extensions();
$defaults_atts = array(
'src' => '',
'poster' => '',
'loop' => '',
'autoplay' => '',
'muted' => 'false',
'preload' => 'metadata',
'width' => 640,
'height' => 360,
'class' => 'wp-video-shortcode',
);
foreach ( $default_types as $type ) {
$defaults_atts[ $type ] = '';
}
$atts = shortcode_atts( $defaults_atts, $attr, 'video' );
if ( is_admin() ) {
// Shrink the video so it isn't huge in the admin.
if ( $atts['width'] > $defaults_atts['width'] ) {
$atts['height'] = round( ( $atts['height'] * $defaults_atts['width'] ) / $atts['width'] );
$atts['width'] = $defaults_atts['width'];
}
} else {
// If the video is bigger than the theme.
if ( ! empty( $content_width ) && $atts['width'] > $content_width ) {
$atts['height'] = round( ( $atts['height'] * $content_width ) / $atts['width'] );
$atts['width'] = $content_width;
}
}
$is_vimeo = false;
$is_youtube = false;
$yt_pattern = '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#';
$vimeo_pattern = '#^https?://(.+\.)?vimeo\.com/.*#';
$primary = false;
if ( ! empty( $atts['src'] ) ) {
$is_vimeo = ( preg_match( $vimeo_pattern, $atts['src'] ) );
$is_youtube = ( preg_match( $yt_pattern, $atts['src'] ) );
if ( ! $is_youtube && ! $is_vimeo ) {
$type = wp_check_filetype( $atts['src'], wp_get_mime_types() );
if ( ! in_array( strtolower( $type['ext'] ), $default_types, true ) ) {
return sprintf( '<a class="wp-embedded-video" href="%s">%s</a>', esc_url( $atts['src'] ), esc_html( $atts['src'] ) );
}
}
if ( $is_vimeo ) {
wp_enqueue_script( 'mediaelement-vimeo' );
}
$primary = true;
array_unshift( $default_types, 'src' );
} else {
foreach ( $default_types as $ext ) {
if ( ! empty( $atts[ $ext ] ) ) {
$type = wp_check_filetype( $atts[ $ext ], wp_get_mime_types() );
if ( strtolower( $type['ext'] ) === $ext ) {
$primary = true;
}
}
}
}
if ( ! $primary ) {
$videos = get_attached_media( 'video', $post_id );
if ( empty( $videos ) ) {
return;
}
$video = reset( $videos );
$atts['src'] = wp_get_attachment_url( $video->ID );
if ( empty( $atts['src'] ) ) {
return;
}
array_unshift( $default_types, 'src' );
}
/**
* Filters the media library used for the video shortcode.
*
* @since 3.6.0
*
* @param string $library Media library used for the video shortcode.
*/
$library = apply_filters( 'wp_video_shortcode_library', 'mediaelement' );
if ( 'mediaelement' === $library && did_action( 'init' ) ) {
wp_enqueue_style( 'wp-mediaelement' );
wp_enqueue_script( 'wp-mediaelement' );
wp_enqueue_script( 'mediaelement-vimeo' );
}
/*
* MediaElement.js has issues with some URL formats for Vimeo and YouTube,
* so update the URL to prevent the ME.js player from breaking.
*/
if ( 'mediaelement' === $library ) {
if ( $is_youtube ) {
// Remove `feature` query arg and force SSL - see #40866.
$atts['src'] = remove_query_arg( 'feature', $atts['src'] );
$atts['src'] = set_url_scheme( $atts['src'], 'https' );
} elseif ( $is_vimeo ) {
// Remove all query arguments and force SSL - see #40866.
$parsed_vimeo_url = wp_parse_url( $atts['src'] );
$vimeo_src = 'https://' . $parsed_vimeo_url['host'] . $parsed_vimeo_url['path'];
// Add loop param for mejs bug - see #40977, not needed after #39686.
$loop = $atts['loop'] ? '1' : '0';
$atts['src'] = add_query_arg( 'loop', $loop, $vimeo_src );
}
}
/**
* Filters the class attribute for the video shortcode output container.
*
* @since 3.6.0
* @since 4.9.0 The `$atts` parameter was added.
*
* @param string $class CSS class or list of space-separated classes.
* @param array $atts Array of video shortcode attributes.
*/
$atts['class'] = apply_filters( 'wp_video_shortcode_class', $atts['class'], $atts );
$html_atts = array(
'class' => $atts['class'],
'id' => sprintf( 'video-%d-%d', $post_id, $instance ),
'width' => absint( $atts['width'] ),
'height' => absint( $atts['height'] ),
'poster' => esc_url( $atts['poster'] ),
'loop' => wp_validate_boolean( $atts['loop'] ),
'autoplay' => wp_validate_boolean( $atts['autoplay'] ),
'muted' => wp_validate_boolean( $atts['muted'] ),
'preload' => $atts['preload'],
);
// These ones should just be omitted altogether if they are blank.
foreach ( array( 'poster', 'loop', 'autoplay', 'preload', 'muted' ) as $a ) {
if ( empty( $html_atts[ $a ] ) ) {
unset( $html_atts[ $a ] );
}
}
$attr_strings = array();
foreach ( $html_atts as $attribute_name => $attribute_value ) {
if ( in_array( $attribute_name, array( 'loop', 'autoplay', 'muted' ), true ) && true === $attribute_value ) {
// Add boolean attributes without their value for true.
$attr_strings[] = esc_attr( $attribute_name );
} elseif ( 'preload' === $attribute_name && ! empty( $attribute_value ) ) {
// Handle the preload attribute with specific allowed values.
$allowed_preload_values = array( 'none', 'metadata', 'auto' );
if ( in_array( $attribute_value, $allowed_preload_values, true ) ) {
$attr_strings[] = sprintf( '%s="%s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) );
}
} elseif ( ! empty( $attribute_value ) ) {
// For non-boolean attributes, add them with their value.
$attr_strings[] = sprintf( '%s="%s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) );
}
}
$html = sprintf( '<video %s controls="controls">', implode( ' ', $attr_strings ) );
$fileurl = '';
$source = '<source type="%s" src="%s" />';
foreach ( $default_types as $fallback ) {
if ( ! empty( $atts[ $fallback ] ) ) {
if ( empty( $fileurl ) ) {
$fileurl = $atts[ $fallback ];
}
if ( 'src' === $fallback && $is_youtube ) {
$type = array( 'type' => 'video/youtube' );
} elseif ( 'src' === $fallback && $is_vimeo ) {
$type = array( 'type' => 'video/vimeo' );
} else {
$type = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() );
}
$url = add_query_arg( '_', $instance, $atts[ $fallback ] );
$html .= sprintf( $source, $type['type'], esc_url( $url ) );
}
}
if ( ! empty( $content ) ) {
if ( str_contains( $content, "\n" ) ) {
$content = str_replace( array( "\r\n", "\n", "\t" ), '', $content );
}
$html .= trim( $content );
}
if ( 'mediaelement' === $library ) {
$html .= wp_mediaelement_fallback( $fileurl );
}
$html .= '</video>';
$width_rule = '';
if ( ! empty( $atts['width'] ) ) {
$width_rule = sprintf( 'width: %dpx;', $atts['width'] );
}
$output = sprintf( '<div style="%s" class="wp-video">%s</div>', $width_rule, $html );
/**
* Filters the output of the video shortcode.
*
* @since 3.6.0
*
* @param string $output Video shortcode HTML output.
* @param array $atts Array of video shortcode attributes.
* @param string $video Video file.
* @param int $post_id Post ID.
* @param string $library Media library used for the video shortcode.
*/
return apply_filters( 'wp_video_shortcode', $output, $atts, $video, $post_id, $library );
}
Hooks
- apply_filters( ‘wp_video_shortcode’,
string $output ,array $atts ,string $video ,int $post_id ,string $library ) Filters the output of the video shortcode.
- apply_filters( ‘wp_video_shortcode_class’,
string $class ,array $atts ) Filters the class attribute for the video shortcode output container.
- apply_filters( ‘wp_video_shortcode_library’,
string $library ) Filters the media library used for the video shortcode.
- apply_filters( ‘wp_video_shortcode_override’,
string $html ,array $attr ,string $content ,int $instance ) Filters the default video shortcode output.
Changelog
| Version | Description |
|---|---|
| 3.6.0 | Introduced. |