I'm trying to add a 'muted' option to the video tag output with the content of a post using the built in wp video shortcode. I found this answer How can I get the [video] shortcode to allow query string parameters? which has led me to the add_filter but I'm really struggling how to use it? I thought the following code might work:

function my_video_shortcode( $output, $atts, $video, $post_id, $library  ) {
    /**
     * @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.
     */

     $html_atts = array(
        'class'    => apply_filters( 'wp_video_shortcode_class', 'wp-video-shortcode' ),
        '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'] ),
        'preload'  => $atts['preload'],
        'muted'    => 'muted',
    );
    $attr_strings = array();

    foreach ( $html_atts as $k => $v ) {
            $attr_strings[] = $k . '="' . esc_attr( $v ) . '"';
    }

    $html = '';
    if ( 'mediaelement' === $library && 1 === $instance ) {
            $html .= "<!--[if lt IE 9]><script>document.createElement('video');</script><![endif]-->\n";
    }
    $html .= sprintf( '<video %s controls="controls">', join( ' ', $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 ( false !== strpos( $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 );

    return $output;

}
add_filter('wp_video_shortcode', 'my_video_shortcode', 10, 2);

I get Undefined variable: for $video, $post_id and $library and the video's in the page are blank. It is because they don't have a video source but muted is there, though I realise not correctly.

Here's one of the output in the page:

<div style="width: 1306px; " class="wp-video">
<video class="wp-video-shortcode" id="video-0-0" width="1306" height="882" poster="" loop="" autoplay="" preload="metadata" muted="muted" controls="controls"></video>

I could write my own shortcode for video's but it's already almost there and built in, so it seems unnecessary to do it.

I would love to add a check box to the media library options as well, but a nice to have.

Any help much appreciated.

up vote 2 down vote accepted

I get Undefined variable: for $video, $post_id and $library and the video's in the page are blank.

Replace:

add_filter( 'wp_video_shortcode', 'my_video_shortcode', 10, 2 );

with:

add_filter( 'wp_video_shortcode', 'my_video_shortcode', 10, 5 );

to access all five input arguments in your filter's callback.

ps: my_ is such a common prefix, that I would consider something more unique.

pps: Here's another approach by overriding the shortcode:

add_shortcode( 'video', function ( $atts, $content ) 
{
    $output = wp_video_shortcode( $atts, $content );

    if( ! isset( $atts['muted'] ) || ! wp_validate_boolean( $atts['muted'] ) ) 
        return $output;

    if( false !== stripos( $output, ' muted="1"' ) )
        return $output;

    return str_ireplace( '<video ', '<video muted="1" ', $output ); 
} );

where the muted attribute is activated with:

[video muted="1" ... ]

Hope you can adjust it to your needs!

  • It's always the way, I looked at the numbers and knew from researching hooks and filtering, it was an ordering thing. Makes sense that running my code afterwards would give me data. Valid point re my_ prefix. I'm actually aware of this but left in for public forum purposes. The second approach is interesting. It's a nice, short answer. Sadly it didn't work out of the box. I think I still need to add the 'muted' option to $atts which I might play about with. For now I have got what I need. Thanks Birgire. – user2078890 Nov 4 '17 at 11:35
  • You're welcome @user2078890 . I updated the alternative approach, that I just tested successfully. – birgire Nov 4 '17 at 14:27

This code will automatically add muted to all videos - clean and simple:

add_filter( 'wp_video_shortcode', function( $output ) {
    $output = str_replace( '<video', '<video muted', $output );
    return $output;
} );

And usually you would only want this for autoplaying videos so you can target those only like such:

add_filter( 'wp_video_shortcode', function( $output ) {
    if ( false !== strpos( $output, 'autoplay="1"' ) ) {
        $output = str_replace( '<video', '<video muted', $output );
    }
    return $output;
} );

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.