Creating document preview for different file formats

In this article, we show how to create the possibility to preview a document, in our case, an mp4 video file. 

Example of data display

preview

Fig. 1. Video file preview on the document’s page

Fig. 2. Video file preview in a pop-up window 

IFilePreviewCreator extension (interface) methods

The IFilePreviewCreator extension point (interface) uses the following methods:

/// <summary>
/// UID
/// </summary>
Guid Uid { get; }
 
/// <summary>
/// Display Name
/// </summary>
string DisplayName { get; }
 
/// <summary>
/// File extensions
/// </summary>
List<string> Extensions { get; }
 
/// <summary>
/// Main file name
/// </summary>
/// <param name="file">File</param>
/// <returns></returns>
string GetMainFileName(BinaryFile file);
 
/// <summary>
/// Text file name
/// </summary>
/// <param name="file">File</param>
/// <returns></returns>
string GetTextFileName(BinaryFile file);
 
/// <summary>
/// Relative path to the main file
/// </summary>
/// <param name="file">File</param>
/// <returns></returns>
string GetRelativeMainFileName(BinaryFile file);
 
/// <summary>
/// Create preview
/// </summary>
/// <param name="path">Path</param>
/// <param name="file">File</param>
void Create(string path, BinaryFile file);
         
/// <summary>
/// Whether it is available for use
/// </summary>
/// <param name="file">File</param>
/// <returns></returns>
bool IsAvaliable(BinaryFile file);
 
/// <summary>
/// Whether there is a generated preview
/// </summary>
/// <param name="file">File</param>
/// <returns></returns>
bool HasPreview(BinaryFile file);
 
/// <summary>
/// Whether there is a generated preview
/// </summary>
/// <param name="file"> File </param>
/// <param name="priority">Priority</param>
/// <returns></returns>
bool HasPreview(BinaryFile file, long priority);
 
/// <summary>
/// Get a textual representation of the preview for indexing
/// </summary>
/// <param name="file">File</param>
/// <returns></returns>
string GetPreviewText(BinaryFile file);
 
/// <summary>
/// A preview in HTML format is generated
/// </summary>
/// <returns></returns>
bool EnableGenerateHtml();

Example of IFilePreviewCreator extension point class

[Component]
public class VideoPreviewCreator : IFilePreviewCreator
{
    private readonly Guid _uid = new Guid("{2B94E4DF-BCE2-4b54-AC85-3ABE24BB5F92}");
 
    public Guid Uid
    {
        get { return _uid; }
    }
 
    public string DisplayName
    {
        get { return SR.T("Video files (.mp4)"); }
    }
 
    public List<string> Extensions
    {
        get { return new List<string> { ".mp4" }; }
    }
 
    public string GetMainFileName(BinaryFile file)
    {
        return file.ContentFilePath;
    }
 
    public void Create(string path, BinaryFile file)
    {
 
    }
 
    public string GetPreviewText(BinaryFile file)
    {
        return null;
    }
 
    public bool EnableGenerateHtml()
    {
        return false;
    }
 
    public IRuntimeApplication RuntimeApplication { get; set; }
 
    public string PreviewDir
    {
        get { return null; }
    }
 
    public string GetRelativeMainFileName(BinaryFile file)
    {
        return null;
    }
 
    public virtual string GetTextFileName(string filePreviewDir, BinaryFile file)
    {
        return null;
    }
 
    public virtual string GetTextFileName(BinaryFile file)
    {
        return null;
    }
 
    public virtual string GetMainFileName(string filePreviewDir, BinaryFile file)
    {
        return GetTextFileName(filePreviewDir, file);
    }
 
    public virtual bool IsAvaliable(BinaryFile file)
    {
        var settings = Locator.GetService<PreviewSettingsModule>();
        return settings == null || settings.IsEnabledPreview(this);
    }
 
    public virtual bool HasPreview(BinaryFile file)
    {
        return HasPreview(file, 5);
    }
 
    public virtual bool HasPreview(BinaryFile file, long priority)
    {
        return true;
    }
 
    protected virtual Encoding GetFileEncoding(string filename)
    {
        var fileContent = File.ReadAllBytes(filename);
        return EncodingTools.DetectInputCodepage(fileContent);
    }
 
}
Note
To implement this extension point you have to implement the IFilePreviewCreatorRenderer extension point.

IFilePreviewCreatorRender extension point (interface) methods

Guid Uid { get; }
 
Type CreatorType { get; }
 
/// <summary>
/// Render (render Preview)
/// </summary>
/// <param name="helper">Helper</param>
/// <param name="file">File</param>
/// <returns></returns>
bool Render(HtmlHelper helper, BinaryFile file);
 
/// <summary>
/// Name of the JavaScript initialization function, which initializes the rendering of the preview (before the preview is rendered)
/// </summary>
/// <param name="uniquePrefix">Unique prefix</param>
/// <returns>Name of the initialization function with the prefix</returns>
string InitFunctionName(string uniquePrefix);
 
/// <summary>
/// Name of the JavaScript onClose function 
/// </summary>
/// <param name="uniquePrefix">Unique prefix</param>
/// <returns>Name of the onClose function with the prefix</returns>
string CloseFunctionName(string uniquePrefix);
 
/// <summary>
/// Name of the JavaScript function for toolbar calculation (if there is a toolbar), for example, to calculate its location on the page
/// </summary>
/// <param name="uniquePrefix">Unique prefix</param>
/// <returns>Name of the function for toolbar calculation  with the prefix</returns>
string CalcToolbarFunctionName(string uniquePrefix);

Example of IFilePreviewCreatorRender extension point class

[Component]
public class VideoPreviewCreatorRenderer : IFilePreviewCreatorRenderer
{
    public static Guid UID = new Guid("{BF13D8F8-2AC4-457b-A96A-2992182AEEB5}");
 
    public Guid Uid
    {
        get { return UID; }
    }
 
    public Type CreatorType
    {
        get { return typeof(VideoPreviewCreator); }
    }
 
    public virtual string InitFunctionName(string uniquePrefix)
    {
        return null;
    }
 
    public virtual string CloseFunctionName(string uniquePrefix)
    {
        return "ClosePreview";
    }
 
    public virtual string CalcToolbarFunctionName(string uniquePrefix)
    {
        return null;
    }
 
    public virtual bool Render(HtmlHelper helper, BinaryFile file)
    {
        var previewService = Locator.GetServiceNotNull<IFilePreviewService>();
        var creator = previewService.GetPreviewCreator(file);
        if (creator != null)
        {
            var model = new BaseFilePreviewInfo
            {
                File = file,
                PreviewCreator = creator
            };
 
            helper.RenderPartial("Video", model);
        }
        return true;
    }
}

As you can see from the code, Render (preview rendering) refers to your Video view with the video file’s markup. The view must be located at Your_Module_Web\Views\Shared. Example of Video.cshtml code:

@model EleWise.ELMA.Web.Mvc.Models.Previews.BaseFilePreviewInfo
@using EleWise.ELMA
 
@{
    var fileUid = UIExtensions.PrepareId(Model.File.Id ?? Model.File.Uid.ToString());
    var uniqueGlobalPrefix = ViewData["UniqueGlobalPrefix"] ?? string.Empty;
    var videoid = String.Format("Video_{0}", Model.File.Uid);
    var previewToolbarId = string.Format("previewImgToolbar_{0}{1}", uniqueGlobalPrefix, fileUid);
    var closePreviewFunc = "ClosePreview";
}
 
<div id="@previewToolbarId" style="text-align:center; height:auto; width:auto;">
    <video id=@videoid controls preload="auto">
        <source src="@(Url.Action("Download", "BinaryFiles", new {area = "EleWise.ELMA.SDK.Web", id = Model.File.Uid}))" type=’video/mp4’ />
        <p>@SR.T("To reproduce the file make sure that your browser supports HTML5")</p>
    </video>
</div>
 
<script type="text/javascript">
    $(’#btnPrint’).next().remove();
    $(’#btnPrint’).remove();
     
    var video = document.getElementById("@videoid");
    function @(closePreviewFunc)() {
        video.pause();
    }
</script>

The document preview is available not only on the document page but also anywhere in the system. For example, you can open the preview when clicking on the document in your message feed. The system will offer to open the document in your browser and will open it in a pop-up window. The preview opened in the pop-up window does not feature the Print and Full Screen buttons. Also, the video stops when the pop-up window is closed.

Important
This implementation only works in browsers that support html5 (for example, IE 9.0, Chrome 4.0, Firefox 3.5, Safari 4.0). Each of these browsers has its own video file player. If the format of your file is not supported by the player (for example, an .avi file was renamed to .mp4), the browser will show a respective warning. For example, IE9.0 will show an “Error” while Firefox will say, “File not found”, and in Chrome the buttons will be locked.

In a similar way, you can implement playback of audio files, just replace the video tag with the audio tag in the view, and replace the file format supported by the extension point. 

Links to API elements

IFilePreviewCreator
IFilePreviewCreatorRenderer