Make WordPress Core

Opened 7 years ago

Last modified 4 years ago

#42718 new defect (bug)

Video shortcode needs muted attribute for Autoplay to work with Safari 11.0.1+

Reported by: deeptiboddapati's profile deeptiboddapati Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 3.6
Component: Shortcodes Keywords: has-patch has-unit-tests
Focuses: Cc:

Description

Safari 11.0.1 disables autoplay on everything that isn't muted by default. Link here:

https://techcrunch.com/2017/06/05/auto-play-block/

Chrome will disable it starting next year:

https://arstechnica.com/tech-policy/2017/09/google-chrome-block-auto-play-video/

For this reason, if we're including the autoplay attribute in the video shortcode, we should add a muted attribute to make it a useable shortcode.

Other than a code change, we should also update the docs about the shortcode here:
https://codex.wordpress.org/Video_Shortcode

How to test this now:

Get on Safari 11.0.1 (or greater)
Create a post with a video shortcode and an autoplay tag.
Go to the front end version and see that it won't play.

Attachments (1)

42718.diff (3.9 KB) - added by birgire 7 years ago.

Download all attachments as: .zip

Change History (9)

@birgire
7 years ago

#1 @birgire
7 years ago

  • Keywords has-patch has-unit-tests added
  • Version changed from trunk to 3.6

@deeptiboddapati thanks for the info on this matter.

42718.diff is a first pass at supporting the muted video shortcode attribute.

It also contains an update for the attributes test in Tests_Media::test_wp_video_shortcode_attributes().

ps: The shortest hack I can currently think of to support this, is something like:

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 ); 
} );

but watch out that his actually replaces the default video shortcode's callback.

#2 @birgire
6 years ago

#44572 was marked as a duplicate.

#3 @simdri
6 years ago

If you set this in line 2596 of wp-includes\media.php, in function wp_video_shortcode:

  if(isset($html_atts['autoplay'])){
    $html_atts['muted'] = '1';
  }

This snippet must be after

	// These ones should just be omitted altogether if they are blank
	foreach ( array( 'poster', 'loop', 'autoplay', 'preload' ) as $a ) {
		if ( empty( $html_atts[$a] ) ) {
			unset( $html_atts[$a] );
		}
	}

This sets the attribute muted to 1, when autoplay is set, regardless of what is set.
Works with Chrome. No other where tested.

Any shortcomings with this change?

This ticket was mentioned in Slack in #core-media by mike. View the logs.


6 years ago

#5 @jepperask
6 years ago

Any news on this? I'm using the Customizer to add a video, and attempting to play the video fails with the exception (if not clicking elsewhere first):

"Uncaught (in promise) NotAllowedError: play() failed because the user didn't interact with the document first."
Last edited 6 years ago by jepperask (previous) (diff)

#6 @sc456a
5 years ago

Would love to see this implemented in core, as you're basically forced to use gifs or plugins if you want video to autoplay.

#7 @sc456a
5 years ago

Just in case someone is looking for a quick fix, the following code should work:

<video autoplay loop muted playsinline>
<source src="video.mp4" type="video/mp4">
</video>

#8 @stepan1860
4 years ago

You should write these filter in your functions.php

add_filter( 'wp_video_shortcode', function( $html ) {
   return str_replace( '<video', '<video muted playsinline autoplay', $html );
} );

also you must initalized your shortcode in index.php or category.php (or somewhere else =))

$post_id = get_the_ID(); 
$media = get_attached_media('video', $post_id);

echo wp_video_shortcode( [
'src'      => $media[0],\\
'loop'     => 'true',\\
'poster'   =>  'your_poster',\\
'preload'  => 'yes',\\
'fullscreen'=> 'false',\\
'class'    => 'jquery-background-video is-playing is-visible',\\
'id'       => '', 
] );

Note: See TracTickets for help on using tickets.