Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

For Wordpress, I want to auto generate thumb of the video embedded on a page using oembed? And then save it as a featured image of the post.

Any idea how to do this?

share|improve this question
3  
oEmbed of what? YouTube? –  kaiser Oct 28 '12 at 19:38

2 Answers 2

up vote 5 down vote accepted
+50

I needed just this for a recent project, so here's my plugin! The code should be self-explanatory, but if there are any questions ask away.

<?php

/**
 * Plugin Name: oEmbed Featured Image
 * Plugin URI: http://wordpress.stackexchange.com/q/70752/1685
 * Description: Automatically set the featured image if an oEmbed-compatible embed is found in the post content.
 * Version: 1.0
 * Author: TheDeadMedic
 * Author URI: http://wordpress.stackexchange.com/users/1685/thedeadmedic
 *
 * @package oEmbed_Featured_Image
 */

add_action( 'wp_insert_post', array( 'ofi', 'init' ) );

/**
 * @package oEmbed_Featured_Image
 */
class ofi
{
    /**
     * The post thumbnail ID
     *
     * @var int
     */
    private $_thumb_id;

    /**
     * The post ID
     *
     * @var int
     */
    private $_post_id;

    /**
     * Sets up an instance if called statically, and attempts to set the featured
     * image from an embed in the post content (if one has not already been set).
     *
     * @param  int $post_id
     * @return object|null
     */
    public function init( $post_id )
    {
        if ( ! isset( $this ) )
            return new ofi( $post_id );

        global $wp_embed;

        $this->_post_id = absint( $post_id );

        if ( ! $this->_thumb_id = get_post_meta( $this->_post_id, '_thumbnail_id', true ) ) {
            if ( $content = get_post_field( 'post_content', $this->_post_id, 'raw' ) ) {

                add_filter( 'oembed_dataparse', array( $this, 'oembed_dataparse' ), 10, 3 );
                $wp_embed->autoembed( $content );
                remove_filter( 'oembed_dataparse', array( $this, 'oembed_dataparse' ), 10, 3 );

            }
        }
    }

    /**
     * @see init()
     */
    public function __construct( $post_id )
    {
        $this->init( $post_id );
    }

    /**
     * Callback for the "oembed_dataparse" hook, which will fire on a successful
     * response from the oEmbed provider.
     *
     * @see WP_oEmbed::data2html()
     *
     * @param string $return The embed HTML
     * @param object $data   The oEmbed response
     * @param string $url    The oEmbed content URL
     */
    public function oembed_dataparse( $return, $data, $url )
    {
        if ( ! empty( $data->thumbnail_url ) && ! $this->_thumb_id ) {
            // if ( in_array( @ $data->type, array( 'video' ) ) ) // Only set for video embeds
                $this->set_thumb_by_url( $data->thumbnail_url, @ $data->title );
        }
    }

    /**
     * Attempt to download the image from the URL, add it to the media library,
     * and set as the featured image.
     *
     * @see media_sideload_image()
     *
     * @param string $url
     * @param string $title Optionally set attachment title
     */
    public function set_thumb_by_url( $url, $title = null )
    {
        /* Following assets will already be loaded if in admin */
        require_once ABSPATH . 'wp-admin/includes/file.php';
        require_once ABSPATH . 'wp-admin/includes/media.php';
        require_once ABSPATH . 'wp-admin/includes/image.php';

        $temp = download_url( $url );

        if ( ! is_wp_error( $temp ) && $info = @ getimagesize( $temp ) ) {
            if ( ! strlen( $title ) )
                $title = null;

            if ( ! $ext = image_type_to_extension( $info[2] ) )
                $ext = '.jpg';

            $data = array(
                'name'     => md5( $url ) . $ext,
                'tmp_name' => $temp,
            );

            $id = media_handle_sideload( $data, $this->_post_id, $title );
            if ( ! is_wp_error( $id ) )
                return update_post_meta( $this->_post_id, '_thumbnail_id', $this->_thumb_id = $id );
        }

        if ( ! is_wp_error( $temp ) )
            @ unlink( $temp );
    }
}

?>

Caveat: This will only work for registered oEmbed providers, and only if no embed handler is registered for the provider (otherwise WP never makes a call to its oEmbed service).

If there are multiple embeds in a post, the first successful thumbnail grab is used.

share|improve this answer
    
Awesome, works a treat! Cool filter as well, oembed_dataparse :) –  brasofilo Nov 5 '12 at 18:21
    
Awesome, this worked great. Thanks. Is there any way to assign same post a tag of video upon saving using the same? All though this answers my question, and works best.. why don't you publish this as plugin? –  Krunal Nov 6 '12 at 16:01
    
Tags aren't part of the oEmbed spec, so 'fraid not. I don't have the time to officially publish it, but anyone else is free to do so (under the CC BY-SA 3.0 & GPL). –  TheDeadMedic Nov 6 '12 at 17:02

Interesting Question, but quoting Mike Schinkel answering a similar Q:

You could hook the save_post action, use WP_Http class to download it and then insert it as an attachment using wp_insert_attachment and wp_update_attachment_metadata(). It's not trivial but shouldn't be that hard.

My emphasis.

In another Q, Milo and Chris_O posted some useful info to deal with extracting an image URL from the content, attaching it to the post and setting it as Featured Image.

Which brings us to Kaiser's comment: what oEmbed is this?

If it is YouTube, this would be the full size thumbnail URL:
http://i3.ytimg.com/vi/YOUTUBE-VIDEO-ID/0.jpg

If Vimeo: http://stackoverflow.com/q/1361149/1287812


Instead of searching the post content each time it's updated/saved, I'd follow this approach:

Create a Metabox with an Input Field for the Video ID

Maybe, one input field per video hosting site. And a correspondent button "Grab thumbnail".

So, the user enters the YouTube/Vimeo video ID, press the button and we execute the side loading, attaching and featuring functions through Ajax.

In this Question ( Unattaching images from a post ), I wrote a plugin that creates a metabox where an Ajax function manipulates the attachments of a post.


Well, this is a roadmap, feel free to expand into working code :)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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