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...
="1.0"="utf-8"
<configuration>
<appSettings>
<add key="LocTrans" value="Location:"/>
<add key="VODRoot" value="/Media" />
<add key="PathSkip" value="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:
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;
}
var vodRoot = ConfigurationManager.AppSettings["VODRoot"];
var locTrans = ConfigurationManager.AppSettings["LocTrans"];
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");
var start = details2.InnerText.IndexOf(locTrans)+
locTrans.Length;
var end = details2.InnerText.IndexOf("\r", start);
var filePath = details2.InnerText.Substring
(start, end - start).Split(Path.DirectorySeparatorChar);
var path = vodRoot + "/" + string.Join("/",
filePath.Skip(locSkip)).Trim().Replace(" ", "%20");
var cover = htmlDoc.DocumentNode.SelectSingleNode("//img[@class='shadow']");
cover.Attributes.Remove("onclick");
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"));
}
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.
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:
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 char
s.
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
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.