Click here to Skip to main content
15,891,033 members
Articles / .NET

VOD using EMDB

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
20 Oct 2020CPOL6 min read 2.9K   3   1
EMDB media catalog builds web content of gallery... why not use as VOD catalog?
Using some very basic HTML protocols, it is possible to modify the HTML content produced by EMDB->Export feature and include HTML based media streaming. While this is NOT robust streaming, it is perfectly suited for home or small audience needs. This project starts with configuration of IIS web server for use of the HTML content... and provides a few lines of C# as example code for VOD modification of EMDB HTML generated content.

Introduction

With the recent advent of smart TV and other devices... I decided it was about time to setup Video On Demand for sharing the media among these smart devices... including cell phones on the patio.

The first step was to get familiar with EMDB Export to web site features, which led to a custom template. The tutorial herein does not require custom templates., so you can relax and use any EMDB template available. Our work starts after the templates are used.

Once you have generated the web content into a folder somewhere on your system... We will assume I:HTML herein...

Next, enable IIS web server and make this I:HTML folder your web site root. We will call this your Media Site... Now add a virtual directory, under Media Site (called Media) that points to your Media Files... hopefully, this will be some sort of ROOT folder with or without sub folders holding your media files. I will be using I:Movies. (see below for folder setup in use as this is important when creating VOD links).

Check that your web site has read access into the Media Files folder... right click the folder and set security for the IIS user account.

Finally, check that the web site has all your MIME types in use... I had to add .MKV file types as mimeType="video/mp4" ... you should open a browser and point to localhost\Media\SomeFile.ext to test your setup... using the defaults as mentioned above.

With this setup, we are ready to begin building our VOD web site/service.

Background

I have a large number of locally stored media files (music and video)... and long ago adopted EMDB as the catalog software of choice. With the sprouting of smart TVs... I decided it was about time to setup Video On Demand for sharing the media among these smart devices... including cell phones on the patio.

Please be aware that this is NOT intended as a heavy media streaming solution... but it works remarkably well for a few users on the household network.

WHERE are the media files: In my case, I started long ago with some very large external storage devices... and now have over 2000 movie files and a much larger number of music files. And I started with a directory structure like this...

I:Movies\

I:Movies\Classic

I:Movies\Classic\Western

I:Movies\Western

This makes it rather easy to create a web site 'virtual directory' that points to I:Movies... to keep things clear, we will call the Virtual Directory 'Media' and the Media Directory 'Movies'.

Looking at the EMDB 'Location field (using EMDB application or looking at a movie.htm file), we find a full OS based file path... for example:

[NO LABEL]i:\Movies\Classic\Wizard Of OZ.mp4

Yes... EMDB carries the volume label around for us... which we will NOT need in this case.

What we are looking for here... is a scheme that allows us to easily parse out the OS leading path segments and replace them with our web based virtual directory path segment.

You should be able to see that by replacing the [No Label]I:\Movies with "/Media" we will get our basic (but not yet valid) web file reference.

Of course, to keep our code flexible, we wish this to be as dynamic as possible when dealing with our movie category sub folders... which can vary greatly and change over time. And thus, the devil is in the details which are found as remarks in the code below.

Basically, you should be able to access your HTML content from your browser and traverse down to a single MOVIE\?.htm page before continuing.

Using the Code

This was done quickly in C# as a desktop console application. But can be accomplished in most any TEXT file parsing/editing coding language... it's the process and approach we are providing here.

Copy and paste the code here... into a new .NET Desktop Console project we will call EMDB_VOD...

Add HtmlAgilityPack using the NuGet interface...

Now onto the heavy lifting (well, not so heavy really)....

You will need these configurations to allow for nuances in your setup...

XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
    <add key="LocTrans" value="Location:"/>
    <add key="VODRoot" value="/Media" />
     <add key="PathSkip" value="2"/> <!--Default is 2-->
  </appSettings>
  </configuration>

The config values are for adjusting your physical setup...

LocTans is the EMDB Location: label used in the HTML Templates... and is user language definable... thus, we need to know how to find the OS path.

VODRoot is the Virtual Directory Name used by your web site...

PathSkip is the array element count to SKIP when converting from OS to WEB pathing... see Points Of Interest below:

JavaScript
using HtmlAgilityPack;
using System;
using System.Configuration;
using System.IO;
using System.Linq;

namespace EMDB_VOD
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Count() != 1)
            {
                Console.WriteLine("INVALID USAGE:  must give EMDB HTML folder => 
                                  EMDB_VOD <HtmlFolderPath>");
               return;
            }
           
            // '/Media' is a virtual directory in web site root
            var vodRoot = ConfigurationManager.AppSettings["VODRoot"];
            // Html page Location label (can be user defined in EMDB templates)
            var locTrans = ConfigurationManager.AppSettings["LocTrans"];
           
            // how much of OS path is skipped to sync with vodRoot
            var locSkip = 2;
            int.TryParse(ConfigurationManager.AppSettings["PathSkip"], out locSkip);

            var files = Directory.GetFiles(args[0], "*.htm", SearchOption.TopDirectoryOnly);
            foreach (string f in files)
            {
                Console.WriteLine(f);
                var htmlDoc = new HtmlDocument();
                htmlDoc.Load(f);
                
                var details2 = htmlDoc.GetElementbyId("details2"); // one big block of 
                                                                   // HTML sans tags
                var start = details2.InnerText.IndexOf(locTrans)+
                                        locTrans.Length;           // find Location Label 
                                                                   // and skip it
                var end = details2.InnerText.IndexOf("\r", start); // rest of line is 
                                                                   // our file path
                var filePath = details2.InnerText.Substring
                               (start, end - start).Split(Path.DirectorySeparatorChar);
                var path = vodRoot + "/" + string.Join("/", 
                           filePath.Skip(locSkip)).Trim().Replace(" ", "%20");

                // get the cover image node
                var cover = htmlDoc.DocumentNode.SelectSingleNode("//img[@class='shadow']");
                // insure only one click event handler
                cover.Attributes.Remove("onclick");
                // add our click event handler
                cover.Attributes.Add("onclick", "window.location.href='" + path + "'");
                
                string tooltip = cover.GetAttributeValue("alt", null);
                if (!string.IsNullOrEmpty(tooltip))
                {
                    cover.Attributes.Remove("title");
                    cover.Attributes.Add("title", tooltip.Replace("cover", "click to play"));
                }
                // make it so
                htmlDoc.Save(f);
            }
        }
    }
}

Running the above code against the EMDB Export folder (I:\Html\Movies) will modify all htm files...

Then using your smart device browser, connected on the same network, you can now enter the address for this web site... like 192.168.6.13... and you should see the site Index page... click on any cover image to get that movie details page and clicking on that page cover image will cause your browser to launch the systems default media player for playing that content.

I prefer to set the system default media player to VLC... but not always possible... which is why we use different codec and Mime types so that our browsers can wire up the player automatically.

Points of Interest

HyperTextAgilityPack makes this a straightforward search and replace operation... but there are a couple of interesting handlers that should be addressed.

JavaScript
var filePath = 
   details2.InnerText.Substring(start, end - start).Split(Path.DirectorySeparatorChar);

This assignment sets up for a quick and dirty 'strip leading parts' of a path.

Checking below, we see that our friend, the 'Array.Join' method, will allow us to pass over or Skip a specific number of 'Parts' or segments of the OS path. Notice that we first threw away everything left of the COLON in the 'Location:' part of our source text... simple SubString using start index and ending indexing.

Then when performing a Split on the OS path, we get a number of array elements depending on how many slashes are in the path... (and that colon by the way)... Thus using the example path to Wizard Of OZ.mp4 above, we will obtain a string array with four elements... the first will be the drive colon... the second will be Movies... the third will be Classic and the final will be the filename complete with extension. Now imagine what we obtain if the path contains Classic\Western\MovieName.Ext... in this case, we will obtain five elements to the array... BUT THE IMPORTANT POINT IS... the first two are always the elements we do not desire in our web relative file path...

And doing that chore is easy with string join on the array that SKIPS the first two elements... as shown below:

JavaScript
var path = vodRoot + "/" + 
          string.Join("/", filePath.Skip(locSkip)).Trim().Replace(" ", "%20");

In addition to making the valid Relative file reference, we also trim out any leading/trailing spaces so we can perform a poor man's HTML.ENCODING for spaces... Note that I have had some very confusing results using HTML.ENCODE methods... so if you have file names with embedded single quotes or some such... you will want to escape them as well.... It is interesting to note that EMDB does not use this file name much... so I normally save my videos with 'friendly names' and use the EMDB Title / Alternate Title which can contain unfriendly chars.

To keep this example concise and clear, we have chosen to add the 'onclick' attribute to the existing Cover Image tag.... we also add a title attribute for use as tool tips.

History

  • 20th October, 2020: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionThank you Pin
Member 1559865911-Apr-22 8:17
Member 1559865911-Apr-22 8:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.