/Airstream

A framework for streaming audio between Apple devices using AirPlay.

Primary LanguageObjective-CMIT LicenseMIT

Airstream

An iOS / macOS framework for streaming audio between Apple devices using AirPlay.

An example gif

You can use Airstream to start an AirPlay server in your iOS or macOS applications. Then, any Apple device can stream audio to your application via AirPlay, with no extra software required.

Table of contents

Installation

Airstream can be installed by using either Carthage or just simply cloning this repository and its submodules in your project.

Carthage

Carthage is a decentralized dependency manager for Cocoa.

You can install it using Homebrew with the following commands:

$ brew update
$ brew install carthage

Then, to include Airstream in your project, specify it in your Cartfile (make sure it's in the same directory as your .xcodeproj):

github "qasim/Airstream" ~> 0.1

Now you can install Airstream:

$ carthage update

You should now see a Carthage/Builds directory. From there, you can drag the built Airstream.framework for your platform of choice into your Xcode project, and then add it as an embedded binary in your project's settings.

Basic usage

First, initialize and start Airstream somewhere (make sure that it's retained). You'll also want to set its delegate.

let airstream = Airstream(name: "My Airstream")

airstream.delegate = self
airstream.startServer()

That's it! Your own AirPlay server is now up and running. You can gracefully shut it down as well:

airstream.stopServer()

Implement any of the delegate methods to actually make use of Airstream's features, like retrieving a song's album artwork:

func airstream(airstream: Airstream, didSetCoverart coverart: NSData) {
  // Coverart for the item that's currently streaming
  let image = NSImage(data: coverart)
}

For a more detailed example on how to use Airstream, you can refer to the example projects which implement Airstream with the streamed audio output going directly to speakers via CoreAudio:

API reference

Airstream

This is the main class, from which you can start and stop the AirPlay server.

func init()
func init(name: String?)
func init(name: String?, password: String?)
func init(name: String?, password: String?, port: UInt)

Basic initializers for the Airstream.

func startServer()

Starts the AirPlay server and begins broadcasting.

func stopServer()

Gracefully shuts down the AirPlay server.

var name: String

The AirPlay server's receiver name. This is what is shown to devices when they go to connect to your AirPlay server. "My Airstream" by default.

var password: String?

The AirPlay server's receiver password. You can set this to prompt any Apple devices that wish to connect to your AirPlay server with a password challenge.

var port: UInt

The port where the AirPlay server should broadcast to. 5000 by default.

var running: Bool

Determines whether the server is currently running or not.

var remote: AirstreamRemote?

The reference to this Airstream's remote control object, which can be used to send commands to the connected device. This variable may not be set until the delegate has called airstream:didGainAccessToRemote:.

var volume: Float?

The connected Apple device's volume, between 0.0 (no volume) and 1.0 (maximum volume).

var metadata: [String: String]?

The metadata for the current item being streamed.

var coverart: Data?

The JPEG artwork (in binary) for the current item being streamed.

var position: UInt

The position (in seconds) of the current item being streamed.

var duration: UInt

The total duration (in seconds) of the current item being streamed.

AirstreamDelegate

This is the delegate class for Airstream. By conforming to this protocol, you can listen for changes in AirPlay server status and be notified when data changes.

optional func airstream(_ airstream: Airstream, willStartStreamingWithStreamFormat streamFormat: AudioStreamBasicDescription)

Called right after a device has connected and is about to stream audio. AudioStreamBasicDescription is a struct outlining the details of the audio output.

optional func airstreamDidStopStreaming(_ airstream: Airstream)

Called right after a device has disconnected.

optional func airstream(_ airstream: Airstream, didGainAccessToRemote remote: AirstreamRemote)

Called right after the remote control connection has been setup.

optional func airstream(_ airstream: Airstream, processAudio buffer: UnsafeMutablePointer<Int8>, length: Int32)

Process linear PCM audio streamed from a device. buffer is a pointer to the audio data, and length is the number of bytes stored there.

optional func airstreamFlushAudio(_ airstream: Airstream)

Reset any audio output buffers you may be using, as the source has either changed or been disrupted.

optional func airstream(_ airstream: Airstream, didSetVolume volume: Float)

Called when a device's volume was changed.

optional func airstream(_ airstream: Airstream, didSetMetadata metadata: [String: String])

Called when a device's metadata for the current item being streamed was changed.

optional func airstream(_ airstream: Airstream, didSetCoverart coverart: Data)

Called when a device's artwork for the current item being streamed was changed.

optional func airstream(_ airstream: Airstream, didSetPosition position: UInt, duration: UInt)

Called when a device's current position or duration for the current item being streamed was changed.

AirstreamRemote

This is the remote control object. If this is present on the Airstream object, then you will be able to send commands to the device connected to your AirPlay server.

func play()

Start playback.

func pause()

Pause playback.

func stop()

Stop playback.

func playPause()

Toggle between starting and pausing playback.

func playResume()

Play after fast forwarding or rewinding.

func forward()

Begin fast forward.

func rewind()

Begin rewind.

func nextItem()

Play next item in playlist.

func previousItem()

Play previous item in playlist.

func shuffle()

Shuffle items in playlist.

func increaseVolume()

Turn audio volume up.

func decreaseVolume()

Turn audio volume down.

func toggleMute()

Toggle mute status.

Shairplay

Airstream works by depending on a C library called shairplay, which is a free portable AirPlay server implementation. You can also visit qasim/shairplay for the fork of shairplay that is used by Airstream, which compiles on both iOS and macOS.

Disclaimer

This framework is really meant for educational purposes only. I hold no guarantee that integrating this framework into your application will allow you to pass Apple's app review process.

License

Airstream is released under the MIT license. See LICENSE for details.