<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Barnabas Kendall</title>
	<atom:link href="http://bkendall.biz/feed/" rel="self" type="application/rss+xml" />
	<link>http://bkendall.biz</link>
	<description>Technology Consultant</description>
	<lastBuildDate>Tue, 15 Jun 2010 19:04:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>OpenVBX Launched</title>
		<link>http://bkendall.biz/2010/06/openvbx-launched/</link>
		<comments>http://bkendall.biz/2010/06/openvbx-launched/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 19:04:01 +0000</pubDate>
		<dc:creator>Barnabas</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[openvbx]]></category>
		<category><![CDATA[twilio]]></category>

		<guid isPermaLink="false">http://bkendall.biz/?p=254</guid>
		<description><![CDATA[I am very pleased that Twilio&#8217;s OpenVBX launched today. This is a project that I had the great pleasure of working on last year for several months with the fine folks at Twilio. When I last touched it, I thought it was 99% ready to go and felt a little frustrated that it wasn&#8217;t launched [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://bkendall.biz/wp-content/uploads/2010/06/openvbx-web-logo.png"><img class="alignleft size-full wp-image-255" title="OpenVBX Logo" src="http://bkendall.biz/wp-content/uploads/2010/06/openvbx-web-logo.png" alt="" width="209" height="54" /></a>I am very pleased that Twilio&#8217;s <a href="http://openvbx.org">OpenVBX</a> launched today. This is a project that I had the great pleasure of working on last year for several months with the fine folks at <a href="http://www.twilio.com">Twilio</a>. When I last touched it, I thought it was 99% ready to go and felt a little frustrated that it wasn&#8217;t launched sooner.</p>
<p>Now that I see what they&#8217;ve been working on in the meantime I understand. A great deal of refinement and documentation has made this product so much better than what it was. They even made <a href="http://www.youtube.com/watch?v=cBDqyvJzRYA">a very Apple-esque intro video</a> to describe what it is and why it is a win for businesses. I am installing it now on my server and will update with my impressions soon.</p>
<p>While not yet advertised anywhere, OpenVBX is based on <a href="http://www.codeigniter.com/">CodeIgniter</a>, a very popular PHP framework. Even if you are more familiar with other frameworks like CakePHP, Kohana, Silverlight, etc., you should find the code easy to understand.</p>
<p>Commenters on this news at <a href="http://news.ycombinator.com/item?id=1432937">HN</a> have been oddly upset over Twilio&#8217;s reasonable per-minute charge, which is not new. &#8220;Why pay 3¢ a minute when you can roll your own PBX with Asterisk and pay 0.0000000000000001¢ per minute with some VOIP provider?&#8221; they ask. Fair enough. But when you go eat a burger for lunch today, ask yourself why you didn&#8217;t raise and slaughter your own beef, grind the meat, and fry your own patties? Why pay a farmer, butcher, grocer, and restauranteur to do what you could have done yourself?</p>
<p>By the way, when it the last time someone has successfully used the word &#8220;restauranteur&#8221; in a sentence?</p>
]]></content:encoded>
			<wfw:commentRss>http://bkendall.biz/2010/06/openvbx-launched/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learning About HR</title>
		<link>http://bkendall.biz/2009/10/learning-about-hr/</link>
		<comments>http://bkendall.biz/2009/10/learning-about-hr/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 05:50:16 +0000</pubDate>
		<dc:creator>Barnabas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bkendall.biz/?p=243</guid>
		<description><![CDATA[Related to my last post about setting up an automated phone screening application, I thought I&#8217;d ask HR professionals on LinkedIn what they thought about they idea. As of now, here are some sample replies: &#8220;The hiring process is already de-humanized why add more humiliation/ tortire [sic] to it&#8221; &#8220;I can’t imagine interviewing my candidates [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://bkendall.biz/2009/10/phone-screen-twilio/">Related to my last post about setting up an automated phone screening application</a>, I thought I&#8217;d <a href="http://www.linkedin.com/answers/hiring-human-resources/staffing-recruiting/HRH_SFF/572889-2236419">ask HR professionals on LinkedIn what they thought about they idea</a>. As of now, here are some sample replies:</p>
<ul>
<li>&#8220;The hiring process is already de-humanized why add more humiliation/ tortire [sic] to it&#8221;</li>
<li>&#8220;I can’t imagine interviewing my candidates via an automated voice system. It’s far too impersonal and I think many of them would find it insulting.&#8221;</li>
<li>&#8220;Quite frankly, if I were to encounter an automated pre-screening system like this, I would hit the off button before the first question is finished.&#8221;</li>
<li>&#8220;I wouldn&#8217;t feel comfortable in using a system such as you suggest. [...] A voice automated system might put off too many candidates to make it worth the investment to get to the qualified candidate a little quicker.&#8221;</li>
<li>&#8220;What kind of a person who is interested in <strong><span style="text-decoration: underline;">Human</span></strong> Resources would use a machine to perform this work. This type of machine is ideal for checking on your packages and airline arrival time. People are not packages or planes.&#8221;</li>
<li>&#8220;Why on earth would you want to dehumanize an already stressed out sector of the population?! As an employer, I would never insult my potential employees by using a system as such.&#8221;</li>
<li>&#8220;As a recruiter I really strongly dislike this idea. I would never use it. And I think it adds another layer of torture for both candidates and recruiters.&#8221;</li>
</ul>
<p>There are clearly some really strong feelings of revulsion about this idea. I especially enjoy comments that allude to yet another layer of torture, which seems to acknowledge that recruiting is already torturous. Also I think there&#8217;s a lot of speculation on how much people would hate it. I would like to find some job seekers who have been out of work for a while and ask them: &#8220;would you avoid working for a company that put all applicants though an automated phone screening process?&#8221; I think that if anything, an applicant will commit to 20-30 minutes of recording answers only for a job they really want, as opposed to the minimal investment in blitzing out your digital resume to 300 openings a day.</p>
]]></content:encoded>
			<wfw:commentRss>http://bkendall.biz/2009/10/learning-about-hr/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Free Phone Screen/Interview App With Twilio</title>
		<link>http://bkendall.biz/2009/10/phone-screen-twilio/</link>
		<comments>http://bkendall.biz/2009/10/phone-screen-twilio/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 21:42:26 +0000</pubDate>
		<dc:creator>Barnabas</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[twilio]]></category>

		<guid isPermaLink="false">http://bkendall.biz/?p=241</guid>
		<description><![CDATA[I have thoroughly enjoyed working with Twilio for the last 6 months or so on an open-source project that will soon be released (can&#8217;t wait!). Now that my part in that project has wrapped up, I&#8217;ve got some extra time to play around with my own projects and look for my next job. Over on [...]]]></description>
			<content:encoded><![CDATA[<p>I have thoroughly enjoyed working with Twilio for the last 6 months or so on an open-source project that will soon be released (can&#8217;t wait!). Now that my part in that project has wrapped up, I&#8217;ve got some extra time to play around with my own projects and look for my next job. Over on the Twilio support forums, <a href="http://getsatisfaction.com/twilio/topics/using_twilio_to_automate_phone_interviews_please_help">someone recently requested help</a>, and it caught my eye:</p>
<blockquote><p>I have to conduct a lot of phone interviews every year for my company with fairly standard questions. Would there be a way to use Twilio to manage this in an automated fashion? I don&#8217;t want to spend the time actually conducting the interviews but would rather listen to them when I have a chance. [...]<br />
During the call, I would like to have the user enter the # sign or something when they have finished answering the question, to prompt the next question. This way, I could have my 10 standard questions recorded in Mp3, and then have the whole process managed through Twilio ideally where i enter the interviewee&#8217;s phone number and a time for the call ideally.</p></blockquote>
<p>Someone posted a link there that lead me to this service: <a href="http://www.voicescreener.com/">VoiceScreener</a> which starts at $169/month. Yikes! Twilio, on the other hand, is 3¢/minute and $5/month/phone number. I got to thinking: this is incredibly easy to set up with Twilio&#8217;s API; why not just whip it up? So I did.</p>
<p><a href="http://interview.bkendall.biz/">Here&#8217;s a demo</a> where you can try a sample phone interview and <a href="http://interview.bkendall.biz/PhoneInterview.zip">here&#8217;s where you can download the code</a>. To install and customize it, just follow these directions:</p>
<ol>
<li>Unzip the file to a directory on a web server that runs PHP 5</li>
<li>Edit the file inc/config.php with your own Twilio authentication credentials and the email address that will receive reports.</li>
<li>I have included my sample MP3 files in the files directory, but you should replace them with your own. The file names should be self explanatory: <a href="http://interview.bkendall.biz/files/intro.mp3">intro.mp3</a>, <a href="http://interview.bkendall.biz/files/thanks.mp3">thanks.mp3</a>, <a href="http://interview.bkendall.biz/files/conclusion.mp3">conclusion.mp3</a>, and question_XX.mp3, where XX is a two-digit number.</li>
</ol>
<p>As it is written now, this works without any database at all because we can use Twilio&#8217;s REST API to query the call details and list of associated recordings. This project is more of a starter and proof of concept, although for simple interview scenarios it would work just fine. Other possible upgrades (some requiring a database) could be:</p>
<ul>
<li>Account for unanswered questions in the report</li>
<li>Allow interviewers to hang up in the middle of the interview and call back later to pick up where they left off</li>
<li>Allow the interviewer to review their answer and re-record</li>
<li>Allow for question branching, where the user enters a touch-tone response for yes/no on some answers and is asked only relevant questions from then on</li>
<li>Set up multiple types of interviews</li>
<li>Show the text of the question in the interviewer&#8217;s web browser  while they are listening to it on the phone using AJAX</li>
<li>Make the interview conclusion a menu, as in: &#8220;To hear more about the company, press 1. To hear more about this position, press 2&#8230;&#8221;</li>
</ul>
<p>If you are interested in having me work on this for you, please <a href="mailto:barnabas@bkendall.biz">contact me</a> and I&#8217;d be happy to help you out. If you have any suggestions or improvements, please send them my way too.</p>
]]></content:encoded>
			<wfw:commentRss>http://bkendall.biz/2009/10/phone-screen-twilio/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
<enclosure url="http://interview.bkendall.biz/files/intro.mp3" length="763609" type="audio/mpeg" />
<enclosure url="http://interview.bkendall.biz/files/thanks.mp3" length="67529" type="audio/mpeg" />
<enclosure url="http://interview.bkendall.biz/files/conclusion.mp3" length="495613" type="audio/mpeg" />
		</item>
		<item>
		<title>Trying out Typekit</title>
		<link>http://bkendall.biz/2009/08/trying-out-typekit/</link>
		<comments>http://bkendall.biz/2009/08/trying-out-typekit/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 05:12:37 +0000</pubDate>
		<dc:creator>Barnabas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[fonts]]></category>
		<category><![CDATA[webdesign]]></category>

		<guid isPermaLink="false">http://bkendall.biz/?p=236</guid>
		<description><![CDATA[I got an invite code to Typekit today and I am trying out two fonts on this site. They are currently Share Regular (headings) and Droid Serif (paragraphs and lists). Interesting concept, this iTunes for fonts. I hope it takes off and there is robust competition. Until then, there are workarounds like Cufón and sIFR.]]></description>
			<content:encoded><![CDATA[<p><a href="http://bkendall.biz/wp-content/uploads/2009/08/typekit-logo.png"><img class="alignright size-full wp-image-237" title="typekit-logo" src="http://bkendall.biz/wp-content/uploads/2009/08/typekit-logo.png" alt="typekit-logo" width="158" height="41" /></a>I got an invite code to <a href="http://typekit.com">Typekit</a> today and I am trying out two fonts on this site. They are currently Share Regular (headings) and Droid Serif (paragraphs and lists). Interesting concept, this iTunes for fonts. I hope it takes off and there is robust competition. Until then, there are workarounds like <a href="http://cufon.shoqolate.com/generate/">Cufón</a> and <a href="http://wiki.novemberborn.net/sifr3/">sIFR</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bkendall.biz/2009/08/trying-out-typekit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding keyboard shortcuts with jQuery</title>
		<link>http://bkendall.biz/2009/07/jquery-shortcuts/</link>
		<comments>http://bkendall.biz/2009/07/jquery-shortcuts/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 19:38:58 +0000</pubDate>
		<dc:creator>Barnabas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bkendall.biz/?p=233</guid>
		<description><![CDATA[I was privileged to spend a yesterday at OSCON with everyone at Twilio, and I managed to catch a few talks. I heard Sigurd Magnusson (of Silverstripe fame) give the talk &#8220;10 Usability Epiphanies for your Open-Source Web App&#8221; which focused on how to improve usability. Point 10 was &#8220;Keyboard&#8221;, and one suggestion was to [...]]]></description>
			<content:encoded><![CDATA[<p>I was privileged to spend a yesterday at <a href="http://en.oreilly.com/oscon2009">OSCON</a> with everyone at <a href="http://www.twilio.com/">Twilio</a>, and I managed to catch a few talks. I heard <a title="@sigurdmagnusson on Twitter" href="http://twitter.com/sigurdmagnusson">Sigurd Magnusson</a> (of Silverstripe fame) give the talk &#8220;10 Usability Epiphanies for your Open-Source Web App&#8221; which focused on how to improve usability. Point 10 was &#8220;Keyboard&#8221;, and one suggestion was to allow enter and escape to proceed and cancel just like native dialog boxes. It just so happens that the web app I&#8217;m working on uses a non-native confirm dialog box with &#8220;yes&#8221; and &#8220;no&#8221; buttons, so on the plane home I changed the behavior to implement this small but crucial usability enhancement. You know, I like it. Small details like this will really improve the overall experience, and I thought I&#8217;d share the essentials of my now-enhanced jQuery dialog function here.</p>
<p><span id="more-233"></span></p>
<p>Here&#8217;s how it works. The script first adds some temporary HTML to the page to build the dialog box but hides it until it&#8217;s all set up. Next, we temporarily bind to the window&#8217;s keydown event (which is needed to capture escape and enter) and fire the associated button click event for key presses that we care about, including the &#8220;y&#8221; and &#8220;n&#8221;. For the button click events, we unbind the keydown event, destroy the dialog, and run the yes or no functions if they exist. As for the structure of the HTML and the CSS, I&#8217;ve only provided a bare minimum here to make it work, but the idea is that the div with the &#8220;modal&#8221; class fills the whole screen and prevents clicks and actions. In our app it has a semi-transparent PNG to grey out the rest of the screen. The Y and N of the yes and no buttons are also underlined to give the clue that they are keyboard shortcuts. I&#8217;m not sure how to hint that &#8220;enter&#8221; and &#8220;esc&#8221; also work, but I think in this case these behaviors are like good special effects in movies: they are best when they are so natural that they are unnoticed. A good enhancement would be to allow an arbitrary number of buttons besides &#8220;yes&#8221; and &#8220;no&#8221;, such as &#8220;Save&#8221; and &#8220;Cancel&#8221; and bind to the first unique character there. Also the best functions are jQuery plugins not in the global namespace, but this has been <a href="http://abeautifulsite.net/notebook/87">debated elsewhere for similar plugins</a>.</p>
<h2>JavaScript</h2>
<pre>function jConfirm(message, yesFn, noFn)
{
	var confHtml = '&lt;div class="modal"&gt;&lt;div class="confirm"&gt;&lt;div class="message"&gt;(message here)&lt;/div&gt;' +
	'&lt;button class="yes_btn"&gt;&lt;u&gt;Y&lt;/u&gt;es&lt;/button&gt;&lt;button class="no_btn"&gt;&lt;u&gt;N&lt;/u&gt;o&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;';
	var dialog = $(confHtml).appendTo('body').hide();

	// keyboard shortcuts
	$(document).bind('keydown', function(evt) {
		switch(evt.which) {
			case 27:	// escape
			case 78:	// letter 'n'
				$('div.confirm button.no_btn').click();
				break;
			case 13:	// enter
			case 89:	// letter 'y'
				$('div.confirm button.yes_btn').click();
				break;
		}
	});

	$('div.message', dialog).html(message);
	$('button', dialog).click(function(event){
		$(document).unbind('keydown');
		dialog.fadeOut(function() { dialog.remove(); });

		if($(this).hasClass('yes_btn')) {
			if(typeof yesFn == 'function') return yesFn(event);
		} else {
			if(typeof noFn == 'function') return noFn(event);
		}
	});
	dialog.fadeIn();
}</pre>
<h2>CSS</h2>
<pre>div.modal {
	position:absolute;
	left:0;
	top:0;
	width:100%;
	height:100%;
	z-index:100;
}

div.confirm {
	background-color:#fff;
	border: 2px solid #666;
	margin:auto;
	padding: 10px;
	position:relative;
	top: 200px;
	width: 300px;
}

div.message {
	color: #000;
	padding:10px 0px;
	text-align:left;
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://bkendall.biz/2009/07/jquery-shortcuts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uptime Metrics</title>
		<link>http://bkendall.biz/2009/05/uptime-metrics/</link>
		<comments>http://bkendall.biz/2009/05/uptime-metrics/#comments</comments>
		<pubDate>Fri, 15 May 2009 16:52:04 +0000</pubDate>
		<dc:creator>Barnabas</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://bkendall.biz/?p=218</guid>
		<description><![CDATA[I read a post at Royal Pingdom the other day (via RWW) regarding Feedburner&#8217;s uptime, and it got me thinking about uptime in general: I feel total percentage of uptime is a misleading metric. For an analogy, if a broadcast meteorologist says there&#8217;s a 50% chance of rain in the next 24 hours, it should mean that [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://bkendall.biz/wp-content/uploads/2009/05/pingdom.png"><img class="alignright size-full wp-image-228" title="pingdom" src="http://bkendall.biz/wp-content/uploads/2009/05/pingdom.png" alt="pingdom" width="150" height="70" /></a>I read <a href="http://royal.pingdom.com/2009/05/12/how-fast-and-reliable-is-your-feedburner-rss-feed/">a post at Royal Pingdom</a> the other day (<a href="http://www.readwriteweb.com/archives/report_feedburner_uptime_may.php">via RWW</a>) regarding Feedburner&#8217;s uptime, and it got me thinking about uptime in general: I feel total percentage of uptime is a misleading metric. For an analogy, if a broadcast meteorologist says there&#8217;s a 50% chance of rain in the next 24 hours, it should mean that there&#8217;s a 1 in 2 chance that rain will fall on me, which is probably how every listener interprets that information. I doubt very much (though I may be wrong) that they take in to account where in their broadcast area the rain will fall and adjust the probability for how many of their listeners will actually be rained upon. I live not far from the Pacific Ocean, and I&#8217;m sure lots of the forecasted rain falls out there on very few people. Although the level of meteorology expertise I expect only exists in Back To The Future Part 2, I think that personalized forecasts are nonetheless a realistic goal.</p>
<p>When it comes to Internet meteorology, which is what Pingdom does, a number like 99.94% uptime is missing critical information. I believe that 0.06% of the time that Pingdom tested Feedburner they got an error, but what does that mean to me? Did everyone who uses Feedburner have similar success, or were there 5,000 people who saw Feedburner down more like 2% of the time? Also, serving up RSS is more like serving up mail than serving up web pages; errors are more hidden and should have graceful recovery. RSS being down is quite different than broken images on an otherwise working site or full outage; it&#8217;s not a binary state in my opinion. Many sites have visitors that only stop by for a few minutes each day &#8212; downtime is less critical in that case. Furthermore, downtime is not necessarily systemic; two hours of downtime may be catastrophic, but if it only happens once every 5 years, then it&#8217;s hardly a trend.</p>
<p>I&#8217;m not sure there&#8217;s a metric that can easily describe the nuances of uptime better than the percentage, but I hope there is one. Here are some ideas. Bear in mind that these stats should be based on data such as the geographic distribution of the site&#8217;s audience and the average session length. In short, I suggest coloring Pingdom&#8217;s downtime stats with Compete.com&#8217;s traffic data to get a better picture of outages and spot trends.</p>
<ul>
<li><strong>Total User Downtime:</strong> the number of hours of server downtime in a specific time period times the number of users affected. Short downtime that affects everyone would be balanced with long downtime on a subset of users.</li>
<li><strong>Daily Audience Percentage Affected:</strong> percentage of users affected at the time an incident. If there&#8217;s a rolling incident that only affects 5% of all users at a time, but gets everyone at some point in the day (as upgrades sometimes do) then the percentage of affected users would be high even though the incident would appear to be 5% downtime from a single user&#8217;s standpoint. On the other hand, 50% outage when 90% of the users are not using the site shows good planning.</li>
<li><strong>Last X Days Peak [TUD/DAPA]:</strong> given one of the above metrics, report the worst (peak) value in the last X number of days. This would mean that it takes a while for incidents to decay, which would be useful for people shopping for reliable hosting.</li>
</ul>
<p>I am not an expert on these things, just a concerned web software developer who wants better data. If better thinking on uptime metrics has been done elsewhere by smarter people, please let me know with a link in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://bkendall.biz/2009/05/uptime-metrics/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Recording Web Audio</title>
		<link>http://bkendall.biz/2009/05/recording-web-audio/</link>
		<comments>http://bkendall.biz/2009/05/recording-web-audio/#comments</comments>
		<pubDate>Fri, 15 May 2009 00:01:01 +0000</pubDate>
		<dc:creator>Barnabas</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://bkendall.biz/?p=220</guid>
		<description><![CDATA[Update 11/05/09: Looks like this might be possible in Flash 10.1! (via) I&#8217;ve been working on a project recently that would really benefit from the ability to record audio in the browser and upload it to a web server. This would be a better experience than an &#8220;upload your sound file&#8221; dialog, where the user [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update 11/05/09:</strong> <a href="http://www.adobe.com/devnet/logged_in/jchurch_flashplayer10.1.html">Looks like this might be possible in Flash 10.1</a>! (<a href="http://www.getmicrophone.com/?p=85">via</a>)</p>
<p>I&#8217;ve been working on a project recently that would really benefit from the ability to record audio in the browser and upload it to a web server. This would be a better experience than an &#8220;upload your sound file&#8221; dialog, where the user would have to record themselves in another app, find the file, and upload it. Here&#8217;s how I imagine a seamless audio capture experience would work inside a web application. There would be a small widget in the page that would look like this (<a href="http://www.famfamfam.com/lab/icons/silk/">icons from FamFamFam.com</a>):</p>
<p><a href="http://bkendall.biz/wp-content/uploads/2009/05/record_1.png"><img class="alignleft size-full wp-image-221" title="Recorder state 1" src="http://bkendall.biz/wp-content/uploads/2009/05/record_1.png" alt="Recorder state 1" width="98" height="18" /></a> When the widget first shows, only the record button would be enabled. The left side has a line-level indicator that reflects the sound level at all times.</p>
<p><a href="http://bkendall.biz/wp-content/uploads/2009/05/record_2.png"><img class="alignleft size-full wp-image-222" title="Recorder state 2" src="http://bkendall.biz/wp-content/uploads/2009/05/record_2.png" alt="Recorder state 2" width="98" height="18" /></a> While recording, the recording button changes to a stop button.</p>
<p><a href="http://bkendall.biz/wp-content/uploads/2009/05/record_3.png"><img class="alignleft size-full wp-image-223" title="Recorder state 3" src="http://bkendall.biz/wp-content/uploads/2009/05/record_3.png" alt="Recorder state 3" width="98" height="18" /></a> Once the recording is stopped, the stop button changes back to a record button. The play and upload buttons are enabled. Clicking upload at this point saves the file to the server, and the whole control would change to an upload progress bar. Clicking record here starts a new recording and erases the old one.</p>
<p><a href="http://bkendall.biz/wp-content/uploads/2009/05/record_4.png"><img class="alignleft size-full wp-image-224" title="Recorder state 4" src="http://bkendall.biz/wp-content/uploads/2009/05/record_4.png" alt="Recorder state 4" width="98" height="18" /></a> During playback, the record button toggles to a stop button again and the play button toggles to a pause button. The line level reflects the playback volume. It is possible that you don&#8217;t want to allow upload during playback, but I&#8217;m not sure.</p>
<p>I want the control to be slightly customizable for the web developer who&#8217;s embedding it. He/she should be able to specify a maximum recording length and a URL where the sound file will be uploaded, or perhaps disable playback and upload immediately, that sort of thing. Maybe the control itself is actually a 1&#215;1 SWF that has methods and events for play, stop, record, and so on, and the controls would be standard HTML wired up with JavaScript.</p>
<p>I assumed that other, smarter people have already tackled this problem and there is some Flash control I could embed in my page and a little PHP script or something to handle saving the file from a POST. If you&#8217;ve ever searched for this sort of thing before, you already know that it does not yet exist, at least not like I have described it.  Microsoft Silverlight doesn&#8217;t yet have microphone access, and I <del datetime="2009-05-14T21:42:58+00:00">can&#8217;t find a Java applet that does this thing either</del>. (<a href="http://www.javasonics.com/">I found this one</a>, hmmm. Wish it was free/Flash). There are several very nice Flash playback scripts (<a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager 2</a>, <a href="http://developer.yahoo.com/mediaplayer/">Yahoo Media Player</a>, <a href="http://www.longtailvideo.com/players/jw-flv-player/">JW FLV Media Player</a>, <a href="http://www.happyworm.com/jquery/jplayer">JPlayer</a>, <a href="http://www.varal.org/media/niftyplayer/">NiftyPlayer</a>, <a href="http://wpaudioplayer.com/">WordPress Audio Player</a>, etc. etc. etc.), but nothing that handles creating uploading and saving recordings. <strong>Yet</strong>.</p>
<p>Flash allows for audio streaming from the client microphone, but in order to capture the stream you need a server that understands Adobe&#8217;s streaming format called <a href="http://en.wikipedia.org/wiki/Real_Time_Messaging_Protocol">RTMP</a> and can do something with it, most likely some kind of crazy-expensive <a href="http://www.adobe.com/products/flashmediaserver/">Flash Media Server</a> or the open source <a href="http://osflash.org/red5/">Red 5 server</a>. Neither solution is exactly straightforward or doable on a simple web host; it&#8217;s huge overkill for this one thing. If your project is meant to be downloaded and run on other servers (like WordPress and my new project) this kind of requirement is deal breaker. Besides, it doesn&#8217;t really allow you to preview the recording before it&#8217;s uploaded. Frustration with Adobe&#8217;s &#8220;closed&#8221; microphone interface has caused some Flash developers to start the <a href="http://www.getmicrophone.com/">Open Mic initiative at GetMicrophone.com.</a> I wish them luck with their effort.</p>
<p>I recently asked my friend <a href="http://www.joeybetz.com/">Joey Betz</a> (a very talented Flash programmer who works for <a href="http://armorgames.com/">Armor Games</a>) if what I describe above is possible. He said that up until Flash 9 it is impossible, but he could imagine that with new access to microphone sound data in Flash 10, it may be possible to get the byte stream of the sound and base-64 encode and post it to a web script. I guess nobody has the combined need, interest and Flash/PHP chops to make it happen &#8211; I have all but the Flash bit. I&#8217;m not sure anyone knows the actual format of the byte stream: is it just raw sound like a WAV or what? Can you turn around and replay that byte stream through Flash? How do you turn it into an MP3/OGG stream? Even if the byte stream is something odd or uncompressed, perhaps the PHP script could do the heavy lifting to re-encode it; many servers also have FFMPEG or Mencode or something like them installed. Alternatively, what about a web service with an API where I can stream data to a Flash Media Server or something like it and get back a URL to the resulting MP3? I just don&#8217;t think recording a few seconds of sound and saving it to a file requires a separate server daemon and all that entails. Real-time voice/video chat &#8212; sure, but that&#8217;s not what I&#8217;m after.</p>
<p>Unless someone can convince me that this is still not possible, I will be happy to offer some of my time and server bandwidth, hosted now at MediaTemple, to help a creative Flash programmer get the server-side bit of this working. I&#8217;d like to release this widget/script as open source to the web community. I am looking especially to the creators of any of the aforementioned Flash playback scripts. Can you help make this happen?</p>
]]></content:encoded>
			<wfw:commentRss>http://bkendall.biz/2009/05/recording-web-audio/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP TwiML Library for Twilio</title>
		<link>http://bkendall.biz/2009/05/php-twiml-lib/</link>
		<comments>http://bkendall.biz/2009/05/php-twiml-lib/#comments</comments>
		<pubDate>Mon, 04 May 2009 19:49:55 +0000</pubDate>
		<dc:creator>Barnabas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bkendall.biz/?p=215</guid>
		<description><![CDATA[I have been working on a fun new Twilio project, and part of it involves generating TwiML markup, a specialized XML syntax. I have done this before by hooking into a Kohana controller, which worked for my other project well enough. There are other Twilio response libraries that range from quite thorough to downright minimalist. [...]]]></description>
			<content:encoded><![CDATA[<p>I have been working on a fun new <a href="http://www.twilio.com/">Twilio</a> project, and part of it involves generating <a href="http://www.twilio.com/docs/api_reference/TwiML/">TwiML markup</a>, a specialized XML syntax. I have done this before by hooking into a Kohana controller, which worked for <a href="http://thislineissecure.com/">my other project</a> well enough. There are other Twilio response libraries that range from <a href="http://code.google.com/p/twilio-php-client/">quite thorough</a> to <a href="http://github.com/Derferman/twilio-libresponse/tree/master">downright minimalist</a>.</p>
<p>I&#8217;m attaching my current version of a Twilio response library for PHP. It&#8217;s a single file and it will do syntax checking when it&#8217;s done. This is the best of both worlds, in my opinion.</p>
<p><a href="http://bkendall.biz/wp-content/uploads/2009/05/twimlphp.zip">TwiML PHP Library</a></p>
]]></content:encoded>
			<wfw:commentRss>http://bkendall.biz/2009/05/php-twiml-lib/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open Geographic Tagging</title>
		<link>http://bkendall.biz/2009/04/geohash/</link>
		<comments>http://bkendall.biz/2009/04/geohash/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 08:41:29 +0000</pubDate>
		<dc:creator>Barnabas</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://bkendall.biz/?p=205</guid>
		<description><![CDATA[I had an idea for making open geographic tags over the weekend so I hacked out a quick proof of concept in JavaScript. If you hate reading, you can skip to my demo here and play with it now. You may have read the recent noise about URL shortening services being &#8220;the herpes of the [...]]]></description>
			<content:encoded><![CDATA[<p>I had an idea for making open geographic tags over the weekend so I hacked out a quick proof of concept in JavaScript. If you hate reading, <a href="/GeoHash.html">you can skip to my demo here and play with it now</a>.</p>
<p>You may have read the recent noise about URL shortening services being &#8220;<a href="http://www.inquisitr.com/22264/url-shorteners-the-herpes-of-the-web/">the herpes of the web</a>&#8220;. <em>Please.</em> I think this comes down to tagging being a closed system, but <a href="http://bkendall.biz/2009/04/open-url/">it&#8217;s not easy to fix</a> and I doubt these kinds of things will ever go away.</p>
<p>It got me thinking, though: links to geographic information could benefit from shortening, and selectively loosing information could even be an advantage. Latitude and longitude is expressed as a pair of numbers, traditionally divided up by degrees, minutes, and seconds, but digitally expressed as floating numbers between -90/90 and -180/180 respectively. For example, a beach near my home is at 33.54240,-117.78559. For example, say I wanted to tell my friends that I&#8217;m at the beach, and my Twitter client could access my GPS and append my location to the message (yes I know about <a href="http://tapulous.com/twinkle/">Twinkle</a>). That&#8217;s 19 characters out of 140 and it&#8217;s very public. Also it&#8217;s a single point, not a whole area, and how do I search for other people near me?</p>
<p>My idea is to create a new kind of geographic code that specifies areas, not points, and is constructed in a text-search friendly way. Here&#8217;s how it works. First divide the world into a grid of 36 x 36, or 1,296 squares. Assign each row a number or letter using 0-9 and A-Z, that&#8217;s why 36. If we specify one of these grids by coordinates, such as &#8220;o6&#8243; for example, that would specify a rather large part of the earth, as you can see below. If we were then to reference a point using a further 36 x 36 subdivision of this grid, we could specify an area even further, such as &#8220;o6p7&#8243;, which would be smaller still, and so on and so forth, all the way down to &#8220;o6p7iy6z&#8221;, the  rough equivalent of the 19-character coordinates above in only 8 characters.</p>

<a href='http://bkendall.biz/2009/04/geohash/geohash-o6/' title='geohash-o6'><img width="150" height="150" src="http://bkendall.biz/wp-content/uploads/2009/04/geohash-o6-150x150.jpg" class="attachment-thumbnail" alt="geohash-o6" title="geohash-o6" /></a>
<a href='http://bkendall.biz/2009/04/geohash/geohash-o6p7/' title='geohash-o6p7'><img width="150" height="150" src="http://bkendall.biz/wp-content/uploads/2009/04/geohash-o6p7-150x150.jpg" class="attachment-thumbnail" alt="geohash-o6p7" title="geohash-o6p7" /></a>
<a href='http://bkendall.biz/2009/04/geohash/geohash-o6p7iy/' title='geohash-o6p7iy'><img width="150" height="150" src="http://bkendall.biz/wp-content/uploads/2009/04/geohash-o6p7iy-150x150.jpg" class="attachment-thumbnail" alt="geohash-o6p7iy" title="geohash-o6p7iy" /></a>
<a href='http://bkendall.biz/2009/04/geohash/geohash-o6p7iy6z/' title='geohash-o6p7iy6z'><img width="150" height="150" src="http://bkendall.biz/wp-content/uploads/2009/04/geohash-o6p7iy6z-150x150.jpg" class="attachment-thumbnail" alt="geohash-o6p7iy6z" title="geohash-o6p7iy6z" /></a>

<p>The more specific you want to be about your location, the more subdivisions your code would include, although using base 36, four levels is about the size of a house, three levels is a few blocks, two levels is about an hour&#8217;s drive, and one level is a day&#8217;s drive. That sizing feels right to me, but perhaps if this ever gets used people will standardize on different subdivisions, such as base 16 or base 24. Anyway, if you&#8217;re sharing your location but want to protect your privacy, leaving your location general and loosing a little specificity is a good thing. The subdivisions function like decimal places in that case. &#8220;o6&#8243; means somewhere in SoCal, while &#8220;o6p7iy6z&#8221; means a certain spot by the volleyball nets on Main Beach in Laguna Beach, California.</p>
<p>When looking for proximity, you can see at a glance if a code is near you. In my case, I wouldn&#8217;t bother with things that don&#8217;t start with &#8220;o6p7&#8243;, although I might look at &#8220;06p8&#8243; or &#8220;o6q7&#8243;, which are adjacent. A text search engine could find nearby items tags a wildcard search pattern (&#8220;06p7*&#8221;).</p>
<p>One other major benefit of a protocol like this is that it would be open. It&#8217;s not perfect; you may live close to the boundary of a big grid, and there&#8217;s an up-front hassle in figuring out exactly what grid you&#8217;re presently in unless your device can calculate your geo tag for you. Once in place, no single company would be the gatekeeper for the information that makes the tags meaningful, as in the case of URL shorteners. A unified location tag protocol could open up many interesting mashups between location aware devices and services, not just Twitter et al.</p>
<p>If someone&#8217;s already done something like this, then I wasn&#8217;t able to find it and I apologize, please let me know. If you want to fix it up and build upon this idea, by all means go for it but please link back here. Please <a href="/GeoHash.html">view the source of the HTML demo file</a> for implementation details and send any errors or suggestions. I think it&#8217;s not a perfect square because of the distortion from the map projection, but I could have flubbed something too.</p>
]]></content:encoded>
			<wfw:commentRss>http://bkendall.biz/2009/04/geohash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open &amp; Distributed URL Shortening</title>
		<link>http://bkendall.biz/2009/04/open-url/</link>
		<comments>http://bkendall.biz/2009/04/open-url/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 23:18:33 +0000</pubDate>
		<dc:creator>Barnabas</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[services]]></category>

		<guid isPermaLink="false">http://bkendall.biz/?p=202</guid>
		<description><![CDATA[Update 8/20: tr.im has since threatened to shut down (then not), and bit.ly has proposed the FDIC of shortners. I look back on my post below and concede that the hashing thing will never happen, but the central backup surely should occur, and 301works.org is the best chance it will come about. Any service that [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update 8/20:</strong> tr.im has since <a href="http://blog.tr.im/post/159369789/tr-im-r-i-p">threatened to shut down</a> (then <a href="http://blog.tr.im/post/160697842/tr-im-resurrected">not</a>), and <a href="http://blog.bit.ly/post/159843105/301working">bit.ly has proposed</a> the <a href="http://301works.org/">FDIC of shortners</a>. I look back on my post below and concede that the hashing thing will never happen, but the central backup surely should occur, and 301works.org is the best chance it will come about. <em>Any service that claims protecting your &#8220;privacy&#8221; prevents them from backing up their link archive with a 3rd party is lying or misunderstands the purpose of a central repository and shouldn&#8217;t be trusted with your links anyway.</em></p>
<p>The latest <a href="http://www.techcrunch.com/2009/04/06/are-url-shorteners-a-necessary-evil-or-just-evil/">brouhaha over URL shorteners</a> is <a href="http://joshua.schachter.org/2009/04/on-url-shorteners.html">overblown</a>. Are they evil or unnecessary? Who cares? They&#8217;re not going away. Proclaiming the death of &#8220;unnecessary&#8221; institutions is a tired cliché. I&#8217;m all for self-documenting pretty URLs like the next guy, but come on.</p>
<p>I feel that the core argument boils down to discomfort with the opaqueness of the the whole thing. Where does a shortened link go? You don&#8217;t know until you&#8217;re there. What kind of permanence does the shortening service itself have? This kind of worry is an echo of the greater distrustful zeitgeist though &#8211; if AIG and GM can teeter on the edge, what hope can we have for TinyURL? That&#8217;s probably how Philistine foot soldiers felt when Goliath fell.</p>
<p>It appears that many shorteners use an auto-incrementing database key to store link references. Thus the first link is http://example.com/1, and the second is http://example.com/2, and by using all letters of the alphabet (using base 36) then link number 999,999,999 will only be http://example.com/GJDGXR, six extra characters. Since they&#8217;re not all using the same database, then the true link for http://shortenerA.com/GJDGXR does not relate to http://shortenerB.com/GJDGXR. If Shortner A looses their database (<a href="http://ma.gnolia.com/">it happens</a>) then goodbye all links. Thus, shortening services are opaque and creaky by design, namely big-honkin&#8217; private central database.</p>
<p>If the digerati can&#8217;t abide secrets, then they should gather up their pitchforks and demand that their favorite shortening and bookmarking services transition away from private, proprietary incrementing keys to an open URL shortening hashing scheme and distributed URL repository for backup. How would this work? Well, <a href="http://news.netcraft.com/archives/2009/03/15/march_2009_web_server_survey.html">Netcraft reported that there were 224,749,695 servers on the Internet in March 2009</a>. Let&#8217;s just round that up to 250 million and say that each site has an average of 200 URLs, which is 50 billion, or MYWPIWW &#8212; just seven characters &#8212; in base-36. You could normalize and hash any URL through a 40-bit hashing function and format that number to a base-36 string. All participating open shortening services would have to use the same hashing method and synchronize their URLs with a central repository. By using a hash function, each service could defer repository synchronization and use it as an insurance policy. The central repository would be queried only when a hash doesn&#8217;t exist locally such as when a competing service goes dark or offline. Storage of 5 billion URL records in the repository (assuming each record is 1kb) would require 4.65 TB of storage, not quite doable with Amazon SimpleDB just yet. Nevertheless, I can easily imagine two guys hacking up a robust shortened URL repository at this scale over a weekend using tools like Amazon&#8217;s EC2, SDB, and <a href="http://aws.amazon.com/sqs/">SQS</a> and charging per-use fees to the services for a syncing API. The repository has the added benefit of being a neutral third party that can validate and lengthen links for security.</p>
<p>I have no illusions that this system will ever actually be built, or if it is, that it will be used widely. You&#8217;re welcome anyway.</p>
]]></content:encoded>
			<wfw:commentRss>http://bkendall.biz/2009/04/open-url/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 1.259 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2010-09-03 17:52:23 -->
<!-- Compression = gzip -->