Breaking Bad Ending Prediction

Going on record with my Breaking Bad prediction:

EAAAAEqhoq0ty5977EFCIguikrRVYzZsL4CiNXNK7VKcLs8Ik5lmrtsI3cJPo19bq2HBZavatk0EalFyeqQx6w2K6RxIuLoRbuddMJ4qSiZgQ8l3VjB1JGUw1ucskXUxL/ZL7HFRGY0424JY/MH4pirH4yCJ/ORGW7fSyiPQNtEDkh2s5Qs8QivN0ueJi1p/v2c4AV7vHYpSqfBf7e6AFQ1DPsMsHOJf05kIvh7BUp/LKssRFoL9jGQ2uqT1R7FnAv9icRbpUOVIDZ74N63JAhGOuye9uNv2dYAb53H53RxWN9b2Em1kXlnKoflf2rEqa6UCNvVvPy+kgMuKQuAEy+/ut70=

Decrypt with:

var key = new Rfc2898DeriveBytes("BreakingBadEndingPrediction", "o6806642kbM7c5");
var bytes = Convert.FromBase64String(cipherText);
using (var msDecrypt = new MemoryStream(bytes))
{
aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
aesAlg.IV = ReadByteArray(msDecrypt);
var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
   using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
        return srDecrypt.ReadToEnd();
}
}

Kiteboarding: Four Days Since Our Last Tiger Shark Attack

I am holding a bar while floating in a murky bay, slowly drifting towards a shipping channel. If I pull on the bar, 6 things can happen, only 1 of which is good. Not to mention the tiger shark. The tiger shark doesn’t care whether I pull the bar or not, but still. So 7 things. I pull the bar.

For the past decade, I’ve had a cocktail-party story about learning to kiteboard — or rather, not learning to kiteboard — with an obscenely overpowered two-line kite and a guy behind me on a JetSki shouting encouragement as I get pulled downwind, in 20-yard increments, across a mile of San Francisco Bay. “Kiteboarding — it’s like bull-riding, but with more drowning.” Subsequent to that lesson (in which I was literally pulled out of one of my wetsuit booties) I thought “Well, I guess I’m too old for it.” Too out-of-shape and too brittle.

But dammit, they make it look so easy.

My friend Florian, who is an expert in getting off his ass, finally convinced me that what we needed to do was take a long weekend, fly to Maui, and take 3 days of lessons. So, here I was, floating like a nerdy dumpling off the beach in Maui, staring up at 86 square feet (8M^2) of kite bucking in the Force 5 winds, a few degrees from the brilliant tropical sun. At the moment, the kite was flying in its most unpowered state, presenting only its thin, inflated lip to the wind. When I pulled the bar, the kite would turn, catch more wind, and accelerate, exponentially increasing in power, which would be transferred down 20M of finger-slicing line to the harness fastened around my waist. And then:

  • The force would pull me out of line and past the board, which would act like a sea anchor and torque my knees perilously before popping off; or
  • My tentativeness would generate so little force that the kite only moved me another 40 or 50 yards closer to the shipping channel; or
  • The kite would turn too sharply and fly directly downwind, launching me into the air before crashing (this was mostly what happened to me in San Francisco); or
  • The kite would lift my butt out of the water, which would be so astonishing that I’d promptly crash; or
  • The kite would lift my butt out of the water, and then launch me into the air; or
  • The kite would lift my butt out of the water, by which time I would have re-turned the kite not-quite towards the vertical, achieving the proper balance between “launch me into the air” power and “sink back on your butt” stalling.

And then there was the tiger shark. Which isn’t a metaphor or one of those “You swim with sharks every time you get in the water” bravados. Florian’s rental board was bitten by a tiger shark, at that very beach, earlier in the week. Marine Biologists measured the bite radius and say it was about 12′. (“Measured the bite radius”: You know, just like Jaws ).

this was no boating accident

I tried not to think about the shark too much.

So the only bad thing I have to say about the experience is that it’s ruined my story. The 4-line kites they have today are literally 180 degrees from what I experienced in San Francisco: my disastrous time in the early 2000s was with kites that, when they crashed, automatically relaunched and tried to fly downwind. So after you crashed you had 5 or 10 seconds to get things under control and if you didn’t, the kite would relaunch, jerk you another 20 yards, crash, and give you another window in which to recover. The modern kites I learned on in Maui were the opposite: they are engineered to skid upwind until they stall, still in the water, and give you all the time in the world to get your bearings.

Ultimately, the hardest thing about kiteboarding for me was that I wasn’t aggressive enough with the kites! They were easy to fly and forgiving, but I had such bad memories about what could go wrong that I was too tentative with the power. Only once did I fly so aggressively that I fell forward rather than backward.

Another hard thing is that when you’re learning, you spend a lot of time using the kite to drag you into position, which involves being pulled through the water by your harness. The force of the water on your chest and all your gear is exhausting and frustrating, because you’re thinking “Why am I panting for breath? I haven’t done anything!”

By the end of my second day, I was getting up and riding for a few seconds. The third day I took a step back because of equipment trouble, and frankly, I was a little worn down from the weekend’s other activities, which included crossing the channel to Molokai to dive with hammerheads (I like sharks just fine when I have a mask on) and shutting down a bar in Ma’alea.

I don’t really know what comes next. I think I have 20 more hours of instruction left before it’s likely I could start doing it myself: 3 more days just getting up and riding consistently and then some time learning beach launches and landings, which are the most dangerous moments in the sport. The Big Island is a poor place to learn to kiteboard — there are no instructors and the only reliable place to kiteboard has a beginner-hostile offshore wind. Flying to Maui for another long weekend of instruction is a possible, but expensive option, but probably not for a few more months, at least.

But on my longest ride, which probably lasted about 20 seconds, I felt like I was looking at an open window. With these kites, physically the sport is open to even old brittle guys like me, and it’s clearly a sport where, once you know what you’re doing you can keep things in balance and not expend a lot of energy. So if I could learn it, I could have a decade or more of a sport that is just perfectly tuned to my sensibilities. So, yeah, I guess I’ll try again.

ChromeCast Xamarin Binding and Sample Source Code on GitHub

Due to popular demand…

Here is source code for a preliminary Xamarin.iOS binding for Google’s ChromeCast

and

Here is C# source code for a simple iOS app that casts a video URL

In order for this to work, you’ll need:

This is just source code, not a step-by-step walkthrough. Everything associated with this is in beta and I don’t want to invest a lot of time making things just so at this point.

You can read an overview of the programming model here.

# ChromeCast Home Media Server: Xamarin.iOS FTW!

As I blogged about last weekend, I got a ChromeCast and had a simple-enough time creating an iOS-binding library for Xamarin.iOS, allowing me to program the ChromeCast in C# (or F#, maybe next weekend…).

This weekend, I wrote a simple Home Media Server that allows me to stream… well, all my ChromeCast-compatible media, primarily mp4s. Here’s how I did it…

ChromeCast Programming: Intro

Essentially the ChromeCast is nothing but a Chrome browser on your TV. If you want to display HTML, no problem, but what you probably want to display is a great big video div:

<video id="vid" style="position:absolute;top:100;left:0;height:80%;width:100%">

But where does this HTML come from? Here’s the first kind-of-bummer about ChromeCast: Every ChromeCast application is associated with a GUID that Google provides you. Google maintains a map of GUID->URLs. And, since you have to send them your ChromeCast serial to get a GUID, it’s a safe bet they check the hardware, too. When you start an application with: session.StartSessionWithApplication("93d43262-ffff-ffff-ffff-fff9f0766cc1"), the ChromeCast always loads the associated URL (in my case, “http://10.0.1.35/XamCast”):

So, as a prerequisite, you need:

  • A ChromeCast that’s been “whitelisted” for development by Google;
  • A Google-supplied GUID that maps to a URL on your home network (a URL you decided during the “whitelist” application to Google)
  • A WebServer at that URL

It’s important to realize that what’s at that URL is not your media, but your “receiver app”: which might be plain HTML but which is likely to be HTML with some JavaScript using the ChromeCast Receiver API that allows you to manipulate things like volume and playback position, etc. I basically just use this file from Google’s demo, with minor tweaks.

Home Media Server : Intro

So if you want to stream your home media, you need a WebServer configured to serve your media. This doesn’t have to be the same as your App Server (it probably will be, but conceptually it doesn’t have to be):

The structure is straightforward:

  1. The mobile controller gets a list of media from the Media Server
  2. The application user selects a piece of media
  3. The controller sends the selected URL (and other data) to the ChromeCast
  4. The ChromeCast loads the media-URL from the Media Server

For me, the “App Server” and “Media Server” are the same thing: an Apache instance running on my desktop Mac.

ChromeCast Media-Serving : Components and Life-Cycle

This is a rough sequence diagram showing the steps in getting a piece of media playing on the ChromeCast using the Xamarin.iOS binding:

  1. Initialization
    1. Create a GCKContext;
    2. Create a GCKDeviceManager, passing the GCKContext;
    3. Create a GCKDeviceManagerListener; hand it to the GCKDeviceManager;
    4. Call GCKDeviceManager.StartScan
  2. Configuring a session
    1. When GCKDeviceManagerListener.CameOnline is called…
    2. Create a GCKApplicationSession;
    3. Create a GCKSessionDelegate, passing the GCKApplicationSession
  3. Playing media
    1. After GCKSessionDelegate.ApplicationSessionDidStart is called…
    2. Create a GCKMediaProtocolMessageStream;
    3. Get the Channel property of the GCKApplicationSession (type GCKApplicationChannel);
    4. Attach the GCKMediaProtocolMessageStream to the GCKApplicationChannel
    5. Create a GCKContentMetadata with the selected media’s URL
    6. Call GCKMediaProtocolMessageStream.LoadMediaWithContentId, passing in the GCKContentMetadata

Here’s the core code:

public override void ApplicationSessionDidStart()
{
    var channel = session.Channel; 
    if(channel == null)
    {
        Console.WriteLine("Channel is null");
    }
    else
    {
        Console.WriteLine("We have a channel");
        mpms = new GCKMediaProtocolMessageStream();
        Console.WriteLine("Initiated ramp");
        channel.AttachMessageStream(mpms);

        LoadMedia();
    }
}

private void LoadMedia()
{
    Console.WriteLine("Loading media...");
    var mediaUrl = Media.Url;
    var mediaContentId = mediaUrl.ToString();
    var dict = new NSDictionary();
    var mData = new GCKContentMetadata(Media.Title, Media.ThumbnailUrl, dict);

    Console.WriteLine(mData);
    var cmd = mpms.LoadMediaWithContentID(mediaContentId, mData, true);
    Console.WriteLine("Command executed?  " + cmd);
}

Plans

The core of a real home media server for the ChromeCast is the Web Server and the UI of the mobile application that browses it and chooses media. To turn this hack into a turnkey solution, you’d need to:

  • Run a public Chromecast application server that
    • Deferred the URL of the media server to the client
  • Write the media server, with all the necessary admin
  • Write a nice client app, that stored the mapping between the public ChromeCast app server and the (strictly-local) media server
  • Make a great user interface for selecting media
  • Make a great user interface for controlling the media

I have no plans on doing any of that stuff. What I plan on doing once ChromeCast and iOS 7 are out of beta is:

  • Make a nicer binding of the ChromeCast API and put it up for free on the Xamarin Component Store; and
  • Play around with serving media and blogging about anything interesting that comes up

Conclusion

The real thing that I wanted to do was see if Xamarin.iOS worked well with ChromeCast (resounding “Yes!”) and come up with a hack for my own use.

Achievement Unlocked.

For Immediate Release…

FOR IMMEDIATE RELEASE:

NEANY Inc. to Exhibit Unmanned Solutions at AUVSI’s Unmanned Systems North America 2013

~ Arrow UAV, Ground Control Station, and Unmanned Surface Vehicle will be on display~

Hollywood, MD – August 07, 2013 (myPressManager.com) —

NEANY Inc., an industry leader in providing time-sensitive tactical solutions for a variety of missions, is a proud supporter at this year’s AUVSI’s Unmanned Systems North America 2013 in Washington, DC August 12 – 15. Conference attendees will see firsthand NEANY’s flagship UAS, the Arrow, integrated with Raytheon’s Pyros™, a UAS weapon specially designed for tactical level missions, and the aXiom™ 9000 Series, Tachyon’s state-of the-art Beyond Line-of-Site communications system. NEANY’s display will also feature its latest autonomous surface vehicle, the DragonSpy, equipped with the ARES Inc. 7.62mm Externally Powered Gun (EPG) mounted on L-3 Communications IOS’s Advanced Remote Weapon Station (ARWS). The DragonSpy is ideal for providing rapid response capabilities in maritime/littoral environments. In addition, visitors will have the opportunity to operate one of NEANY’s signature ground control stations to further experience the capabilities of these systems.

NEANY Inc. is a minority-owned, SBA 8(a)-certified research, design, test and evaluation engineering firm specializing in unmanned systems with integrated payloads supporting a variety of global missions. These missions include homeland defense and security, border and port patrol, urban mapping, counter-narcotics applications, disaster preparedness, and Intelligence, Surveillance, and Reconnaissance (ISR). In addition to unmanned systems, NEANY’s expertise includes ground control stations, systems integration, rapid prototype fabrication, pilot training, and theater deployment and logistics. NEANY continues to demonstrate unprecedented in-theater expertise that includes deployment-to-extraction logistical support as nearly 50% of NEANY’s personnel are currently forward deployed. In a period where financial resources are limited, NEANY is confident in its ability to offer cost-effective unmanned solutions capable of supporting national and international defense applications.

NEANY will have literature and personnel on hand to demonstrate and discuss our full line of available products and systems. Please take time to visit NEANY at booth #2103.

For more information on the NEANY advantage, please visit www.neanyinc.com.

For more information on AUVSI’s Unmanned Systems North America 2013, please visit

Programming the ChromeCast with Xamarin

ChromeCast Notes

I guess I got under the wire with the Netflix deal, so the net cost of the thing was $11. Even at $35, it’s a no-brainer for a developer to pick up and see if they can target.

Experience

Very good OOBE: plug it in to HDMI port, power via USB, and… yeah, that works. Setup via iOS didn’t work for me (hung), so I set it up via Chrome on laptop: fine.

Add extension to Chrome, can “cast” any single tab. Works great with Comedians in Cars Getting Coffee. Integrated is better, though: very easy to watch Netflix and cue up next issue of “Breaking Bad, Season 5” (they’ve just released, dontcha’ know). YouTube app was a little confusing.

Local files cast from Chrome

Mixed bag. Worked well with raw GoPro MP4s, but not my QuickTime output Content On This Page Is Not Supported. Some MKVs played fine, others didn’t have sound (DTS not supported?).

Photos cast perfectly, but obviously would benefit from a native app.

ObHacks

The one that jumps out is, of course, “DLNA -> Cast.” This would presumably require setting up an auto-transcode to supported formats. Would be best with an XPlat mobile controller: use iOS, Android, or Computer to select files on DLNA server. ? Is there a barebones DLNA library / app that could be hacked?

“It’s not a slide projector, it’s a time machine…” Photo browser.

Video logger: Watch raw footage on TV, hit “in/out”, make notes, triage.

Imperfect information turn-based games (e.g., card games, Eurogames): TV is public, devices are private. Better than “pass-and-play” for, e.g., “Ticket to Ride”. Poker.

Party photos: QR code on screen specifies photos taken in next N hours with device are shown / shared with others with same guid. (How to make work with different photosite / storage options?)

Development

Beta SDK available and simple apps at Github.

I downloaded the iOS SDK and used Objective Sharpie to create Xamarion.iOS C# bindings. Very straightforward; tool did 95% of work. Needed to massage some stuff (some things improperly changed to fields, needed to change FieldAttribute.

“Hello world” Sender app easy-peasy lemon-squeezie:

var gckContext = new GCKContext("net.knowing.xamcast");
    var deviceManager = new GCKDeviceManager(gckContext);
    var dmListener = new DeviceManagerListener();
    dmListener.CameOnline += (s,e) => CreateSession(gckContext, e.Device);
    deviceManager.AddListener(dmListener);
    deviceManager.StartScan();

etc.

BUT… No generic media-receiver app? Can’t just write Sender app and send “GET endpoint to supported format”?

That means all dev requires going through “whitelisting” phase, which takes at least 48 hours. Just figured this out this AM, so guess limited dev this weekend.

Plans…

It’s a beta SDK, so I’m not going to invest much effort in “C#”-ifying the bindings yet. Eventually, I’d like to make it available as a free component on the Xamarin Component Store, but initially I’ll probably just put it up on Github. I’ve already put up the silly Hello XamCast!.

UIWebView.SetCenterCoordinate is asynchronous

You cannot rely on the value of UIWebView.CenterCoordinate after setting UIWebView.SetCenterCoordinate and I don’t know of any event that is raised when it is finally set. To be more specific:

var map = new MKMapView();

var ctr = new CLLocationCoordinate2D(37.8, -122.4);
map.SetCenterCoordinate(ctr, false);
map.SetRegion(new MKCoordinateRegion(ctr, new MKCoordinateSpan(0.025, 0.025)), false);
Console.WriteLine("Center coordinate is still NaN: " + map.CenterCoordinate.Latitude.ToString());

/*
Error: NaN Lat & Long var 
circle = MKCircle.Circle(map.CenterCoordinate, 100);

Must use explicit location instead, a la:
*/
var circle = MKCircle.Circle(ctr, 100);

map.AddOverlay(circle);

Lemme’ get some SEO terms in here like MapKit, MKOverlay, and NaN