NT Konferenca 2012 lectures schedule for mobile devices

I’ve created a simple ASP MVC 4/jQuery Mobile UI web site that helps you with NT Konferenca 2012 lectures schedule if you have a mobile device (now, who doesn’t?). Note that it isn’t a well thought, thoroughly and carefully crafted site. Instead it is a quick and simple one, actually it took me an hour (thanks to wonderful tools – VS2010, NuGet and technologies - .net 4.0, OData, WCF Data Service, jQuery Mobile UI, ASP MVC 4 and so forth).

Feel free to browse the lectures schedule through ntk.rthand.com. I might add additional features in next days – feedback me if you’d like to see a feature.

Calling WCF services from within Sql Server

It is possible to create a managed .net stored procedure for SQL Server that acts like a WCF client. SQL Server 2005 at least is required. But I won't talk about how to. I'd rather discuss an odd error you can encounter while performing this stunt.

On development machines one can encounter this odd error when WCF client is being initialized, after managed stored procedure is being invoked through T-SQL.

Msg 6522, Level 16, State 1, Procedure CalcAdd, Line 0 A .NET Framework error occurred during execution of user-defined routine or aggregate "CalcAdd": System.Configuration.ConfigurationErrorsException: The type 'Microsoft.VisualStudio.Diagnostics.ServiceModelSink.Behavior, Microsoft.VisualStudio.Diagnostics.ServiceModelSink, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' registered for extension 'Microsoft.VisualStudio.Diagnostics.ServiceModelSink.Behavior' could not be loaded. (C:\Windows\Microsoft.NET\Framework\v2.0.50727\Config\machine.config line 192) System.Configuration.ConfigurationErrorsException: at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult) at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSection(String configKey, Boolean getLkg, Boolean checkPermission) at System.C...

Note that everything is configured properly and WCF client inside stored procedure should initialize just fine. The problem is somehow connected to machine.config file or better, to some initialization of types defined there.

After few google searches I've come across this post from MS' Jason Pang. Looks like the exception is linked to WCF debugging feature, usually installed on development machines - this debugging service has problems with WCF client running under SQL Server.

Workaround: (Temporary) disable WCF debugging by invoking this command line utility:

[Program Files]\Microsoft Visual Studio 9.0\Common7\IDE\vsdiag_regwcf.exe -u

Now the WCF client inside SQL Server runs just fine. After you've done you can re-enable WCF debugging services by calling same exe with different parameter:

[Program Files]\Microsoft Visual Studio 9.0\Common7\IDE\vsdiag_regwcf.exe -i

Note that administrator privileges are required to disable/enable it.

Building your own Media Center

Since I have IPTV I am really annoyed by not having an option to save programs, like in old video recorder and cable network days. True, one can still save using video recorder, but the problem is that video recorder can't change channels on STB (set top box) and thus you are limited to a single channel. Pretty much useless. The other option is using personal recorder, a feature provided by my IPTV provider. But again, the drawbacks are enormous: there is a monthly fee, you are limited to 6 hrs of total saved content. Even worse limitation is that your content can be stored for maximum of two days (forget vacation, or drive back to home every two days to watch the saved content). But there's another drawback, in fact mother of all drawbacks: only a few channels and not all shows on those channels are allowed to be saved. Total useless crap.

Hence the idea of my own media center. After all I live by using my development skills, why not use them for this one. So, RH Media Center project was born.

The main objectives:

  1. ability to save from IPTV
  2. ability to schedule saving
  3. ability to playback saved content
  4. ability to control RH Media Center by remote

Hardware requirements

  1. A computer (server which is always on preferably) that will be used to save content
  2. A computer to playback the saved content (possibly attached to TV). In my case this is my laptop.
  3. A PocketPC device (remote control)

1. and 2. can be the same computer, whatever is feasible for you.

Implementation

VLC media player ActiveX control is at the core of RH Media Center. VLC media player is a free, open source, cross platform application that plays just everything out there, including SIOL IPTV streams. And luckily for me, they have an ActiveX control, too. In fact I've build my application around this ActiveX control using Windows Forms UI. Here is how it looks:

 image

Video (both IPTV stream and saved content playback) is rendered and saved by VLC. You can also see a bunch of controls on the top and the channel listing on the right. There is also saved content listing in the docking panel next to channel listing.

image

Test saved contents listing

Note that UI is pretty rough at this time as prettiness wasn't one of the objectives. Anyway the objectives 1. and 3. are done now.

Scheduling

Once the core functionality is done (see above) the scheduling is pretty easy. The application should parse command line arguments and start saving given channel for given time. The content file name should be made of given argument (i.e. name of the show) plus date. Here is an example:

RhMediaCenter.exe rec "Channel" ShowName 120

This means that content from "Channel" will be recorded for 120 minutes to a file name

ShowName_hh_mm__dd_MM_YYYY.ps

ps is MPEG-PS extension. You'll note that I didn't specify when should the recording start aka scheduling. This step is done using Task Scheduler - no wonders there, just run that command line at any time you specify and that's it. A bit rough to configure but it works just fine (in future I'll enhance the configuration step).

Remote control

Every decent media center has remote control capabilities. How can you skip those commercials otherwise? I've figured out, that I have a bunch of PocketPCs lying around and collecting dust. At the same time I have a Wi-Fi network at home. Get the idea? Yes, I'll use PocketPC over Wi-Fi to control my media center. The technology of choice is WCF which is partially supported with .NET Compact Framework 3.5. BasicHttpBinding, here we go.

So I've build a simple Windows Mobile 6 application which looks like this:

image

It allows to connect to preferred RH Media Center through providing a proper IP, it can get a list of saved content and it allows you to play any of them. It features also a Pause button and move forward (left group of buttons) or backward (right group of buttons) for a given time span. And after creating a hole in Windows Firewall on computer where RH Media Control runs it just works.

The only problem is how to build WCF service client code for .net compact framework. This feature is provided by Power Toys for .NET Compact Framework 3.5's NetCFSvcUtil utility that does the similar job as Service Metadata Utility (SvcUtil.exe) for .net framework.

Conclusion

I solved the biggest IPTV issue - saving programs and playback of saved content using a remote control. By using .net 3.5/Windows Forms/WCF/Compact framework and VLC ActiveX control it took me only around 10 hours of total time over the weekend (most of the time I used for plumbing , user interface and figuring out VLC ActiveX oddities). If you wonder why I'd used Windows Forms instead of WPF: because I was experimenting at the beginning (and the project is still an experiment) and I have no 3rd party controls for WPF yet - so it was easier with Windows Forms. In future I'll be definitely using WPF.

I have to say that .net/VLC made it so easy to build this pet project - the ease of putting pieces together is amazing.

BTW, Is anybody interested in binaries? (I am not saying I'll provide them nor that I won't provide them :-))

"The target assembly contains no service types. You may need to adjust the Code Access Security policy of this assembly." annoyance

Did you ever encounter this dialog box when dealing with WCF services?

"The target assembly contains no service types.  You may need to adjust the Code Access Security policy of this assembly."

It might happen when you run application at debug time. It is highly annoying and time consuming (it pauses application for more than one minute without any apparent reason). But what does it mean and why does it happen?

When you create a project from a WCF project templates Visual Studio knows that this project is a WCF service and thus it offers two debug time helpers: WCF Service Host and WCF Client. These two guys are intended to help you with running and testing WCF services without writing any code - they just appear at debug time. So far so good. But why the annoying dialog?

The dialog in question means that you have a project, created using one of the WCF project templates, with an interface marked with ServiceContract attribute and in the same project you don't have a class that implements this interface (perhaps you implemented that interface in another project). So, the WCF Service Host can't find a suitable class to host the service and it complains through that dreaded dialog box. Note that WCF Service Host is pretty dumb and it is incapable of searching through other projects in same solution. OK, the solution is to stop running WCF Service Host or even better, instruct it which class implements the interface in question. Well, AFAIK the later is impossible while the former can be done through project file modification using notepad. Here is how:

Delete this line from your project file:

<ProjectTypeGuids>{3D9AD99F-2412-4246-B90B-4EAA41C64699};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

And you won't see WCF Service Host or dreaded dialog anymore.

The question is, why didn't [MS] think of these scenarios before?

BTW, if you just want to stop WCF Client from runing then delete this command line argument: /client:"WcfTestClient.exe", created by WCF project template.