当前您所在的位置:首页>新闻中心>新品发布
新品发布
行业动态
营销活动

如何用Wowza Gocoder SDK Android版开发一个基本功能的直播APP?

发布时间:2021/01/10 浏览量:2218

这篇文章介绍了如何用Wowza Gocoder SDK Android版开发一个基本功能的直播APP。

一、创建一个新的开发项目


首先你需要在Android Studio中创建一个APP开发项目。 

 

二、添加一个直播按钮

在这一步,你需要在APP的界面上添加一个直播按钮. 

 

      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">

 

 

     

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:id="@+id/camera_preview"

        wowza:scaleMode="fill"

        wowza:defaultCamera="back"

        wowza:frameSizePreset="frameSize1280x720"/>

 

 

 

 

        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" />

 

 

          

在 [project_root]/app/src/main/AndroidManifest.xml 文件中,为 activity 元素添加 android:configChanges 参数。

 

        android:configChanges="orientation|keyboardHidden|screenSize">

          

为 MainActivity Class添加 onWindowFocusChanged() 方法,以此来开启Android的immersive full-screen 模式。

?

//

?

// 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);

?

}

 

三、定义APP的参数

在 MainActivity.java 文件中为 MainActivity Class 添加下面的成员变量:

public class MainActivity extendsAppCompatActivity {

 

   // 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 intPERMISSIONS_REQUEST_CODE = 0x1;

   private boolean mPermissionsGranted = true;

   private String[] mRequiredPermissions = new String[] {

            Manifest.permission.CAMERA,

            Manifest.permission.RECORD_AUDIO

   };

 

四、注册和初始化SDK

在这一步,你需要在 MainActivity Class的 onCreate() 方法中添加下面的代码来注册和初始化GoCoder SDK 的License。 
请用你的License key替换下面的 GOSK-XXXX-XXXX-XXXX-XXXX-XXXX 。

// 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;

}

 

五、检查APP的权限

接下来,你必须为APP定义它所需要的权限:

?

 

xmlns:android="http://schemas.android.com/apk/res/android"

?

              package="com.cintimedia.foobar">

   

   

   

   

   

   

 

对于Android     6.0及以上版本,你需要在 MainActivity class中添加 onResume() 和 onRequestPermissionsResult() 方法来检查用户已经授权APP来访问摄像头和麦克风。

?

//

// 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;

?

}

 

六、开启摄像头预览

接下来,我们需要配置和开启摄像头预览:

?

// 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();

 

?

// Start the camera preview display

if (mPermissionsGranted && goCoderCameraView != null) {

    if     (goCoderCameraView.isPreviewPaused())

            goCoderCameraView.onResume();

    else

           goCoderCameraView.startPreview();       

}

?

七、配置直播相关参数

在 MainActivity Class的 onCreate 方法中加入对直播的相关参数,包括服务器地址(hostAddress)、端口(portNumber)、 应用名(applicationName)和流名(streamName)。这个服务器不限于Wowza Streaming Engine或Wowza Streaming Cloud。 
如果你要往Wowza Streaming Cloud 云平台推流,那么你可以在Wowza Streaming Cloud的Web界面的live streaming详情的 Overview Tab页上找到 Connection Code 

// Get a copy of the active config

WowzaConfig *goCoderBroadcastConfig =self.goCoder.config;

 

// Set the defaults for 720p video

[goCoderBroadcastConfigloadPreset:WZFrameSizePreset1280x720];

 

// Set the connection properties for thetarget Wowza Streaming Engine server or Wowza Cloud account

goCoderBroadcastConfig.hostAddress =@"live.someserver.net";

goCoderBroadcastConfig.portNumber =1935;

goCoderBroadcastConfig.applicationName =@"live";

goCoderBroadcastConfig.streamName =@"myStream";

 

// Update the active config

self.goCoder.config =goCoderBroadcastConfig;

  

八、添加流传输的状态回调

在这一步,我们添加对流传输状态监控的回调。 
1、我们首先要在primary activity( MainActivity )添加WZStatusCallback接口,用来对直播流的传输做状态监控:

// Main app activity class

public class MainActivity extends AppCompatActivity

   implements WZStatusCallback {

   

2、在 MainActivity Class中添加WZStatusCallback接口中定义的方法:

//

// The callback invoked upon changes tothe state of the steaming broadcast

//

@Override

public void onWZStatus(final WZStatusgoCoderStatus) {

 // A successful status transition has beenreported by the GoCoder SDK

 final StringBuffer statusMessage = newStringBuffer("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/Ithread

 new Handler(Looper.getMainLooper()).post(newRunnable() {

 @Override

 public void run() {

  Toast.makeText(MainActivity.this, statusMessage,Toast.LENGTH_LONG).show();

 }

 });

}

 

//

// The callback invoked when an erroroccurs during a broadcast

//

@Override

public void onWZError(final WZStatusgoCoderStatus) {

 // If an error is reported by the GoCoder SDK,display a message

 // containing the error details using the U/Ithread

 new Handler(Looper.getMainLooper()).post(newRunnable() {

 @Override

 public void run() {

  Toast.makeText(MainActivity.this,

  "Streaming error: " +goCoderStatus.getLastError().getErrorDescription(),

  Toast.LENGTH_LONG).show();

 }

 });

}

 

九、开始直播

在开始直播之前,您还需要为直播按钮加上启动和停止直播的代码: 

在 MainActivity Class中添加 View.onClickListener 接口:

// Main app activity class

public class MainActivity extends AppCompatActivity

 implements  WZStatusCallback, View.OnClickListener      {

       

在 MainActivity Class的 onCreate() 方法的最底部,它在直播按钮被按下时被调用:

//

// 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);

  }

}   

?

?

// 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);

 

十、构建和运行你的APP

最后,可以编译和测试的APP了,请点击 Run 菜单,选择 Run 或者 Debug 。 

十一、MainActivity的例子程序

下面是一个完整的 MainActivity Class的例子,代码包括上面讲到的所有内容:

public class MainActivity extendsAppCompatActivity

 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-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;

 }

 

 // Associate the WZCameraView defined in the U/I layout with thecorresponding 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 Engineserver or Wowza 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 broadcastbutton'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 thenecessary 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 toActivityCompat.requestPermissions() to interpret

 // the results of the permissions request

 //

 @Override

 public void onRequestPermissionsResult(int requestCode, Stringpermissions[], 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 anarray 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 specifiednecessary 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 steamingbroadcast

 //

 @Override

 public void onWZStatus(final WZStatus goCoderStatus) {

 // A successful status transition has been reported by the GoCoder SDK

 final StringBuffer statusMessage = new StringBuffer("Broadcaststatus: ");

 

 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);

 }

 

}

 

Wowza Streaming Engine 4是业界功能强大、API接口丰富的流媒体Server产品,采用它作为流媒体服务器产品的案例很多,直播、在线教育、IPTV都有它的用武之地。

北京哲想软件有限公司