Header Image - charles newman's blog

WordPress “Fatal error: Allowed memory size of n bytes exhausted (tried to allocate x bytes) in …”

by Charles Newman

This one took me a while to figure out…

Clicking the “Appearance” then “Customize” options from the WordPress Dashboard suddenly started yielding this error on a site I was working on with a fairly detailed theme:

“Fatal error: Allowed memory size of n bytes exhausted (tried to allocate x bytes) in …”

Replace ‘n‘ and ‘x‘ with what you are seeing.

Here’s how I fixed it after trying to update the php5.ini file had no effect (this site is hosted by GoDaddy):

Modify your wp_config.php file by adding these two lines at the top of the file, just before your database settings:

define( ‘WP_MEMORY_LIMIT’, ’96M’ );
define( ‘WP_MAX_MEMORY_LIMIT’, ‘256M’ );

// ** MySQL settings – You can get this info from your web host ** //
/** The name of the database for WordPress */
define(‘DB_NAME’, ‘abcXXXXXXXX’);

That immediately fixed my issue.

How to write to a NAS (Network Attached Storage) drive from a Raspberry Pi

by Charles Newman

This post applies to a WD MyCloud 2TB NAS (Network Attached Storage) but the process should be similar for other brands.  NAS drives connect to your wi-fi router via ethernet cable and are available to other laptops and computers connected to your wi-fi network. So for example, you could set up your Mac laptops and desktops anywhere in your house to back up to these drives using Apple’s Time Machine without having to physically connect a drive to the Macs.

My main goal was to write to the drive from a few Raspberry Pi‘s. I’ve built motion sensing security cameras with the pi’s (more on this in a future post). This gives much more storage than the pi’s SD cards and allows me to view the images without having to copy them to a computer first. The Mac mounts the NAS drive and it appears in the finder. You can also make the WD MyCloud visible outside your home network but I don’t turn that on unless I’m traveling.

All of my Raspberry Pi’s are running Raspbian Wheezy.

Here are the steps I took to get this to work:

1- Follow the directions in the WD MyCloud product package to install the drive and the WD Setup software to initially configure it. I’m assuming your Pi’s are all set up with wi-fi access to your network.

2- Next, download and install these two: WD Quick View and WD My Cloud. The first one makes it easy to launch the dashboard from your Mac menu bar and the dashboard lets you configure the drive, for example we’ll need to enable SSH access to the drive (these things are actually little Debian servers).

wd-software-scrnshot

 

 

 

 

 

 

 

 

3- Make sure you can see the drive in the Finder on any Mac connected to your wi-fi network.

4- Click on the WD Quick View icon on your Mac menu and launch the MyCloud dashboard and click on the Settings icon:

wd-mycloud-db-settings

 

 

5- Next, click on Network on the left and then under Network Services, enable SSH. IMPORTANT: write down the username and password in the pop-up window. This will allow you to connect to the server and enable NFS (network file sharing). This is key to writing to the drive from the Raspberry Pi.

6- On any computer connected to your home network open a Terminal window and connect to the NAS:

ssh root@xxx.xx.x.x

Where “xxx.xx.x.x” is the IP address of the NAS drive (this will be on the same screen as step 5 above).

7- Next we’ll edit the exports file with this command:

sudo nano /etc/exports

Add this line to the bottom of the file:

/nfs/Public xxx.xx.xx.x/24(rw,subtree_check,secure)

Where “xxx.xx.xx.x” is the IP address of your router. If you have an Apple router the easiest way to determine it’s IP address is to launch AirPort Utility and click on the router. In my case I have the NAS drive connected to an Apple AirPort Extreme:

Screen-Shot-AirPort

 

When finished hit CTRL X and press ‘Y’ and enter to save and exit.

8- Next step is to SSH into your Raspberry Pi. I’m going to assume you know how to do that. The next step is to edit /etc/fstab on the pi and tell it to mount the NAS drive as a path you’ll use on the pi. For example, if you want to write files on the pi to a directory called /tmp/myfiles, then we’ll mount the NAS as /tmp/myfiles. Any file you write on the pi to /tmp/myfiles will actually be written to the NAS. So type this to edit /etc/fstab on the pi:

sudo nano /etc/fstab

Add this line to the bottom of the file:

xx.x.x.xx:/nfs/Public/myfiles /tmp/myfiles nouser,atime,auto,rw,dev,exec,suid 0 0

Where “xx.x.x.xx” is the IP address of the NAS drive you used in step 6 above. Hit CTRL X and ‘Y’ and Enter to save and exit.

8- Next, this command will mount all partitions in your fstab file:

sudo mount -a

You might get an error, if you do, type this:

sudo rpcbind start

Then repeat the “sudo mount -a” line again.

9- Test this by writing a file to /tmp/myfiles (in this example) and you should see that file on the NAS from any Mac on your network.

That’s it. You should now be able to access the NAS drive from the pi by simply accessing the directory on the pi you assigned as the mount point. This will make more sense if you do a “df -h” on the pi you’ve connected to via SSH.  You’ll see the NAS file system and the mount.

How to back up and restore your Raspberry Pi SD card to your Mac

I periodically take a “snapshot” of my Raspberry Pi’s SD cards, especially before I make a major change, by copying the SD card image to one of my Macs.  Subsequently, that image file gets backed up again by Time Machine running on the Mac. This allows me to return the pi to some determinate state if the card gets corrupted or if I mess something up experimenting.

Note these instructions are for Mac OS X but you can probably figure out other platforms by looking at this page.

These are Terminal commands. Therefore…
DISCLAIMER: if you don’t know what you’re doing on the command line leave this post now. I take no responsibility for you obliterating either your Mac or your SD card. I use both of these procedures on a regular basis but again, you need to understand what you’re doing here, don’t just type away blindly.

Back up the SD card to OS X:

  1. Type “diskutil list” to find the SD Card (it’s helpful to do this before you insert the SD card into your reader, it will be obvious which one is the pi’s SD card). If your Mac doesn’t have an SD card reader you can find a USB card reader fairly cheap, such as this one.
  2. Note the disk number of SD card. I’ll use disk2 in this example.
  3. Type “sudo dd if=/dev/disk2 of=~/Desktop/raspberrypi-[date].img” to create a disc image of the SD card on the desktop.
    Obviously you can supply a directory path there other than Desktop.
    Note: If you are running as a non-admin user on a Mac, type “su <adminusername>” and it will prompt you for the password for that account. This will switch your session to an admin session. Then include the sudo in the command above and type the admin user password again.

Restore the SD card from an OS X back up:

  1. Type “diskutil list” before you insert the card so it’s obvious which one is the SD card.
  2. Insert a blank SD card into the Mac’s SD card reader. If your Mac doesn’t have an SD card reader you can find a USB card reader fairly cheap, such this one.
  3. Type “diskutil list” to find the SD Card to be restored. I’ll use disk2 in this example. Again, you need to know what you’re doing here. Don’t blame me if you wipe out your Mac’s system drive. If you don’t understand these commands don’t type them into a terminal window.
  4. Unmount the SD card with this command: “diskutil unmountDisk /dev/disk2”.
  5. Format the SD Card: “sudo newfs_msdos -F 32 /dev/disk2”. Make damn sure you’ve got the correct disk number.
  6. To restore from the SD card image in the backup sample above: “sudo dd if=~/Desktop/raspberrypi-[date].img of=/dev/disk2”. This may take a very long time and you’ll get no feedback while it’s working. Don’t touch anything until you get the command prompt again, it will give you a summary of the blocks written when it’s complete.

HDMI to DVI not working with Raspberry Pi

Looking to re-use an old Samsung SyncMaster 930B monitor and save some money by avoiding the purchase of an HDMI monitor, I bought a cheap HDMI to DVI cable.  I thought I could re-use the old monitor for development on the Raspberry Pi and avoid dumping the dinosaur at an electronics recycle place.

So the cable arrived and I plugged it in, powered up the pi and… …nothing.  It flashed from “digital” to “analog” and back a few times and then more of nothing.  Messed with the monitor settings, nothing.

So I wondered if there might be a config setting on the pi that might help me.  I started reading up on config.txt (I’m running RASPBIAN (Debian Wheezy)). And sure enough, the solution was to uncomment this line in /boot/config.txt and restart the pi:

hdmi_force_hotplug=1

This line forces the pi to use the HDMI port even if it doesn’t detect a connected display.  Works every time now.

 

Using an AirPort Express to extend your wifi network

On a whim, I bought an Apple AirPort Express to see if I could extend my wifi signal to my backyard.  My existing setup was an Apple AirPort Extreme connected to an Arris cable modem.  Very solid and reliable, but I wanted to do some geeky stuff with a Raspberry Pi on my property and for that, I needed wifi where my current signal was very poor or non-existent.

I had no idea if this would work, I did zero research, I was at Best Buy to buy a new surround sound amplifier and for some reason came up with this idea.

I opened the AirPort Express box and the directions contained nothing about using the device as a network extender.  So I started searching the Web and got a few ideas.  None of them worked.  Including launching the AirPort utility on my iMac.  It saw the Express, but kept getting a general connectivity error that was of no help.  I tried a lot of things like positioning the Express in the same room as the Extreme and even connecting it via an ethernet cable to the Extreme.  Same error.  I reset the Express with a paper clip and tried again while it was connected via wire.  Same error.

After muttering a few choice words I plugged it into an outlet where I originally started this whole exercise, in a location that would give me the best coverage in the far reaches of my property.  I’m not sure why, because this makes no sense, but I picked up my iPhone and launched “settings” then “wifi”.  The AirPort Express was in the list.  I selected it and it asked me if I wanted to extend my current network!  “Well, hell yes”.  It then prompted me for my wifi password and started working.  It was that easy.  If you launch the AirPort Utility on a Mac or any iOS device you’ll see the wifi routers.

I don’t know why this is such a secret but hopefully someone trying this will find this post before they give up.

 

Location of OSMFCCDecoder

I didn’t see any helpful information on this when I did a search so I’m posting this in case it helps anyone looking for the OSMFCCDecoder class mentioned on this page. We’ve had a few customers ask us where this class is after reading that article.

You can find it in the Adobe Media Server installation in this location (on Windows):

C:\Program Files\Adobe\Adobe Media Server 5\samples\osmfcc\OSMFCCLib

So search for Adobe Media Server and install the trial, then look in that folder for the readme.txt file that shows you how to use the code in the OSMFCCLib.swc file you’ll find in that folder.

iPad AirPlay Mirroring not working with Apple TV / Apple TV won’t update

by Charles Newman

If you bought a new Apple TV and AirPlay Mirroring is not working, here’s how I fixed mine:

  1. On the Apple TV, go to settings, general, about and check the software version.  If it’s 2.3, this is your problem.  There is a bug in this version that causes some Apple TV’s to not update to 2.4.  So you can select Update Software all day on the Apple TV and it’s not going to work.
  2. Disconnect the HDMI and power from the Apple TV.
  3. Connect the Apple TV to your iMac or your Mac laptop using a mini USB cable. It will show up in iTunes.
  4. Click the reset “Restore” button (updated after an astute reader corrected me) in iTunes for the Apple TV.  It will reset it to factory settings and install the latest Apple TV firmware.
  5. When the update is finished, iTunes will tell you to disconnect it from your Mac and connect back to your TV. Do that.
  6. Once the Apple TV finishes booting, go back to step 1 above and check the software version.   It should be updated now and mirroring should work.

OSMF – Loading plug-ins locally with the file:/// protocol

Some of you may already know you can load an OSMF plug-in locally using the file protocol like this:

For Mac:

file:///Users/me/Documents/dev/projects/myproject/plugins/SomeOSMFPlugin.swf

For Win:

file:///C:/dev/projects/myproject/plugins/SomeOSMFPlugin.swf

This is very handy when developing a player because you don’t need to copy your player to localhost or a Web server to run and test.

However, I just discovered this oddity:
The plug-in will fail to load if the plug-in is a release build and the player is a debug build.

The failure happens down in the OSMF 1.5 core class DynamicPluginLoader in the onSWFLoaderStateChange method on this line:

var pluginInfo:PluginInfo = root[PLUGININFO_PROPERTY_NAME] as PluginInfo;

Flash Builder clearly shows the pluginInfo property on the root variable but the pluginInfo local variable is null after the above line executes.

This is not an OSMF bug, just something that you need to be aware of. I wasted about 30 minutes on this.

Dynamically loading a SWF and instantiating a Class in that SWF

There are a few blog posts out there on how to do this, but most of them involve a solution that requires a dummy reference in your Application code to the class you wish to instantiate, which forces the compiler to pull in the class, and therefore, allows getDefinition() to work.  But that solution defeats the whole purpose of loading a SWF dynamically.

If you want to load a SWF remotely, and then instantiate a class within that SWF at run-time, you are in the right place.

In the example below, the “application” is Foo and the class we’ll instantiate will be called Bar.  Let’s look at the SWF containing Bar first. Our goal, is to load the SWF that contains Bar and instantiate Bar in our application.

Dynamic.swf

Below is the root level class of the SWF we’ll dynamically load, let’s say it’s called Dynamic.swf. Notice the private var of type Bar. This is necessary to get the compiler to pull the Bar class into our Dynamic.swf. The idea here, is we’ll build Dynamic.swf and put it up on a server somewhere, or localhost so we can test this.

package
{
	import com.charlespatricknewman.sample.Bar;

	import flash.display.Sprite;

	public class Dynamic extends Sprite
	{
		// Need a dummy reference
		private var bar:Bar;

		public function Dynamic()
		{

		}
	}
}

And here is the Bar class we want to instantiate in our Application at run-time:

package com.charlespatricknewman.sample
{
	public class Bar
	{
		public function Bar()
		{
			trace(">>> Bar() constructor!");
		}

		public function doSomething():void
		{
			trace(">>> Bar.doSomething() called!");
		}
	}
}

All this class does is trace out some text, but this is sufficient to prove this is working.

The Application

Next is Foo, the application that will load the SWF and instantiate Bar.  Note this project has no reference or dummy variables of type Bar.

Here is the root level class:

package
{
import com.charlespatricknewman.sample.DynamicClassLoader;

import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;

public class Foo extends Sprite
{
	public function Foo()
	{
		this.addEventListener(Event.ADDED_TO_STAGE,
					onAddedToStage);
	}

	private function onAddedToStage(event:Event):void
	{
		go();
	}

	private function go():void
	{
		var loader:DynamicClassLoader = new DynamicClassLoader();
		setupListeners();
		loader.loadSWF("http://localhost/test/Dynamic.swf",
				"com.charlespatricknewman.sample.Bar");

		function setupListeners(add:Boolean=true):void
		{
			if (add)
			{
				loader.addEventListener(Event.COMPLETE,
					onClassLoaded);
			}
			else
			{
				loader.removeEventListener(Event.COMPLETE,
					onClassLoaded);
			}
		}

		function onClassLoaded(event:Event):void
		{
			setupListeners(false);
			var Bar:Class = loader.instantiateClass(
				"com.charlespatricknewman.sample.Bar");
			var bar:Object = new Bar();
			bar.doSomething();
		}
	}
}
}

And here is the DynamicClassLoader class you see referenced above. This class could reside in the Application SWF or a library (SWC) the application uses at compile time. It’s job is to load the SWF and allow the Application to instantiate a class in the loaded SWF.

package com.charlespatricknewman.sample
{
 import flash.display.Loader;
 import flash.errors.IllegalOperationError;
 import flash.events.Event;
 import flash.net.URLRequest;
 import flash.system.ApplicationDomain;
 import flash.system.LoaderContext;

 public class DynamicClassLoader extends Loader
 {
	public function DynamicClassLoader()
	{
		super();
		contentLoaderInfo.addEventListener(Event.COMPLETE,
						onComplete);
	}

	public function loadSWF(swfPath:String, classPath:String):void
	{
		if (ApplicationDomain.currentDomain.hasDefinition(classPath))
		{
			throw new IllegalOperationError("Class is already loaded!");
		}

		var request:URLRequest = new URLRequest(swfPath);
		var context:LoaderContext = new LoaderContext();

		context.applicationDomain = ApplicationDomain.currentDomain;

		load(request, context);
	}

	public function instantiateClass(classPath:String):Class
	{
		return ApplicationDomain.currentDomain.getDefinition(classPath)
				as Class;
	}

	private function onComplete(event:Event):void
	{
		dispatchEvent(new Event(Event.COMPLETE));
	}
}
}

Due to the security restrictions in the Flash Player, both Dynamic.swf and the Application SWF need to be loaded from either localhost or a web server. You might also need a crossdomain.xml file on the web server, but it’s best to try this from localhost first so you can see it working.

This might be a good solution if you have a SWF or a SWC that contains a large amount of code that is rarely used. Adding that code to your SWF or SWC might cause an unnecessarily large SWF. But loading that bloated Class only when you need it, will provide a much faster initial download and startup for your end users.