This is the final piece required to replace the need for Skype with only opensource and free tools on mac OSX. I'll put another post together to link all the pieces soon.
#prep
#install VLC on both isight video server and client machines
#create passwordless ssh login to a trusted host so both client and server have scriptable access
This post details a method to send and receive audio simply and securely over the net using opensource free standard command line tools.
What makes this approach powerful is that clients need only setup ssh key-based passwordless authentication to a trusted server of their choosing in the usual way, so that they can read from the fifo over an ssh tunnel. No proprietary closed source software or intermediary is needed for this communication, and once ssh public keys are added to .ssh/authorized_keys on the trusted host for a the given user, no man in the middle is possible.
Your system requires:
[sox – Sound eXchange](http://sox.sourceforge.net/) (or any tool that can pipe audio streams to plain unix fifo pipes)
[openssh](http://www.openssh.org/)
[dd] (you probably already have this, its been standard on computers since before I was born)
I use the following to make that trivial to setup
OSX 10.6+
[macports](http://sox.sourceforge.net/)
sudo port install openssh
sudo port install sox
But it’s easy to see how this could work on any linux/unix system as well.
In order to allow any computer to talk to any other its best to setup a proxy somewhere out on the net
that both the client and server have ssh access to.
>First ssh to the intermediary server and make a fifo pipe that the sound will travel through:
ssh user@myserver.com "mkfifo one_directional_voice_channel"
>Then on the sound receiving client side where you want to play the sound back:
ssh user@myserver.com "dd if=one_directional_voice_channel" | sox -p -d --buffer 32
>Next on the sound transmission end with the microphone you want to send the audio from simply:
sox -d -p --buffer 32 | ssh user@myserver.com "dd of=one_directional_voice_channel"
> Presto. done. On my computer, the default sound input device is the microphone so my voice immediately starts being relayed across the net to the client over the ssh tunnel.
***Well you do need to setup another channel in the other direction for two way voice communication but that's it.
Starting the client listener first ensures the buffers are empty so there is no lag between sending and receiving sound. In my tests a voice stream from my location to a server 1500km away and back has a delay of less than 1 sec.
If it's working you should see an output similar to this:
I've learned it's best to download the ADT bundle rather than try to add the ADT plugin to an existing eclipse install.
http://developer.android.com/sdk/index.html
This version seems to have good performance on mac too.
Android Developer Tools
Build: v22.0.0-675183
Just create a sample Android application using the usual eclipse menus.
Then convert to maven use m2e-android
then edit with the following to get it to work at the command line.
Then update project settings from the maven context menu.
you can now deploy to emulator and usb with the following command lines.
mvn clean install android:redeploy -Dandroid.device=emulator android:run -X -Dandroid.ndk.path=/opt/local/share/java/android-ndk-macosx -Dandroid.sdk.path=/opt/local/share/java/android-sdk-macosx/
mvn clean install android:redeploy -Dandroid.device=usb android:run -X -Dandroid.ndk.path=/opt/local/share/java/android-ndk-macosx -Dandroid.sdk.path=/opt/local/share/java/android-sdk-macosx/
or run as Android Application in the usual way in eclipse.
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>SupportAppNavigation</groupId><artifactId>SupportAppNavigation</artifactId><version>0.0.1-SNAPSHOT</version><packaging>apk</packaging><properties><platform.version>4.1.1.4</platform.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>com.google.android</groupId><artifactId>android</artifactId><version>${platform.version}</version><scope>provided</scope></dependency><dependency><groupId>com.google.android</groupId><artifactId>annotations</artifactId><version>${platform.version}</version></dependency><dependency><groupId>com.google.android</groupId><artifactId>support-v4</artifactId><version>r7</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.1</version></dependency></dependencies><build><finalName>${project.artifactId}</finalName><sourceDirectory>src</sourceDirectory><pluginManagement><plugins><plugin><groupId>com.jayway.maven.plugins.android.generation2</groupId><artifactId>android-maven-plugin</artifactId><version>3.6.0</version><extensions>true</extensions></plugin></plugins></pluginManagement><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version><configuration><source>1.6</source><target>1.6</target></configuration></plugin><plugin><groupId>com.jayway.maven.plugins.android.generation2</groupId><artifactId>android-maven-plugin</artifactId><version>3.6.0</version><configuration><androidManifestFile>${project.basedir}/AndroidManifest.xml</androidManifestFile><assetsDirectory>${project.basedir}/target/assets</assetsDirectory><classifier>${classifier}</classifier><resourceDirectory>${project.basedir}/res</resourceDirectory><nativeLibrariesDirectory>${project.basedir}/src/main/native</nativeLibrariesDirectory><sdk><platform>17</platform></sdk><sign><debug>true</debug></sign><undeployBeforeDeploy>true</undeployBeforeDeploy></configuration><extensions>true</extensions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><version>2.5.1</version></plugin></plugins></build></project>
Ever wanted to mock certain methods in a class but not all? Unit Testing in Java got a whole lot easier when I discovered this trick.
ClassToMock classToMockPartialMock = EasyMock .createMockBuilder(ClassToMock.class) //create builder first .addMockedMethod("meth1") .addMockedMethod("meth2") //note unspecified methods are not mocked and can be called directly! .addMockedMethod("meth4") .createMock();