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?
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.
oembed_dataparse
:)
Commented
Nov 5, 2012 at 18:21
Interesting Question, but quoting Mike Schinkel answering a similar Q:
You could hook the
save_post
action, useWP_Http
class to download it and then insert it as an attachment usingwp_insert_attachment
andwp_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: https://stackoverflow.com/q/1361149/1287812
Instead of searching the post content each time it's updated/saved, I'd follow this approach:
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 :)