Friday, December 3, 2010

Android: My Android Non-Phone

I recently purchased a Samsung Epic 4G on eBay to use as a personal media device.  It is not activated on any carrier’s voice or data plan, I use it like an iPod Touch.  I was able to get it for a pretty reasonable price because it has a bad ESN, meaning Sprint  will no longer activate this phone on their network due to a non-paying user.  Verizon also does this, so you can get phones for their network cheaply also.

Its nice to be able to check for new emails at glance, and I also have the Google Voice app installed so I can text from it and listen to voicemails.  Keep in mind that this only works when I’m on a wifi network, but for me that is home and work which covers 80% of my day.

I also use Google Listen to download podcasts for listening during my daily commute.  Unfortunately there is a bug in the current version which required me to associate my gMail account when previously I had only had it associated with my Google Apps for Domain account.

The GPS is functional, although Google maps downloads data in real time, so you have to download a different map application that is built for offline usage if you want to see maps in your car.

You can install Skype, but unfortunately Skype for Android is not fully implemented due to the fact that it would compete with the carrier’s service, so you can only use to chat and make Skype to Skype calls.  I did however get calling functional following a lifehacker article (which I’m unable to find now).  It involved getting a SipGate.com number and installing SipDroid and Google Voice Callback apps.  However there was about a 2 second audio delay during one test call, and less delay, but much more static on a second text call.  My cell phone contract expires in 6 months, so I’ll probably re-evaluate a calling solution then.

Android: Can’t establish a reliable data connection to the server

I have a Samsung Epic 4G and received the following error when attempting to add a 2nd Google account to my phone: “Can’t establish a reliable data connection to the server”.  Apparently this is a bug in Android.  The work around for me was to open the YouTube application and log in with my desired Google account.  After logging in to YouTube my account showed up in settings and I was able to use the account.  This does not seem to work for all users, some apparently have to do a hard reset.

Wednesday, November 24, 2010

Phone: Transfer Your Google Voice Number to a Google Apps Account

I have a Google Apps account and a regular ‘ol gMail account, but now that Google Apps offers Google’s full line of product offerings, I’m trying to phase out and move my old data.  Part of this is moving my Google Voice number to my Google Apps account.  Turns out you can move it by filling out this form.  Took them about a week to complete the move.

Friday, November 12, 2010

Code: Silverlight Media Element Relative Urls

The best way I’ve found to use relative urls for media items in Silverlight is to place the media files (mp3, wmv, mp4, etc) in the ClientBin folder of the website (same directly as the .xap file) 

image

Ensure that the Build Action is set to Content and Copy To Ouput Directory is set to Copy if Newer:

image

Then you can reference the files with a single forward slash then the file name:

<MediaElement x:Name="DangerZoneTune" Source="/DangerZoneTune.mp3"></MediaElement>

Monday, October 11, 2010

Code: jQuery AJAX and Templates

The jQuery Templating plugin Microsoft’s web team has been working on has been accepted by the jQuery team check out the code below for usage with an AJAX web service.

1.  Reference jQuery 1.4.2 or later, and the template .js file (Templates will be an included part of jQuery 1.5)

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<
script type="text/javascript" src="/Scripts/jquery.tmpl.js"></script>


2.  create the template that will be applied to each item in your result set, notice the ${} syntax



<script id="clientTemplate" type="text/html">
<li><a href="Detail.aspx?q=${Id}" target="_blank">${Description}</a></li>
</script>


3.  Give the DOM element that will house the template an ID



<div>
<
ul id="MatchingQuestions">
</
ul>
</
div>


4.  Create the AJAX Call to your web service.  Notice that it is binding to the “d” element of the resulting msg object.



function SearchQuestions(text) {
$.ajax({
type: "POST",
url: "/NotifierWS.asmx/SearchQuestions",
data: "{'searchText': '" + text + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
$("#clientTemplate").tmpl(msg.d).appendTo("#MatchingQuestions");
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.statusText);
}
});
}


5. Create a web service method (the service class will also need to have the ScriptService attribute)


[WebMethod]
public QuestionItem[] SearchQuestions(string searchText)
{
List<QuestionItem> result = new List<QuestionItem>();
foreach (Business.Question q in Business.Question.SearchQuestions(searchText, 5))
{
result.Add(new QuestionItem(){ Id = q.Id, Description = q.Title});
}
return result.ToArray();
}


public class QuestionItem
{
public long Id { get; set; }
public string Description { get; set; }
}

Friday, September 24, 2010

Audiobook: Call of The Wild by Jack London

I have a 35 minute drive to work, and lately I've been listening to some free audiobooks from Librivox.  I recently finished Call of the Wild by Jack London.  It was a great book and the readers do a good job as well.  I wish the first reader would have done the entire book, but the rest of the readers do a pretty good job.

Wednesday, September 8, 2010

Computer: How to Replace a Key on a Dell Studio Laptop

My cute as a button daughter pulled the caps lock key off my Dell Studio Notebook the other day and it took me a while to figure out how to put it back on.  The keys on this keyboard have 3 pieces.  The black part your fingers touch, a metal U shaped paper clip looking piece, and a white scissor piece of plastic.  The trick to reinstall is to carefully pull the white scissor off of the key and attach it standalone to the notebook.  Then make sure the metal piece is attached to the black caps lock key, slide the metal piece into its holder on the keyboard and press the caps lock key firmly down.  The white scissor piece then clicks into place and its attached.

Tuesday, September 7, 2010

Code: No source control? Use DropBox

Recently I was working on a small development project that was only semi-work related.  I didn't want to use my work's source control since it was non-work and I didn't need versioning, just backup.  I created the project in my Dropbox folder and it worked really well to backup and keep the project synced across machines.

Wednesday, August 25, 2010

Code: FullText Search in SQL Server 2008 Express

In order to do full text search in SQL Server 2008 Express (Original or R2) you have to install the "Advanced Services". You can find the download for original here or R2 here.




After upgrading your current instance (or installing the new instance) you also need to make sure the Full Text service is enabled

You can then follow this guide to add a full text catalog and index.

If you are using SSMS and want the full text index scripts to be generated when you generate the create script for a table, you'll need to modify a setting.  Go to  Tools | Options - Scripting page and then scroll down to table options and select "Script full-text indexes". This will script the full-text indexes with the table definition.

If you are using the scripts then in a Visual Studio Database project, don't forget to set the Build Action property of the file to "Build", otherwise it will drop the indexes when it deploys

Tuesday, August 17, 2010

Code: Silverlight Navigation from a UserControl

For some reason Silverlight does not provide the ability to access a page's NavigationService from a user control, so in order to navigate correctly you have to manually walk the control tree. See the method below to use as a helper class.

public static class NavigationHelper
    {
        public static void Navigate(Uri url, UserControl control)
        {
            Page pg = GetDependencyObjectFromVisualTree(control, typeof(Page)) as Page;
            pg.NavigationService.Navigate(url);
        }

        private static DependencyObject GetDependencyObjectFromVisualTree(DependencyObject startObject, Type type)
        {
            //Walk the visual tree to get the parent(ItemsControl)
            //of this control
            DependencyObject parent = startObject;
            while (parent != null)
            {
                if (type.IsInstanceOfType(parent))
                    break;
                else
                    parent = VisualTreeHelper.GetParent(parent);
            }
            return parent;
        }
    }

Monday, August 2, 2010

Code: Create Thumbnail from Video using VLC command line

If you want to create a thumbnail from a video, you can use VLC and its command line arguments as seen below. This was tested using VLC 1.1.2

C:\Users\amiller.NG>"C:\Program Files (x86)\VideoLAN\VLC\vlc.exe" --video-filter scene -V dummy --scene-width=80 --scene-format=jpeg --scene-replace --scene-ratio 24 --start-time=6 --stop-time=7 --scene-path=D:\ --scene-prefix=thumb D:\1.mp4 vlc://quit

--scene-path is the output directory
--scene-prefix is the output filename
--scene-format can be jpeg, jpg, or png
--start-time is the location in the video (in seconds) to grab the image from
--stop-time tells the vlc to stop playing the video at that point
--scene-width specifies the output width of the thumbnail in pixels, you can optionally include --scene-height, but the image will be stretched to fit that dimension.

Thursday, June 24, 2010

Code: WPF Binding a TreeView to an Array of Complex Objects

I’m taking my first stab at WPF as a learning exercise and figured out how to bind an array of objects (with sub-objects) to a TreeView control. 

First, here is the resulting output:

image

 

This TreeView binds to an Array of type ClientWithAssets, which contains an array of Asset and a Client as properties. 

image

Step 1: make sure your sub-objects are public properties and not members! (I was stuck for an hour because of this).

Step 2: Drop a TreeView control on your window and define the hierarchy:

        <TreeView HorizontalAlignment="Stretch" Margin="12,41,12,12" Name="treeView1" VerticalAlignment="Stretch" ItemsSource="{Binding}" >
<
TreeView.ItemTemplate>
<
HierarchicalDataTemplate ItemsSource="{Binding Assets}">
<
TextBlock Text="{Binding ClientItem.ClientName}"/>
<
HierarchicalDataTemplate.ItemTemplate>
<
DataTemplate>
<
TextBlock Text="{Binding Name}"/>
</
DataTemplate>
</
HierarchicalDataTemplate.ItemTemplate>
</
HierarchicalDataTemplate>
</
TreeView.ItemTemplate>
</
TreeView>


Step 3: Bind on window load:



private void Window_Loaded(object sender, RoutedEventArgs e)
{
treeView1.ItemsSource = ClientWithAssets.FindAll();
}

There are many, many ways to perform this same functionality, but this is what made most sense to me.

Thursday, June 17, 2010

Code: Create Properties for ASP.Net Web Form Pages

When developing web form pages I like to create properties to interact with user input controls that are more complex than simple strings (Enums, DateTime, etc).  This allows me to keep more of my page strongly typed.

using System;

namespace WebFormsSamples
{
public partial class PageProperties : System.Web.UI.Page
{
public enum PrimaryColors
{
Red,
Blue,
Yellow
}

public PrimaryColors SelectedColor
{
get
{
PrimaryColors result;
Enum.TryParse<PrimaryColors>(ColorInput.SelectedValue, out result);
return result;
}
set
{
ColorInput.SelectedValue = value.ToString();
}
}

public DateTime SelectedDate
{
get
{
DateTime result = DateTime.MinValue;
DateTime.TryParse(DateInput.Text, out result);
return result;
}
set
{
DateInput.Text = value.ToShortDateString();
}
}

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindControls();
SelectedColor = PrimaryColors.Yellow;
SelectedDate = DateTime.Today;
}
}

/// <summary>
///
Notice the strong types here!
/// </summary>
protected void SaveInput_Click(object sender, EventArgs e)
{
SaveItem(SelectedColor, SelectedDate);
}

private void BindControls()
{
ColorInput.DataSource = Enum.GetNames(typeof(PrimaryColors));
ColorInput.DataBind();
}

private void SaveItem(PrimaryColors color, DateTime date)
{
lblResult.Text = SelectedColor.ToString() + " " + date.ToLongDateString();
}
}
}

Tuesday, June 8, 2010

Code: Encoding Videos using Expression Encoder

I wrote an article for MSDN magazine about Expression Encoder, check it out at http://msdn.microsoft.com/en-us/magazine/ff714558.aspx. This is my first article pretty exciting!

Friday, June 4, 2010

Events: Tech Ed 2010

Next week I’ll be attending TechEd 2010 in New Orleans.  If you are also going I recommend attending at least one of Jonathan Carter’s talks.  I went to a couple of his last year, and he is a pretty good presenter.  I don’t travel very often so I found a recent podcast by Scott Hanselman on travel tips very timely.  One of his recommendations was taking public transit instead of cabs to save money.  To get from the Louis Armstrong Airport in New Orleans to the convention center, it looks like you can use Jefferson Transit buses.   Take the E2 bus to the Superdome and then the W3 bus from the Superdome to the convention center.

Wednesday, June 2, 2010

Code: C# Optional Parameters

One of the new features of C# in .Net 4.0 is optional parameters.  VB has had this language feature for a while, and its nice to see it make its way to C#.  If you don’t like optional parameters you can still use method overloading, but it will definitely be useful in some situations.  To make a parameter optional, you just need to specify what the default value for the parameter is:

public int Add(int firstNumber, int secondNumber = 0, bool isAbsolute = false)
{
int result = firstNumber + secondNumber;

if (isAbsolute)
result = Math.Abs(result);

return result;
}

add

Wednesday, April 28, 2010

Code: Handling Back, Forward, and Middle Mouse Button Clicks

I’m currently studying to become a MCPD in Windows Forms development.  I don’t do very much development in windows forms, so some of what I’m learning is pretty new.  I learned today that .Net Windows Forms can easily handle mouse clicks that come from the back and forward buttons as well as the middle mouse button.  To do this you just need to handle the MouseClick event of a control as shown in the code below.

private void Form1_MouseClick(object sender, MouseEventArgs e)
{
switch (e.Button)
{
case System.Windows.Forms.MouseButtons.XButton1:                   
case System.Windows.Forms.MouseButtons.XButton2:
case  System.Windows.Forms.MouseButtons.Middle:
MessageBox.Show(e.Button.ToString());
break;
}
}

Friday, March 26, 2010

Code: C# Simple Multithreading Example using ThreadPool

Below you will find a simple, complete code sample for multithreading in C# using the ThreadPool class.  This sample uses a simple counter to track the number of threads that are active to prevent the application from closing before all threads have completed.  Although there are other ways to force a method to wait for all threads to complete before exiting, using a static counter allows you to create a separate method to determine when the application is allowed to exit.  This is useful for handling OnStop events on windows services.  Within the StopProcessing() method you could also set a flag that would prevent your application from creating new threads.

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6.  
  7. namespace MultiThreadedApp
  8. {
  9.     class Program
  10.     {
  11.         static int _threadCounter = 0;
  12.  
  13.         static void Main(string[] args)
  14.         {
  15.             for (int i = 0; i < 10; i++)
  16.             {
  17.                 CreateThread(i);
  18.             }
  19.  
  20.             StopProcessing();
  21.  
  22.             Console.WriteLine("Finished");
  23.         }
  24.  
  25.         private static void CreateThread(int threadId)
  26.         {
  27.             Console.WriteLine("Creating Thread {0}", threadId);
  28.             MethodParameters newParameter = new MethodParameters();
  29.             newParameter.ThreadId = threadId;
  30.             newParameter.ThreadCreated = DateTime.Now;
  31.             Interlocked.Increment(ref _threadCounter);
  32.             ThreadPool.QueueUserWorkItem(new WaitCallback(LongRunningProcess), (object)newParameter);
  33.         }
  34.  
  35.         private static void LongRunningProcess(object input)
  36.         {
  37.             MethodParameters inputParams = (MethodParameters)input;
  38.             Random random = new Random(((MethodParameters)input).ThreadId);
  39.             Thread.Sleep(random.Next(500, 5000));
  40.             Console.WriteLine("Thread {0} complete in {1} seconds", inputParams.ThreadId,
  41.                 (DateTime.Now - inputParams.ThreadCreated).TotalSeconds);
  42.  
  43.             Interlocked.Decrement(ref _threadCounter);
  44.         }
  45.  
  46.         private static void StopProcessing()
  47.         {
  48.             Console.WriteLine("Waiting for {0} threads to complete", _threadCounter);
  49.             while (_threadCounter > 0)
  50.                 Thread.Sleep(500);
  51.         }
  52.  
  53.         private class MethodParameters
  54.         {
  55.             public DateTime ThreadCreated { get; set; }
  56.             public int ThreadId { get; set; }
  57.         }
  58.     }
  59. }

Tuesday, March 23, 2010

Tech: HTPC build

I built a home theater PC recently using parts from Newegg and running Windows 7 media center.  I’ve been pretty happy with it so far, watching Netflix, Hulu, DVD’s, and home videos has worked out well.  There are however a couple issues I’ve noticed:

1.  I had to uninstall the Realtek audio drivers to get the HDMI audio to work.
2.  The HDMI video connection to my television doesn’t always work.  Sometimes I have to restart the computer or put it to sleep for the connection to be made.  It seems to work best if I turn the television on and set it to the correct input before turning on the computer.  I haven’t read any other reviewers having this issue, so it might be an issue with my Panasonic plasma.
3.  There is about a 1/2 inch black border on the outside of the television.  This isn’t all that surprising, however I did expect the ATI catalyst control center to allow me to correct the overscan.  This really is not noticeable though, and doesn’t bother me too much.

Here are the parts I used:
Motherboard: GIGABYTE GA-MA785GM-US2H
CPU: AMD Athlon II X2 240 Regor 2.8GHz Socket AM3 65W Dual-Core Processor
RAM: G.SKILL 2GB (2 x 1GB) 240-Pin DDR2 SDRAM DDR2 800 (PC2 6400)
Hard Drive: Western Digital Caviar Blue WD5000AAKS 500GB 7200 RPM SATA 3.0Gb/s 3.5
DVD: Sony Optiarc 24X DVD/CD Rewritable Drive Black SATA Model AD-7240S-0B
Case: hec Black 0.7mm Thickness SECC 7K09 Micro ATX Media Center / HTPC Case

The total cost for the system was $325.  I had access to Windows 7 via my TechNet subscription so that saved me an extra $200.  This was my first build using a micro-ATX motherboard and case, it was a tight fit getting all of the pieces in the case.  I also had to use an IDE to SATA power adapter I had, the power supply only had one SATA power connector.

Monday, March 15, 2010

Code: C# Best Practices

I found a nice C# coding best practices doc from DotNetSpider today: http://www.dotnetspider.com/tutorials/BestPractices.aspx

Great to use as a starting point for your own standards.

A couple things I’d change:

1.  There should only be 1 exit point in a method.  The word return should only appear once, and it should be the last line in the method.

2.  The Public regions should appear before Private regions in a class.  When navigating to a business method from a UI class it seems more natural to jump into the top of a file and work your way down.

Friday, March 12, 2010

Code: How To Run a .Net Windows Service as a Console Application

Attempting to debug a windows service can be a nightmare, especially if you are trying to debug the OnStart event by attaching to a local process.  To get around this you can configure the windows service to launch as a console application.  To do this go to the property pages of your service and select the Application tab.  Change the output type to Console Application:

image

Next modify the program.cs file by adding an args input parameter to the Main method and surrounding the logic in the method with an if statement like so:

Code Snippet
  1. static void Main(string[] args)
  2. {
  3.     if (args.Length == 0)
  4.     {
  5.         ServiceBase[] ServicesToRun;
  6.         ServicesToRun = new ServiceBase[]
  7.         {
  8.         new Service1()
  9.         };
  10.         ServiceBase.Run(ServicesToRun);
  11.     }
  12.     else
  13.     {
  14.         //DoWork();
  15.     }
  16. }

Now modify your service1.cs file to call the same worker method on start:

Code Snippet
  1. public partial class Service1 : ServiceBase
  2. {
  3.     public Service1()
  4.     {
  5.         InitializeComponent();
  6.     }
  7.  
  8.     protected override void OnStart(string[] args)
  9.     {
  10.         //DoWork();
  11.     }
  12.  
  13.     protected override void OnStop()
  14.     {
  15.     }
  16. }

Finally go to the Debug tab on the property pages and add a word to the Command line arguments text box:

image

Now just start debugging and your breakpoint will be hit!

image

Wednesday, March 3, 2010

Tech: One box to rule them all

I have home movies, I have downloaded movies, I subscribe to Netflix, I watch Hulu, and I have Dish Network with DVR service.  I want to do all of this on my Panasonic TV, why can’t one box handle all of this content?  Currently I’ve got my system down to two boxes with my new HTPC build and Dish Network DVR box.  How awesome would it be if those two boxes were combined?  Windows Media Center would support this if Dish Network would create (or allow the Windows team to) a PCI satellite card and WMC plug in.  Alternatively it could be accomplished for free with Boxee.  That box would sell like hotcakes.  It appears that DirecTV is partnering with Tivo again with Tivo’s new DVR service with online content support, but local content is still left out of the picture.

Why can’t cable/satellite providers realize this is what people want and partner up with hardware/software vendors to make it happen?  The first company to accomplish this would get a very strategic lead on the competition.

Code: An attempt was made to load a program with an incorrect format.

I received the following error message today when setting up a website in IIS 7 (on Windows 7):

Could not load file or assembly X or one of its dependencies. An attempt was made to load a program with an incorrect format.

This error was due to a 32 bit website on a 64 bit system.  To fix this you need to go to the Advanced Settings on the Application pool and set “Enable 32-Bit Applications” to True.

image

Tech: How To Permanently Set a Program To Run as Administrator

I got tired of right clicking notepad to run as administrator to edit my hosts file, and figured there had to be a way to make it always run as administrator. 

Right click on the program in the start menu and select Properties->Advanced check “Run as Administrator”. 

image

Monday, February 22, 2010

Code: The type 'int' must be a reference type in order to use it as parameter

I received a new error message developing and ASP.Net MVC page today:

The type 'int' must be a reference type in order to use it as parameter 'TModel' in the generic type or method 'System.Web.Mvc.ViewPage<TModel>'. 

Apparently MVC requires a reference type to use the constructor that accepts a type as a parameter.  I was trying to pass an int as the Model type.  The workaround was pretty simple, I just used ViewData and a generic MVC page (Inherits="System.Web.Mvc.ViewPage").

Tuesday, January 19, 2010

Code: Serializing and Deserializing Objects (Converting Objects to a String and Back)

Object serialization in .Net is pretty easy, once you have the right code.  It took me a few minutes to figure out the right code so I thought I’d post it here.  The code below is a working C# console app.

Code Snippet
  1. using System;
  2. using System.IO;
  3. using System.Xml.Serialization;
  4.  
  5. namespace TestApp
  6. {
  7.     public class Program
  8.     {
  9.         static string serializedObject;
  10.  
  11.         static void Main(string[] args)
  12.         {
  13.             Serialize();
  14.             Deserialize();
  15.         }
  16.  
  17.         static void Serialize()
  18.         {
  19.             Person p = new Person() { Age = 20, Name = "Bob" };
  20.             XmlSerializer serializer = new XmlSerializer(p.GetType());
  21.             using (StringWriter sw = new StringWriter())
  22.             {
  23.                 serializer.Serialize(sw, p);
  24.                 serializedObject = sw.GetStringBuilder().ToString();
  25.             }
  26.         }
  27.  
  28.         static void Deserialize()
  29.         {
  30.             XmlSerializer serializer = new XmlSerializer(typeof(Person));
  31.             Person p = (Person)serializer.Deserialize(new StringReader(serializedObject));
  32.             Console.WriteLine("Name:" + p.Name + " Age:" + p.Age);
  33.             Console.ReadLine();
  34.         }
  35.  
  36.         public class Person
  37.         {
  38.             public int Age { get; set; }
  39.             public string Name { get; set; }
  40.         }
  41.     }
  42. }

Friday, January 15, 2010

Code: Multiple Startup Projects in Visual Studio

Visual Studio has the capability to have multiple projects listed as startup projects.  This will allow you to launch and attach debugging to multiple applications at once.  This is very handy when debugging the encoding system locally.
To do this right click on the Solution icon in Visual Studio and select Properties.
Check the "Multiple Startup Projects" radio button
in the list of projects below the radio button change the Action to "Start" for the projects you want to launch.

image

Thursday, January 14, 2010

Code: Launch a Console Application in a New Window

I ran into a tricky situation today, How do I use a batch file to launch other batch files or console applications in a new console window?  The key to this is the START keyword.  So if you open up a new command prompt window and enter

test.bat

You will effectively transfer control of your current window to the test.bat file.  However, if you change your command to

start test.bat

The batch file will be launched in a new window allowing your first window to continue operation to perform other commands or launch more programs.

Wednesday, January 6, 2010

Code: Build an Adaptive Bitrate SMIL File Using XmlDocument

Code Snippet
  1. /// <summary>
  2. /// Builds a smil file based on .mp4 files found in a given directory
  3. /// Assumes files are named XXX_bitrate.mp4 (movie_300.mp4)
  4. /// </summary>
  5. public static XmlDocument BuildSmilFile(DirectoryInfo sourceDirectory)
  6. {
  7.     List<FileInfo> files = new List<FileInfo>();
  8.     files.AddRange(sourceDirectory.GetFiles("*.mp4"));
  9.  
  10.     //biggest file (highest bitrate) first.
  11.     files.Sort(delegate(FileInfo p1, FileInfo p2)
  12.     {
  13.         return p2.Length.CompareTo(p1.Length);
  14.     });
  15.  
  16.     XmlDocument result = new XmlDocument();
  17.  
  18.     //create element nodes
  19.     XmlNode smilNode = result.CreateElement("smil");
  20.     XmlNode headNode = result.CreateElement("head");
  21.     XmlNode bodyNode = result.CreateElement("body");
  22.     XmlNode switchNode = result.CreateElement("switch");
  23.  
  24.     //add video nodes for each file
  25.     foreach (FileInfo mp4File in files)
  26.     {
  27.         XmlNode videoNode = result.CreateElement("video");
  28.  
  29.         //Create and add attributes
  30.         XmlAttribute srcAttr = result.CreateAttribute("src");
  31.         srcAttr.Value = mp4File.Name;
  32.         XmlAttribute bitrateAttr = result.CreateAttribute("system-bitrate");
  33.         bitrateAttr.Value = Path.GetFileNameWithoutExtension(mp4File.Name).Substring(mp4File.Name.LastIndexOf("_") + 1) + "000";
  34.         videoNode.Attributes.Append(srcAttr);
  35.         videoNode.Attributes.Append(bitrateAttr);
  36.  
  37.         //add video node to switch
  38.         switchNode.AppendChild(videoNode);
  39.     }
  40.  
  41.     //append nodes to parent elements
  42.     bodyNode.AppendChild(switchNode);
  43.     smilNode.AppendChild(headNode);
  44.     smilNode.AppendChild(bodyNode);
  45.     result.AppendChild(smilNode);
  46.  
  47.     return result;
  48. }

Monday, January 4, 2010

Electronics: Plasma vs. LCD

It seems as if the nation has fallen out of love with plasma televisions, and I can’t figure out why.  Generally speaking plasma’s have better color, higher refresh rates, and deeper blacks than LCD TVs.  Typically the counter argument is that plasma’s use more electricity and their screens are more reflective, which can be a problem in rooms with windows.  Recently I purchased a 42” 720p Panasonic TC-P42X1 plasma to replace my 3 year old 720p 42” Sony Wega LCD projection TV. 

The picture quality of the plasma is outstanding.  One of my biggest complaints with my old Sony was the black levels. This was the main reason I wanted to get a plasma over an LCD, and the Panasonic does not disappoint.  Furthermore it has a 600hz refresh rate so I never notice any ghosting in action movies.  I bought this TV for under $600.  Comparable LCD’s will run you $600-$1000, but at $600 for an LCD you’ll be getting an off-brand with mediocre picture quality.  My friend recently spent $1500 on a 50” 1080p 120hz LCD TV, and I’d take mine over his any day.  Motion images on his 120hz set are so unrealistic that it’s distracting.  Also the color was overly bright, but that was probably more a result of his choice of settings.

The power consumption of TC-P42X1 is also very good.  According to tests done by televisioninfo.com it used between 80 and 200 watts depending on how much white was on the screen at once.  That’s probably the same amount of energy you are using to light your room if you’re not using CFL bulbs.  A similar sized LCD set consumed 137 watts, so I’d actually call the power usage a wash.

Although Panasonic has done work to create anti-glare screens on their plasma’s, I definitely can’t watch the TV with the windows uncovered.  However we do have window blinds in our living room so its a non-issue for me.

Also this television is not 1080p, but I personally think 1080p is overrated.  Right now the only content in 1080p is blu-ray disks, which are expensive, and I don’t have a blu-ray player anyway.  I’ve never watched 720p content and wished for a higher resolution.  I’ll take a 720p TV with great colors and blacks over a poor 1080p TV any day.

So the rest of the world can enjoy spending extra money on LCD and LED sets, I just hope cheap, great plasma’s are still around the next time I need to purchase a TV.