Using the Wowza Stream Class

I mentioned in the previous post about using ffmpeg in a cron job to create Simulated Live events via Wowza. In this post, I’ll explain how to do it using the Wowza Stream Class module, which allows you to set a broadcast schedule to play a mix of recorded and live content.

Wowza has a pretty good document on how to add this module in to your server and do a test playlist.If you’re setting this up on Amazon EC2, you’ll need to update your startup package by putting the module in the wowza/lib directory and the playlist in the wowza/content directory

Unfortunately, the tutorial doesn’t really cover playlist creation beyond the example. This is especially tricky, given that the scheduling parameters don’t seem to conform to any known SMIL standard. Yes, it’s XML, so theoretically, it doesn’t matter, but there are extensions in SMIL 3.0 that are meant to deal with server-side playlists for automating programming.

Unless you specified a different application name in the Properties section of Server.xml, the automated playlist will publish to the live application.

The basic structure of the SMIL file body consists of <stream> and <playlist> statements.

Stream Element

The <stream> element defines one or more virtual stream names that the playlists will feed into:

<stream name="playlist-high"></stream>
<stream name="playlist-low"></stream>

In this example, I have a high and low bandwidth stream. In your player, you reference the stream name, rather than the streamshedule.smil file, like this:

Flash RTMP:

streamer: rtmp://wowza.server.address(:port)/live
file: playlist-high

Flash HTTP:

http://wowza.server.address/live/playlist-high/manifest.f4m

HLS:

http://wowza.server.address/live/playlist-high/playlist.m3u8

Silverlight

http://wowza.server.address/live/playlist-high/Manifest

Playlist element

The <playlist> element defines specific video sequences that go into the virtual stream. There are four key parameters to the playlist element:

  • name : This is a unique name for that particular sequence.
  • playOnStream : This tells the Stream Class module which of the previously defined streams this playlist is associated with.
  • repeat : Valid values are true/false. This defines whether this playlist loops when it gets to the end.
  • scheduled : When this playlist is scheduled, in the format “YYYY-MM-DD HH:MM:SS” (24-hour time)

Within the playlist element are one or more <video> statements that use the following parameters:

  • src: the video to be played. Can either be:
    • a stream within the same live application (use the stream name only)
    • an MP4 video file in the Wowza content directory (use mp4:filename.mp4)
    • A stream elsewhere (requires some additional modules)
  • start : The number of seconds into the video to start playing. If this is a live source, use the value -2.
  • length : The number of seconds to play the video. The value -1 indicates to play until it ends.

Using start/length is a useful way to introduce commercial breaks or intermissions into a stream. This example would show BigBuckBunny.mp4 from the start, for 60 seconds, then cut to a commercial for the duration of the advertisement-1.mp4 file. After the commercial, it would resume and play for 2 more minutes, play a 30-second commercial from advertisement-2.mp4 and then plays the rest of the BigBuckBunny.mp4 file. If the playlist set to repeat, this will loop.

<video src="mp4:BigBuckBunny.m4v" start="0" length="60"/>
<video src="mp4:advertisement-1.mp4 start="0" length="-1"/>
<video src="mp4:BigBuckBunny.m4v" start="60" length="120"/>
<video src="mp4:advertisement-2.mp4 start="0" length="30"/>
<video src="mp4:BigBuckBunny.m4v" start="180" length="-1"/>

When a particular playlist has ended, and there are no others currently scheduled, it will default to the last playlist, even if that playlist’s repeat is set to false.

Here’s an example for our weekly service replays, and live sunday events:

<smil>
 <head>
 </head>
 <body>

  <stream name="playlist-high"></stream>
  <stream name="playlist-low"></stream>

  <playlist name="mon-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-17 07:45:00">
   <video src="mp4:traditions-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="mon-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-17 07:45:00">
   <video src="mp4:traditions-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="mon-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-17 09:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="mon-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-17 09:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="tue-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-18 12:45:00">
   <video src="mp4:praise-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="tue-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-18 12:45:00">
   <video src="mp4:praise-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="tue-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-18 14:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="tue-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-18 14:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="wed-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-19 21:45:00">
   <video src="mp4:praise-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="wed-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-19 21:45:00">
   <video src="mp4:praise-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="wed-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-19 23:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="wed-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-19 23:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="thu-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-20 03:15:00">
   <video src="mp4:traditions-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="thu-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-20 03:15:00">
   <video src="mp4:traditions-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="thu-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-20 05:00:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="thu-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-20 05:00:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="fri-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-21 07:45:00">
   <video src="mp4:traditions-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="fri-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-21 07:45:00">
   <video src="mp4:traditions-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="fri-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-21 09:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="fri-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-21 09:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sat-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-22 02:45:00">
   <video src="mp4:praise-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sat-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-22 02:45:00">
   <video src="mp4:praise-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sat-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-22 04:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sat-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-22 04:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sun-am-high" playOnStream="playlist-high" repeat="false" scheduled="2011-01-23 11:30:00">
   <video src="mobile-2" start="-2" length="6300"/>
  </playlist>

  <playlist name="sun-am-low" playOnStream="playlist-low" repeat="false" scheduled="2011-01-23 11:30:00">
   <video src="mobile-1" start="-2" length="6300"/>
  </playlist>

  <playlist name="sun-am-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-23 13:15:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sun-am-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-23 13:15:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sun-pm-high" playOnStream="playlist-high" repeat="false" scheduled="2011-01-23 17:45:00">
   <video src="mobile-2" start="-2" length="6300"/>
  </playlist>

  <playlist name="sun-pm-low" playOnStream="playlist-low" repeat="false" scheduled="2011-01-23 17:45:00">
   <video src="mobile-1" start="-2" length="6300"/>
  </playlist>

  <playlist name="sun-pm-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-23 19:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sun-pm-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-23 19:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="default-high" playOnStream="playlist-high" repeat="true" scheduled="2011-01-01 00:00:01">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="default-low" playOnStream="playlist-low" repeat="true" scheduled="2011-01-01 00:00:01">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

 </body>
</smil>

Video files can either be uploaded, or recorded on the server using a live-record application type.

Once your playlist is built, you’ll need to restart the Wowza service for it to read the new playlist in and schedule it internally.

Update(July 18, 2001) : I’ve added a post about my Excel playlist generator.

Simulated Live with Wowza and Apple HTTP Live Streaming

Last summer, we switched our primary Flash streaming over to 316 Networks partly because of the simulated live capability they offered, and partly for the Media Suite backend. We continued to use Wowza on EC2 for our mobile users, since the solution works very well. Unfortunately, simulated doesn’t work for our mobile users, who are limited to live.

We have 3 replays a week for each of our two web services: the traditional service from Sunday morning, and the praise service from Sunday night.

I should probably step back for a moment and explain what “Simulated Live” means. It’s a recorded event, but from a user standpoint, it behaves like a live event. There’s a set start time, and if you come in 20 minutes after the start of the event, you get the video 20 minutes in; there are no “trick play” DVR functions like fast-forward or rewind. This gives a shared experience for everyone who is watching, and also keeps us legit with the copyright restrictions, as our “live” events are considered extensions of the actual live event in the sanctuary. Simulated live is also known as “pseudostreaming”

Wowza doesn’t natively support pseudostreaming (although the Stream Class API does have some scheduling capability — see this post), so we needed some way of broadcasting recordings on a schedule. I could use the VT5 machine and the Scheduler to replay the recordings on a schedule, but the big downside is that it consumes local bandwidth, which is in short supply.

What I needed was a way of streaming the archive files (high and low bandwidth) that were created by the Kulabyte encoder during the live event. Ideally, since I already upload these to 316 for rebroadcast, I’d like to not have to upload it to two locations.

Enter the lovely open-source encoder, ffmpeg. My concern about using ffmpeg was that re-encoding an already encoded file had the potential of introducing compression artifacts and adding CPU load. I was very happy to find an obscure command-line setting that tells it to copy the input file’s audio and video codec directly. The only thing ffmpeg would be doing would be extracting the audio and video streams from the MPEG-4 container and stuffing them into a Flash container without molesting the actual streams at all. Added bonus: ffmpeg can also not only output to RTMP, but can take RTMP as an input as well.

Fortunately, Media Suite’s media bin makes videos available via direct RTMP and HTTP and helpfully provides the CDN URL for those files. Another method of storage would be to use Amazon S3 and get the files either via HTTP or Cloudfront RTMP.

Attempt #1: Installed ffmpeg on a local Ubuntu box via apt-get, no dice. It refused to connect to the RTMP server. After some research, I found that the version of ffmpeg on the Jaunty version of Ubuntu is 0.50, and seems to have some weird build options.

Attempt #2: I downloaded the ffmpeg 0.61 source, ran a quick configure/make/make install on it, and tried again. Success! I was taking an MP4 recording on a disk, and streaming to Wowza. I then changed the input from a local file to to the URL provided by 316, and weird stuff started happening. And then I realized that the URL had some GET parameters in it that left a question mark and two ampersands in the URL that I needed to escape before bash would parse it correctly. Once I fixed that, it started running happily, and I was seeing the stream on my iPod.

Attempt #3: I Downloaded the ffmpeg 0.61 source to my Wowza server on EC2 and crossed my fingers that the build would go off without a hitch. Success! I then transplanted the command line I used on my test box, tweaked the destination server to the local Wowza install, and fired it off. Success again!

Now that I’d proved the concept, it was simply a matter of putting that command into a cron job and waiting to see if it fired off. And then realizing that the server is in eastern time. And then realizing that I should probably correctly specify the path to ffmpeg (doh!). But once I got those silly details ironed out, off it went.

So now I have ffmpeg on my EC2 system, consuming virtually no CPU, pulling my archive files from 316 (only had to upload them once), streaming to Wowza on a scheduled basis, without chewing up T1 bandwidth at our main site.

Unfortunately, there’s a little bit of brain damage involved in pulling it from 316, because I’ll have to go change the filename in the cron job every week. Perhaps I’ll end up uploading it to S3 after all and just giving it a static name.

Here’s the commandline used:

/path_to/ffmpeg -i rtmp://rtmp.server/filename.mp4 -re -sameq -acodec copy -vcodec copy -f flv rtmp://localhost/live/stream

Commandline options used:

  • -i : specifies input. This can be either RTMP, HTTP, or a local file.
  • -re : near-realtime mode
  • -sameq : Keep quality settings
  • -acodec copy : send input audio stream unmolested to the output
  • -vcodec copy : send input video stream unmolested to the output
  • -f flv : Force output to FLV container

Sony VISCA RS-422 Control

Update – January 2014: Wow, 3 years later this is still one of the most popular posts on this blog! I’ve had some questions about using this with the EVI-HD1, which has only RS-232 DIN ports. Theoretically, it should work, but you might need to alter some pinouts in the breakout box, and I would highly recommend using shielded/grounded cable, as RS-232 is an unbalanced signal. A reader is going to give it a try, and if it’s successful, I’ll update the post with some pictures.

Update – October 2021: It blows my mind that nearly 11 years later, this is still one of the most frequently visited posts on the site…

Now, back to our regularly scheduled blog post!

We recently acquired a few more of Sony’s excellent EVI-D70 cameras for use in our chapel for streaming weddings, funerals, and other events in our smaller worship space.

When we remodeled the space a few years back, it was originally designed with these cameras in mind.  The original intent was to provide some additional angles for videographers to use, but the idea never really took off. Due to lack of use, the cameras originally installed were re-purposed for Resurrection Online in the main sanctuary. Things have come full circle now, and the ability to stream services and events from this space is being requested. As a result, we acquired some more cameras, and are in the process of updating the camera system in that room.

The original design used an AMX touchscreen/joystick controller and a custom integration over RS-232, with each camera homerun to the control rack. There were numerous difficulties with the cameras randomly freezing up and not responding to controls, requiring someone to get on a ladder and power-cycle the unit.

As part of the updated system, we’ve ditched the AMX controller and are using Sony’s RM-BR300 control unit which is designed for this particular camera. We also have user familiarity, since we already have one of these controllers in our main sanctuary for the BRC-H700 remote camera mounted on the catwalks (aka, the “SkyCam”). The controller can do Sony’s VISCA protocol over RS-232 (via a Mini-DIN) or RS-422 (via a Phoenix connector).

This is where it got sticky. We have an 8-conductor homerun cable from each camera position, but the Sony controller is designed to daisy-chain the VISCA ports. Each camera has two RS-232 Mini-DIN ports (one in, one out). Fortunately, both RS-422 and RS-232 in this application only require four wires, so we can loop out and back on the same cable.

Due to the annoyance factor of having to re-terminate Mini-DIN connectors, I opted for the RS-422 port which uses a Phoenix screw terminal (Part # 1840434 in case you need to order one – Sony wants an obscene amount of money for them, they’re dramatically cheaper at an electronics supplier like Mouser). RS-422 also has the advantage of much longer signal path due to its balanced signal. Since we’re also adding a new location, I wanted to be able to wire it up with standard Category 6 twisted-pair cabling. This cable also has eight conductors, making it ideal for the task. In terms of flexibility, RJ-45 is king in the twisted-pair world, so I had do design a means of daisy-chaining my VISCA ports via ordinary patch cords.

At first, I was a little baffled by the wiring of VISCA, since the RM-BR300 connector pinout is exactly backwards from that of the one on the cameras, and the documentation provided is a little confusing. Fortunately, the Sony POSC was quick to help and they e-mailed me a wiring diagram for this specific application (and were kind enough to allow me to post it. I translated that into two main components, a breakout box and a standard cable, that would work on either the controller or the cameras.

To make the cable, I simply took a patch cord off the shelf, lopped one end off, and terminated it on the Phoenix connector:

The wiring is as follows:

Now, you’ll notice my wiring diagram shows the orange pair on the first two, and the picture shows green. This is because I found out (after much frustration of tracing signals) that the patch cord I grabbed happened to be wired for 568A rather than the more common 568B. Simply swap orange and green if this is the case.

Once I got the cables sorted out, I then replicated Sony’s wiring diagram with a handful of data jacks. The connections go like this:

I used bits I had on the shelf, but I would recommend using a different jack color for the control input so you don’t get it confused. Once I got it wired up, this is what I had (I colored the control jack black with a Sharpie):

Even if this install only has three cameras, I wired it up for five, to fill a six-way biscuit box that I had on the shelf (these are Lucent/Avaya components):

.. and put the lid on it with some labels:

As for the hookup, set the DIP switches on the bottom of the controller and the cameras to use RS-422 and either 9600 or 38400 bps, and hook them up. Note that they must be in sequence, or the whole chain will be broken if you skip a slot. Plug a camera into #1, it will be #1 on the controller after they self-enumerate on startup, in order of closest to farthest on the chain. Connecting a camera will cause the controller to re-initialize.

Action Shot:

I used a biscuit box, but you could also use a modular patch panel to do the same thing. I hope to use a second category 6 run with an S-Video termination on it (2 pairs) and power (other 2 pairs) so that the whole system can run off a standard 2-cable pull.

Review: EcoSmart A19 LED bulb (40W Equivalent)

EcoSmart A19 LED BulbI’ve posted before about LED lighting, and consider myself an early adopter.

Recently, Home Depot significantly expanded their selection of LED bulbs beyond the Philips brand that I’ve been using for a few years, mostly in my kitchen track lights (GU10 formfactor). I’ve been quite happy with those, and I only have two more halogens left in the track that seem to be hanging on, knowing their fate should they burn out.

The EcoSmart line appears to be a Home Depot house brand, and as such is only available there. The brand encompasses both CFL and LED lighting technologies. The bulbs are less expensive than the Philips bulbs.

I picked up eight of the 40W-equivalent A19-style bulbs. These have a form factor that matches that of a traditional incandescent bulb, so they’ll fit anywhere a regular bulb will fit, unlike the bulbs I blogged about previously. I bought these to use in our master bath above the vanity, and the  master bedroom ceiling fan, where solid-state bulbs are a much better option due to the vibrations of the fan which drastically shorten the life of filament bulbs. Because of this application, these bulbs are also dimabble.

The specs on the bulb are as follows:

While this bulb is listed as a 40W equivalent, because of the directionality of the bulb, it’s roughly equivalent to the light you’d get from a 75W bulb in directional applications. I tried it in my regular bathroom fixture, which assumes a standard bulb emitting light in all directions, and it’s not up to the task. Side-by-side comparisons in a reading lamp, on the other hand, give a result that looks almost identical to the 75W incandescent bulb that was in it previously.

In the ceiling fan application (four bulbs), it lights up the large master bedroom quite nicely and dimming is not only smooth and flicker-free, but quiet. The overall consumption of  35W is a dramatic improvement over the set of 75W halogens that used to be in there.

This is the packaging for eight bulbs. The tiles are 12" across.

My only real gripe about these bulbs is the logical disconnect between the “eco-smart” name and the ridiculous amount of packaging they come in. The bulb itself is in a plastic clamshell that is not coded for recylcing (but is likely PET), which is then encased in a fairly convoluted cardboard box big enough for a PAR38. These then come four each in a corrugated cardboard tray for retail display. I haven’t been able to confirm it, but the boxes look like they may use the same box die for all their bulbs, and swap out the plastic shell for the appropriate one. At least it’s not your typical wound-inducing plastic retail shell. If I needed to return these to the store, it looks simple enough to repackage them such that they can be resold.

Home Depot also offers EcoSmart LED bulbs in PAR30, PAR38, PAR20, G25, MR16, and E26 formats, as well as a whole host of holiday lighting options.

Time will tell how well these hold up. Next up are likely going to be the G25 bulbs in the dining room fixture.

The video game is changing

Nope. Not talking about your XBox or Playstation or even your Wii.

A while back, I posted about why Blockbuster is screwed. The scene just got bleaker, and not just for Blockbuster. Now the entire Cable TV industry is facing a major conceptual shift.

Mark Melanson blogged today about Netflix mulling over the idea of ditching the physical media distribution concept that they perfected. Netflix has already induced a lot of insomnia with the senior management at Blockbuster. The cable people need to start worrying for two reasons:

  1. This is going to clobber Pay-Per-View revenues, especially if Netflix gets major licensing deals on fresh content.
  2. This is going to clobber the data networks that these same cable operators are selling to their TV customers.

But there’s more. The way we watch content in general, not just movies, is changing dramatically. What the cable companies fail to realize is that they’re not really in the content business. They’re in the business of selling a wire into your house, and they need to provide you with a compelling reason to pay them for that wire, so they piggyback a bunch of TV on it. In many cases, they’ll bundle IP and phone service too.

One of the problems is that when you’re selling a wire as a content delivery mechanism, you either have to produce a lot of compelling content, or acquire it somehow. There’s plenty of that out there to be had, but at a price. And that can lead to the content producers holding their customers hostage as a bargaining chip against the middleman. By the way, Fox and Cablevision, have you noticed that this makes your customers very angry? I bet Major League Baseball is selling a ton of online viewing subscriptions. That was revenue that could have been yours.

Fortunately, consumers have a few options to consume content that isn’t dependent on the company providing the wire into the house. One only has to look at the success of Hulu, Major League Baseball, and Netflix to see that. Of course if your internet access is coming from the same place as your TV, the content provider can quite easily lock you out, as Fox did to their Cablevision consumers.

The problem is, in the current environment, TV is still very much something tied to time and place. What content you get over cable or broadcast is subject to the scheduling whims and programming choices made by the stations, networks, and cable operators.

We as consumers have tried to work around this with DVRs (timeshifting) and devices like SlingBox (placeshifting) in order to consume content on our terms.

This works, but to a point. It also provides unecessary stress on the last mile of the networks. It’s also ridiculously expensive for the consumer. I no longer have cable. Or a TV, for that matter. Most everything I watch is picked up over-the-air by my Windows Media Center DVR and watched via another machine on my network, or online via Hulu or the content provider’s website.

The downside to this arrangement is that when watching online, there’s still a delay from the original airtime to when it’s actually made available on the web. This generally doesn’t bother me as I’m not a slave to TV schedules, but I do miss out somewhat on the shared experience of millions of others watching (and tweeting about) a show at the same time.

Then there are other shows that aren’t available in either format. I can’t watch Mythbusters on the web very easily without violating copyright law. There’s always Netflix and TV Show DVDs (which have been hugely successful) for that, but it’s not convenient.

Here’s what most of the content companies are failing to realize: Consumers will find a way to watch the content they want to watch, when they want to, on the device they want to, and generally care little about intellectual property laws meant to preserve originality.

If you’re a content company that’s not making your full content available via streaming, you’re missing out on a potential audience. It also has to be easier to consume legally than illegally.

Hulu is a great example of making it easy to consume content. Netflix is doing a great job of adapting.

The other great challenge with cable providers is that there’s a finite amount of content that can be stuffed down the wire. The current model involves sending everything down the wire at once and having the machine at the consumer’s end of the wire display a given one. Some great technological progress has been made to increase that capacity, but it’s still finite. Wouldn’t it be a lot simpler to send only the content actively being consumed down the wire?

Better still, give me a virtual DVR in the cloud and let me pick from a whole host of content. I still want to watch my favourite shows when I’m on the road. I can’t do that with cable. I may have eclectic tastes that don’t line up with what makes money for the cable operator. If I like to watch Curling and Cricket, I’m out of luck, because there may be 3 of us in the whole area who care about those sports.

Say you’re the Discovery Channel, or Fox. Instead of selling your content wholesale to the cable operators, stream your content directly to the consumer, in HD. I still think you can make money doing this, either with advertising or paywalls.

Imagine a virtual “cable” operator. Not bound by geography or cable plants, but rather open to the entire planet, and you offer a menu of content. Charge by the channel. Or by the show. (We’re talking micropayments here, but if most people are willing to shell out 60-100 bucks a month for a buffet of channels, and ultimately go back to the same 10 channels, there should be money to be made). You don’t even have to provide the streaming infrastructure, let the content providers worry about that. Just sell/broker access to it. The distribution is handled by the major CDNs anyway.You can even offer obscure content that doesn’t have a lot of demand. Stop being a slave to schedules. Sure, release new content every week, but let people watch it on their schedule. If you’re not sure how to make that work for you, go ask Felicia Day. She’s got it figured out.

The 2010 Winter Olympics were a good step in that direction. Even so, geographical restrictions on content (imposed mainly due to licensing issues) really got in the way. Many people found ways around it with proxies. Here’s a clue to content providers: Consumers don’t really care about geography. Why should I be disallowed from watching a show or event on the CBC or the BBC simply because of where I happen to live? Your content is compelling to me! I’m even willing to pay for it, either with real money or by watching your ads (just don’t get too crazy with the ads or I’ll go somewhere else). You’re missing out on a revenue opportunity when you should be going after every one of those you can get.

Suddenly, the guys in the business who are charging for a wire to the house should be getting nervous. The current cable paradigm is tantamount to charging $100 for a chinese buffet with only one steam table. The value proposition simply isn’t there. That fact that you’re still in business at all is a testament to the power of monopolies and heavy-handed legal action.

Cable operators need to get out of the content business. It’s killing them. Might as well get out of the voice business too, since that’s not going to stick around long. But if you’re willing to take that wire and provide me with a transport mechanism for all this content out there (in other words, IP access), I’m all over it. I’m a customer of my cable company. And all I buy from them is data. I’m fortunate enough to have cable competition in my area, but the competitor wants to charge me extra for not having TV content clogging up my wire. Sorry, that doesn’t fly with me.

Why on earth would you want to restrict the size of your audience? There are millions of consumers wanting to consume a ton of available content out there. Don’t get in the way. If you do, the consumers will cut you out of the action and you’ll eventually find yourself off in the booth in the corner with the magazines and newspapers, crying into your beer and wondering why nobody loves you anymore.

Update (10/23/10): CBS, ABC, and NBC demonstrate that they don’t get it. They are shutting out Google TV users from viewing their content. Oh well, they’ll figure it out eventually. If they’re lucky, before they become completely irrelevant.

Update 2 (10/29/10): And now we hear that XBox Live is now bigger than Comcast.

On School Lunches…

Another school year is upon us, and that means that children are once again subjected to the abuse that is the federally-guided school lunch program.

We decided to allow F one school lunch a week as a treat. After the first school lunch, we’ve put an all-out moratorium on it. You see, F doesn’t react well to high-fructose corn syrup. Her behaviour goes bonkers within a few hours, and it takes her a couple of days to recover, culminating in an ugly, whiny mess of being unable to deal with anyone or anything. F’s lunch on friday consisted of hot dogs (contain HFCS), Cheetos (HFCS), and fruit snacks (HFCS). The whole weekend was downright ugly. Naturally, I’m taking an interest in what they’re serving the kids at school, and what I’m seeing isn’t pretty.

I’ve asked the school district for ingredient statements on their menu, but haven’t heard anything yet.

On Tuesday, she turned 7, and we told her she could buy her lunch (so she wouldn’t pack one) and the rest of the family was going to surprise her with Chick-Fil-A as a treat.

At lunch, I looked around me at what all the other second-graders were eating. It was a sea of brown (although I’ll admit, there wasn’t a whole lot of color in our own lunch, but we eat a lot of fresh veggies at home).

Tuesday’s lunch menu at school was:

  • Whole Wheat Pasta with Marinara Sauce & a “Bosco Stick”
  • Grilled Cheese Sandwich
  • Mini Corn Dogs
  • Bagel with [flavored] cream cheese
  • [Flavored] Yogurt with poppyseed muffin
  • Peanut Butter & Jelly (actually, an Uncrustable)

Sides:

  • Steamed Edamame
  • Steamed Peas & Carrots
  • Chilled Fruit Cocktail

Beverage options are:

  • Milk (white, chocolate, strawberry)
  • Juice (Orange, Grape, Apple, Fruit blend)

According to the school program, Every lunch “Full Meal” includes students’ choice of one entrée and self-serve offering bar including menued sides PLUS a variety of fresh fruits and vegetables with two drink choices.

Notice what the vegetables are: self-server offering bar. Federal guidelines mandate a certain amount of vegetables in the school lunch, but for the kids, it’s strictly optional. And they’re soggy, mushy, and have had the life cooked out of them. The number of trays containing fruit or vegetables could be counted on a single hand, and much of that ended up in the trash. Much of the pasta was devoid of sauce. The steam trays containing the vegetables were virtually untouched (and students eat in grade order, approximately 80-100 students per grade)

So, let’s break this down.

Whole wheat pasta. pretty benign stuff, but nutritionally pretty vapid. Lotta carbs, not a lot else. It may be whole wheat, but it’s still pasta.

Bosco Stick. What the heck is that? It’s some sort of breadstick with cheese in the middle. One stick contains 210 calories, a third of which are from fat.. Key indredients: Sugar and partially hydrogenated soybean and cottonseed oil, and vegetable glycerides. Yummy.

Grilled Cheese. ‘Nuff said. Hunk of bread surrounding pseudo-cheese and fried on the griddle.

Mini Corn Dogs. Hot dogs, ergo, HFCS.Wrapped in corn batter. An Iowa farmer’s dream.

Bagel w/ Cream Cheese. The cream cheese was strawberry flavored and contains sugar. Better than even chance that the bagel contains HFCS as well.

Yogurt w/ Poppyseed muffin. Again with the loads of sugar.

Peanut Butter & Jelly. The school can’t even be bothered to make the simplest of sandwiches, they have to use the prefabricated abomination that is the Uncrustable. 38 ingredients, including HFCS (in both the “bread” and the jelly), dextrose, and palm oil, not to mention a whole boatload of preservatives.

Edamame. Pure soy (although to its credit, pretty much unadulterated)

Fruit Cocktail. Let’s take fruit, and then pickle it in sugar water. Brilliant.

Flavored milk (chocolate or strawberry). 30 grams of sugar in a single serving, and the kids usually take two. By comparison, the same amount of Coke contains a mere 26g of sugar. In our school, it’s real sugar, but HFCS is common. 12g of those sugars are from the milk itself.

White Milk. I didn’t see a single kid with this. Otherwise, pretty healthy stuff.

Juice. A serving of this contains 28 grams of sugars, virtually all of it fructose, with no fiber to buffer it (except perhaps in the orange juice)

So, we have a menu loaded with sugars and not-so-complex carbohydrates. The second-graders arrive at 11:30. By 11:45, they’re being herded outside, where they have 10 minutes to run off all that sugar. They technically have the option to stay and finish their meal, but there’s intense pressure from both their peers and from the lunchroom staff for them to get out and play. Net result is that the amount of waste is mind-boggling.

In 15 minutes, these kids will practically inhale well over 100 grams of sugars and starches. They will then have 10 minutes to run it off before it’s even had a chance to hit their system, followed by over three hours in the classroom, punctuated by 15 minutes of recess in the middle. And they wonder why kids get fat and inattentive. Even our school’s nurse cringes at the school’s lunches.

And this is a pretty typical day on the menu. The district swears they’re abiding by federal guidelines. The common thing on this menu is that it’s virtually all made from four of the top five USDA-subsidized crops: wheat, corn, soy, cotton (Tobacco is the 5th).

I think the USDA overseeing the school lunch program (and overall nutritional policy) is not only a massive conflict of interest, but a primary cause behind the obesity epidemic. You can’t have the people setting production policy and subsidies be the same ones overseeing policy related to its consumption. When ketchup (which contains a lot of HFCS) is considered a “vegetable”, there’s a problem.

If the school lunch program and nutrition policy were overseen by health officials (like DHHS or the Surgeon General), I think we’d be a lot better off.

Social Media: Doing it Wrong

There’s an up-and-coming local business (who shall remain nameless) that hired someone to handle their social media presence. Unfortunately, it seems they hired someone who is a marketer first, and who happens to know that social media tools are out there, but doesn’t have a clue how to use them appropriately.

Today, they posted a special on facebook: “Come by before we close, and will give you <free stuff>”. Since their <free stuff> is mind-blowingly good, I stopped by on the way home from work. The owner himself was a little baffled, and didn’t even know what the special was. He had to call his “social media person” (who didn’t answer the phone), and then resort to looking it up on Facebook. He tried to explain that their new social media person was “going a little crazy”.

Previously, they’d had a twitter special that involved DMing them a certain phrase when you got there, and they would DM you back a coupon code worth 10%. When I tried that, it took 5 days for me to get my coupon code. I’ve frequently received random DMs from them that indicate to me that something is amiss with their twitter auto-responder. Comments to their twitter account pointing this out went ignored. I’ve never had this business respond to anything I’ve posted to Twitter or Facebook about them.

The person handling their social marketing has neglected the crucial element of social media: the SOCIAL aspect. I get wanting to outsource it. But a good social media practitioner absolutely HAS to keep the business owner in the loop. The key aspect of social media is that it’s a conversation with your customers, not a one way communications blast. The owners/staff should know what’s being put out there with their name on it. They should be aware of the people that are conversing with them, who they are, and ideally, when they show up at the business.

Haiti Mission Trip… From my couch!

This week, I’ve been assisting our mission team in Haiti with networking upgrades for the Guest House. I really wanted to go on this trip, but there’s way too much going on back at Resurrection. So I get to do my part through the magic of the Internet.

With the help of Liz and Bryon on the ground, as well as Thomas, our local IT guy there, we got remote management enabled on the Sonicwall, and from there I was able to reconfigure it for Dynamic DNS, WAN failover to the satellite when the WiMax link goes out.

The following day, I got word from the team that the failover works like a champ and that performance is much improved. Now we have a static IP on the WiMax link, so we can remote into the device when our teams aren’t there.

The other piece that needed to happen was to secure the wireless so that folks in the neighbourhood can’t mooch the limited bandwidth at the guest house. We tried to do WPA, but realized afterward that you can’t do WDS and WPA on a Ubiquiti radio because the MAC addresses are encrypted in WPA. Going to have to fall back to WEP. Key management isn’t nearly as easy with WEP, but it is what it is. Maybe Ubiquiti isn’t the solution here. That will be for a future team to figure out.

Blockbuster is screwed.

Digital distribution is the future of media. Physical media is dead. Yeah, I know, you’ve heard it but don’t believe it.

Today, Penny preached at Resurrection and showed a clip from The Blind Side. Andrea and I had been meaning to see the movie for a while. Since the kids actually went to bed quietly and early, we figured we’d RedBox it and have a nice movie night at home.

One problem though – when your pastor preaches to a couple thousand people and include a clip, there’s a pretty good chance that you’re going to have a hard time finding said movie anywhere near the church. As a backup plan, I fired up google and searched for a torrent version of it. Within about 30 seconds, it was downloading. I then went to Redbox.com, searched for the movie (got lucky and the local box actually had one!), reserved it online, hopped into the car, drove over to the price chopper and picked up the movie. (in retrospect, it would have been faster to take my bike, but it was warm and VERY humid) . I took less than thirty seconds at the kiosk, and drove home. As I sat down in front of my computer, the download had just completed.

Total time elapsed: 17 minutes. In that time, 700MB had downloaded, and hadn’t even uploaded a complete single block (so don’t worry, MPAA, I didn’t actually share any of it). Since I had the DVD, I watched that instead, and had to confront issues such as cleaning the last renter’s fingerprints off the disc and sitting through commercials on the DVD that I paid to rent. I’ll go on faith that the file I downloaded contained the video, and it was kinda nice having a backup plan in case the disc was unusable. Either way, the content owners did get paid.

The process of reserving and picking up a movie on redbox is insanely easy and quick. And downloading a torrent was even easier. If you’re in the business of physical entertainment media, I hope that you’re trying to figure out your exit from that strategy. Browsing and renting at Blockbuster is a painful and expensive process, and that’s why their days are numbered. Redbox has a good thing going, but looking five to ten years down the line, they should be seeing a world of digitally distributed content, not physical media. Netflix has the right idea, but their streaming catalog could use much improvement.

How can content producers leverage the ease and efficiency of peer-to-peer technologies like BitTorrent? The distributed distribution model is incredibly efficient as several companies have discovered where software distribution is concerned. They need to stop fearing peer-to-peer digital distribution and instead leverage its power.

Why Bud Selig Was Right

I don’t often blog about sports. Sports writing is not my thing. There are others way better at it than I. But I’ve had a passion for the game of baseball since I was little and my dad took me to a couple of Expos games every summer (which, looking back, prepared me quite nicely for the perpetual disappointment that comes with being a Royals fan these days)

Yesterday’s quasi-perfect game in Detroit was a heartbreaker for any fan of baseball (especially Tigers fans), and certainly for the two people most closely involved: Tigers pitcher Armando Galarraga and MLB umpire Jim Joyce. Galarraga saw his perfect game evaporate in the split second that Joyce missed the ball beating the runner to first base (which, ironically, was being manned by none other than Galarraga).

Joyce has admitted he blew it. Galarraga has clearly forgiven Joyce for denying him a spot in the baseball record books. Both have handled this with grace and absolute class that are one of the great things about baseball. These two checked their egos and remembered, even in the heat of controversy that this is ultimately just a game.

There were cries from all corners for MLB Commissioner Bud Selig to overturn the call and give Galarraga his perfect game. Today he declined to do so, much to the dismay of those fans. I think Selig did the right thing for the purity of the game. The umpires on the field are the ones making the calls, and they need to know without a doubt that the league, especially the commissioner, has their back. Overturning a call in response to public outcry is bad for the game. We can’t have umpires second-guessing themselves during the game, wondering if every call is going to get appealed up the chain.

Even worse, Selig overturning the call would have set an ugly precedent that would likely ultimately lead to video replays in baseball, and that would be a the greatest tragedy to hit baseball since the strikes and night games at Wrigley. Gone would be the drama of managers going up and arguing a bad call, only to have the umpire stand is ground and stick to his decision. There’s no second-guessing in this game. You may think the umpire’s call sucks, but human fallibility is an essential part of baseball, or any sport for that matter.Never mind that video replay would slow the already quite leisurely pace of the game to a crawl.

Ultimately, Galarraga knows he pitched a perfect game, regardless of what ends up in the history books. Joyce admitted he blew it. But then again, these two have achieved something that they otherwise wouldn’t have if it had been a perfect game just like the other twenty (two of which happened in the last month!!). These two have inadvertently (but symbiotically) achieved a great honor: They’re now going to be a part of baseball and sports trivia and will be talked about by fans for years. What more could a ball player ask for?