Skip to content

Instantly share code, notes, and snippets.

@pnomolos
Created September 4, 2011 00:29
Show Gist options
  • Save pnomolos/1192009 to your computer and use it in GitHub Desktop.
Save pnomolos/1192009 to your computer and use it in GitHub Desktop.
Set post featured thumbnail and duration field automatically from youtube/vimeo thumbnail image pulled from embed code.
<?php
function set_video_info($post_id) {
$id = wp_is_post_revision($post_id);
$post_id = $id ? $id : $post_id;
$post = get_post($post_id);
if (get_the_post_thumbnail($post_id) || $post->post_type != 'videos')
return;
$upload_dir = wp_upload_dir();
// Use the correct name of the custom field for the iframe code
$embed_code = get_post_meta($post->ID, 'embed-code', true);
if (!$embed_code)
return;
preg_match('/src=\".*\/([^\/\?\"]+)\??[^\/\"]*\"/', $embed_code, $matches);
$video_id = $matches[1];
if (!$video_id)
return;
$video_data = array('image' => '', 'duration' => 0);
// We only know how to handle youtube/vimeo right now
if (strpos($embed_code, 'youtube') !== FALSE) {
$data = file_get_contents('https://gdata.youtube.com/feeds/api/videos/' . $video_id . '?v=2');
if (!preg_match('/<media:thumbnail[^>]*hqdefault[^>]*>/', $data, $matches))
return;
$xml = simplexml_load_string($data);
foreach($xml->xpath('//@yt:name') as $thumb) {
if ('hqdefault' == (string)$thumb['name']) {
$video_data['image'] = (string)$thumb['url'];
}
}
$video_data['duration'] = (string)reset($xml->xpath('//@duration'));
} else if (strpos($embed_code, 'vimeo') !== FALSE) {
$data = file_get_contents('http://vimeo.com/api/v2/video/' . $video_id . '.php');
if ($data == 'Method not found.' || !($data = @unserialize($data)))
return;
$video_data['image'] = $data[0]['thumbnail_large'];
$video_data['duration'] = $data[0]['duration'];
} else {
return;
}
if (!get_post_meta($post_id, 'length', true)) {
update_post_meta($post_id, 'length', $video_data['duration']);
}
$image_data = file_get_contents($video_data['image']);
if (!$image_data)
return;
$extension = pathinfo($image_url, PATHINFO_EXTENSION);
$filename = $upload_dir['path'].'/generated_video_thumbnail_' . $post->ID . '.' . $extension;
if (!file_put_contents($filename, $image_data))
return;
$wp_filetype = wp_check_filetype(basename($filename), null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $filename, $post_id );
$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
wp_update_attachment_metadata( $attach_id, $attach_data );
update_post_meta($post_id, '_thumbnail_id', $attach_id);
}
if (is_admin()) {
add_filter('save_post', 'set_video_info');
}
@pnomolos
Copy link
Author

This works for YouTube and Vimeo iframe embeds.

This assumes that the post contains an 'embed-code' and 'length' field.

The embed code field is expected to contain the entire iframe tag, not just the url to the embed. If you are just using the url, tweak the preg_match call on line 15 to match the ID properly. If you are just entering the video ID, you'll need to update the code a bit more to otherwise identify whether it's a Vimeo or YouTube video (presumably you'd have a custom field to do this already) as that information is needed to properly pull the info.

The 'length' field will but updated with the duration of the video in seconds - format it as you need in your front-end template.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment