Thursday, January 16, 2014

Free OSX iSight Secure Video Streaming with VLC Over SSH using Pipes


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
#create required fifo pipe on trusted host
ssh user@trustedhost.com "mkfifo one_directional_video_channel"

#on the server
  #create fifo pipe to send captured video
    mkfifo myfifo
  #capture video from isight using VLC, transcode it, limit its size and pipe it to your fifo
    /Applications/VLC.app/Contents/MacOS/VLC qtcapture:// --no-drop-late-frames --no-skip-frames --sout='#transcode{vcodec=h264,fps=15,venc=x264{preset=ultrafast,tune=zerolatency,keyint=30,bframes=0,ref=1,level=30,profile=baseline,hrd=cbr,crf=20,ratetol=1.0,vbv-maxrate=1200,vbv-bufsize=1200,lookahead=0}}:standard{access=file,mux=ts,dst=myfifo}' --clock-synchro=1 --sout-ts-shaping=2000 --sout-ts-use-key-frames --qtcapture-width=320 --qtcapture-height=240 --live-caching=200 --intf=macosx
  #pipe the video over the Secure ssh tunnel to the trusted host
    dd if=myfifo | ssh user@trustedhost.com "dd of=one_directional_video_channel"


#on the client
  #fetch the video from the trusted host over ssh and pipe it to vlc
  ssh user@trustedhost.com "dd if=one_directional_video_channel" | /Applications/VLC.app/Contents/MacOS/vlc -

Roll Your Own Free Opensource Secure ChatRoom From The Command Line


chat participants need only have passwordless ssh login to a shared trusted host.

#just fill out the following parameters:

trusted_user_host=user@mydomain.com
chat_username=pick_a_username
chat_room=pick_a_chatroom

#first set up a chat window where chats will be displayed:
  ssh $trusted_user_host "touch $chat_room; tail -f $chat_room" 

#second setup another window for sending in chat messages:
  while read line; do echo "$chat_username: " $line | ssh $trusted_user_host "cat -u >> $chat_room"; done; 

#sample output:

~/Desktop$  ssh $trusted_user_host "touch $chat_room; tail -f $chat_room" 
me:  test
me:  hey
you:  hey back at you
me:  we are chatting without a hassle
you:  we sure are


#to terminate the chat simply  ctrl-c exit the loop:
#Any participant can truncate the chat history at anytime with:
  ssh $trusted_user_host "echo "" > $chat_room"; 
#looks like this in the log:
 tail: mytopic: file truncated 

Tuesday, August 6, 2013

Free OpenSource Secure Voice Communication over SSH using SOX on OSX.

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:


-: (sox)

  Encoding: Signed PCM
  Channels: 2 @ 32-bit
Samplerate: 44100Hz
Replaygain: off
  Duration: unknown


In:0.00% 00:10:02.08 [00:00:00.00] Out:26.6M [      |      ]        Clip:34

  • your days are numbered M$ Skype *

Saturday, May 25, 2013

Sample Android App Maven Pom for Eclipse ADT Bundle


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. 


<project xmlns="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.0 http://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>

Monday, September 17, 2012

EasyMock Partial Mocks FTW. (in progress)

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();

Simple and no extensions necessary.

Distributed Concurrent HTTP Requests in Java. (in progress)


import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;

import org.apache.commons.beanutils.BeanPredicate;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.functors.EqualPredicate;

public class JavaCallable implements Callable {

private Object caller;
String method;
Object[] args;

public JavaCallable(Object caller, String method, Object[] args) {
super();
this.method = method;
this.args = args;
this.caller = caller;

}

@SuppressWarnings("unchecked")
private Method getReflectedMethod() {
List allMethods = Arrays.asList(caller.getClass().getMethods());
List methods = (List) CollectionUtils.select(allMethods, new BeanPredicate("name", new EqualPredicate(method)));
//todo: make this look at argument class types not just argument length.
Method res = (Method) CollectionUtils.find(methods, new Predicate() {
@Override
public boolean evaluate(Object object) {
Method m = (Method) object;
return m.getGenericParameterTypes().length == args.length;
}
});
return res;
}
@Override
public Object call() throws Exception {
return getReflectedMethod().invoke(caller, args);
}
}

//then somewhere else in your code you can distribute get requests like so.


List calls = new ArrayList();
List methods = new ArrayList();
for (HashMap node : nodes) {
GetMethod getMethod = new GetMethod(someUri);
getMethod.setRequestHeader(HTTPLayer.REQUESTHEADERACCEPT);
getMethod.setRequestHeader(HTTPLayer.REQUESTHEADERCONTENTTYPE);
methods.add(getMethod);
calls.add(new JavaCallable(getClient(), "executeMethod", new Object[]{getMethod }));
}
ExecutorService es = Executors.newFixedThreadPool(calls.size());
List> futures = es.invokeAll(calls);
es.shutdown();
//loop through looking for exceptions
for(Future future: futures){
future.get();
}
return methods;

Tuesday, July 24, 2012

untitled

Random data to fit with a fourier transform

data fit with the FFT

    1 # some Discrete and Fast fourier transforms in sage following
    2 # a Gilbert Strang Mit Linear Algebra lecture.
    3 
    4 #http://www.youtube.com/watch?v=M0Sa8fLOajA
    5 #not sure why strang's and everybody else's versions are negative/conjugate of each other, must be a change in convention...
    6 
    7 spacetime_domain = [100*random() for x in range(10)]
    8 
    9 def makeDFTNorm(n, w):
   10     rows = []
   11     for i in range(n):
   12         row = []
   13         for j in range(n):
   14             row.append(w^(-i*j))
   15         rows.append(row)
   16     return (1/sqrt(n))*matrix(rows)    
   17 
   18 def makeDFT(n, w):
   19     rows = []
   20     for i in range(n):
   21         row = []
   22         for j in range(n):
   23             row.append(w^(-i*j))
   24         rows.append(row)
   25     return matrix(rows)    
   26 
   27        
   28 #basis vectors  
   29 var('n,x')
   30 def wfunc(t):
   31     return e^(i*((2*pi)*t))
   32 #fbasis(x, y, z)=(w((-1)*(1/(x*y))*z));#*(1/z)
   33 def basisfunc(x,y,z):
   34     return wfunc((x*y)/z)
   35 
   36 # sage fast dft
   37 def performFFT(spacetime_domain):
   38     var('n,x')
   39     print "spacetime_domain data"
   40     print spacetime_domain
   41     n = len(spacetime_domain)
   42     #frequency_domain=vector(map(conjugate, vector(CDF, spacetime_domain).fft().list())).transpose();
   43     frequency_domain=vector(CDF, spacetime_domain).fft().transpose()
   44     print "real frequency domain "
   45     print map(lambda x: round(x.real_part(), 10), frequency_domain.list())
   46     #invdft = vector(map(conjugate, vector(map(conjugate, frequency_domain.list())).fft(direction='backward'))).transpose()
   47     invdft = vector(frequency_domain.list()).fft(direction='backward').transpose()
   48     reconstructed = map(real_part, invdft.list())
   49     plota = points([ (k, spacetime_domain[k]) for k in range(len(spacetime_domain)) ], rgbcolor=(1, 0, 0))
   50     plotb = points([ (k, reconstructed[k]) for k in range(len(reconstructed)) ], rgbcolor=(0, 1, 1))
   51     print "perfect point reconstruction"
   52     show(plota + plotb)
   53     var('axis')
   54     print axis
   55     basisVector = vector([basisfunc(axis,y,n) for y in range(n)])
   56     print basisVector.transpose()  
   57     #simplify/round frequency_domain for speedy plotting
   58     #frequency_domain = vector([round(frequency_domain.list()[l].real_part(), 10) + i*round(frequency_domain.list()[l].imag_part(), 10) for l in range(len(frequency_domain.list()))]).transpose()
   59     allBasesWithWeights=(basisVector*frequency_domain*(1/n)).list()[0].real_part()
   60     allBasesNoWeights=sum(basisVector*(1/n)).real_part()
   61     plotc = plot(allBasesWithWeights, xmin=0, xmax=n, color='red')
   62     plotd = plot(allBasesNoWeights, xmin=0, xmax=n, color='green')
   63     print "perfect point curve fitting"
   64     show(plota+plotb+plotc+plotd)
   65     var('n,x')
   66 
   67 
   68 performFFT(spacetime_domain)
   69 
   70 # strang slow DFT
   71 def performDFT(spacetime_domain):
   72     var('n,x')
   73     print "spacetime_domain data"
   74     print spacetime_domain
   75     n=len(spacetime_domain)
   76     myDFT=makeDFT(n, wfunc(1/n))
   77     frequency_domain=myDFT*(vector(CDF, spacetime_domain).transpose())
   78     print "real frequency domain "
   79     print map(lambda x: round(x.real_part(), 10), frequency_domain.list())
   80     myDFTH = Matrix(CDF, n,n, [x.conjugate() for x in myDFT.transpose().list()])
   81     invdft=(myDFTH*frequency_domain*(1/n))
   82     reconstructed = map(lambda x: round(x.real_part(), 10), invdft.list())
   83     print "perfect point reconstruction"
   84     #print reconstructed
   85     plota = points([ (k, spacetime_domain[k]) for k in range(len(spacetime_domain)) ], rgbcolor=(1, 0, 0))
   86     plotb = points([ (k, reconstructed[k]) for k in range(len(reconstructed)) ], rgbcolor=(0, 1, 1))
   87     show(plota + plotb)
   88     var('axis')
   89     print axis
   90     basisVector = vector([basisfunc(axis,y,n) for y in range(n)])
   91     print basisVector.transpose()
   92     #simplify/round frequency_domain for speedy plotting
   93     #frequency_domain = vector([(round(frequency_domain.list()[x].real_part(), 10) + i*round(frequency_domain.list()[x].imag_part(), 10)) for x in range(len(frequency_domain.list()))]).transpose()    
   94     allBasesWithWeights=(basisVector*frequency_domain*(1/n)).list()[0].real_part()
   95     allBasesNoWeights=sum(basisVector*(1/n)).real_part()
   96     plotc = plot(allBasesWithWeights, xmin=0, xmax=n, color='red')
   97     plotd = plot(allBasesNoWeights, xmin=0, xmax=n, color='green')
   98     print "perfect point curve fitting"
   99     show(plota+plotb+plotc+plotd)
  100     var('n,x')
  101 
  102 #performDFT(spacetime_domain)