Mobile Zone is brought to you in partnership with:

Den is a DZone Zone Leader and has posted 460 posts at DZone. You can read more from them at their website. View Full User Profile

“What Time Is It” explained and ported to Windows Phone

05.27.2012
| 2653 views |
  • submit to reddit

Today’s highlight from Hacker News is What Time Is It? – a web page that shows how some construction workers are putting together a wooden representation of the current time. As much as we would want that to be a real-time process, it is not. The purpose of this blog post is to explain what’s behind the process.

NOTE: The original video project is called Standard Time and was created by Mark Formanek.

First things first, I decided to analyze the network layer. Wireshark seems to be doing the job pretty well so far, so I noticed this:

image

The full URL looks like this:

http://176.9.156.38/big_10-25.mp4?start=0&radius=0.794870455716131

The application is fetching MPEG-4 videos that were filmed prior to the actual display. You probably already noticed that there are two parameters – one called start and the other one called radius.

Let’s see what start is about. Obviously, the videos are not filmed for every minute. Instead, each video file is structured in 10 minute chunks. In this case, the source video starts when the clock hits 10:25 AM, but it’s 270 seconds in already (4.5 minutes, therefore it starts at 10:29:30 AM, where workers finish up the :30 sign.

That being said, video URLs are structured like this (from the beginning of the day):

Basically, you can initiate the download from any point out of 5 minute intervals. The maximum value for the start parameter is 590. After that, you have to switch to the next video.

The radius parameter seems to be useless at this point.

Let’s see how to implement this for Windows Phone. I created a project and named it BerlinTime, since the videos were filmed in Berlin. The application itself consists of one page with a MediaElement on it.

<phone:PhoneApplicationPage 
    x:Class="BerlinTime.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    SupportedOrientations="Landscape" Orientation="Landscape"
    shell:SystemTray.IsVisible="True">
    
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <MediaElement BufferingTime="0:0:01" x:Name="mediaPlayer"></MediaElement>
    </Grid>
</phone:PhoneApplicationPage>

In the code-behind, I have a custom model for keeping the “normalized” (within 5 minute intervals) time:

public class TimeUnit
{
    public string Hours { get; set; }
    public string Minutes { get; set; }
    public string SecondsIn { get; set; }
}

To get the current time in a manner that can be applied to get the correct video file (remember – the video files are based on 5 minute intervals) I have GenerateCurrentTime:

private TimeUnit GenerateCurrentTime()
{
    TimeUnit unit = new TimeUnit();

    TimeSpan current = DateTime.Now.TimeOfDay;
    Debug.WriteLine(current.ToString());

    int minutes = current.Minutes;
    int seconds = 0;
    int modulusResult = minutes % 5;

    minutes = minutes - modulusResult - 5;

    seconds = (modulusResult + 5) * 60 + current.Seconds;
    Debug.WriteLine(seconds);

    unit.Hours = current.Hours.ToString("D2");
    unit.Minutes = minutes.ToString("D2");
    unit.SecondsIn = seconds.ToString();

    return unit;
}

Here is where 5 minute chunks and the start parameter become useful. To minimize the amount of downloaded data (and therefore to make the streaming smoother), I am constantly looking for the video that represents the time 5 minutes behind the actual one, so the number of seconds goes beyond 300 (5 minutes), therefore I cut the amount of media to be downloaded at least in half. If I would not be doing this, the user would have a high chance of downloading 50MB+ videos on every 10 minute reset.

I need a URL template, that can be used to generate the video URL. For this I have:

public const string UrlTemplate = "http://176.9.156.38/big_{0}-{1}.mp4?start={2}";

When the user first navigates to the page, I am getting the current time and setting the source for the MediaElement (that will buffer the data automatically) to the video file that corresponds to the current time:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    PlayVideo();
    base.OnNavigatedTo(e);
}

private void PlayVideo()
{
    CurrentUnit = GenerateCurrentTime();

    mediaPlayer.Source = new Uri(string.Format(UrlTemplate, CurrentUnit.Hours, CurrentUnit.Minutes, CurrentUnit.SecondsIn));
    mediaPlayer.Play();
}

Eventually, the buffer will be exhausted and I will need to reload the media. So when MediaEnded is triggered for the MediaElement, I am simply playing the video again, with new time indicators:

void mediaPlayer_MediaEnded(object sender, RoutedEventArgs e)
{
    PlayVideo();
}

The end result looks something like this:

image

There might be slight delays, depending on your connection speed. You can download the project on GitHub.