Wednesday, June 4, 2014

Retrieve thumbnail from uploaded video in a Document Library

After a lot of months ignoring SharePointPills I decided to post a new blog entry with an interesting situation that happened in my current project.

The goal was to generate an image from a video used as a thumbnail or splash screen for an external web video player (FlowPlayer in this case, which works really good in almost every single browser). The video was meant to be allocated in a document library that, for external reasons, don't have the Video Content Type. This means that we were not able to access all the nice metadata that SharePoint 2013 generates for you when you upload a video, including a thumbnail for the video located in /[current_path]/[video_name]/Preview%20Images/[video_name].png. So my idea was to copy this video into the OOTB PublishingImages library, which contains the Video Content Type, and then get the thumbnail. Unfortunately using the File.CopyTo method I was able to get only a normal file uploaded into this library. No metadata at all. Even setting specifically the Video Content Type to the item.

After looking for a solution, crawling a thousand blogs and searching in MSDN I found something (a little bit hidden) that could work:  http://msdn.microsoft.com/en-us/library/microsoft.office.documentmanagement.videosets.videoset_members(v=office.15).aspx, and specially this, VideoSet.MigrateVideo: http://msdn.microsoft.com/en-us/library/microsoft.office.documentmanagement.videosets.videoset.migratevideo(v=office.15).aspx

It seems that MigrateVideo generates all the necessary metadata (including thumbnails) for your SPFile video. So I modified my code and the result was something like this:

var videoFile = web.GetFile(itemVideoId);
SPList publishingImagesList = web.GetList("/PublishingImages");

var fileExtension = new FileInfo(videoFile.Name).Extension;
videoFile.CopyTo("/PublishingImages/" + videoFile.Name, true);

var query = new SPQuery();
query.Query = string.Format("{0}", videoFile.Name);
var copiedFiles = publishingImagesList.GetItems(query);
var copiedFile = copiedFiles[0];

// Generate video metadata (thumbnail, etc)
var copiedVideo = VideoSet.MigrateVideo(copiedFile.File);
copiedVideo.SystemUpdate();

Now you can go to your PublishingImages library and see that your video has all the automatic metadata for Video Content Type, including the thumbnail, that you can easily get back using something similar to the code below:

SPFolder thumbnailVideoFolder = web.GetFolder("/PublishingImages/" + copiedVideo.Name + "/Preview Images/");
// Get single thumbnail generated
if (thumbnailVideoFolder.ItemCount > 0)
{
var thumbnailFile = thumbnailVideoFolder.Files[0];
}

As I said, there is not a lot of information about this on the Internet, so I hope this helps someone else.

Cheers!