a. Open Xcode and select the option to create a new project from the File menu.
b. On the template selection dialog, select Single View Application.
c. On the project options dialog, enter values for the Product Name and Organization Identifier such that the Bundle Identifier matches the id that was used to generate your SDK license key.
d. Follow the instructions on the SDK installation page to add the SDK library to the project and configure the project setting accordingly.
a. Open Android Studio and select Start a New Android Studio Project from the Welcome to Android Studio dialog or select New Project from the File / New menu if you already have a project open.
b. On the New Project dialog, select Edit next to the Package Name field and enter the same application package name that was used to generate your SDK license key and press Next.
c. On the Target Android Devices dialog, select Phone and Tablet and select a minimum SDK version of API 19 or higher and press Next.
d. On the Add an Activity dialog, select Empty Activity and press Next.
c. On the Customize the Activity dialog, accept the default values and press Finish.
f. Follow the instructions on the SDK installation page to update the project's build.gradle
file and add the SDK library to the project's app\libs
folder.
a. Open Main.storyboard
and add a button to the View
element.
b. Change the title of the button to Broadcast.
c. Add a referencing outlet property named broadcastButton
to the ViewController
interface definition in ViewController.m
:
@interface ViewController ()
// Referencing outlet for the broadcast button
@property (weak, nonatomic) IBOutlet UIButton *broadcastButton;
@end
d. Connect the newly defined broadcastButton
outlet to the View Controller
in the storyboard editor.
Update the U/I layout defined in the file activity_main.xml
located in the project's app/src/main/res/layout
folder to match the definition below to add a view for the camera preview and a button to start and stop the live streaming broadcast.
Change the value of the tools:context
property displayed below and replace com.mycompany.myapp
with the specific package name for your app's MainActivity
class.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:wowza="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.mycompany.myapp.MainActivity">
<!-- The camera preview display -->
<com.wowza.gocoder.sdk.api.devices.WZCameraView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/camera_preview"
wowza:scaleMode="fill"
wowza:defaultCamera="back"
wowza:frameSizePreset="frameSize1280x720"/>
<!-- The broadcast button -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Broadcast"
android:id="@+id/broadcast_button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Update the definition of the activity
element in the AndroidManifest.xml
file located in the project's app\src\main
folder. to include the android:configChanges
property as defined below:
<activity android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize">
Add a onWindowFocusChanged()
method to the MainActivity
class to enable Android's immersive full-screen mode.
//
// Enable Android's sticky immersive full-screen mode
//
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
if (rootView != null)
rootView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
If you didn't do so as part of the installation instructions, add an #import
statement for the GoCoder SDK's API header and then add a goCoder
property to the ViewController
class defined in ViewController.m
:
#import <WowzaGoCoderSDK/WowzaGoCoderSDK.h>
@interface ViewController ()
// The top level GoCoder API interface
@property (nonatomic, strong) WowzaGoCoder *goCoder;
// Referencing outlet for the broadcast button
@property (weak, nonatomic) IBOutlet UIButton *broadcastButton;
@end
Add the following member variables to the MainActivity
class in MainAcivity.java
:
public class MainActivity extends AppCompatActivity {
// The top level GoCoder API interface
private WowzaGoCoder goCoder;
// The GoCoder SDK camera view
private WZCameraView goCoderCameraView;
// The GoCoder SDK audio device
private WZAudioDevice goCoderAudioDevice;
// The broadcast configuration settings
private WZBroadcastConfig goCoderBroadcastConfig;
// Properties needed for Android 6+ permissions handling
private static final int PERMISSIONS_REQUEST_CODE = 0x1;
private boolean mPermissionsGranted = true;
private String[] mRequiredPermissions = new String[] {
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO
};
The first step is to register the SDK license key with [WowzaGoCoder registerLicenseKey]
and then initialize the SDK itself by calling WowzaGoCoder.init
. Add the following to the viewDidLoad
method of the ViewController
class, replacing the string "GOSK-XXXX-XXXX-XXXX-XXXX-XXXX"
with your SDK license key:
// Register the GoCoder SDK license key
NSError *goCoderLicensingError = [WowzaGoCoder registerLicenseKey:@"GOSK-XXXX-XXXX-XXXX-XXXX-XXXX"];
if (goCoderLicensingError != nil) {
// Log license key registration failure
NSLog(@"%@", [goCoderLicensingError localizedDescription]);
} else {
// Initialize the GoCoder SDK
self.goCoder = [WowzaGoCoder sharedInstance];
}
The first step is to initialize the SDK by calling WowzaGoCoder.init()
and supplying the Android application context and license key. Add the code below to the bottom of the onCreate()
method in the MainActivity
class, replacing the string "GOSK-XXXX-XXXX-XXXX-XXXX-XXXX"
with your SDK license key:
// Initialize the GoCoder SDK
goCoder = WowzaGoCoder.init(getApplicationContext(), "GOSK-XXXX-XXXX-XXXX-XXXX-XXXX");
if (goCoder == null) {
// If initialization failed, retrieve the last error and display it
WZError goCoderInitError = WowzaGoCoder.getLastError();
Toast.makeText(this,
"GoCoder SDK error: " + goCoderInitError.getErrorDescription(),
Toast.LENGTH_LONG).show();
return;
}
For iOS 10 and above, if you haven't done so as part of the SDK installation instructions, follow the steps below to define the messages displayed to the user when the app requests permission to access the camera and microphone.
a. Select your build target in the project inspector, and select the Info tab.
b. Add a string-valued key with the name "Privacy - Camera Usage Description"
to Custom iOS Target Properties and set it's value to "The camera will be used to capture video for live streaming"
.
c. Add a string-valued key with the name "Privacy - Microphone Usage Description"
to Custom iOS Target Properties and set it's value to "The microphone will be used to capture live audio for streaming"
.
If you haven't done so as part of the SDK installation instructions, add the following permissions to the AndroidManifest.xml
file located in the project's app\src\main
folder. Place the permission declarations just below the top level <manifest>
element:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cintimedia.foobar">
<!-- Define the required application permissions -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
Add the onResume()
and onRequestPermissionsResult()
methods to the MainActivity
class with logic for Android 6.0 and above to check that the user has granted the app the necessary permissions it needs to access the camera and microphone.
//
// Called when an activity is brought to the foreground
//
@Override
protected void onResume() {
super.onResume();
// If running on Android 6 (Marshmallow) or above, check to see if the necessary permissions
// have been granted
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mPermissionsGranted = hasPermissions(this, mRequiredPermissions);
if (!mPermissionsGranted)
ActivityCompat.requestPermissions(this, mRequiredPermissions, PERMISSIONS_REQUEST_CODE);
} else
mPermissionsGranted = true;
}
//
// Callback invoked in response to a call to ActivityCompat.requestPermissions() to interpret
// the results of the permissions request
//
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
mPermissionsGranted = true;
switch (requestCode) {
case PERMISSIONS_REQUEST_CODE: {
// Check the result of each permission granted
for(int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
mPermissionsGranted = false;
}
}
}
}
}
//
// Utility method to check the status of a permissions request for an array of permission identifiers
//
private static boolean hasPermissions(Context context, String[] permissions) {
for(String permission : permissions)
if (context.checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED)
return false;
return true;
}
Add the following code to the bottom of the viewDidLoad
method to associate the view defined in the U/I storyboard for the camera preview with the corresponding class property and start the preview display:
if (self.goCoder != nil) {
// Associate the U/I view with the SDK camera preview
self.goCoder.cameraView = self.view;
// Start the camera preview
[self.goCoder.cameraPreview startPreview];
}
Associate the view defined in the activity's layout with the corresponding goCoderCameraView
class member and create an audio input device instance just below the section that initializes the SDK in the onCreate()
method. :
// Associate the WZCameraView defined in the U/I layout with the corresponding class member
goCoderCameraView = (WZCameraView) findViewById(R.id.camera_preview);
// Create an audio device instance for capturing and broadcasting audio
goCoderAudioDevice = new WZAudioDevice();
Add the following code to the bottom of the onResume()
method, after the permission checking logic, to turn on the camera preview when the application is brought to the foreground:
// Start the camera preview display
if (mPermissionsGranted && goCoderCameraView != null) {
if (goCoderCameraView.isPreviewPaused())
goCoderCameraView.onResume();
else
goCoderCameraView.startPreview();
}
Add the following to the viewDidLoad
method, replacing "live.someserver.net"
, "1935"
, "live"
, and "myStream"
with appropriate values for your Wowza Streaming Engine server or Wowza Streaming Cloud account (if you are unsure of the settings for your Wowza Streaming Cloud account, see this note):
// Get a copy of the active config
WowzaConfig *goCoderBroadcastConfig = self.goCoder.config;
// Set the defaults for 720p video
[goCoderBroadcastConfig loadPreset:WZFrameSizePreset1280x720];
// Set the connection properties for the target Wowza Streaming Engine server or Wowza Streaming Cloud account
goCoderBroadcastConfig.hostAddress = @"live.someserver.net";
goCoderBroadcastConfig.portNumber = 1935;
goCoderBroadcastConfig.applicationName = @"live";
goCoderBroadcastConfig.streamName = @"myStream";
// Update the active config
self.goCoder.config = goCoderBroadcastConfig;
Add the code below to the bottom of the onCreate()
method, replacing "live.someserver.net"
, "1935"
, "live"
, and "myStream"
with the values appropriate for your Wowza Streaming Engine server or Wowza Streaming Cloud account (if you are unsure of the settings for your Wowza Streaming Cloud account, see this note):
// Create a broadcaster instance
goCoderBroadcaster = new WZBroadcast();
// Create a configuration instance for the broadcaster
goCoderBroadcastConfig = new WZBroadcastConfig(WZMediaConfig.FRAME_SIZE_1920x1080);
// Set the connection properties for the target Wowza Streaming Engine server or Wowza Streaming Cloud account
goCoderBroadcastConfig.setHostAddress("live.someserver.net");
goCoderBroadcastConfig.setPortNumber(1935);
goCoderBroadcastConfig.setApplicationName("live");
goCoderBroadcastConfig.setStreamName("myStream");
// Designate the camera preview as the video source
goCoderBroadcastConfig.setVideoBroadcaster(goCoderCameraView);
// Designate the audio device as the audio broadcaster
goCoderBroadcastConfig.setAudioBroadcaster(goCoderAudioDevice);
a. Update the interface definition for the ViewController
class to include the WZStatusCallback
protocol:
// Implements the WZStatusCallback protocol
@interface ViewController () <WZStatusCallback>
b. Add the methods defined by the WZStatusCallback
protocol for monitoring status updates and errors during a live streaming broadcast.
- (void) onWZStatus:(WZStatus *) goCoderStatus {
// A successful status transition has been reported by the GoCoder SDK
NSString *statusMessage = nil;
switch (goCoderStatus.state) {
case WZStateIdle:
statusMessage = @"The broadcast is stopped";
break;
case WZStateStarting:
statusMessage = @"Broadcast initialization";
break;
case WZStateRunning:
statusMessage = @"Streaming is active";
break;
case WZStateStopping:
statusMessage = @"Broadcast shutting down";
break;
}
if (statusMessage != nil)
NSLog(@"Broadcast status: %@", statusMessage);
}
- (void) onWZError:(WZStatus *) goCoderStatus {
// If an error is reported by the GoCoder SDK, display an alert dialog
// containing the error details using the U/I thread
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertDialog =
[[UIAlertView alloc] initWithTitle:@"Streaming Error"
message:goCoderStatus.description
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertDialog show];
});
}
a. Update the class definition for the primary activity class to include the WZStatusCallback
interface:
// Main app activity class
public class MainActivity extends AppCompatActivity
implements WZStatusCallback {
b. Add the methods defined by the WZStatusCallback
interface for monitoring status updates and errors during a live streaming broadcast.
//
// The callback invoked upon changes to the state of the steaming broadcast
//
@Override
public void onWZStatus(final WZStatus goCoderStatus) {
// A successful status transition has been reported by the GoCoder SDK
final StringBuffer statusMessage = new StringBuffer("Broadcast status: ");
switch (goCoderStatus.getState()) {
case WZState.STARTING:
statusMessage.append("Broadcast initialization");
break;
case WZState.READY:
statusMessage.append("Ready to begin streaming");
break;
case WZState.RUNNING:
statusMessage.append("Streaming is active");
break;
case WZState.STOPPING:
statusMessage.append("Broadcast shutting down");
break;
case WZState.IDLE:
statusMessage.append("The broadcast is stopped");
break;
default:
return;
}
// Display the status message using the U/I thread
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, statusMessage, Toast.LENGTH_LONG).show();
}
});
}
//
// The callback invoked when an error occurs during a broadcast
//
@Override
public void onWZError(final WZStatus goCoderStatus) {
// If an error is reported by the GoCoder SDK, display a message
// containing the error details using the U/I thread
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,
"Streaming error: " + goCoderStatus.getLastError().getErrorDescription(),
Toast.LENGTH_LONG).show();
}
});
}
Add an event handler method to the ViewController
class to be invoked when the broadcast button is pressed:
- (IBAction)broadcastButtonTapped:(UIButton *)button
{
// Ensure the minimum set of configuration settings have been specified necessary to
// initiate a broadcast streaming session
NSError *configValidationError = [self.goCoder.config validateForBroadcast];
if (configValidationError != nil) {
UIAlertView *alertDialog =
[[UIAlertView alloc] initWithTitle:@"Incomplete Streaming Settings"
message: self.goCoder.status.description
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertDialog show];
} else if (self.goCoder.status.state != WZStateRunning) {
// Start streaming
[self.goCoder startStreaming:self];
}
else {
// Stop the broadcast that is currently running
[self.goCoder endStreaming:self];
}
}
Add the code below to the bottom of the viewDidLoad
method to associate the broadcastButtonTapped
event handler with the broadcast button:
[self.broadcastButton addTarget:self action:@selector(broadcastButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
Update the definition for the MainActivity
class to include the View.OnClickListener
interface:
// Main app activity class
public class MainActivity extends AppCompatActivity
implements WZStatusCallback, View.OnClickListener {
Add an onClick()
event handler to the MainActivity
class to be invoked when the broadcast button is pressed:
//
// The callback invoked when the broadcast button is pressed
//
@Override
public void onClick(View view) {
// return if the user hasn't granted the app the necessary permissions
if (!mPermissionsGranted) return;
// Ensure the minimum set of configuration settings have been specified necessary to
// initiate a broadcast streaming session
WZStreamingError configValidationError = goCoderBroadcastConfig.validateForBroadcast();
if (configValidationError != null) {
Toast.makeText(this, configValidationError.getErrorDescription(), Toast.LENGTH_LONG).show();
} else if (goCoderBroadcaster.getStatus().isRunning()) {
// Stop the broadcast that is currently running
goCoderBroadcaster.endBroadcast(this);
} else {
// Start streaming
goCoderBroadcaster.startBroadcast(goCoderBroadcastConfig, this);
}
}
Add the code below to the bottom of the onCreate()
method to associate the onClick()
event handler with the broadcast button defined in the U/I layout:
// Associate the onClick() method as the callback for the broadcast button's click event
Button broadcastButton = (Button) findViewById(R.id.broadcast_button);
broadcastButton.setOnClickListener(this);
At this stage you are ready to build and deploy your application. Choose Run from the Xcode Product menu.
The completed code for the ViewController
class is displayed below:
#import "ViewController.h"
#import <WowzaGoCoderSDK/WowzaGoCoderSDK.h>
@interface ViewController () <WZStatusCallback>
// The top level GoCoder API interface
@property (nonatomic, strong) WowzaGoCoder *goCoder;
// Referencing outlet for the broadcast button
@property (weak, nonatomic) IBOutlet UIButton *broadcastButton;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Register the GoCoder SDK license key
NSError *goCoderLicensingError = [WowzaGoCoder registerLicenseKey:@"GOSK-8743-0103-A68E-7B1B-BD18"];
if (goCoderLicensingError != nil) {
// Log license key registration failure
NSLog(@"%@", [goCoderLicensingError localizedDescription]);
} else {
// Initialize the GoCoder SDK
self.goCoder = [WowzaGoCoder sharedInstance];
}
if (self.goCoder != nil) {
// Associate the U/I view with the SDK camera preview
self.goCoder.cameraView = self.view;
// Start the camera preview
[self.goCoder.cameraPreview startPreview];
}
// Get a copy of the active config
WowzaConfig *goCoderBroadcastConfig = self.goCoder.config;
// Set the defaults for 720p video
[goCoderBroadcastConfig loadPreset:WZFrameSizePreset1280x720];
// Set the connection properties for the target Wowza Streaming Engine server or Wowza Streaming Cloud account
goCoderBroadcastConfig.hostAddress = @"live.someserver.net";
goCoderBroadcastConfig.portNumber = 1935;
goCoderBroadcastConfig.applicationName = @"live";
goCoderBroadcastConfig.streamName = @"myStream";
// Update the active config
self.goCoder.config = goCoderBroadcastConfig;
[self.broadcastButton addTarget:self action:@selector(broadcastButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) onWZStatus:(WZStatus *) goCoderStatus {
// A successful status transition has been reported by the GoCoder SDK
NSString *statusMessage = nil;
switch (goCoderStatus.state) {
case WZStateIdle:
statusMessage = @"The broadcast is stopped";
break;
case WZStateStarting:
statusMessage = @"Broadcast initialization";
break;
case WZStateRunning:
statusMessage = @"Streaming is active";
break;
case WZStateStopping:
statusMessage = @"Broadcast shutting down";
break;
}
if (statusMessage != nil)
NSLog(@"Broadcast status: %@", statusMessage);
}
- (void) onWZError:(WZStatus *) goCoderStatus {
// If an error is reported by the GoCoder SDK, display an alert dialog
// containing the error details using the U/I thread
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertDialog =
[[UIAlertView alloc] initWithTitle:@"Streaming Error"
message:goCoderStatus.description
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertDialog show];
});
}
- (IBAction)broadcastButtonTapped:(UIButton *)button
{
// Ensure the minimum set of configuration settings have been specified necessary to
// initiate a broadcast streaming session
NSError *configValidationError = [self.goCoder.config validateForBroadcast];
if (configValidationError != nil) {
UIAlertView *alertDialog =
[[UIAlertView alloc] initWithTitle:@"Incomplete Streaming Settings"
message: self.goCoder.status.description
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertDialog show];
} else if (self.goCoder.status.state != WZStateRunning) {
// Start streaming
[self.goCoder startStreaming:self];
}
else {
// Stop the broadcast that is currently running
[self.goCoder endStreaming:self];
}
}
@end
At this stage you are ready to build and deploy your application. Choose Run or Debug from the Android Studio Run menu and select a device for deployment.
The completed code for the MainActivity
class is displayed below:
public class MainActivity extends AppCompatActivity
implements WZStatusCallback, View.OnClickListener {
// The top level GoCoder API interface
private WowzaGoCoder goCoder;
// The GoCoder SDK camera view
private WZCameraView goCoderCameraView;
// The GoCoder SDK audio device
private WZAudioDevice goCoderAudioDevice;
// The GoCoder SDK broadcaster
private WZBroadcast goCoderBroadcaster;
// The broadcast configuration settings
private WZBroadcastConfig goCoderBroadcastConfig;
// Properties needed for Android 6+ permissions handling
private static final int PERMISSIONS_REQUEST_CODE = 0x1;
private boolean mPermissionsGranted = true;
private String[] mRequiredPermissions = new String[] {
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize the GoCoder SDK
goCoder = WowzaGoCoder.init(getApplicationContext(), "GOSK-8743-0103-A68E-7B1B-BD18");
if (goCoder == null) {
// If initialization failed, retrieve the last error and display it
WZError goCoderInitError = WowzaGoCoder.getLastError();
Toast.makeText(this,
"GoCoder SDK error: " + goCoderInitError.getErrorDescription(),
Toast.LENGTH_LONG).show();
return;
}
// Associate the WZCameraView defined in the U/I layout with the corresponding class member
goCoderCameraView = (WZCameraView) findViewById(R.id.camera_preview);
// Create an audio device instance for capturing and broadcasting audio
goCoderAudioDevice = new WZAudioDevice();
// Create a broadcaster instance
goCoderBroadcaster = new WZBroadcast();
// Create a configuration instance for the broadcaster
goCoderBroadcastConfig = new WZBroadcastConfig(WZMediaConfig.FRAME_SIZE_1920x1080);
// Set the connection properties for the target Wowza Streaming Engine server or Wowza Streaming Cloud account
goCoderBroadcastConfig.setHostAddress("live.someserver.net");
goCoderBroadcastConfig.setPortNumber(1935);
goCoderBroadcastConfig.setApplicationName("live");
goCoderBroadcastConfig.setStreamName("myStream");
// Designate the camera preview as the video broadcaster
goCoderBroadcastConfig.setVideoBroadcaster(goCoderCameraView);
// Designate the audio device as the audio broadcaster
goCoderBroadcastConfig.setAudioBroadcaster(goCoderAudioDevice);
// Associate the onClick() method as the callback for the broadcast button's click event
Button broadcastButton = (Button) findViewById(R.id.broadcast_button);
broadcastButton.setOnClickListener(this);
}
//
// Called when an activity is brought to the foreground
//
@Override
protected void onResume() {
super.onResume();
// If running on Android 6 (Marshmallow) or above, check to see if the necessary permissions
// have been granted
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mPermissionsGranted = hasPermissions(this, mRequiredPermissions);
if (!mPermissionsGranted)
ActivityCompat.requestPermissions(this, mRequiredPermissions, PERMISSIONS_REQUEST_CODE);
} else
mPermissionsGranted = true;
// Start the camera preview display
if (mPermissionsGranted && goCoderCameraView != null) {
if (goCoderCameraView.isPreviewPaused())
goCoderCameraView.onResume();
else
goCoderCameraView.startPreview();
}
}
//
// Callback invoked in response to a call to ActivityCompat.requestPermissions() to interpret
// the results of the permissions request
//
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
mPermissionsGranted = true;
switch (requestCode) {
case PERMISSIONS_REQUEST_CODE: {
// Check the result of each permission granted
for(int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
mPermissionsGranted = false;
}
}
}
}
}
//
// Utility method to check the status of a permissions request for an array of permission identifiers
//
private static boolean hasPermissions(Context context, String[] permissions) {
for(String permission : permissions)
if (context.checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED)
return false;
return true;
}
//
// The callback invoked when the broadcast button is pressed
//
@Override
public void onClick(View view) {
// return if the user hasn't granted the app the necessary permissions
if (!mPermissionsGranted) return;
// Ensure the minimum set of configuration settings have been specified necessary to
// initiate a broadcast streaming session
WZStreamingError configValidationError = goCoderBroadcastConfig.validateForBroadcast();
if (configValidationError != null) {
Toast.makeText(this, configValidationError.getErrorDescription(), Toast.LENGTH_LONG).show();
} else if (goCoderBroadcaster.getStatus().isRunning()) {
// Stop the broadcast that is currently running
goCoderBroadcaster.endBroadcast(this);
} else {
// Start streaming
goCoderBroadcaster.startBroadcast(goCoderBroadcastConfig, this);
}
}
//
// The callback invoked upon changes to the state of the steaming broadcast
//
@Override
public void onWZStatus(final WZStatus goCoderStatus) {
// A successful status transition has been reported by the GoCoder SDK
final StringBuffer statusMessage = new StringBuffer("Broadcast status: ");
switch (goCoderStatus.getState()) {
case WZState.STARTING:
statusMessage.append("Broadcast initialization");
break;
case WZState.READY:
statusMessage.append("Ready to begin streaming");
break;
case WZState.RUNNING:
statusMessage.append("Streaming is active");
break;
case WZState.STOPPING:
statusMessage.append("Broadcast shutting down");
break;
case WZState.IDLE:
statusMessage.append("The broadcast is stopped");
break;
default:
return;
}
// Display the status message using the U/I thread
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, statusMessage, Toast.LENGTH_LONG).show();
}
});
}
//
// The callback invoked when an error occurs during a broadcast
//
@Override
public void onWZError(final WZStatus goCoderStatus) {
// If an error is reported by the GoCoder SDK, display a message
// containing the error details using the U/I thread
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,
"Streaming error: " + goCoderStatus.getLastError().getErrorDescription(),
Toast.LENGTH_LONG).show();
}
});
}
//
// Enable Android's sticky immersive full-screen mode
//
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
if (rootView != null)
rootView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
Where To Go Next
Installation Information | Information about installing the GoCoder SDK and using it within your mobile app projects |
Developer Guides | In depth information for common GoCoder SDK-related tasks and topics |
API Reference | Detailed GoCoder SDK API reference docs for each platform |
FAQ | Common GoCoder SDK-related questions |
Release Notes | Information related to each of the GoCoder SDK releases |