How to stream TV to VLC

This method works a lot better than the first method. It works with phones, windows, Linux and other devices that support HLS. Mainly in this blog post we will be streaming to VLC Player. VLC Player is available for the phone and windows. HLS stands for HTTP Live Stream. You will also use a RAM Disk to store the stream pieces on. Don’t worry, you only need 32MB of RAM free, since your storing 5 video files that are 5-seconds each. We use a RAM Disk because its faster since it is not a motorized disk(like a HDD) and when computer loses power all files on that disk are gone. It writes 5 files, after the 5th file is done it deletes the first file and creates a new one. Plus it stores a M3U8 Playlist that is updated everytime a new file is created.

The steps

  1. Install Unreal Live Server and Unreal Media Server. See the first blog post here for instructions you don’t need the archival server. Also Microsoft Internet Information Services(if not installed).
  2. Install SoftPerfect RAMDisk from MajorGeeks not the offical website. MajorGeeks have the freeware version. The newer ones are shareware and are not free.
  3. After installing the RAM Disk open RAM Disk control panel up and add a ramdrive NTFS Formatted and 32MB of memory.
  4. After that download the HLS Configurator tool for IIS. Its a tool that I made that will configure the .m3u8 MIME type and set UMediaServer service startup type to Manual. Make sure to put that file somewhere the file can always be available on the computer.
  5. Next run the tool as administrator, and tell it the drive letter of the RAM Drive that was mounted. If you get an error saying that a file could not be found, then you probably didn’t install Unreal Media Server
  6. Next in the RAM Disk control panel click Tools then Applications then add the downloaded tool to the list. This will create the IIS Config file and start UMediaServer service after the drive is mounted on next restart.
  7. Next open Internet Information Services Manager from Administrative Tools
  8. If you want to use the orignal Port# delete the Default Website
  9. Right click The Sites folder and click Add Website…
  10. For Site Name type My TV if you are wanting to keep the default website type port 8321 for the port.
  11. For Physical path type the root path of the RAMDisk. For example if its Drive V then the root path is V:\
  12. Click Connect as… button and enter a administrator Username and password that is used in Windows
  13. Click OK button on all Windows
  14. Next open Unreal Media Server Configuration tool
  15. Right click the TV live broadcast that you named and click Start HLS Broadcasting…
  16. Enter the website URL of your TV stream for example if your hostname is delphijustintv.com then enter http://delphijustintv.com But if you are using port 8321 then its http://delphijustintv.com:8321
  17. For the Web Folder path enter the root of the RAMDisk. For example Drive V will be V:\
  18. Check always running.
  19. Click OK. Your all done now in VLC Media player it should play the TV stream. You will have to open tv.m3u8 or whatever file in the ram drive that ends with .m3u8. So for tv.m3u8 and http://delphijustintv.com as root URL will be http://delphijustintv.com/tv.m3u8 or if it uses port 8321 http://delphijustintv.com:8321/tv.m3u8
TV Streaming in VLC
program HLSIIS;
{$RESOURCE HLS-IIS-DATA.RES}
{
 This is the source code.
 HLS Configurator for Microsoft Internet Information Services
 You will need Unreal Media Server.
}
uses
  SysUtils,math,
  windows,
  dialogs,
  Classes,
  shellapi;
const
appkey='Software\Justin\TVStreaming';//settings key name
EVENTLOG_TYPES:dword=EVENTLOG_INFORMATION_TYPE or eventlog_warning_type;
REG_RAMDISK='RAMDisk';//Registry Value that has the Drive Letter
ServiceManual:dword=3;//Manual Service Startup type
AppName='TV Streaming';//The name of this tool
type ERegistry=class(Exception);//Registry error exception
ENet_exe=class(exception);//net.exe execution error exception
var hk:hkey=0;//Tool setting key
hksrv:hkey=0;//Service Key
S:String='V';//String that contains the drive letter
DriveLetter:AnsiChar;//Drive letter
WebConfig:tresourcestream;//web.config file
rs,dispConfig,Error:dword;//some dword variables
regerror:longint;//registry error variable
UMediaServer:Shellexecuteinfo;//net.exe execution info variable
HEL:thandle;//eventlog handle
label setRamdisk;//for retrying when a bad drive letter has been typed in

procedure InstallEventLog;
{
 Installs this tool for errors to be put in the event log.
}
var hk:hkey;
disp:Dword;
begin
regcreatekeyex(HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Services\Eventlog\Application\HLS-IIS',0,NIL,
REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NIL,HK,@Disp);
regsetvalueex(hk,'EventMessageFile',0,reg_sz,pchar(paramstr(0)),(1+length(
paramstr(0)))*sizeof(char));
regsetvalueex(hk,'TypesSupported',0,reg_dword,@EVENTLOG_TYPES,4);
regclosekey(hk);
end;

procedure ReportError(E:Exception);
{
 Reports any errors to the eventlog.
}
var EStrings:array[0..1]of pchar;
cname:string;
errorcode:dword;
begin
errorcode:=getlasterror;
cname:=e.classname;
estrings[0]:=pchar(cname);
estrings[1]:=pchar(e.message);
if(not reportevent(hel,eventlog_warning_type,1,2,nil,2,4,@estrings,@errorcode))
or(dispConfig=reg_created_new_key)then MessageBox(0,pchar(E.ClassName+': '+
e.message),appname,mb_iconerror);
if dispconfig=reg_created_new_key then begin regclosekey(hk);hk:=0;regdeletekey(
hkey_local_machine,appkey);end;
end;

function HasDrive:boolean;
{
Checks drive letter that has been enter to see if it is correct
returns true for valid letter otherwise false
}
begin
result:=(Length(s)<>0);//checks the length of the string to be sure that it has aleast one charactor
if not result then exit;
driveletter:=upcase(s[1]);//set drive letter to the uppercase letter.
result:=(ord(driveletter)>=ord('A'))and(ord(driveletter)<=ord('Z'))and(
GetLogicalDrives and trunc(Power(2,ord(driveletter)-ord('A')))>0);
//^ Performs drive letter checking and also see if it exists.
if result then setvolumelabel(pchar(driveletter+':\'),'HLSDrive');
//^ If the drive letter is correct then label the drive.
end;

begin
installeventlog;
hel:=registereventsource(nil,'HLS-IIS');
try
zeromemory(@umediaserver,sizeof(umediaserver));//initialize the shellexecuteinfo buffer
umediaserver.cbSize:=sizeof(umediaserver);//set its size
umediaserver.fMask:=SEE_MASK_NOCLOSEPROCESS;//set flags
umediaserver.lpFile:='net.exe';//set filename to net.exe
webconfig:=tresourcestream.CreateFromID(hinstance,1,'CONFIG');
//^ Load web.config from resource
dispconfig:=reg_created_new_key;
regerror:=regcreatekeyex(hkey_local_machine,appkey,0,nil,reg_option_non_volatile,
key_all_access,nil,hk,@dispconfig);
//^ Create tool settings key
if regerror<>error_success then raise ERegistry.Create(syserrormessage(regerror));
//^ Checks to see if it has successfully created or opened the key
rs:=1;//sets the registry size for the driveletter buffer
if regqueryvalueex(hk,reg_ramdisk,nil,nil,@driveletter,@rs)<>error_success then
begin
//^ Checks to see if the drive letter has been set or not
regerror:=regopenkeyex(hkey_local_machine,
'SYSTEM\CurrentControlSet\Services\UMediaServer',0,key_all_access,hksrv);
//^ Opens the UMediaServer service key
if regerror<>error_success then raise ERegistry.Create(syserrormessage(regerror));
//^ Checks to see if it successfully opened the key
umediaserver.lpParameters:='stop UMediaServer';
umediaserver.nShow:=sw_show;
//^ prepare for stopping UMediaServer
if not shellexecuteex(@umediaserver) then raise ENet_exe.Create(syserrormessage(
getlasterror));//stop umediaserver
waitforsingleobject(umediaserver.hProcess,infinite);//wait for net.exe to finish
getexitcodeprocess(umediaserver.hProcess,error);//get errorlevel
if error>0then raise ENet_exe.createfmt(
'Net.exe return %d when stopping Unreal Media Server',[error]);
//^ Checks to see if errorlevel is > 0
closehandle(umediaserver.hprocess);
umediaserver.hProcess:=0;
//^ closes net.exe process handle
regerror:=regsetvalueex(hkSrv,'Start',0,reg_dword,@servicemanual,4);
//^ Changes UMediaServer service started type to manual
if regerror<>error_success then raise ERegistry.Create(syserrormessage(regerror));
//^ if failed throw an exception
setRamdisk://Drive letter retry label
if not inputquery(appname,'Enter RAMDisk drive letter:',s)then
raise exception.Create('Installation aborted');
//^ ask for drive letter
if(length(s)>1)or(length(s)=0)or(not hasdrive)then begin
messagebox(0,'Bad drive letter or drive doesn'#39't exist','TV Streaming',
mb_iconerror);
goto setRamdisk;
end;// validate drive letter
regerror:=regsetvalueex(hk,reg_ramdisk,0,reg_binary,@driveletter,1);
//^ save drive letter
if regerror<>error_success then raise ERegistry.Create(syserrormessage(regerror));
//^ check to see if it did write to registry
end;
s:=driveletter;
if not hasdrive then raise Exception.Create('The drive letter setting in registry is invalid');
//^ validate drive letter read from registry
webconfig.SaveToFile(driveletter+':\web.config');
//^ create Internet Information Services configuration in the root of ramdisk
umediaserver.nShow:=sw_minimize;
umediaserver.lpParameters:='start UMediaServer';
if not shellexecuteex(@umediaserver)then raise ENet_exe.Create(
'Failed to start Unreal Media Server');
//^ Start Unreal Media Server
waitforsingleobject(umediaserver.hprocess,infinite);//wait for it to finish
getexitcodeprocess(umediaserver.hProcess,error);//get errorlevel
if error>0 then raise ENet_exe.CreateFmt(
'Net.exe return %d when starting Unreal Media Server',[error]);
//^ if errorlevel >0 then throw an exception.
// now if we get to this line,we know everything went through
reportevent(hel,eventlog_information_type,1,1,nil,0,0,nil,nil);
except
on E:exception do
reportError(E);
end;
if hk<>0 then regclosekey(hk);
if hksrv<>0 then regclosekey(hksrv);
if umediaserver.hProcess<>0then closehandle(umediaserver.hprocess);
deregistereventsource(hel);
//^ cleanup before closing
end.

Published by Justin Roeder

I am an electronics engineer and computer programmer that has autism. I learned by myself

Leave a comment

Your email address will not be published. Required fields are marked *