How to Replace YouTube Videos with a “Click to Play” Thumbnail?

I use a lot of embedded videos (via oembed) on my blog, and that can slow down page loads.

Is there a way to automatically replace YouTube (and other) videos with a thumbnail (preferably the post’s featured image). And then replace the thumbnail with the video iframe when clicked?

Related posts

Leave a Reply

4 comments

  1. Notes

    • Solution for YouTube and Vimeo.
    • Uses Featured Image or default thumbnail from video provider.
    • If more than one oEmbed exists in the same page, using the Featured Image provoques duplicate “thumbs”.
    • Post has to be updated before changes are seen.
    • To do: <iframe> and <img> sizes, other oEmbeds.

    Sources of Inspiration

    oEmbed

    oEmbed, thumbnails and wordpress

    Replace Image with Embed

    https://stackoverflow.com/q/838878/1287812

    Plugin

    <?php
    /**
     * Plugin Name: oEmbed Replace Iframe with AutoPlay-Image
     * Plugin URI: https://wordpress.stackexchange.com/q/73996/12615
     * Description: Replaces the iFrame embed with the Featured Image 
     * and if this not exists replaces with the Video Thumbnail
     * Version: 1.0
     * Author: brasofilo
     * Author URI: https://wordpress.stackexchange.com/users/12615/brasofilo
     */
    
    //avoid direct calls to this file
    if (!function_exists ('add_action')) {
            header('Status: 403 Forbidden');
            header('HTTP/1.1 403 Forbidden');
            exit();
    }
    
    add_filter( 'oembed_dataparse', 'wpse_73996_oembed_click2play', 10, 3 );
    
    function wpse_73996_oembed_click2play( $return, $data, $url ) 
    {
        // Create Unique ID, case more than one oembed is used in the page 
        // https://stackoverflow.com/questions/3656713/
        $uuid = gettimeofday();
        $uuid = mt_rand() . $uuid['usec'];
    
        // Use Featured Image, if exists
        // This only works visually if 1 oEmbed per post is used
        $post_thumbnail_id = get_post_thumbnail_id( $_REQUEST['post'] );
        if( $post_thumbnail_id )
        {
            $thumb = wp_get_attachment_image_src( $post_thumbnail_id, 'medium' );
            $image = $thumb[0];
        }
    
        if( !$image ) 
            $image = $data->thumbnail_url; 
    
        // YouTube
        if ( $data->provider_name == 'YouTube' ) 
        {
            $autoplay = str_replace('feature=oembed', 'feature=oembed&autoplay=1', $return );
    
            $return = '<script type="text/javascript">var embedCode' 
                . $uuid . ' = ''
                . $autoplay .'';</script><div id="videocontainer' 
                . $uuid . '"><img src="'
                . $image
                . '" onclick="document.getElementById('videocontainer'
                . $uuid . '').innerHTML = embedCode'
                . $uuid . ';" height="360" width="480" /></div>';
        }
    
        // Vimeo
        elseif ( $data->provider_name == 'Vimeo' ) 
        {
            $autoplay = str_replace('" width=', '?autoplay=1" width=', $return );
    
            $return = '<script type="text/javascript">var embedCode'
                . $uuid . ' = ''
                . $autoplay . '';</script><div id="videocontainer'
                . $uuid . '"><img src="'
                . $image
                .'" onclick="document.getElementById('videocontainer'
                . $uuid . '').innerHTML = embedCode'
                . $uuid . ';" height="360" width="480" /></div>';
        }
        return $return;
    }
    

    Contents of the $data returned by the video providers

    stdClass(
        type = 'video'
        version = 1.0
        provider_name = 'Vimeo'
        provider_url = 'http://vimeo.com/'
        title = 'Earth'
        author_name = 'Michael König'
        author_url = 'http://vimeo.com/michaelkoenig'
        is_plus = 1
        html = '<iframe src="http://player.vimeo.com/video/32001208" width="540" height="304" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
        width = 540
        height = 304
        duration = 300
        description = 'lorem ipsum'
        thumbnail_url = 'http://b.vimeocdn.com/ts/307/031/307031094_295.jpg'
        thumbnail_width = 295
        thumbnail_height = 166
        video_id = 32001208
    )
    
    stdClass(
        provider_url = 'http://www.youtube.com/'
        thumbnail_url = 'http://i2.ytimg.com/vi/552yWya5RgY/hqdefault.jpg'
        title = 'Tu cara me suena - Arturo Valls imita a Rihanna'
        html = '<iframe width="540" height="304" src="http://www.youtube.com/embed/552yWya5RgY?fs=1&feature=oembed" frameborder="0" allowfullscreen></iframe>'
        author_name = 'antena3'
        height = 304
        thumbnail_width = 480
        width = 540
        version = 1.0
        author_url = 'http://www.youtube.com/user/antena3'
        provider_name = 'YouTube'
        type = 'video'
        thumbnail_height = 360
    )
    
  2. Here is enhanced verison of brasofilo plugin:

    add_filter( 'oembed_dataparse', function($str, $data, $url) {
    
        if ( ($yt = $data->provider_name == 'YouTube') || ($vm = $data->provider_name == 'Vimeo') ) 
        {
            if($yt) $html = str_replace('feature=oembed', 'feature=oembed&autoplay=1', $str);
            else $html = str_replace('" width=', '?autoplay=1" width=', $str);
    
            $html = htmlentities($html, ENT_QUOTES);
            $img = $data->thumbnail_url; 
            $title = esc_attr($data->title);
    
            return '<img src="'. $img . '" onclick="this.outerHTML='' . $html . ''" title="' . $title . '">';
        }
    
        return $str;
    
    }, 10, 3);
    

    Do not remember to clean oembed cache! You can use this SQL command to do that:

    DELETE FROM wp_postmeta WHERE meta_key LIKE '_oembed%'
    

    More info at https://siteorigin.com/clearing-oembed-cache/

  3. This is a good method…but a less involved one (for those of us less experienced) would be to use this tutorial.

    Do not plug in the YouTube embed code as YT(YouTube) gives it (you can try, but it will be ganky)…instead just replace the source from the embed code of your vid UP TO &amp;autoplay=1 (leave this on the end as it is).

    eg.

    original code YT gives:

    <object width="420" height="315">
        <param name="movie" value="//www.youtube.com/v/5mEymdGuEJk?hl=en_US&amp;version=3"></param>
        <param name="allowFullScreen" value="true"></param>
        <param name="allowscriptaccess" value="always"></param>
        <embed src="//www.youtube.com/v/5mEymdGuEJkhl=en_US&amp;version=3" type="application/x-shockwave-flash" width="420" height="315" allowscriptaccess="always" allowfullscreen="true"></embed>
    </object>
    

    Code used in tutorial with same YT src:

    <object width="420" height="315" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0">
        <param name="allowFullScreen" value="true" />
        <param name="allowscriptaccess"value="always" />
        <param name="src" value="http://www.youtube.com/v/5mEymdGuEJk?version=3&amp;hl=en_US&amp;autoplay=1" /><param name="allowfullscreen" value="true" />
        <embed width="420" height="315" type="application/x-shockwave-flash" src="http://www.youtube.com/v/5mEymdGuEJk?version=3&amp;hl=en_US&amp;autoplay=1" allowFullScreen="true" allowscriptaccess="always" allowfullscreen="true" />
    </object>
    

    Other than that, just replace the img source and path with your own, and voilà!

  4. Try this code. Just copy and paste in a HTML file.

    <!DOCTYPE html>
    <html>
    <body>
        <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
        <script>
            var tag = document.createElement('script');
    
            tag.src = "https://www.youtube.com/iframe_api";
            var firstScriptTag = document.getElementsByTagName('script')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    
            var player;
            function onYouTubeIframeAPIReady() {
                player = new YT.Player('player', { // "player" id of youtube player container where video comes using youtube iframe api.
                    height: '390',
                    width: '640',
                    videoId: 'M7lc1UVf-VE',
                    events: {
                        'onReady': onPlayerReady, // on ready event below callback function "onPlayerReady" will be called.
                    }
                });
            }
    
            function onPlayerReady(event) { // as youtube player will ready
                $('#play_vid').click(function() {  // it will wait to click on overlay/image
                    event.target.playVideo();  // as overlay image clicked video plays.
                });
            }
    
            $(document).ready(function() {
                $('#player').hide(); // on document ready youtube player will be hiden.
                $('#play_vid').click(function() {  // as user click on overlay image.
                    $('#player').show();    // player will be visible to user 
                    $('#play_vid').hide(); // and overlay image will be hidden.
                });
            });
        </script>
    
        <div id="player"></div> <!-- Youtube player container -->
        <img id="play_vid" src="YOUR_IMAGE_PATH" /> <!-- overlay image that comes in front of youtube video. when user click on this, image will be hidden and video plays using youtube api.-->
    </body>
    </html>