title: iPhone AVPlayer Streaming from Remote URL in PhoneGap
body: <p>We are working on getting audio streaming from a remote URL in a iPhone application using a PhoneGap plugin written in Obj-C. For some reason, it is not playing the audio through the speakers, it only plays through headphones. We've tried using AVAudioPlayer with no luck. Do I need to set the audio output somewhere?</p>
  
  <pre><code>--CharStream.m--
  
  #import "CharStream.h"
  #import "AppDelegate.h"
  
  @implementation CharStream
  
  -(CDVPlugin*) initWithWebView:(UIWebView*)theWebView {
      self = (CharStream*)[super initWithWebView:theWebView];
      return self;
  }
  
  -(void) loadPlaylist:(NSArray*)arguments withDict:(NSMutableDictionary *)options {
      //currentSong = 0;
      //playlist = [[arguments objectAtIndex:currentSong] objectFromJSONString];
      item = [[AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://music.clayfreeman.com/music/Hybrid%20Minds%20-%20Inner%20Beauty.m4a"]] retain];
      [item addObserver:self forKeyPath:@"playbackBufferEmpty" options:0 context:nil];
      [item addObserver:self forKeyPath:@"status" options:0 context:nil];
      player = [[AVPlayer alloc] initWithPlayerItem:item];
      [player addObserver:self forKeyPath:@"status" options:0 context:nil];
      NSLog(@"Loading song.");
  }
  
  -(void) play:(NSArray*)arguments withDict:(NSMutableDictionary *)options {
      [self play];
  }
  
  -(void) play {
      [player play];
  }
  
  -(void) pause:(NSArray*)arguments withDict:(NSMutableDictionary *)options {
      [player pause];
  }
  
  -(void) nextSong:(NSArray*)arguments withDict:(NSMutableDictionary *)options {
      [self nextSong];
  }
  
  -(void) nextSong {
      currentSong++;
      item = [[AVPlayerItem playerItemWithURL:[NSURL URLWithString:[playlist objectAtIndex:currentSong]]] retain];
      [item addObserver:self forKeyPath:@"status" options:0 context:nil];
      [item addObserver:self forKeyPath:@"playbackBufferEmpty" options:0 context:nil];
      player = [AVPlayer playerWithPlayerItem:item];
  }
  
  -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
      if ([object isKindOfClass:[AVPlayerItem class]]) {
          AVPlayerItem* changedItem = (AVPlayerItem *)object;
          if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {
              [item removeObserver:self forKeyPath:@"playbackBufferEmpty"];
              [self nextSong];
              NSLog(@"Song over. Moving to next item.");
          } else if ([keyPath isEqualToString:@"status"]) {
              if (changedItem.status == AVPlayerItemStatusFailed) {
                  [item removeObserver:self forKeyPath:@"status"];
                  [self nextSong];
                  NSLog(@"Item failed. :( Moving to next item.");
              } /*else if (changedItem.status == AVPlayerItemStatusReadyToPlay) {
                  [self play];
                  NSLog(@"Item is ready to play.");
              }*/
          }
      } else if ([object isKindOfClass:[AVPlayer class]]) {
          AVPlayer* playerLol = (AVPlayer *) object;
          if ([keyPath isEqualToString:@"status"]) {
              if (playerLol.status == AVPlayerStatusReadyToPlay) {
                  [self play];
              }
          }
      }
  }
  
  @end
  
  
  --CharStream.h--
  
  #import &lt;AVFoundation/AVFoundation.h&gt;
  
  #ifdef CORDOVA_FRAMEWORK
  #import &lt;Cordova/CDVPlugin.h&gt;
  #else
  #import "CDVPlugin.h"
  #endif
  
  @interface CharStream : CDVPlugin {
      NSMutableArray* playlist;
      AVPlayerItem* item;
      int currentSong;
      AVPlayer* player;
  }
  
  -(CDVPlugin*) initWithWebView:(UIWebView*)theWebView;
  -(void)loadPlaylist:(NSArray*)arguments withDict:(NSMutableDictionary*)options;
  -(void)pause:(NSArray*)arguments withDict:(NSMutableDictionary*)options;
  -(void)play:(NSArray*)arguments withDict:(NSMutableDictionary*)options;
  -(void)play;
  -(void)nextSong:(NSArray*)arguments withDict:(NSMutableDictionary*)options;
  -(void)nextSong;
  
  @end
  
  
  --CharStream.js--
  function CharStream() {
      this.init = true;
  };
  
  CharStream.prototype.loadPlaylist = function(array, options) {
      Cordova.exec("CharStream.loadPlaylist", array, options);
  };
  
  CharStream.prototype.pause = function(options) {
      Cordova.exec("CharStream.pause", options);
  };
  
  CharStream.prototype.play = function(options) {
      Cordova.exec("CharStream.play", options);
  };
  
  CharStream.prototype.nextSong = function(options) {
      Cordova.exec("CharStream.nextSong", options);
  };
  
  Cordova.addConstructor(function() 
  {
      if(!window.plugins)
      {
          window.plugins = {};
      }
      window.plugins.CharStream = new CharStream();
  
  });
  </code></pre>