<?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>chemicaloliver</title>
	<atom:link href="http://chemicaloliver.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://chemicaloliver.net</link>
	<description>experimentation, criticism and geekiness</description>
	<lastBuildDate>Fri, 03 Feb 2012 18:21:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Streaming audio from Ubuntu Linux to a DLNA player (Blu Ray or PS3) using Rygel</title>
		<link>http://chemicaloliver.net/linux/streaming-audio-from-ubuntu-linux-to-a-dlna-player-blu-ray-or-ps3/</link>
		<comments>http://chemicaloliver.net/linux/streaming-audio-from-ubuntu-linux-to-a-dlna-player-blu-ray-or-ps3/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 20:15:43 +0000</pubDate>
		<dc:creator>chemicaloliver</dc:creator>
				<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1277</guid>
		<description><![CDATA[This project started out of researching how to play sound from spotify or rhythmbox from my laptop running ubuntu 11.10 through my hifi. Initially I set out to see if an airport express would work using raop and pulseaudio but it seems that support for the new 802.11 version is flakey so I didn&#8217;t wish to invest £80 [...]]]></description>
			<content:encoded><![CDATA[<p>This project started out of researching how to play sound from spotify or rhythmbox from my laptop running ubuntu 11.10 through my hifi. Initially I set out to see if an airport express would work using raop and pulseaudio but it seems that support for the new 802.11 version is flakey so I didn&#8217;t wish to invest £80 in a device that might not work. During my research I found that DLNA supported streaming, DLNA is a protocol commonly used for sharing media files with devices such as networked dvd players, internet tvs and consoles like the ps3 so I explored further.</p>
<p>DLNA is supported in Ubuntu (and other modern linux distros) by <a href="http://live.gnome.org/Rygel">Rygel</a>, part of the Gnome project. Rygel provides a DLNA server which also has the capability to capture a pulseaudio sink (an input or output stream) and stream it to a DLNA enabled device.</p>
<p>Below are the steps I took to enable me to stream audio from my computer to my Sony BDP-S370, they should be applicable to any similar device:<br />
<span id="more-1277"></span></p>
<ol>
<li>Install required packages:
<pre class="brush: bash; title: ; notranslate">sudo apt-get install rygel rygel-gst-launch wavpack</pre>
</li>
<li>Find the name of the pulseaudio sink which you wish to capture:<br />
To list the choices, use:
<pre class="brush: bash; title: ; notranslate">pacmd list-sinks</pre>
<p>Then make a note of the name attribute (minus surrounding brackets), in my case it was:</p>
<pre class="brush: bash; title: ; notranslate">alsa_output.usb-C-Media_INC._USB_Sound_Device-00-Device.analog-stereo</pre>
<p>I found that adding .monitor to this was required for the next stage, this can be achieved in one command:</p>
<pre class="brush: bash; title: ; notranslate">pactl list | egrep -A2 '^(\*\*\* )?Source #' | grep 'Name: .*\.monitor$' | awk '{print $NF}' | tail -n1</pre>
</li>
<li>Edit /etc/rygel.conf:<br />
Replace (or comment out)</p>
<pre class="brush: bash; title: ; notranslate">
[GstLaunch]
enabled=true
launch-items=audiotestsrc;videotestsrc;videotestoverlay
audiotestsrc-title=Audiotestsrc
audiotestsrc-mime=audio/x-wav
audiotestsrc-launch=audiotestsrc ! wavenc
videotestsrc-title=Videotestsrc
videotestsrc-mime=video/mpeg
videotestsrc-launch=videotestsrc ! ffenc_mpeg2video ! mpegtsmux
videotestoverlay-title=Videotestsrc with timeoverlay 2
videotestoverlay-mime=video/mpeg
videotestoverlay-launch=videotestsrc ! timeoverlay ! ffenc_mpeg2video ! mpegtsmux
</pre>
<p>with</p>
<pre class="brush: bash; title: ; notranslate">[GstLaunch]
enabled=true
launch-items=mypulseaudiosink
mypulseaudiosink-title=Audio on @HOSTNAME@
mypulseaudiosink-mime=audio/x-wav
mypulseaudiosink-launch=pulsesrc device=alsa_output.usb-C-Media_INC._USB_Sound_Device-00-Device.analog-stereo.monitor ! wavpackenc
</pre>
<p>replacing the device on the last line with the output from the previous stage.</li>
<li>Start Rygel (type rygel in the terminal)</li>
<li>Connect your player to the DLNA device which should have appeared (probably as GstLaunch) and you should hear any audio played on your computer through your DLNA device.</li>
<li>If you wish (I don&#8217;t) add rygel to run at startup.</li>
</ol>
<div><em>This worked perfectly for my desktop but for my laptop I had to fiddle with which hardware output of the soundcard was being used under the standard gnome sound settings, changing the profile for the selected device to an option with no output (ie input only or disabled).</em></div>
<h2>Alternatives</h2>
<ul>
<li>If you just wish to share audio and video files then something like <a href="http://mediatomb.cc/">mediatomb</a> with be much more simple (although rygel also shares files).</li>
<li>There is meant to be a simpler way to link rygel and pulseaudio where everything works out of the box and rygel appears as a separate audio out but it&#8217;s currently broken with the supplied pulseaudio/rygel combination in ubuntu.</li>
</ul>
<h2>Acknowledgements</h2>
<p>I figured all this out with the help of these guys:</p>
<ul>
<li><a href="http://ubuntuforums.org/showpost.php?p=11010331&amp;postcount=4">http://ubuntuforums.org/showpost.php?p=11010331&amp;postcount=4</a></li>
<li><a href="http://www.outflux.net/blog/archives/2009/04/19/recording-from-pulseaudio/">http://www.outflux.net/blog/archives/2009/04/19/recording-from-pulseaudio/</a></li>
<li><a href="http://mpd.wikia.com/wiki/PulseAudio">http://mpd.wikia.com/wiki/PulseAudio</a></li>
</ul>
<p>Thanks.</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/linux/streaming-audio-from-ubuntu-linux-to-a-dlna-player-blu-ray-or-ps3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP 5.4 File Upload Progress and HTML5 Progress Bars</title>
		<link>http://chemicaloliver.net/programming/php-5-4-file-upload-progress-and-html5-progress-bars/</link>
		<comments>http://chemicaloliver.net/programming/php-5-4-file-upload-progress-and-html5-progress-bars/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 00:35:07 +0000</pubDate>
		<dc:creator>chemicaloliver</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1221</guid>
		<description><![CDATA[Developers who work with PHP applications that upload files commonly struggle with providing user feedback on the upload progress, usually using flash and javascript solutions like uploadify. In PHP 5.4 there is now integrated functionality to allow file upload progress to be passed back to the browser. In this post I&#8217;ll describe the basic operation of this feature and describe a [...]]]></description>
			<content:encoded><![CDATA[<p>Developers who work with PHP applications that upload files commonly struggle with providing user feedback on the upload progress, usually using flash and javascript solutions like uploadify. In PHP 5.4 there is now integrated functionality to allow file upload progress to be passed back to the browser.</p>
<p>In this post I&#8217;ll describe the basic operation of this feature and describe a quick example of its use.</p>
<p style="text-align: center;"><a href="http://playground.chemicaloliver.net/progress/"><img class="size-medium wp-image-1234 aligncenter" title="PHP 5.4 Upload Progress" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/12/Screenshot-at-2011-12-03-234816-300x156.png" alt="" width="300" height="156" /></a></p>
<p style="text-align: center;"><a title="PHP 5.4 Upload Progress Demo" href="http://playground.chemicaloliver.net/progress/">PHP 5.4 File Upload Progress Demo</a></p>
<h2>How it Works</h2>
<p>The upload progress functionality stores the current progress in a session variable which can then be queried as required to give the current progress, it requires the use of PHP native sessions. The $_SESSION key is set by the form name and a prefix defined in php.ini</p>
<p><span id="more-1221"></span></p>
<p>An example of the data stored is shown below:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php $_SESSION[&quot;upload_progress_123&quot;] = array(  &quot;start_time&quot; = 1234567890,
 &quot;content_length&quot; =&gt; 57343257,
 &quot;bytes_processed&quot; =&gt; 453489,
 &quot;done&quot; =&gt; false,
 &quot;files&quot; =&gt; array(
  0 =&gt; array(
   &quot;field_name&quot; =&gt; &quot;file1&quot;,
   // The following 3 elements equals those in $_FILES
   &quot;name&quot; =&gt; &quot;foo.avi&quot;,
   &quot;tmp_name&quot; =&gt; &quot;/tmp/phpxxxxxx&quot;,
   &quot;error&quot; =&gt; 0,
   &quot;done&quot; =&gt; true,
   &quot;start_time&quot; =&gt; 1234567890,
   &quot;bytes_processed&quot; =&gt; 57343250,
  ),
  // An other file, not finished uploading, in the same request
  1 =&gt; array(
   &quot;field_name&quot; =&gt; &quot;file2&quot;,
   &quot;name&quot; =&gt; &quot;bar.avi&quot;,
   &quot;tmp_name&quot; =&gt; NULL,
   &quot;error&quot; =&gt; 0,
   &quot;done&quot; =&gt; false,
   &quot;start_time&quot; =&gt; 1234567899,
   &quot;bytes_processed&quot; =&gt; 54554,
  ),
 )
);
</pre>
<p>It is up to the developer how they wish to present this data to the user.</p>
<h2>Setup</h2>
<p>This functionality is included as standard in PHP 5.4 which can be simply installed from an ubuntu package as discussed in my previous post: <a href="http://chemicaloliver.net/internet/installing-php-5-4-in-ubuntu/">http://chemicaloliver.net/internet/installing-php-5-4-in-ubuntu/</a></p>
<p>This feature should be enabled by default.</p>
<h2>Example</h2>
<p>Complete code can be found on <a href="https://github.com/chemicaloliver/PHP-5.4-Upload-Progress-Example">github</a>.</p>
<h3>Upload Form</h3>
<p>The upload form is standard html file upload form apart from an additional hidden value defining the progress name attribute so the upload can be identified in the session variables later:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;form id=&quot;upload&quot; action=&quot;/progress/upload.php&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
 &lt;input type=&quot;hidden&quot; name=&quot;&quot; value=&quot;upload&quot; /&gt;

 &lt;input id=&quot;file1&quot; type=&quot;file&quot; name=&quot;file1&quot; /&gt;
 &lt;input id=&quot;file2&quot; type=&quot;file&quot; name=&quot;file2&quot; /&gt;

 &lt;input class=&quot;btn primary&quot; type=&quot;submit&quot; value=&quot;Upload&quot; /&gt;&lt;/form&gt;
</pre>
<p>In my example I&#8217;ve used the <a href="http://jquery.malsup.com/form/">jquery form plugin</a> to make submitting the form using AJAX more simple.</p>
<h3>Recieving Script</h3>
<p>In this example the receiving script needs to do nothing except start a session, I added a var_dump for debugging initially:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php session_start(); var_dump($_SESSION); var_dump($_FILES); ??
</pre>
<h3>Monitoring Progress</h3>
<p>This is performed through a combination of javascript and PHP, the client polls a server page which echos the current progress as JSON:</p>
<h4>Client:</h4>
<p>The client uses an interval time to get the progress every 200ms and pass it to an HTML5 progress bar.</p>
<pre class="brush: jscript; title: ; notranslate">
interval_id = setInterval(function() {
$.getJSON('/progress/progress.php', function(data){
    //if there is some progress then update
    if(data)
    {
        $('#progress').val(data.bytes_processed / data.content_length);
        $('#progress-txt').html('Uploading '+ Math.round((data.bytes_processed / data.content_length)*100) + '%');
    }

    //When there is no data the upload is complete
    else
    {
        $('#progress').val('1');
        $('#progress-txt').html('Complete');
        stopProgress();
    }
})
}, 200);
</pre>
<h4>Server Side:</h4>
<p>The server side just echos a json encoded version of the session variable:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
session_start();
echo json_encode( $_SESSION['upload_progress_upload']);
?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/programming/php-5-4-file-upload-progress-and-html5-progress-bars/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Installing PHP 5.4 in Ubuntu</title>
		<link>http://chemicaloliver.net/internet/installing-php-5-4-in-ubuntu/</link>
		<comments>http://chemicaloliver.net/internet/installing-php-5-4-in-ubuntu/#comments</comments>
		<pubDate>Sat, 03 Dec 2011 23:46:02 +0000</pubDate>
		<dc:creator>chemicaloliver</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1223</guid>
		<description><![CDATA[I&#8217;ve been excitedly awaiting some of the new features found in PHP 5.4, in particular array notation and file upload progress monitoring so I decided to try and install PHP 5.4 on Ubuntu. Fortunately there is a repository of prebuilt packages for Ubuntu 11.04 (Natty Narwhal) at  http://apt.damz.org/ I recommend using a VM so you don&#8217;t mess up [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been excitedly awaiting some of the new features found in PHP 5.4, in particular array notation and file upload progress monitoring so I decided to try and install PHP 5.4 on Ubuntu. Fortunately there is a repository of prebuilt packages for Ubuntu 11.04 (Natty Narwhal) at  <a href="http://apt.damz.org/">http://apt.damz.org/</a></p>
<p>I recommend using a VM so you don&#8217;t mess up any stable PHP install &#8211; I only tested this on Ubuntu 11.04 as that&#8217;s what was recommended and I already had a VM with it installed.</p>
<h2>Installation</h2>
<p>Installation is a very simple matter of adding the gpg key:</p>
<pre class="brush: bash; title: ; notranslate">
curl http://apt.damz.org/key.gpg | sudo apt-key add -
</pre>
<p>Adding the repository to /etc/apt/sources.list:</p>
<pre class="brush: bash; title: ; notranslate">
deb http://apt.damz.org/ubuntu natty php54
</pre>
<p>Then installing as normal</p>
<pre class="brush: bash; title: ; notranslate">
sudo apt-get install php5 libapache2-mod-php5
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/internet/installing-php-5-4-in-ubuntu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Codeigniter Unit Testing with Simpletest and PHP 5.3</title>
		<link>http://chemicaloliver.net/internet/codeigniter-unit-testing-with-simpletest-and-php-5-3/</link>
		<comments>http://chemicaloliver.net/internet/codeigniter-unit-testing-with-simpletest-and-php-5-3/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 22:03:04 +0000</pubDate>
		<dc:creator>chemicaloliver</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[simpletest]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1212</guid>
		<description><![CDATA[I&#8217;m a regular user of codeigniter-simpletest developed by Eric Barnes however I ran into a number of issues when attempting to run some features under PHP5.3, this was due to using an old version of Simpletest. I have now updated this and had my pull request accepted and merged into the main repo so that [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a regular user of <a title="Github: Codeigniter-Simpletest" href="http://github.com/ericbarnes/codeigniter-simpletest">codeigniter-simpletest</a> developed by Eric Barnes however I ran into a number of issues when attempting to run some features under PHP5.3, this was due to using an old version of Simpletest. I have now updated this and had my pull request accepted and merged into the main repo so that it now uses the most recent versions (1.1alpha3).</p>
<p>There is however one important change to note which will stop old tests working, that is the way that test classes define a label, these are optional so this only applies if you use them in your project. The name of the test is now passed through the simpletest constructor otherwise the default is to use the classname of the test.</p>
<h3>Before</h3>
<pre class="brush: php; title: ; notranslate">
class test_users_model extends CodeIgniterUnitTestCase
{
	public function __construct()
	{
		parent::__construct();

		$this-&gt;UnitTestCase('Users Model');

		$this-&gt;load-&gt;model('users/users_model');
	}

etc...
</pre>
<h3>After</h3>
<pre class="brush: php; title: ; notranslate">
class test_users_model extends CodeIgniterUnitTestCase
{
	public function __construct()
	{
		parent::__construct('Users Model');

		$this-&gt;load-&gt;model('users/users_model');
	}
etc...
</pre>
<p>I&#8217;m also working on integration with CI systems, Jenkins in particular based on this rather cool presentation: <a href="http://www.cs.northwestern.edu/academics/courses/394/ci-server-setup/orange-ci-setup-2011.pdf" target="_blank">Setting up a Continuous Integration Server for Ubuntu with Codeigniter and Github</a></p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/internet/codeigniter-unit-testing-with-simpletest-and-php-5-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP North West 2011</title>
		<link>http://chemicaloliver.net/programming/php-north-west-2011/</link>
		<comments>http://chemicaloliver.net/programming/php-north-west-2011/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 13:23:41 +0000</pubDate>
		<dc:creator>chemicaloliver</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[manchester]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpnw]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1202</guid>
		<description><![CDATA[This was my first PHPNW conference but after hearing so many good things about the conference in previous years I thought I&#8217;d give it a go. In this post I&#8217;ll summarise some of my highlights. Talks (Selected) PHP Tester&#8217;s Toolbox &#8211; Sebastian Bergmann A quick run through different testing frameworks for use with PHP, as Sebastian is [...]]]></description>
			<content:encoded><![CDATA[<p>This was my first PHPNW conference but after hearing so many good things about the conference in previous years I thought I&#8217;d give it a go. In this post I&#8217;ll summarise some of my highlights.</p>
<p style="text-align: center;"><img class="size-full wp-image-1203 aligncenter" title="PHPNW11 Logo" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/phpnw11-logo.png" alt="" width="200" height="68" /></p>
<p><span id="more-1202"></span></p>
<h2>Talks (Selected)</h2>
<h3>PHP Tester&#8217;s Toolbox &#8211; Sebastian Bergmann</h3>
<p>A quick run through different testing frameworks for use with PHP, as Sebastian is the creator of PHPUnit this talk had an obvious bias but I didn&#8217;t feel this overwhelmed the talk. For me who has used phpunit and simpletest for unit testing there was nothing ground breaking here but gave me an introduction to BDD and reassured me I was doing the existing bits right.</p>
<h3>Deploying PHP Applications with Phing &#8211; Michiel Rook</h3>
<p>Phing is one of those things I keep meaning to get around to, I&#8217;ve used various methods for deployment from mercurial to FTP and ant (when using html5 boilerplate) but Phing seems like a logical thing to use for PHP deployment, as with the previous talk this just provided reassurance that I&#8217;d understood it correctly and didn&#8217;t really provide anything new. It also only half filled the slot which felt like a bit of a waste.</p>
<h3>Estimation or &#8216;How to dig your own grave&#8217; &#8211; Rowan Merewood</h3>
<p>Without a doubt this was the most entertaining talk of the day, plagued by early technical issues Rowan breezed through it all with a casual air of confidence and a good measure of humour. The content of the talk was also pretty spot on discussing common sense ways to improve estimating how long your projects will take, much of it rang true for me and will be bearing it in mind in the future, if only my boss got to watch it he might understand that actually my estimations are not so long after all.</p>
<h3>Are your tests really helping &#8211; Laura Beth Denker</h3>
<p>Another entertaining talk centring on best practice when testing with anecdotes from LB&#8217;s experience at Google and Etsy liberally mixed in. For me this was a talk which described a way of working to aspire to; Etsy have over 100 developers and can deploy new code up to every 20 minutes due to the efficiency of the test and deployment process. The approach LB presented was a nice common sense approach of testing what needs to be tested rather than every little thing.</p>
<h3>Introducing Pyri the new aggregator for Pear &#8211; Jeremy Coates</h3>
<p>The only talk I&#8217;m going to mention here that I watched from the unconference track given by the organiser of the event (or at least one of them). It described an aggregator and search engine for the PEAR PHP package system which is notoriously fragmented. The system, which is only in its early stages of development at the moment  (humorously described as Conference Driven Development), crawls submitted PEAR repos and grabs the XML data on the packages and indexes it. The data is then accessed via an API. The eventual aim is to have a one stop reference site for all PEAR packages available. Development is set to continue on the project over the coming months.</p>
<h2>Organisation</h2>
<p>In general the organisation of the conference seemed great pretty much everything ran smoothly and there were no real frustrations.</p>
<p>I&#8217;m still not sure in my mind if three tracks + an unconference track are too much, there were odd things in the unconference track I would liked to have seen but clashed with one or more things on the schedule. However I did appreciate the unconference track as it filled in a few gaps when other talks finished early. It&#8217;s probably better this way than having times when there was nothing I wished to see.</p>
<h2>Venue</h2>
<p>The physical location for the conference was great, the Ramada Hotel in Manchester is about 10 minutes walk from the station, however the hotel itself wasn&#8217;t amazing; the chairs were the most uncomfortable I&#8217;ve ever sat on at a conference and some of the hotel looked a bit tired.When it came to lunchtime for some (me included) the queue was unbearable and lack of space to be seated was a disappointment so I retreated to the local Pret a Manger which also allowed me to get some welcome fresh air.</p>
<h2>Overall</h2>
<p>All in all I had an enjoyable day and will probably return next year, however I didn&#8217;t leave inspired to go home an instantly start a new exciting project to make use of something I&#8217;d learnt, more a host of useful little things to integrate into existing projects and ways to improve what I&#8217;m already doing, so still good but not mind blowing.</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/programming/php-north-west-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speeding up PHP &#8211; Using process forking to accelerate image resizing</title>
		<link>http://chemicaloliver.net/programming/speeding-up-php-using-process-forking-for-image-resizing/</link>
		<comments>http://chemicaloliver.net/programming/speeding-up-php-using-process-forking-for-image-resizing/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 13:42:23 +0000</pubDate>
		<dc:creator>chemicaloliver</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1182</guid>
		<description><![CDATA[Most of my projects at work involve resizing images in PHP applications, usually the result is loaded via AJAX so it needs to be generated as fast as possible for optimum user experience. Recently I discovered the ability to fork processes in PHP, this gives the ability to run multiple functions at the same time. [...]]]></description>
			<content:encoded><![CDATA[<p>Most of my projects at work involve resizing images in PHP applications, usually the result is loaded via AJAX so it needs to be generated as fast as possible for optimum user experience. Recently I discovered the ability to fork processes in PHP, this gives the ability to run multiple functions at the same time. In the example below I&#8217;ll demonstrate how parallel processing can be used in PHP to speed the generation of several different sizes of preview images from a large uploaded image.</p>
<p>This code uses the <a href="http://www.php.net/manual/en/book.pcntl.php">PCNTL</a> extension which was installed as standard on my Ubuntu 11.04 PHP 5.3 install.</p>
<p><span id="more-1182"></span></p>
<p>Conventionally to generate a couple of different sizes of images from a large JPEG image one might use something like this:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

/**
 * Create a thumbnail image from the specified file
 *
 * @param int $height output image height
 * @param int $width  output image width
 */

function create_preview($height, $width)
{
    //Input image
    $img = 'test.jpg';

    //Output image
    $new_img = 'test -'.$width.'x'.$height.'.jpg';

    //get the current image size
    list($full_width, $full_height) = getimagesize($img) ;

    //Create a blank image to load in the new resized image
    $tn = imagecreatetruecolor($width, $height) ;

    //Load the original file
    $image = imagecreatefromjpeg($img) ;

    //Do the crop
    imagecopyresampled($tn, $image, 0, 0, 0, 0, $width, $height, $full_width, $full_height) ;

    //Save the file
    imagejpeg($tn, $new_img, 100);
}        

// The thumbnail sizes to be generated
$image_sizes = array(
    array(100,100),
    array(200, 200),
    array(300, 300),
    array(400, 400),
    array(500, 500),
    array(1000, 1000)
);

// Loop through the images sequentially
foreach($image_sizes as $image_size)
{
    create_preview($image_size[0], $image_size[1]);
}

?&gt;
</pre>
<p>To get an idea of the speed of this script we can run it from the command line:</p>
<pre class="brush: bash; title: ; notranslate">
time php single_process.php
</pre>
<p>This takes couple of seconds, as you might expect, in my case:</p>
<pre class="brush: bash; title: ; notranslate">
real	0m2.325s
user	0m2.210s
sys	0m0.100s
</pre>
<p>However rather than performing the resizing sequentially it can be performed in parallel using the same <code>create_preview()</code> function as before:</p>
<pre class="brush: php; title: ; notranslate">
// The thumbnail sizes to be generated
$image_sizes = array(
    array(100,100),
    array(200, 200),
    array(300, 300),
    array(400, 400),
    array(500, 500),
    array(1000, 1000)
);

//Counter for number of processes
$i = 1;

//Loop through the image sizes but this time fork a process for each size.
foreach($image_sizes as $image_size)
{
    //Fork a process
    $pid = pcntl_fork();

    //if we're in a child thread then grab an image size and process it.
    if (!$pid)
    {
        echo 'starting child ', $i, PHP_EOL;
        create_preview($image_size[0], $image_size[1]);

        //Die otherwise the process will continue to loop and each process will create all the thumbnails
        die();
    }

    $i++;
}

//Wait for all the subprocesses to complete to avoid zombie processes
foreach($image_sizes as $image_size)
{
    pcntl_wait($status);
}
</pre>
<p>Now running the script using the same command line again the advantage is instantly noticeable:</p>
<pre class="brush: bash; title: ; notranslate">
time php multi_process.php

starting child 1
starting child 2
starting child 3
starting child 4
starting child 5
starting child 6

real	0m0.693s
user	0m3.030s
sys	0m0.140s
</pre>
<p>As you can see from this very unscientific test running the processes in parallel increases the speed by over 3.5x. As long as you&#8217;re careful to watch for threads terminating and not just leaving them unattended this seems like a great way to speed up simple repetitive tasks, <del>I&#8217;d certainly hope to find a place for it in some of my applications in the future</del> I&#8217;ll probably not use this in a production web application due to the warning that Paul kindly posted below, I guess should read the manual before getting excited&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/programming/speeding-up-php-using-process-forking-for-image-resizing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MQTT Caller Display &#8211; Hacking the BT Caller Display 50 Serial Port</title>
		<link>http://chemicaloliver.net/electronics/mqtt-caller-display-hacking-the-bt-caller-display-50-serial-port/</link>
		<comments>http://chemicaloliver.net/electronics/mqtt-caller-display-hacking-the-bt-caller-display-50-serial-port/#comments</comments>
		<pubDate>Sun, 02 Oct 2011 16:03:35 +0000</pubDate>
		<dc:creator>chemicaloliver</dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[circuit]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[mqtt]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[serial]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1156</guid>
		<description><![CDATA[This post describes a recent project I completed to display caller id information for incoming calls on my computers. The project uses a BT Caller Display 50 connected via an optoisolating bridge to an arduino with an ethernet shield. When an incoming call is received the telephone number is transmitted via MQTT to a python client on [...]]]></description>
			<content:encoded><![CDATA[<p>This post describes a recent project I completed to display caller id information for incoming calls on my computers. The project uses a BT Caller Display 50 connected via an optoisolating bridge to an arduino with an ethernet shield. When an incoming call is received the telephone number is transmitted via MQTT to a python client on any computer I happen to be using at the time. This project is a great example of someone putting great effort into being lazy, the caller id data is alredy displayed on my phone but the phone generally resides in the next room so this avoids me needing to run for stupid cold callers. Initially I&#8217;d wanted to do this project just using the arduino, which may have been possible but using the CD50 makes it a huge amount easier.</p>
<p style="text-align: center;"><a href="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/IMG_3470.jpg"><img class="size-medium wp-image-1161 aligncenter" title="BT Caller Display 50 and Arduino" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/IMG_3470-300x199.jpg" alt="" width="300" height="199" /></a></p>
<p><span id="more-1156"></span></p>
<h2>UK Caller ID Protocol</h2>
<p>The caller id system in the UK transmits the callers telephone number (and date and time) as a burst of 1200 baud serial between the first and second ring, this is then decoded and displayed.</p>
<h2>Hardware</h2>
<p>The hardware is very simple as the CD50 has an internal serial port so all that&#8217;s required is to safely isolate the phone line from any sensitive computer systems with an optoisolator.</p>
<h3>CD50</h3>
<p>The CD50 has been hacked to provide serial output in a couple of projects before, however all the pages documenting this have long gone (the unit is around 10yrs old). Internally the unit uses two EXAR XR-2211 FSK Demodulator/ Tone Decoders, one to detect the presence of the signal and one to decode it (allegedly). In this configuration this means serial data is outputted on pin 7 of the left chip (see below)</p>
<p style="text-align: center;"><a href="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/IMG_3461.jpg"><img class="size-medium wp-image-1164 aligncenter" title="BT Caller Display 50 Interior" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/IMG_3461-300x200.jpg" alt="" width="300" height="200" /></a><a href="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/IMG_3465.jpg"><img class="size-medium wp-image-1166 aligncenter" title="BT Caller Display 50 Front Interior" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/IMG_3465-255x300.jpg" alt="" width="255" height="300" /></a></p>
<p>If you wish to power the unit from a source other than the internal batteries this can be easily achieved by connecting to the points below the LCD as shown, this must be done with caution as the unit will not work if connected to mains earth as used by many PSUs it must be fully isolated.</p>
<h3>Bridge</h3>
<p style="text-align: center;"><a href="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/isolator-circuit1.png"><img class="size-medium wp-image-1169 aligncenter" title="Optoisolating circuit" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/isolator-circuit1-300x162.png" alt="" width="300" height="162" /></a></p>
<p>The optoisolating bridge protects connected equipment from high voltages which can occur in telephone lines, here I used the Vishay 6N137 device as shown (I chose the Vishay as it requires very low current). I powered the CD50 side using the power supply on pin 1 and the arduino side using the internal power supply from the arduino. The 6N137 was sourced from <a href="http://uk.farnell.com/">Farnell</a>.</p>
<h3>Arduino</h3>
<p>The arduino simply receives the serial data using its hardware serial port (I had mixed results with a software serial port), parses the telephone number from the output and then sends it in an MQTT message it would be simple to pass it using over usb back to the computer if you are not using MQTT too.</p>
<h2>Software</h2>
<p>The serial output from the CD50 has some apparently (but probably not) random letters appended to the beginning of each transmission and the data and time directly in front of the telephone number so once messages have been received this must be parsed at some stage, I choose to do it on the arduino.</p>
<p>All code is also on my <a href="github.com/chemicaloliver">github</a>.</p>
<h3>Arduino</h3>
<p>I wrote this simple sketch to parse and send the data, it requires the Arduino MQTT Library - <a href="http://knolleary.net/arduino-client-for-mqtt/">http://knolleary.net/arduino-client-for-mqtt/</a>.</p>
<pre class="brush: cpp; title: ; notranslate">
/*
 * Quick arduino sketch to recieve a telephone number over
 * serial (1200 baud using hardware serial) and broadcast it
 * using MQTT.
 *
 * This sketch is part of a project to read caller id data from
 * a BT Caller Display 50.
 *
 * @author Oliver Smith
 *
 */

#include &lt;SPI.h&gt;
#include &lt;Ethernet.h&gt;
#include &lt;PubSubClient.h&gt;

byte mac[]    = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
byte server[] = { 192, 168, 1, 2 };
byte ip[]     = { 192, 168, 1, 8 };

PubSubClient client(server, 1883, callback);

const int bufferLength = 19;      //Length of buffer
char stringBuffer[bufferLength];  //Buffer to hold input
int stringIndex = 0;              //Index of next free element in buffer

void setup()
{
  Serial.begin(1200);

  Serial.println(&quot;Serial Connected&quot;);

  Ethernet.begin(mac, ip);
  Serial.println(&quot;Network Connected&quot;);

  if(client.connect(&quot;arduino&quot;))
  {
    Serial.println(&quot;MQTT Connected&quot;);
  }

}

void loop()
{
  while(Serial.available() &amp;&amp; stringIndex &lt; bufferLength)
  {
    char inputChar = Serial.read();

    //Check if the char read is a number
    if(inputChar  &gt;= '0' &amp;&amp; inputChar &lt;= '9' )
    {

        //Add number to buffer
        stringBuffer[stringIndex] = inputChar;

      //Serial.println(stringBuffer);
      stringIndex++;
    }
  }

  //If the buffer is long enough
  if(stringIndex == bufferLength)
  {
    Serial.println(&quot;Buffer full&quot;);
    //remove initial irrelevant digits

    String output = String(stringBuffer);
    String telephoneNumberString = output.substring(8);

    char charBuf[12];
    telephoneNumberString.toCharArray(charBuf, 12);

    //Send the telephone number back over serial for debugging
    Serial.println(charBuf);
    client.publish(&quot;topic&quot;,charBuf);

    stringIndex = 0;
  }
}

void callback(char* topic, byte* payload,int length) {
  // no action required
}
</pre>
<h3>Example Python Client</h3>
<p>I used a simple MQTT subscribe script with pynotify in ubuntu to display messages on the desktop, details are available in my previous post: <a title="First steps using Python and MQTT (using pynotify on Ubuntu)" href="http://chemicaloliver.net/programming/first-steps-using-python-and-mqtt/">First steps using Python and MQTT</a></p>
<p>I&#8217;d rather not show it working as that would give away my telephone number! But it does work, so far 100% of the time.</p>
<h2>Getting There</h2>
<p>Initially there was lots of head scratching, probing and logic analysing to check the information I&#8217;d read:</p>
<p style="text-align: center;"><a href="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/IMG_3456.jpg"><img class="size-medium wp-image-1174 aligncenter" title="BT CD50 Under Test" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/IMG_3456-300x211.jpg" alt="" width="300" height="211" /></a></p>
<h3>History</h3>
<p>The circuit used seems to be a duplicate of a previous project which was documented at:</p>
<p><a href="http://www.amarok.demon.co.uk/dl/cd50_mod/">http://www.amarok.demon.co.uk/dl/cd50_mod/</a></p>
<p>and</p>
<p><a href="http://www.photon.dyndns.org/projects/btcd50conversion/old_index.html">http://www.photon.dyndns.org/projects/btcd50conversion/old_index.html</a></p>
<p>However these pages are long gone and the wayback machine only has the text not the images detailing the hardware. I never managed to find a copy of them so I built my own version.</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/electronics/mqtt-caller-display-hacking-the-bt-caller-display-50-serial-port/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Simple sitemaps in codeigniter</title>
		<link>http://chemicaloliver.net/programming/simple-sitemaps-in-codeigniter/</link>
		<comments>http://chemicaloliver.net/programming/simple-sitemaps-in-codeigniter/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 19:30:25 +0000</pubDate>
		<dc:creator>chemicaloliver</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1145</guid>
		<description><![CDATA[Creating sitemaps is a bit of a hassle for any site bigger than a couple of pages, especially where a database is involved. While working on a recent project I created a library for codeigniter which allows the simple creation of sitemaps either by manually adding pages which might be appropriate for a blog, or [...]]]></description>
			<content:encoded><![CDATA[<p>Creating sitemaps is a bit of a hassle for any site bigger than a couple of pages, especially where a database is involved. While working on a recent project I created a library for codeigniter which allows the simple creation of sitemaps either by manually adding pages which might be appropriate for a blog, or allowing the library to scan controllers and adding all pages defined by methods. Common search engines can also be notified.</p>
<p>A simple example of it in use is shown below:</p>
<pre class="brush: bash; title: ; notranslate">
//if you're using sparks
$this-&gt;load-&gt;spark('codeigniter-sitemaps/0.0.1')

$this-&gt;load-&gt;library('sitemaps');

//assuming a hypothetical posts_model
$posts = $this-&gt;posts_model-&gt;get_posts();

foreach ($posts AS $post)
{
$item = array(
&quot;loc&quot; =&gt; site_url(&quot;blog/&quot; . $post-&gt;slug),
&quot;lastmod&quot; =&gt; date(&quot;c&quot;, strtotime($post-&gt;last_modified)),
&quot;changefreq&quot; =&gt; &quot;hourly&quot;,
&quot;priority&quot; =&gt; &quot;0.8&quot;
);

$this-&gt;sitemaps-&gt;add_item($item);
}

// file name may change due to compression
$file_name = $this-&gt;sitemaps-&gt;build(&quot;sitemap_blog.xml&quot;);

$reponses = $this-&gt;sitemaps-&gt;ping(site_url($file_name));
</pre>
<p>You can download the spark from: <a href="http://getsparks.org/packages/codeigniter-sitemaps">http://getsparks.org/packages/codeigniter-sitemaps</a></p>
<p>Or get the code from my github: <a href="http://github.com/chemicaloliver/codeigniter-sitemaps">http://github.com/chemicaloliver/codeigniter-sitemaps</a></p>
<p>Simple documentation is included and should be self explanatory.</p>
<p>This library is based on work by Philipp Dörner 2010 <a href="http://signalkraft.com/google-sitemaps-for-codeigniter">http://signalkraft.com/google-sitemaps-for-codeigniter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/programming/simple-sitemaps-in-codeigniter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Double sided male headers &#8211; ease your FTDI cable to breadboard connections woes!</title>
		<link>http://chemicaloliver.net/hardware/double-sided-male-headers-ease-your-ftdi-cable-to-breadboard-connections-woes/</link>
		<comments>http://chemicaloliver.net/hardware/double-sided-male-headers-ease-your-ftdi-cable-to-breadboard-connections-woes/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 20:33:20 +0000</pubDate>
		<dc:creator>chemicaloliver</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[circuit]]></category>
		<category><![CDATA[components]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[ftdi]]></category>
		<category><![CDATA[prototyping]]></category>
		<category><![CDATA[samtec]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1130</guid>
		<description><![CDATA[When prototyping circuits I often use a breadboard and an FTDI cable which usually leaves some kind of hacky looking unstable connection using wires stuck into the FTDI cable female header connector. This arrangement often leads to failiure as the wires fall out. After much searching I&#8217;ve managed to locate a solution to allow neat [...]]]></description>
			<content:encoded><![CDATA[<p>When prototyping circuits I often use a breadboard and an FTDI cable which usually leaves some kind of hacky looking unstable connection using wires stuck into the FTDI cable female header connector. This arrangement often leads to failiure as the wires fall out. After much searching I&#8217;ve managed to locate a solution to allow neat connection of a female header to the breadboard.</p>
<p style="text-align: center;"><a href="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/09/DSC04686.jpg"><img class="size-medium wp-image-1133 aligncenter" title="Connecting an ftdi cable to a breadboard with jumper wires" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/09/DSC04686-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>See below for details:<br />
<span id="more-1130"></span><br />
Surprisingly there seem to be only one or two retailers carry the part to solve this issue, a double sided male header:</p>
<p style="text-align: center;"><a href="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/09/DSC04685.jpg"><img class="size-medium wp-image-1134 aligncenter" title="Samtec TSW-113-16-G-S Double Sided Male Header" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/09/DSC04685-300x207.jpg" alt="" width="300" height="207" /></a> <a href="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/09/DSC04682.jpg"><img class="size-medium wp-image-1135 aligncenter" title="Double sided header in breadboard" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/09/DSC04682-300x238.jpg" alt="" width="300" height="238" /></a><a href="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/09/DSC04683.jpg"><img class="size-medium wp-image-1136 aligncenter" title="FTDI Cable connected to double sided header" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/09/DSC04683-300x226.jpg" alt="" width="300" height="226" /></a></p>
<p>The small downside to the part I used is that the pins are slightly too long and could damage the female connector if forced on. The part I used was Samtec TSW-150-16-G-S which comes as a row of 50 pins with ~8mm of pin above and below the plastic, with hindsight TSW-150-08-G-S with ~6mm above and below would probably have worked better if you&#8217;re planning to buy some. (I&#8217;m probably going to get some and then update). You buy them direct on Samtec&#8217;s website. WHile you&#8217;re there have a look around, there is an amazing array of potentially useful hard to find connectors.</p>
<p><em>Edit: I&#8217;ve now tested the shorter TSW-150-08-G-S and this is indeed the perfect length to fit into the breadboard and female header without damaging either.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/hardware/double-sided-male-headers-ease-your-ftdi-cable-to-breadboard-connections-woes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating a Remote Webcam using NodeJS, Android, Opera Mobile, Web Sockets and HTML5</title>
		<link>http://chemicaloliver.net/programming/creating-a-remote-webcam-using-nodejs-android-opera-mobile-web-sockets-and-html5/</link>
		<comments>http://chemicaloliver.net/programming/creating-a-remote-webcam-using-nodejs-android-opera-mobile-web-sockets-and-html5/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 17:20:14 +0000</pubDate>
		<dc:creator>chemicaloliver</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1103</guid>
		<description><![CDATA[Recently I&#8217;ve been experimenting with using webcams in the browser with Javascript, while I was browsing Google on related topics I came across an interesting video on youtube. As I couldn&#8217;t find any code for how the demo had been created I decided to create my own (see below). The idea of streaming video from a phone [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve been experimenting with using webcams in the browser with Javascript, while I was browsing Google on related topics I came across an<a title="Remote Webcam using NodeJS, Android, Opera Mobile, Web Sockets and HTML5" href="http://www.youtube.com/watch?v=cjmuwA8l1LQ"> interesting video on youtube</a>. As I couldn&#8217;t find any code for how the demo had been created I decided to create my own (see below). The idea of streaming video from a phone to a server via a websocket had occurred to me before I viewed this video but I dismissed it as impractical, an opinion which has only been reinforced after testing it myself.</p>
<p>This is the video that gave me the inspiration (my code replicates this exactly so I didn&#8217;t see the need to recreate the video too), the only difference is I used linux all round rather than windows:</p>
<p style="text-align: center;"><object width="410" height="256"><param name="movie" value="http://www.youtube.com/v/cjmuwA8l1LQ?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/cjmuwA8l1LQ?version=3" type="application/x-shockwave-flash" width="410" height="256" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p><span id="more-1103"></span></p>
<h2>Code</h2>
<p>The code can be found on my <a href="http://github.com/chemicaloliver/HTML5-Device-Streamer">github</a>.</p>
<h2>System Structure</h2>
<p>The system consists of three main elements, a client which streams video, a client for viewing the video and a server to route the video via websockets and host the web pages.</p>
<h3>Camera Client</h3>
<p>The camera is created using getUserMedia to send a video stream from a devices camera to the html5 video tag which is displayed on the page. Capture happens by pulling frames onto a canvas and then saving the canvas as a base 64 encoded image and transmitting it over websockets to the server. Repeated frames are captured using setInterval. I&#8217;ve tested this demo using the custom <a href="http://my.opera.com/core/blog/2011/03/23/webcam-orientation-preview">Opera Mobile for Android build with getUserMedia support</a> on my HTC Desire Z (T mobile G2) about 2fps is achievable due to the limitations of processing the large amount of data. On faster devices this should improve. I intend to produce a second version using a desktop client to test this.</p>
<h3>Viewer Client</h3>
<p>The viewer is very simple, it receives frames over a websocket connection as base64 encoded images and displays them in as standard images in html.</p>
<h3>Server</h3>
<p>The server uses node.js to receive frames via a websocket and then resends them back out to all clients, it is also used to host the static files for the clients.</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/programming/creating-a-remote-webcam-using-nodejs-android-opera-mobile-web-sockets-and-html5/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

