Instant Replays on Wowza

One of the useful features of Wowza is its ability to record a stream to disk and then be able to use that recording for a replay. In version 3.5, it would simply take the stream name, slap an MP4 extension on the end, and version any previous ones with _0, _1, etc. In 3.6, the default naming scheme for these recordings was a timestamp, with a configuration option to use the legacy naming convention. In Version 4, it appears this legacy naming convention option has disappeared altogether, meaning you can’t set up a player to just play back “streamname.mp4″ and it would always grab the most recent one. EDIT: It appears that this loss of functionality was unintentional and has been classified as a bug, which should be fixed very soon.

This became a problem for one of my clients after their Wowza server got updated to V4. It wasn’t practical to re-code the player every week, or to go into the server and manually rename the file. Since it’s on a Windows server, PowerShell to the rescue:

$basepath= "C:\Program Files (x86)\Wowza Media Systems\Wowza Streaming Engine 4.0.3\content\"
$replayfile =  gci $basepath\streamname*.mp4 | sort LastWriteTime | select -last 1
$link = $replayfile.Name

cmd /c del $basepath\replay.mp4
cmd /c mklink $basepath\replay.mp4 $basepath\$link

I then put this into a scheduled task, with time-based triggers. Powershell is a little tricky to get into a scheduled task, but I finally got the syntax right:

Action: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Arguments: -nologo -file “C:\Program Files (x86)\Wowza Media Systems\Wowza Streaming Engine 4.0.3\content\replay.ps1″

If you’re on Linux or OSX, you can do this in bash instead:

#!/bin/bash

basepath='/usr/local/WowzaStreamingEngine/content'
unset -v replayfile
for file in "$basepath"/streamname*.mp4
 do
  [[ -z $replayfile || $file -nt $replayfile ]] && replayfile=$file
 done;
rm -f $basepath/replay.mp4
ln -s $replayfile $basepath/replay.mp4

and put it in your crontab (this example is every sunday at 11:30am)

30 11 * * 0 /bin/bash /usr/local/WowzaMediaServer/content/replay.sh

In the wild: EGO cordless electric mower

It’s a clean, green, mowing machine!

mower_largeI’m going to veer off my usual topics here to give you my thoughts on a recently acquired tech toy of a different flavor: My lawnmower. This is NOT a sponsored post.

When we moved into our previous house almost 11 years ago, we went on a coupon-fueled shopping spree at Home Depot, and picked up your standard 4-stroke gas-powered mower. It worked well, but after a while, the tedium of dealing with oil and gas and all those moving parts makes you think “there’s got to be a better way”. We’d been eyeing electric mowers for a while, but either they were corded (obnoxious – chance of mowing the cord is high!), or had enough battery life to make you need a wagon full of spare batteries, and in neither case did they have enough oomph to cut grass that had gone more than about 12 hours since the last mowing.

When the Toro died this spring (I think it busted a rod, or something else pretty major in the engine), I started looking at battery-powered options again. At our new place, the lot is nearly half an acre. Anyone in their right mind would have bought a small riding mower. Consumer Reports narrowed me down to two options: The Black & Decker CM1936, with a 19″ deck and self-propelled version for $439 at Amazon (now $379), or the EGO LM2001, with a 20″ deck for $499 at Home Depot. I was initially leaning toward the B&D’s lower price, but was eventually won over by the EGO’s slightly wider cutting deck, its 5-year warranty, and the 30-minute charger (which would have been another $130 for the B&D). That the EGO is 50 pounds lighter was a big plus as well.

Since Home Depot had it in stock, I headed over there and picked it up. It comes in a large cardboard box that easily fit in the back seat of my full-size Toyota. Because the mower handle folds down and collapses, there was no assembly to speak of. It’s pretty much a matter of taking it out of the box, removing the requisite bits of tape and protective film, and a few plastic bags, and putting the box on the curb for the recyclers to pick up. Virtually all of the packaging is recyclable, which is a plus.

EGO Battery Pack

This is alien technology. Or at least from the future.

The battery pack and the charger look like something right out of a sci-fi movie. The battery is the heart of the system, and battery technology has made significant progress in the last few years. Power tool manufacturers love to tout the voltage of their battery system, under the idea that “More Volts = Better”. Being a geek with a background in electronics, I know that this is mostly bunk, but when it comes to battery systems, there’s some validity to it, because virtually all power tool batteries consist of a serial/parallel array of 1.2V rechargeable cells. More cells = more oomph. EGO says the motor in this mower is 600 watts, which works out to a little over 10 amps. The battery pack is 4Ah, so at full load, one should expect about 25 minutes of use. Since in the real world, the motor isn’t under full load the whole time, it gets pretty close to EGO’s claimed run time of about 45 minutes. I’ve found that this isn’t enough to do my whole yard, but after the battery runs out, I’m usually ready to go sit inside for half an hour, and cool off with a cold beverage and some air conditioning, while the battery charges back up (and yes, it DOES only take half an hour!).

Performance-wise, it does OK with normal mowing, but heavy grass is something best approached in phases at different cutting heights (which are adjustable to 5 levels with a single lever somewhat reminiscent of the shifter in my minivan). On my gas mower, I’d usually deal with heavy grass by putting the discharge chute on and letting it eject the cuttings rather than mulch them. On the EGO mower, this plan is no good. While it comes with a discharge chute that attaches in the same place as the bag, it clogs easily, and is generally useless. Bagging works pretty well, though.

So easy a kid can mow!

Where this mower really shines is how easy it is to use. Much of the body is molded polypropylene, so at 40-odd pounds, it weighs about half what my old gas mower did (the B&D unit is actually 15 pounds HEAVIER than my Toro), and is so quiet that it won’t bother the neighbors. When sitting inside while someone is mowing, it sounds like a gas mower several blocks away. A typical gas mower is usually over 90dB, where permissible exposure levels are not much more than an hour. I don’t know offhand what this unit is, but it’s a LOT quieter. There’s no fuel to mess with, or oil changes, or any of that. When you’re done, it folds up neatly and can be stood on end, taking up no more than 2 square feet of your garage. Between the light weight, the quiet, and the lack of fumes, my 10-year-old daughter is actually willing to mow the lawn. (Another major motivating factor is that mowing the grass pays for her cell phone service).

Other than keeping it clean, there’s really no long-term maintenance to worry about. It comes with a 5-year warranty, although the blade isn’t covered, as it’s considered a wear part. There are no moving parts other than the motor itself (compare to a 4-stroke gasoline engine, which even with a single cylinder is a very complex piece of machinery).

As for energy consumption, a full charge is 224 watts of electricity. A full charge will run you somewhere between 2 and 4 cents worth of electricity, depending on where you live. The EPA defines a gallon of gasoline as equivalent to about 33.4kW of electrical energy. My old Toro would go through about a quart of gas to mow the yard. At nearly 4 bucks a gallon for the non-ethanol stuff that won’t wreck the engine, that’s a buck a mow. With 2 charges, that’s also about 20x the amount of energy that the EGO uses to achieve the same job. Oddly enough, the “fuel” cost of the electric mower is also about 1/20 that of the gasoline.

EGO in storage mode

If carbon footprint is something you care about, 1 full mow is about half a pound of CO2 if your electricity is from natural gas, and about a full pound if it’s from coal. Zero if it’s from nuclear, solar, or wind. The gasoline mower belches out about 4.5 pounds per mow, along with a whole bunch of other nasty stuff that your car has the decency to clean up first.

As for quirks, there are a couple. The handle has a couple of different safety interlocks, and must be fully extended and locked for the mower to operate. There’s a dead-man switch on the push bar, much like virtually any other mower. There’s also a removable safety key that must be pushed in to start the mower. I’ve found that when mowing close to bushes that the slide lock tends to come undone, allowing the handle to slide in just enough to cut the mower out. The first few times, you find yourself standing there wondering why the mower won’t work, until you notice the bright green latch on the handle hanging open.

When going through heavy grass, if the current draw on the motor becomes too much, the green power light will start flashing yellow. If you don’t ease up on it, it will stop the mower. Once the battery gets low, the indicator light will turn red, at which point you’ve got about 3-5 minutes until break time. The battery is really good at delivering a fairly flat and constant amount of power, so there’s not really much decline in power until the battery decides to go completely dead.

EGO also has a blower, edger, and hedge trimmer that work with the same battery (they also make a smaller and lighter 2Ah battery for those devices, but all batteries in the EGO tool family are interchangeable, so if you find yourself about 10 minutes short on the mower, get the trimmer or blower with its battery, run the mower on the small battery for 20 minutes, and then switch to the big battery to finish the lawn while you recharge the small battery, which will be ready for trimming or blowing by the time you get done mowing. If you already have batteries and chargers, you can order just the tools without batteries directly from EGO for less money. Similarly, you can order extra batteries from them (the big one is $199, the little one is $129).

Bottom line, It may be a spendy piece of equipment, but not having to deal with gasoline, fumes, noise, maintenance, and being able to send the kid out to mow instead of doing it myself is well worth the price of admission. Oh, and it also has an LED headlight, for those midnight mowing escapades.

X-Plane in its full 39" 4K Glory

My God, It’s Full Of Pixels!

One of my desktop monitors gave it up last week, the backlight started flickering and randomly disconnecting from my Mac (which causes all attached displays to go dark for a second while it recomputes your workspace). Needless to say, it was sapping productivity even worse than Facebook. I’ve been eyeing 4K monitors for a while now, and both Dell and Lenovo have some decent low-cost options in 28″ sizes ($700ish), but that was still more than I was willing to cough up for a new monitor right now, even with the Lenovo dealer demo discount.

Then came last weekend, where TigerDirect ran a $70 rebate on a Seiki SE39UY04 39″ (yes, you read that right, thirty-nine inches) 4K TV with a whole mess of inputs (3 HDMI, 1 VGA, 1 Component, as well as a tuner). Base price before rebate: $400. Four hundred bucks. BEFORE the rebate. For 4K. That brings it down into the realm of even inexpensive 27″ monitors. Some googling found that the tech press actually has good things to say about this “off-brand” display (with the caveat that there are very few graphics chips currently out there that can drive this resolution, and that HDMI 1.4 is limited to 30Hz refresh at 4K). Since the rebate was a very limited-time offer, I jumped on it, figuring I was gonna have spend that much on a monitor anyway. For those who missed last weekend’s rebate from TD, It’s currently available on Amazon (with Prime!) for $299 (plus larger sizes too!).

Three days later, UPS shows up bearing goodies, and I hooked it up this morning. The unit is generally well built, comes with a solid but unobtrusive pedestal, and the bezel is not huge. It even comes with a decent HDMI cable. There’s been a lot of discussion online as to whether the first-generation Retina MacBook Pro can drive this monster at native resolutions at all. Let me put those to rest: it can, with Mavericks 10.9.3, at 30Hz. Because of the refresh rate, it’s not a great rig for gaming (but it’s still beautiful with X-Plane!!!), but it’s great for sheer pixel space to put my calendar, e-mail, a couple of network monitoring screens, multiple RDP sessions, and lots of other things that don’t require high refresh rates. Colors are quite good, as is brightness, and the built-in speakers are surprisingly loud (almost too loud to use with my computer even at the lowest volume setting) If you press “Menu” on the remote, followed by “0 0 0 0″, you can get into the factory menu which allows you to tweak the color temperature, and the “Warm” setting is shockingly close to my MacBook. The factory menu also lets you dial down the backlight (which I did – even so, this TV is already near the bottom of its category when it comes to energy consumption). I also dialed the default sharpness setting down to 0, as, like most TVs, the edge enhancement algorithms designed for making TV pictures look better really butcher computer signals.

Tweetdeck is 1440x900, RDP window is 1920x1080.  No scaling. Just pixels.

Tweetdeck is 1440×900, RDP window is 1920×1080. No scaling. Just pixels.

Did I mention that 4K is an awful lot of pixels? It is a LOT of pixels. 8,294,400 of them . Holy cow. I’m a lifelong pixel junkie, and I’m loving this. The 39″ display is big enough to use on your desktop at native resolution at a comfortable distance of about 4′ (rather than driving it at a pixel-doubled 1920×1080 workspace). Drawing network maps in Visio and Ekahau at 4K resolution is something out of a dream.

Visio at 3840x2160.

Visio at 3840×2160.

Ekahau Site Survey

Ekahau Site Survey

My biggest problem? Losing my mouse cursor. Gotta use a solid color background. That’s OK, my GPU is probably just as glad it doesn’t have to deal with an 8MP image.

X-Plane in its full 39" 4K Glory

X-Plane in its full 39″ 4K Glory

Bottom line, for under $400, this is a surprisingly good piece of hardware. Seiki may be considered an “off-brand” label, but don’t forget that Vizio was in the same position when they started selling good HD televisions for dirt cheap. The only real downside I see right now is using a VGA port that is limited to 1920×1080 instead of putting a DisplayPort interface there instead. OK, Roku, When can I expect a 4K version of your box so I can watch Breaking Bad and House of Cards in their full 4K glory? Et tu, Chromecast?

This video looks utterly spectacular on this screen (Downloaded with YTD and played with QuickTime)

Browser-Aware Player Code, 2014 Edition

Yet another installment in the never-ending series of dealing with different platforms. This is precipitated by the continued boneheadedness of Google when it comes to supporting any live streaming transports in the native browser (they just simply don’t). Some handset manufacturers are adding HLS support back, though.

You’ll notice there’s also code in here to reference an MPEG-DASH manifest as well as “sanjose” and “smooth” (in Wowza parlance). This script doesn’t make use of those capabilities at the moment, but once I get a good list of which browsers can support MSE and DASH.js, I’ll update it to be able to use that player.

This assumes that you’re using cloud-hosted JW Player with a key, but if you’re not, simply replace the first SCRIPT reference with your locally hosted JWPlayer file and comment out the jwplayer.key line.

If you wish to use a different player such as FlowPlayer, you can replace the appropriate code in the flashPlayer() function.


<HTML>
<HEAD>
<TITLE>Player</TITLE>


<script type="text/javascript" src="http://p.jwpcdn.com/6/8/jwplayer.js?ver=3.9"></script>
<script type="text/javascript">

jwplayer.key='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';

jwplayer.defaults = { "ph": 2 };

</script>


</HEAD>
<BODY STYLE="margin: 0px; background-color: white">
<div id="videoframe"></div>

<SCRIPT type="text/javascript">
// Browser-aware video player for JW Player and Wowza
// V0.3 - May 19, 2014
// (c)2014 Ian Beyer
// Released under the GPL

var container='videoframe';
var width="100%";
var aspect="4:3";



//This section calculates actual sizes for player when using non-responsive elements.

var multiplier=aspect.split(":");
var fixedwidth = Math.floor(window.innerWidth*width.split("%")[0]/100);
var fixedheight = Math.floor(window.innerWidth*multiplier[1]/multiplier[0]*width.split("%")[0]/100);
console.log ('Size: '+width+', '+aspect+' ('+fixedwidth+' x '+fixedheight+')');

var streamserver='wowzanode1.tvwmedia.net';
var streamport='1935';
var streamapp='srcEncoders';
var streamname='TVW01';

var streambase=streamserver+':'+streamport+'/'+streamapp+'/_definst_/'+streamname;
var cupertinourl='http://'+streambase+'/playlist.m3u8';
var sanjoseurl='http://'+streambase+'/Manifest.f4m';
var smoothurl='http://'+streambase+'/Manifest';
var dashurl='http://'+streambase+'/manifest.mpd';
var rtmpurl='rtmp://'+streambase;
var rtspurl='rtsp://'+streambase;

var agent=navigator.userAgent.toLowerCase();
var is_iphone = (agent.indexOf('iphone')!=-1);
var is_ipad = (agent.indexOf('ipad')!=-1);
var is_ipod = (agent.indexOf('ipod')!=-1);
var is_safari = (agent.indexOf('safari')!=-1);
var is_iemobile = (agent.indexOf('iemobile')!=-1);
var is_blackberry = (agent.indexOf('blackberry')!=-1);
var is_android1= (agent.indexOf('android\ 1')!=-1);
var is_android2= (agent.indexOf('android\ 2')!=-1);
var is_android3= (agent.indexOf('android\ 3')!=-1);
var is_android4 = (agent.indexOf('android\ 4')!=-1);

var is_chrome = (agent.indexOf('chrome')!=-1);

if (is_iphone) { iosPlayer(); }
else if (is_ipad) { iosPlayer(); }
else if (is_ipod) { iosPlayer(); }
else if (is_android1) { rtspPlayer(); }
else if (is_android2) { rtspPlayer(); }
else if (is_android4) { a4Player(); }
else if (is_blackberry) { rtspPlayer(); }
else if (is_iemobile) { rtspPlayer(); }
else { flashPlayer(); }

function iosPlayer()
{
var player=document.getElementById(container)
player.innerHTML='<VIDEO '+
' SRC="'+cupertinourl+'"'+
' HEIGHT="'+fixedheight+'"'+
' WIDTH="'+fixedwidth+'"'+
' poster="poster.png"'+
' title="Live Stream"'+
' CONTROLS>'+
'</video>';
}

function windowsPlayer()

{

// Need to add code here for silverlight player in Windows Phone to support the 12 users that actually have one. Until then use rtspPlayer();

}

function a4Player()
{
var player=document.getElementById(container)
player.innerHTML='<A HREF="'+cupertinourl+'">'+
'<IMG SRC="player.png" '+
'ALT="Start Mobile Video" '+
'BORDER="1" '+
'WIDTH="'+width+'">'+
'</A>';
}

function dashPlayer()

{

// Reserved for future use

}

function rtspPlayer()
{
var player=document.getElementById(container)
player.innerHTML='<A HREF="'+rtspurl+'">'+
'<IMG SRC="player.png" '+
'ALT="Start Mobile Video" '+
'BORDER="0" '+
'WIDTH="'+width+'">'+
'</A>';
}

function flashPlayer()
{


//If using JW6 Premium or Enterprise, you can also use the cupertinourl here.

jwplayer(container).setup({
 width: width,
 aspectratio: aspect,
 file: rtmpurl,
 autostart: false
 });


}

</SCRIPT>
</BODY>
</HTML>

Multi-Tenant/IP Hosting for Wowza Streaming Engine

For most users, running Wowza Media Server/Wowza Streaming Engine (which I’ll refer to as just “Wowza”) are perfectly content running it out of the box as is on a dedicated server. Where it gets a little more interesting is when you have to co-exist with other server applications that want some of the same ports (I’m lookin’ at YOU, web servers!).

By default, Wowza binds itself to all available IP addresses on ports 1935 (RTMP, but will also take HTTP requests on that port), 8086 (for some basic management functions), 8083 and 8084 (for JMX), and with WSE4, 8087 (REST) and 8088 (WSE Manager). It won’t bind itself to port 80 specifically because of the common problem of co-existing with web servers. If you have Wowza enabled for IPv6, it will also bind to all available IPv6 addresses on the same ports.

This technique is also good for reducing surface area, where you can have remote management such as SSH or RDP listening on one address, and someone scanning your streaming server IP won’t find any open management ports to attempt to exploit.

Read more

Mobile Voice in Haiti

As a follow-on to my previous post about getting mobile internet, here’s one about getting voice service on your US phone (at least if you have a Sprint phone).

I have a Samsung Galaxy S4 on Sprint. Sprint’s CDMA voice network is incompatible with the GSM networks in most of the rest of the world, but recent Samsung Galaxy devices (at least the S3 and S4, and other devices of the same generation/platform) use a software-defined radio that can be made to speak GSM or CDMA at will, with a simple settings change. CDMA doesn’t require a SIM but LTE and GSM do, so the Galaxy is a de facto international phone.

Sprint lets you do international roaming calls for $2/min, which is absurdly high. It’s much better to get a SIM from a local carrier and use that. Making it do this is relatively simple. If your account is in good standing, a simple phone call to Sprint will unlock your phone for using other SIMs (and before you try to do this for a GSM carrier in the US, it explicitly does NOT work on AT&T or T-Mobile). This unlock process does require a data connection (mobile or Wi-Fi) for the phone to receive the unlock signal. After doing that, there’s a simple process that the Sprint rep will give you over the phone to complete the process.

Once that’s done (took me about 5 minutes on the phone – which I did via Skype from Haiti!), all you have to do is go find a local SIM (and in the case of the Galaxy, trim it down to size), pop it in the phone, switch it over to GSM in the Mobile Networks settings, pick your carrier, and off you go.

I’ll add screenshots just as soon as I can make the phone do them. The normal S4 tricks aren’t working.

 

Mobile Internet in Haiti

I’m back down in Haiti, as some of you already know, working on some of the wireless networks linking the different sites of the Église Méthodiste d’Haïti (EMH), which is the Haitian Methodist Church. Knowing that I was coming into an environment where the internet connection was not functioning properly, and that I was likely going to need internet access for troubleshooting, I armed myself with a 3G GSM hotspot that I picked up on eBay.

After parting with about 50 bucks (plus another 15 for a charger and 2 spare batteries), the Huawei E583C unit showed up via USPS on my doorstep 4 days later bearing a postmark from Hong Kong (color me impressed, I can’t even get postcards from Toronto that quickly!)

20131125_150332I opened it up and inside was a “T-Mobile Wireless Pointer” from the UK division of T-Mobile. I popped on down to the local T-Mobile store and get a SIM for testing, and fired it up. After much futzing around trying to get it to speak 3G to the network without any success, I go back to T-Mobile and pick a tech’s brains. Turns out this one operates on the 800/1800/1900 band, which T-Mobile has phased out 3G on to make room for more LTE. Meanwhile, Jay was in Haiti, so I asked him to pick up a NatCom SIM and bring it home with him.

I’ll pause briefly here to talk a bit about mobile in Haiti. There are two major players, Digicel (which has a thing for island nations all over the world) and NatCom, which is formed out of what was left of the national telephone company (Teleco) and the Vietnamese national telecom (VietTel) that bought up a 70% interest in Teleco not long after the earthquake. What little copper telecom infrastructure existed in the country has long since been destroyed by a number of different Screen Shot 2013-11-25 at 3.20.19 PMmeans, both natural and human. Since the earthquake, NatCom has been building out a LOT of fiber. Digicel operates the only direct fiber link out of the country to Columbus Networks‘ Fibralink fiber network that links the Caribbean up to the rest of the world. The other way out of Haiti to the internet is via microwave backhaul to the Dominican Republic which has 2 landings of the ARCOS fiber ring.

In the nearly 4 years since the quake, mobile internet in Haiti has gone nuts. It’s now quite reliable, and surprisingly cheap if you know how to do it. Monthly postpaid plans for data cost about a quarter what they do in the US – a 10GB plan on digicel will set you back 1000 HTG (about 25 bucks). The same plan on Verizon in the US by comparison is about $100! Digicel offers current-generation Android phones like the S4 (but be prepared to part with full unsubsidized price for it), and Apple recently started making unlocked SIM-less iPhones available on its own store. The smartphone revolution is coming to Haiti, and it’s going to be interesting to watch. There was someone at church on sunday using an iPad, and it wasn’t someone from our team.

When I got down to Haiti and put the SIM Jay obtained for me into the hotspot (erm, “Pointer”… can any Brits enlighten me as to the origin of that term?), and getting no joy. Realizing that the zillion config changes I’d made to try and get it to work on T-Mobile’s network were probably interfering, I hit the factory reset button, and as soon as it rebooted, it was speaking 3G on Natcom’s network. It was that easy.

Next step was to load up some funds on the card, since it was a basic card that came empty of funds. Normally you can do this from the phone, but since this was a hotspot, I didn’t have the ability to dial numbers (although the Huawei firmware does allow you to SMS, which turned out to be a critical component). Natcom partners with a third party called EzeTop which allows you to reload phone cards online (yours or anyone else’s). So I dropped 10 bucks onto it (which translates to 392 HTG, a fairly lousy exchange rate) plus a penny per 10 Goudes as a transaction fee, and off I go. No sign anywhere of what the per-MB cost is. NatCom’s website isn’t particularly helpful in that regard (I later find out that it’s 1.9HTG/MB, about 4 cents.)

Now that I had mobile internet, I fired up the iPad and did some testing on the drive to Petit-Goave, and was getting quite reasonable speeds around 1.5-2Mbps in both directions, very much capable of posting pictures to facebook and whatnot.

Once we got to the guest house where we were staying, we discovered that the wifi there was indeed out of service. I put the hotspot to good use downloading information I was going to need to fix it. In very short order, net access ceases, and I get a screen from NatCom saying that my card is empty, and provides a helpful list of plans and how to activate them. I then go find our hostess and borrow her laptop and internet access to load up some more funds on the card, and then try to activate one of the listed plans. It tells me I can’t do that because I have the wrong type of card.

Then, disaster. Within a matter of little more than an hour, 20 bucks worth of data on the card had vanished. After some digging, I discovered that my good buddy CrashPlan had stabbed me in the back and decided to start a big backup. I killed CrashPlan and reloaded the card (this is getting expensive, and I’m still not entirely sure how much data I’m burning through, especially now that the team is sharing in the internet joy — and the cost!)

Now that I’m back online, I start digging around the NatCom site again to figure out what plans I can access through the SIM I already have. Turns out that they have slightly different SIMs and plans for laptop/USB modems and for mobile phones. I had the latter, a “Nat-Mango” card, which can be had from any street vendor for 25 HTG. I finally found the list of mobile internet plans for the phones, and the correct number to SMS the plan change to. So I send off the text, only to get back “You don’t

Screen Shot 2013-11-05 at 8.03.55 AM

have enough funds for this plan”. I keep moving down the list until even the cheapest one kicks back the message… Uh-oh, I’m running on fumes again. Just as I go to top it up again, it shuts off. Fortunately, one of our Haitian team members had data on his Digicel phone, and I was able to get the account charged up, and switched over to the “Unlimited” plan. Unlimited in this case means 3.5GB at max HSPA+ speeds, then you’re rate-limited to 3.5 Mbps after that. Given that I never saw 3Mbps anywhere, this isn’t really a huge hindrance (that may be a factor of the device more than the network, too). By the time the week was out, our team had gobbled up nearly 25 gigabytes of data through the device.

So, in short, mobile internet from local carriers in Haiti is reliable and cheap (if you know the trick to not paying out the nose per MB), and can be done on a fairly inexpensive piece of hardware. If you’re so inclined, you can also get USB sticks from NatCom for about 1500 HTG. My next step is going to be to see if a device from Cradlepoint can handle the Natcom USB sticks, since they don’t have such a tight limitation on clients.

HLS distribution with Amazon CloudFront

I’ve blogged extensively about Wowza RTMP distribution with edge/origin and load balancing, but streaming distribution is moving more to HTTP-based systems such as Apple’s HTTP Live Streaming (known inside Wowza as “cupertino”), Adobe’s HTTP Dynamic Streaming (Wowza: “sanjose”), and Microsoft’s Smooth Streaming (Wowza: “smooth”). Future trends suggest a move to MPEG-DASH, which is a standard based on all three proprietary methods (I’ll get into DASH in a future post as the standard coalesces – we’re talking bleeding edge here). The common element in all of them, however, is that they use HTTP as a distribution method, which makes it much easier to leverage CDNs that are geared towards non-live content on HTTP. One of these CDNs is Amazon’s CloudFront service. With edges in 41 locations around the world and 12 cents a gigabyte for transfer (pricing may vary by region), it’s a good way to get into an HTTP CDN without paying a huge amount of money or committing to a big contract with a provider like Akamai.

On the player side, JW Player V6 now supports HLS, and you can do Adobe HDS with the Strobe Media Player.

With the 3.5 release, Wowza Media Server can now act as an HTTP caching origin for any HTTP based CDN, including CloudFront. Doing so is exceedingly simple. First, configure your Wowza server as an HTTP caching origin, and then create a CloudFront distribution (use a “download” type rather than a streaming type – it seems counterintuitive, but trust me on this one!), and then under the origin domain name, put the hostname of your Wowza server. You can leave the rest as defaults, and it will work. It’ll take Amazon a few minutes to provision the distribution, but once it’s ready, you’ll get a URL that looks something like “d1ed7b1ghbj64o.cloudfront.net”. You can verify that the distribution is working by opening a browser to that address, and you should see the Wowza version information. Put that same CloudFront URL in the player URL in place of the Wowza server address, and your players will now start playing from the nearest CloudFront edge cache.

See? Easy.

Browser-Aware Player Code: Episode V, IE Strikes Back

Not so long ago, I updated my browser-aware player code to check for the presence of a stream. Recently, it’s come to light that Internet Explorer 9 doesn’t play nice with this particular snippet, because in IE9, the Javascript engine is rather brain-damaged when it comes to cross-site requests. In order to deal with this properly, we must alter the way we query the server for the presence of a stream:


console.log("Starting stream Check");
if (is_ie9) {
console.log ("Using XDR because IE9 is stupid");
streamcheckXDR();
setInterval(function(){streamcheckXDR()},10000);
}
else {
streamcheck();
setInterval(function(){streamcheck()},10000);
}
function streamcheckXDR() {
 console.log("Starting XDR");
 xdr = new XDomainRequest();
 if(xdr) {
 xdr.onerror = function(){ console.log("XDR Error"); };
 xdr.onload = function(){ startPlayer(xdr.responseText,"XDR"); };
 url = "http://"+streamer+":8086/streamcheck?stream="+stream;
 xdr.open("get",url);
 xdr.send();
 } else {
 console.log("Failed to create XDR object");
 }

}

function startPlayer(result,mode){

// for some inexplicable reason, running "Boolean" on the XDR output doesn't work

// so we have to call the function and tell it if we're dealing with XDR data or AJAX data.

&nbsp;

if(mode == "XDR") {
 if (result === "true") { curstatus = true;}
 if (result === "false") { curstatus = false;}
 } else {
 curstatus = Boolean(result);
 }

//console.log("Result: "+result);
 //console.log("Previous: "+prevstatus);
 //console.log("Current: "+curstatus);
 if (curstatus == prevstatus) {
 //console.log("No Change");
 } else {
 if (curstatus) {
 if (is_iphone || is_ipad || is_ipod) { iOSPlayer("videoframe",plwd,plht,server,stream);}
 else if (is_blackberry) { rtspPlayer("videoframe",plwd,plht,server,stream+'_+240p');}
 else { flashPlayer("videoframe",plwd,plht,server,stream); }
 console.log("Changed from false to true");
 } else {
 var vframe=document.getElementById("videoframe")
 if (is_iphone || is_ipad || is_ipod || is_blackberry) {
 } else {
 jwplayer("videoframe").remove();
 }
 vframe.innerHTML = '<IMG SRC="image.png" WIDTH="'+plwd+'" HEIGHT="'+plht+'">';


 console.log("Changed from true to false");
 }

}
 prevstatus = curstatus;
}

function streamcheck() {
 console.log("Starting AJAX");
 $.ajax({
 dataType: "json",
 contentType: "text/plain",

type: "GET",
 url: "http://"+streamer+":8086/streamcheck?stream="+stream,
 error: function(XMLHttpRequest, textStatus, errorThrown)
 {
 console.log('AJAX Failure:'+ textStatus+':'+errorThrown);
 //some stuff on failure
 },
 success: function(result){startPlayer(result)}
 });
}