title: WOWZA to IOS - How to Live Stream
body: <p>So far i almost developed a Flash Air for IOS App and i was 50% done. I got all the live streaming to work with RED5 Media Server but came to a Dead End when i found that the iPhone Camera was displaying 90 degrees so the stream being sent and saved to the RED5 Server was also recorded 90 degrees. I read lots of articles online even on Stack Overflow that this is a known Bug. Not sure when this will be fixed. I also tried some ANE Air Native Extensions that would work the camera rotation in my Air App, these were the DiaDraw and StarlingCamera ANE, but could not find any information tutorial, online so could not get this to work.</p>
  
  <p>Flash Adobe Air for IOS code that connects to RED5 Server and shows tat the iPhone Camera is 90 degrees: </p>
  
  <pre><code>import flash.display.DisplayObject;
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  import flash.events.ActivityEvent;
  import flash.events.MouseEvent;
  import flash.media.Camera;
  import flash.media.Video;
  import flash.events.NetStatusEvent;
  import flash.net.NetStream;
  import flash.net.NetConnection;
  
   var nc:NetConnection;
   var cam:Camera;
   var vid:Video;
   var nsOut:NetStream;
   var nsIn:NetStream;
  
  
  
  
          // support autoOrients
          stage.align = StageAlign.TOP_LEFT;
          stage.scaleMode = StageScaleMode.NO_SCALE;
          cam = Camera.getCamera();
          cam.setMode(320, 300, 25); 
          cam.setQuality(0,100);
          if (!cam) 
          {
              txt.text ="No camera is installed.";
          }
          else 
          {
  
              nc = new NetConnection(); 
              nc.connect("rtmp://192.168.1.5/RED5Hugt");
              nc.addEventListener(NetStatusEvent.NET_STATUS,getStream);     
              nc.client = this;
  
  
              //connectCamera();
          }
  
      function getStream(e:NetStatusEvent):void
      {
  
          connectCamera();
          nsIn = new NetStream(nc); 
          nsOut = new NetStream(nc); 
  
          vid.attachNetStream(nsIn);
          nsIn.play("tester");
  
           nsOut=new NetStream(nc);
           netOut.attachAudio(mic);
           nsOut.attachCamera(cam);
           nsOut.publish("tester", "live");
  
  
      // add click event to record button
      // add event for stage video render state
      }
  
       function connectCamera():void 
      {
          vid             = new Video();
          vid.width       = cam.width;
          vid.height      = cam.height; 
          vid.x = 0;
          vid.y = 0;
          vid.attachCamera(cam);
          addChild(vid);    
  
          //stage.addEventListener(MouseEvent.CLICK, clickHandler);
      }
  
       function clickHandler(e:MouseEvent):void 
      {
  
          return;
  
          switch (cam.width) {
              case 160:
                  cam.setMode(320, 240, 10); 
                  break;
              case 320:
                  cam.setMode(640, 480, 5); 
                  break;
              default:
                  cam.setMode(160, 120, 15); 
                  break;
          } 
          removeChild(vid);           
          connectCamera();
      }
  </code></pre>
  
  <p>RED5 server code:</p>
  
  <pre><code>package com;
  
  
  
  import java.lang.reflect.Array;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Hashtable;
  
  import org.red5.server.adapter.ApplicationAdapter;
  import org.red5.server.adapter.MultiThreadedApplicationAdapter;
  import org.red5.server.api.IClient;
  import org.red5.server.api.IConnection;
  import org.red5.server.api.Red5;
  import org.red5.server.api.scope.IScope;
  import org.red5.server.api.service.IPendingServiceCall;
  import org.red5.server.api.service.IPendingServiceCallback;
  import org.red5.server.api.service.IServiceCapableConnection;
  import org.red5.server.api.service.IServiceHandlerProvider;
  import org.red5.server.api.stream.IBroadcastStream;
  import org.red5.server.api.stream.IServerStream;
  import org.red5.server.api.stream.support.SimplePlayItem;
  import org.red5.server.api.stream.support.StreamUtils;
  import org.red5.server.stream.ClientBroadcastStream;
  import org.red5.server.stream.RecordingListener;
  
  import static java.lang.System.*;
  
  
  public class Application extends  MultiThreadedApplicationAdapter{
  //private static final Log log = LogFactory.getLog( Application.class );
  private IBroadcastStream serverStream;
  
  
  @Override
  public boolean appStart(IScope scope)
  {
      if(!super.appStart(scope))
      {
          return false;
      }
      else
      {
          super.appStart(scope);
          return true;
      }
  }
  
  @Override
  public void appStop(IScope scope)
  {
  
  }
  
  //User connecting/disconnecting to/from application
  @Override
  public boolean appConnect(IConnection connection, Object[] parameters) {
  
      super.appConnect(connection, parameters);
      //connection.getClient().setAttribute("userName", parameters[0]);
      return true;
  }
  
  @Override
  public void appDisconnect(IConnection connection) {
      super.appDisconnect(connection);
  }
  
  
  //User joining/leaving scope
  @Override
  public boolean appJoin(IClient client, IScope scope) 
  {
      super.appJoin(client, scope);
      return true;
  }
  
  @Override
  public void appLeave(IClient client, IScope scope)
  {
      super.appLeave(client,scope);
  }
  
  
  public boolean connect(IConnection conn, IScope scope, Object[] params) {
  
      super.connect(conn, scope, params);
  
      return true;
  }
  
  
  }
  </code></pre>
  
  <p>So Then i decided to stream natively, and i used the Media and CommLib libraries in objective-c and found this code, i pasted this on Pastebin because there was too much code to edit when pasting on here:  </p>
  
  <p>This is the RTMP CLIENT which successfully connects to RED5 Java Application Adapter running on another PC.</p>
  
  <p><a href="http://pastebin.com/0KQvTL0b" rel="nofollow">http://pastebin.com/0KQvTL0b</a></p>
  
  <p>When running the RTMP CLIENT using Xcode, the App was streaming live but every few seconds the Audio would glitch and i couldn't find anything that could fix this issue, maybe i needed to alter some code but i found this RTMP CLIENT code online and modified the Stream Name and RTMP Url to point to my Application on the RED5 server.</p>
  
  <p>Why does the audio keep glitching. So now i feel like giving WOWZA Media Server a go.</p>
  
  <p>So far i download the Wowza Media Server then installed Eclipse. Once Eclipse was installed i then installed the Wowza IDE which i intalled in Eclipse but make sure you install the Wowza Media Server first before installing the Wowza IDE.</p>
  
  <p>I then found some code online which would be the Server running on the Wowza Server, the new Wowza Server is run in the browser, i tried running this in the Terminal but couldn't get it running as it kept saying "Operation could not run" in the terminal.</p>
  
  <p>This is the code i used for the Server:</p>
  
  <pre><code>package com;
  
  import com.wowza.wms.application.*;
  import com.wowza.wms.amf.*;
  import com.wowza.wms.client.*;
  import com.wowza.wms.module.*;
  import com.wowza.wms.request.*;
  import com.wowza.wms.stream.*;
  import com.wowza.wms.rtp.model.*;
  import com.wowza.wms.httpstreamer.model.*;
  import com.wowza.wms.httpstreamer.cupertinostreaming.httpstreamer.*;
  import com.wowza.wms.httpstreamer.smoothstreaming.httpstreamer.*;
  
  public class RED5Hugt extends ModuleBase {
  
  public void doSomething(IClient client, RequestFunction function,
          AMFDataList params) {
      getLogger().info("doSomething");
      sendResult(client, params, "Hello Wowza");
  }
  
  public void onAppStart(IApplicationInstance appInstance) {
      String fullname = appInstance.getApplication().getName() + "/"
              + appInstance.getName();
      getLogger().info("onAppStart: " + fullname);
  }
  
  public void onAppStop(IApplicationInstance appInstance) {
      String fullname = appInstance.getApplication().getName() + "/"
              + appInstance.getName();
      getLogger().info("onAppStop: " + fullname);
  }
  
  public void onConnect(IClient client, RequestFunction function,
          AMFDataList params) {
      getLogger().info("onConnect: " + client.getClientId());
  }
  
  public void onConnectAccept(IClient client) {
      getLogger().info("onConnectAccept: " + client.getClientId());
  }
  
  public void onConnectReject(IClient client) {
      getLogger().info("onConnectReject: " + client.getClientId());
  }
  
  public void onDisconnect(IClient client) {
      getLogger().info("onDisconnect: " + client.getClientId());
  }
  
  public void onStreamCreate(IMediaStream stream) {
      getLogger().info("onStreamCreate: " + stream.getSrc());
  }
  
  public void onStreamDestroy(IMediaStream stream) {
      getLogger().info("onStreamDestroy: " + stream.getSrc());
  }
  
  }
  </code></pre>
  
  <p>So now i run the Xcode Project the RTMP CLIENT and find that the RTMP CLIENT does connect but i don't get no Live Stream. Just wanted to ask where i need to change my code in order to get the live streaming to work?</p>
  
  <p>Also with my experience using Adobe Air for IOS and using RED5, Should i be taking this last route because I'm not sure. I have researched a lot and really i want to find the no cost way of knowing how to stream from IPhone camera. I have tried Adobe for IOS to RED5 Server and found the there is a known Bug and i have tried Native to RED5 and found the Audio Glitch so is Wowza the best bet? </p>
  
  <h2>UPDATE</h2>
  
  <p>I get an output in Xcode console that the stream could not be found, here is the output:</p>
  
  <pre><code>2014-07-30 13:33:06.246 RTMPStreamComeback[340:4003]  $$$$$$ &lt;MPIMediaStreamEvent&gt; stateChangedEvent: sender = MediaStreamPlayer, 4 = NetStream.Play.StreamNotFound
  </code></pre>
  
  <p>I have set the UpStream name "tester" and the DownStream name "tester"</p>
  
  <h2>Update</h2>
  
  <p>The Streaming now works i found this tutorial online and found that i needed to include the Application.xml and configure the file. Here is the tutorial:</p>
  
  <pre><code>https://www.youtube.com/watch?v=XoojcVfdHWg
  </code></pre>
  
  <p>But again just like RED5 the Audio seems to glitch, but the stream never gets disrupted apart from the audio.</p>
  
  <p>How can i FIX this?</p>
  
  <p>This is the trace from Xcode:</p>
  
  <pre><code>                   2014-07-30 15:19:48.296 RTMPStreamComeback[397:60b] connectControl: host = rtmp://192.168.1.4:1935/RED5Hugt
  2014-07-30 15:19:49.325 RTMPStreamComeback[397:60b] Video encoding is initialized: bit_rate = 272000, rc_max_rate = 0, rc_min_rate = 0, qmin=2, qmax=31, qcompress=0.500000
  2014-07-30 15:19:49.334 RTMPStreamComeback[397:60b] AudioCodec: codecID = 86050, codecType = 42, bitRate = 16000, _sampleBytes = 4
  encoder supports the sample formats:
  flt, 
  audio codec best options: sample_rate = 44100
  2014-07-30 15:19:49.340 RTMPStreamComeback[397:60b] audio codec context: codec_type = 1, sample_fmt = flt, bit_rate = 16000, sample_rate = 16000, channels = 1, frame_bits = 4, channel_layout = 0, frame_size = 0, buffer_size = 256
  2014-07-30 15:19:49.344 RTMPStreamComeback[397:60b] initVideoCapture -&gt; preset AVCaptureSessionPresetLow is supported, orientation = 3
  2014-07-30 15:19:49.414 RTMPStreamComeback[397:60b] BroadcastStreamClient STREAM ----&gt; name: tester, type: 2, [socket retainCount] = 3
  2014-07-30 15:19:49.789 RTMPStreamComeback[397:60b]  $$$$$$ &lt;MPIMediaStreamEvent&gt; stateChangedEvent: sender = BroadcastStreamClient, 1 = RTMP.Client.isConnected
  2014-07-30 15:19:49.831 RTMPStreamComeback[397:3f03]  $$$$$$ &lt;MPIMediaStreamEvent&gt; stateChangedEvent: sender = BroadcastStreamClient, 2 = RTMP.Client.Stream.isCreated
  2014-07-30 15:19:50.585 RTMPStreamComeback[397:3f03]  $$$$$$ &lt;MPIMediaStreamEvent&gt; stateChangedEvent: sender = BroadcastStreamClient, 3 = NetStream.Publish.Start
  [flv @ 0x1883d000] Error, Invalid timestamp=0, last=0
  [flv @ 0x1883d000] Error, Invalid timestamp=0, last=0
  [flv @ 0x1883d000] Error, Invalid timestamp=0, last=0
  2014-07-30 15:20:01.677 RTMPStreamComeback[397:60b] publishControl: stream = slavav
  2014-07-30 15:20:01.680 RTMPStreamComeback[397:60b] NellyMoserDecoder -&gt; audio codec context: codec_type = 1, sample_fmt = flt, bit_rate = 16000, sample_rate = 16000, channels = 1, frame_bits = 4, channel_layout = 0, frame_size = 0
  2014-07-30 15:20:01.681 RTMPStreamComeback[397:60b] Set Player's Framework -&gt; 'AudioUnit'
  2014-07-30 15:20:01.685 RTMPStreamComeback[397:60b] VideoStream decoding is initialized: context-&gt;pix_fmt = 0, width = 0, height = 0
  2014-07-30 15:20:01.689 RTMPStreamComeback[397:60b]  $$$$$$ &lt;MPIMediaStreamEvent&gt; stateChangedEvent: sender = MediaStreamPlayer, 1 = RTMP.Client.isConnected
  2014-07-30 15:20:01.712 RTMPStreamComeback[397:3f03]  $$$$$$ &lt;MPIMediaStreamEvent&gt; stateChangedEvent: sender = MediaStreamPlayer, 2 = RTMP.Client.Stream.isCreated
  2014-07-30 15:20:01.758 RTMPStreamComeback[397:3f03]  $$$$$$ &lt;MPIMediaStreamEvent&gt; stateChangedEvent: sender = MediaStreamPlayer, 3 = NetStream.Play.Start
  [flv @ 0x1808c600] Bad picture start code
  [flv @ 0x1808c600] header damaged
  2014-07-30 15:20:01.764 RTMPStreamComeback[397:3f03] VideoStream -&gt; decodeFrame: (ERROR) got_packet = 0, processed_size = -1
  [swscaler @ 0x2e38000] No accelerated colorspace conversion found from yuv420p to bgra.
  2014-07-30 15:20:01.775 RTMPStreamComeback[397:7a03] MPAudioUnitEngine -&gt; nextFrame: &lt; NO PCM - WHITE NOISE &gt; timestamp = 11192, dropWhiteNoise = 0
  2014-07-30 15:20:01.799 RTMPStreamComeback[397:7a03] MPAudioUnitEngine -&gt; nextFrame: &lt; NO PCM - WHITE NOISE &gt; timestamp = 11215, dropWhiteNoise = 0
   2014-07-30 15:20:01.821 RTMPStreamComeback[397:7a03] MPAudioUnitEngine -&gt; nextFrame: &lt; NO PCM - WHITE NOISE &gt; timestamp = 11238, dropWhiteNoise = 0
   2014-07-30 15:20:01.845 RTMPStreamComeback[397:7a03] MPAudioUnitEngine -&gt; nextFrame: &lt; NO PCM - WHITE NOISE &gt; timestamp = 11261, dropWhiteNoise = 0
    2014-07-30 15:20:01.867 RTMPStreamComeback[397:7a03] MPAudioUnitEngine -&gt; nextFrame: &lt; NO PCM - WHITE NOISE &gt; timestamp = 11284, dropWhiteNoise = 0
  [flv @ 0x1808c600] Bad picture start code
  [flv @ 0x1808c600] header damaged
    2014-07-30 15:20:01.888 RTMPStreamComeback[397:3f03] VideoStream -&gt; decodeFrame: (ERROR) got_packet = 0, processed_size = -1
    2014-07-30 15:23:31.088 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -&gt; dropPcm: *** DROPPED = 320, dropWhiteNoise = 8600, pcm.remaining = 16036
    2014-07-30 15:23:31.090 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -&gt; dropPcm: *** DROPPED = 1024, dropWhiteNoise = 7576, pcm.remaining = 16036
    2014-07-30 15:23:31.093 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -&gt; dropPcm: *** DROPPED = 2048, dropWhiteNoise = 5528, pcm.remaining = 16036
    2014-07-30 15:23:31.164 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -&gt; dropPcm: *** DROPPED = 640, dropWhiteNoise = 4888, pcm.remaining = 16056
    2014-07-30 15:23:31.219 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -&gt; dropPcm: *** DROPPED = 128, dropWhiteNoise = 4760, pcm.remaining = 16028
    2014-07-30 15:23:31.298 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -&gt; dropPcm: *** DROPPED = 192, dropWhiteNoise = 4568, pcm.remaining = 16036
    2014-07-30 15:23:31.604 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -&gt; dropPcm: *** DROPPED = 128, dropWhiteNoise = 4440, pcm.remaining = 16048
    2014-07-30 15:23:31.740 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -&gt; dropPcm: *** DROPPED = 320, dropWhiteNoise = 4120, pcm.remaining = 16024
    2014-07-30 15:23:32.296 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -&gt; dropPcm: *** DROPPED = 192, dropWhiteNoise = 3928, pcm.remaining = 16008
    2014-07-30 15:24:47.575 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -&gt; dropPcm: *** DROPPED = 64, dropWhiteNoise = 3864, pcm.remaining = 16000
  </code></pre>
  
  <p>These are the default settings for audio and video format:
  Default streaming settings are shown below:</p>
  
  <pre><code>Audio:
  codec - Nelly Mozer 16KHz, mono
  bitrate - 128000
  
  Video:
  codec - H.263 (Sorenson)
  bitrate - 200000
  resolution - 192x144px
  fps = 25
  intra frame - 10
  </code></pre>
  
  <p>ALSO SUGGESTS: </p>
  
  <pre><code>Currently the library does not provide an instrument to control the stream quality. This is planned for a future release.
  </code></pre>
  
  <p>So i dont think this is possible to change the Audio Stream Format</p>