Play a Wowza Streaming Cloud ultra low latency stream with Wowza GoCoder SDK for iOS

Learn how to add a player view to a Wowza GoCoder™ SDK for iOS app and play an ultra low latency live stream from the Wowza Streaming Cloud™ service.

Notes:

Before you begin


Before adding the functionality below to an app, make sure you've set up the Wowza GoCoder SDK for your project:

  • Request a free license and download the latest version of the SDK.
  • Configure your Xcode project to use the SDK.

See Download and install GoCoder SDK for iOS for detailed instructions.

Set up an ultra low latency stream target in Wowza Streaming Cloud


For Wowza Gocoder playback from the Wowza Streaming Cloud with Ultra Low Latency service, start by setting up an ultra low latency stream target. For instructions, see one of these resources:

Note: If you want to configure the ultra low latency target to enable HLS fallback, you must do so while creating the target. HLS fallback helps ensure successful playback but increases latency.

After you set up the stream target, note the WOWZ Playback URL and the optional HLS fallback URL, as you will use them to set up the WowzaConfig object.

Add a player view to an app


Use the WOWZPlayer and WowzaConfig classes to add a player view to an app.

  1. Create configuration and player properties.
     
    #pragma mark - GoCoder SDK Components
    @property (nonatomic, strong) WowzaConfig *goCoderConfig;
    @property (nonatomic, strong) WOWZPlayer *player;
  2. Create a WOWZPlayer object and, if desired, register it for data events.
     
    // Register the GoCoder SDK license key
      NSString *SDKSampleAppLicenseKey = @"your-GoCoder-SDK-license-key";
      NSError *goCoderLicensingError = [WowzaGoCoder registerLicenseKey:SDKSampleAppLicenseKey];
      if (goCoderLicensingError != nil) {
        // Handle license key registration failure
      }
      else {
        self.player = [WOWZPlayer new];
        //Set default preroll buffer duration if you want a preroll buffer before a stream starts
         self.player.prerollDuration = 3; // 1-3 second buffer
        //Optionally set up data sink to handle in-stream events
        [self.player registerDataSink:self eventName:@"onTextData"];
      }
    
  3. Implement the WOWZStatusCallback methods to respond and assign your player view.
     
    #pragma mark - WOWZStatusCallback Protocol Instance Methods
    
    - (void) onWOWZStatus:(WOWZStatus *) goCoderStatus {
      // A successful status transition has been reported by the GoCoder SDK
      
      switch (goCoderStatus.state) {
          
        case WOWZStateIdle:
                break;
          
        case WOWZStateStarting:
          // A streaming broadcast session is starting up
          self.player.playerView = self.view;
    
          break;
          
        case WOWZStateRunning:
          
          break;
          
        case WOWZStateStopping:
                 break;
          
        case WOWZStateBuffering:
              break;
          
        default:
          break;
      }
    }

Configure the streaming server


Specify the streaming server connection properties.

  1. Write a configuration method that instantiates and assigns a configuration object to your property.
     
    -(void)setupConfig{
      WowzaConfig *config = [WowzaConfig new];
      config.hostAddress = @"your_server_ip";
      config.portNumber = 1935;
      config.streamName = @"your_stream_name";
      config.applicationName = @"your_application_name";
      config.audioEnabled = YES;
      config.videoEnabled = YES;
      self.goCoderConfig = config;
    }

    Parse the ultra low latency WOWZ playback URL to get the necessary values. For example, using this WOWZ playback URL,
    wowz://edge.cdn.wowza.com/live/_definst_/0ABC2R1FvREJWak43cmxBOGhQTH12345
    The configuration should look something like this:
    -(void)setupConfig{
      WowzaConfig *config = [WowzaConfig new];
      config.hostAddress = @"edge.cdn.wowza.com";
      config.portNumber = 1935;
      config.streamName = @"0ABC2R1FvREJWak43cmxBOGhQTH12345";
      config.applicationName = @"live";
      config.audioEnabled = YES;
      config.videoEnabled = YES;
      self.goCoderConfig = config;
    }
  2. Call the configuration method.
     
    - (void)viewDidLoad {
      [super viewDidLoad];
      [self setupConfig];
  3. Instruct the self.player object to play with the configuration method and register self as a delegate for callbacks.
     
    - (IBAction) didTapPlaybackButton:(id)sender {
      if ([self.player currentPlayState] == WOWZStateIdle) {
        [self.player play:self.goCoderConfig callback:self];
      }
      else {
        [self.player stop];
      }
    }

Configure HLS fallback


You can instruct the Wowza GoCoder SDK app to play an HLS stream as a fallback if the primary ultra low latency WOWZ over Websocket stream fails to connect.

HLS fallback also helps with viewer limits. Ultra low latency streams are subject to a default viewer limit of simultaneous viewers per stream according to the subscription plan you select. If this limit is exceeded, new stream viewers will receive an error and won't be able to establish a connection. If you have enabled and configured HLS as a backup for playback, ultra low latency stream viewers beyond the allotted limit can view the steam via the fallback HLS connection. See Wowza Streaming Cloud REST API limits for more information about limits.

Use the following properties in WowzaConfig to set up HLS fallback:

Property Type Description
allowHLSPlayback Boolean Specify true to enable HLS fallback. When enabled, the player will switch to the HLS URL after three failed attempts to play over the primary protocol.
hlsURL string The .m3u8 HLS playlist URL from the Wowza Streaming Cloud ultra low latency stream target. This is an NSString object.

Update the WowzaConfig object to add the HLS fallback properties:

-(void)setupConfig{
  WowzaConfig *config = [WowzaConfig new];
  config.hostAddress = @"your_server_ip";
  config.portNumber = 1935;
  config.streamName = @"your_stream_name";
  config.applicationName = @"your_application_name";
  config.audioEnabled = YES;
  config.videoEnabled = YES;
  
  //Configure HLS fallback
  config.allowHLSPlayback = YES;
  config.hlsURL = @"your_hls_playback_url";
  self.goCoderConfig = config;
}
 

Set play options


syncOffset

If your source stream has a constant audio/video sync offset, use the syncOffset option to adjust how the audio/video sync is set.

-(IBAction)syncSliderChanged:(id)sender {
  UISlider *slider = (UISlider *)sender;
  Float32 value = slider.value;
  self.player.syncOffset = value;
  
}

prerollDuration

Use the prerollDuration option to set the time, in seconds, that the stream should buffer before playing.

self.player.prerollDuration = 3;  //3 second buffer.

play and stop

Use play to start playing the stream and stop to stop playing the stream.

- (IBAction) didTapPlaybackButton:(id)sender {
  if ([self.player currentPlayState] == WOWZStateIdle) {
    [self.player play:self.goCoderConfig callback:self];
  }
  else {
    [self.player stop];
  }
}

mute

Use the mute option to silence the audio of the stream.

- (IBAction)didTapMuteButton:(id)sender {
  self.player.muted = !self.player.muted;
  UIImage *muteButtonImage = [UIImage imageNamed:self.player.muted ? @"volume_mute" : @"volume_unmute"];
  [self.muteButton setImage:muteButtonImage forState:UIControlStateNormal];
  self.volumeSlider.enabled = !self.player.muted;
}

volume

Use the volume option to adjust the audio volume of the stream.

- (IBAction)didChangeVolume:(id)sender {
  UISlider *slider = (UISlider *)sender;
  self.player.volume = slider.value;
}

playerViewGravity

Use the following playerViewGravity properties to specify how the player preview should display:

Property Description
WOWZPlayerViewGravityResizeAspect Scale the camera preview to fit within the screen area. Letterboxing may be applied to maintain the aspect ratio.
WOWZPlayerViewGravityResizeAspectFitFill Scale the camera preview to fill the screen area. The preview may be cropped to maintain the aspect ratio.

Set the previewGravity mode.

self.player.playerViewGravity = WOWZPlayerViewGravityResizeAspect;

Get the bitrate during playback


You can get the bitrate of a live stream as it's received across the network socket for playback. 

The bitrate is updated every three seconds based on the average bitrate from the start of playback to the current time.

You can get the bitrate either by using the currentInjestBitrate property in the WowzaPlayer class or by listening for the value with NSNotificationCenter.

To get the bitrate by using currentInjestBitrate:

// Get the bitrate of the stream at the network socket
self.player.currentInjestBitrate

To listen for the bitrate:

// Listen for the bitrate of the stream at the network socket
name@"WOWZBitrateUpdate" object:nil

More resources