Using Java to mimic an Airplay Server

This is a brief outline of how to write a basic airplay server in Java. There has been some very interesting work already been done with regard to writing custom airplay servers that can be used to stream content from your iPhone. The following code is a basic outline of how to write a Java based application that listens for incoming airplay connections and allows the video url to be extracted.

Register the airplay service

On the command line, run the following command. With this service registered, the entry MyAirplayService should appear as an airplay option on your iPhone.

mDNS -R MyAirplayService _airplay._tcp local 22555

Listen for Connections

   public listener(){

            int port =22555
            while (true) {
                providerSocket = new ServerSocket(port);
                Socket s = providerSocket.accept();
                while (true) {
                    byte[] ba = read(s);
                    if (ba.length > 0) {
                        String read = new String(ba);
                        if (read.indexOf(“/reverse”) != -1) {

                            String response = “HTTP/1.1 101 Switching Protocols\r\nDate: “
                                    + new Date()
                                    + “\r\nUpgrade: PTTH/1.0\r\nConnection: Upgrade\r\n\r\n”;

                            write(s, response.getBytes());
                            s = providerSocket.accept();
                        } else if (read.indexOf(“POST /scrub”) != -1) {
                            String response = “HTTP/1.1 200 OK\r\n” + “Date: “
                                    + new Date() + “\r\n”
                                    + “Content-Length: 0\r\n\r\n”;
                            
                            write(s, response.getBytes());

                        } else if (read.indexOf(“POST /play HTTP/1.1″) != -1) {
                            //the play http packet should contain the video url
                            String url = getUrl(read);
                            String startPos = getStartPos(read);
                            break;
                       
                        }
                    }
                    Thread.sleep(1000);
                }
                s.shutdownInput();
                s.shutdownOutput();
                s.close();
                providerSocket.close();

            }
   }

    private void write(Socket s, byte[] bytes) throws Exception {
        OutputStream os = s.getOutputStream();
        os.write(bytes);
    }

 

    private byte[] read(Socket s) throws Exception {
        InputStream is = s.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        while (is.available() > 0) {
            System.out.println(is.available());
            byte[] ba = new byte[10000];
            int read = is.read(ba);
            while (read > 0) {
                baos.write(ba, 0, read);
                if (is.available() > 0) {
                    read = is.read(ba);
                } else {
                    read = 0;
                }
            }
        }
        return baos.toByteArray();
  }

 

The ServerSocket is registered to listen on the same socket that is being broadcast by the multicast DNS service (mDNS). When the socket receives an the reverse directive we respond with a 101 and set the socket to listen for the new connection. When the “POST /play HTTP/1.1″ http packet is received we can extract the published stream url.

 

About these ads
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s