Switching Live Streams

Continuing on the rack theme mentioned yesterday, I got to wondering about a stream monitor that could be switched to any of a number of live streams, without reloading the page. Fortunately, JW Player makes this easy. I threw together a player embedded inside some CSS and then added a button panel. Each button is a DIV with an onclick() action that calls jwplayer().load(). While it’s well known that you can use this to switch files simply by passing the filename to the file flashvar, we need to also pass the streamer¬†value. Fortunately, the load() method has the ability to pass on not only files as a string value, but also objects, which are nothing more than an array of flashvars (it can also take playlist items, but that’s beyond the scope of this post). So, all you need to do in order to switch streams with JW Player is call the following JavaScript method:

jwplayer().load({file: 'streamname', streamer: 'rtmp://w.streampunk.tv/live'})

The result I got was this:Clicking on each of the buttons in the bar below the screen will switch the stream. A live example can be found here. If you want to see what else the JWPlayer API can do, head on over to the API docs. FlowPlayer appears to have something similar in the clip.update() method (flowplayer API documentation), but I haven’t tested it.

Page code:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>

	<title>JW Player Switching</title>

	<style type="text/css">
		body { background-color: #fff; padding: 0 20px; color:#000; font: 13px/18px Arial, sans-serif; }
		a { color: #360; }
		h3 { padding-top: 20px; }
		ol { margin:5px 0 15px 16px; padding:0; list-style-type:square; }
	</style>

</head>
<body>
	<!-- START OF THE PLAYER EMBEDDING TO COPY-PASTE -->
	<div class="rack" style="width: 600px;">
	<div class="rackmonitor" style="width: 600px; height: 323px; background-image: url('rackmonitor.png'); position: relative">
	&nbsp;
	<div class="screen" style="width: 455px; height: 275px; position: absolute; left: 60px; top: 28px;">
	<div id="mediaplayer">Player...</div>
	<script type="text/javascript" src="/jwplayer/jwplayer.js"></script>
	<script type="text/javascript">
		jwplayer("mediaplayer").setup({
			flashplayer: "/jwplayer/player.swf",
			height: "275",
			width: "455",
			file: "commons.stream",
			streamer: "rtmp://w.streampunk.tv/live",
			autostart: true,
			controlbar: 'none',
			mute: true
		});
	</script>
	</div>
	</div>
	</div>
	<div class="panel" 
	style="width: 600px; 
	height: 57px; 
	background-image: url('blankPanel.png'); 
	position: relative
	">	
		<div class="button1" 
		style="width: 75px; 
		height: 20px; 
		position: absolute; 
		left: 50px; 
		top: 20px; 
		border-radius: 10px; 
		background-color: #009900; 
		color: #cccccc; 
		border: 1px solid black; 
		text-align: center;" 
		onclick="jwplayer().load({file: 'playlist-high', streamer: 'rtmp://wms.rezonline.org/redirect'})
		">
		RezOnline
		</div>
		<div class="button2" 
		style="width: 75px; 
		height: 20px; 
		position: absolute; 
		left: 150px; 
		top: 20px; border-radius: 10px; 
		background-color: #009900;
		color: #cccccc; 
		border: 1px solid black;text-align: center;" 
		onclick="jwplayer().load({file: 'commons.stream', streamer: 'rtmp://w.streampunk.tv/live'})
		">
		Commons
		</div>
		<div class="button3" 
		style="width: 75px; 
		height: 20px; 
		position: absolute; 
		left: 250px; 
		top: 20px; border-radius: 10px; 
		background-color: #990000;
		color: #cccccc; 
		border: 1px solid black;text-align: center;" 
		onclick="jwplayer().load({file: 'streamclass', streamer: 'rtmp://w.streampunk.tv/live'})
		">
		StreamClass
		</div>
		<div class="button4" 
		style="width: 75px; 
		height: 20px; 
		position: absolute; 
		left: 350px; 
		top: 20px; border-radius: 10px; 
		background-color: #990000;
		color: #cccccc; 
		border: 1px solid black;text-align: center;" 
		onclick="jwplayer().load({file: 'aircam.stream', streamer: 'rtmp://w.streampunk.tv/live'})
		">
		AirCam
		</div>
	</div>
</body>
</html>

Stupid CSS Tricks: Wowza Load Graphs

I’ve been experimenting with ways to generate load graphs for Wowza. The best way for doing bar graphs on a webpage is to go all crazy with CSS. It’s really well suited to doing this. Here’s a PHP script that will query a Wowza origin server for its repeaters, and then polls the repeaters for their load stats. This also provides buttons for launching/terminating repeaters, and visually representing them as a rack full of servers:

Read more

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.

Browser-Aware Player

One of the big challenges of streaming to the web is the sheer diversity of devices out there.

This past week, I pushed out some modifications to the player code on our live page that switches the player code based on what the user is connecting with. The genesis of this change was a problem with our change to JW Player Version 5 causing our PlayStation users to no longer be able to watch our video since JW v5 requires Flash 10 and Sony apparently doesn’t care about its customers. After a successful test with the Playstation, I extended the code to provide an HTML5 <VIDEO> tag for our iPhone users (allowing us to clear up some the clutter on the sidebar), as well as MMS and RTSP links around a graphic mimicking the Flash-based player in order to provide a consistent user experience for our Android/WebOS/BlackBerry/WinMo users.

EDIT: The main reason I’m not doing straight HTML5 with Flash fallback (a much more elegant solution) is that we’re sending out VP6 for our flash users and a lower-bandwidth h.264 stream for our mobile users. We’re not currently using h.264 for our flash users because of the poor quality of the h.264 encoder in Flash Media Live Encoder. Once we get a “real encoder“, we’ll send out a single set of h.264 streams and use HTML5 with fallback.

The code is here.

Live geoanalytics – need help!

I’m looking to put together a live map for seeing where people are coming from on our live stream. One format of this map would be a full-screen display at the ops console, the other would be a small map on the website itself. If you’re using this kind of technology, Id love to know how you are doing it, whether it’s with a monthly service, or you rolled your own code.What I’ve looked at so far:

Google Analytics: Doesn’t come anywhere close to realtime. Looks like about a 24-hour waiting period for your data. Looking at the historical data for the live site, it doesn’t seem to be all that accurate either. Numbers, locations, and durations of visits seem to be way off what we’re seeing in our feedback and in our logs.

W3Counter: Seems interesting, but their site performance/availability is a major problem. I smell scalability issues.

VisiStat: Very nice product, but a little spendy for what I’m after, considering its shortcomings. Live map doesn’t appear to have the ability to specify a timeframe. Either you refresh the page and it adds new visits to a blank map, or you leave it up and nothing falls off the back.

Feedjit: I use this for my blog, and it’s great for that (see widget in the sidebar). But I can’t see using this for a “real” site. I greatly dislike the inability to customize the widget beyond text color (I really don’t want it showing the geoblogosphere link, it’s completely irrelevant and a distraction). It too seems to lack the ability to restrict the map by timeframe.

None of these products appeared to have the ability to customize the map display, most of them had a map that was ridiculously small and didn’t scale with the browser window.

If you rolled your own, how complex was it? What was the cost for the geolocation data?

EDIT: Forgot about Woopra… Looks awesome, but it’s still vaporware.

EDIT^2: OK, so Woopra isn’t technically vaporware, apparently real people are using it, but it’s been in “beta” for a very long time.

Bible goes Web 2.0

Here’s a neat new idea from Terry Storch and the folks at LifeChurch… It’s called “YouVersion” and launches this week. The Bible has just gone Web 2.0! I can see some really cool potential if I can use this from my smartphone and add notes and commentary during sermons, and if preachers can feed XML with tags and scripture references. Hello, mashups!

TOTH: Jim Walton @ Church Tech Matters