Skip to end of metadata
Go to start of metadata

Example of Android application to publish device screen

Work with example code

To analyze the code let's take the class ScreenSharingActivity.java of the screen-sharing example, which can be downloaded with build 1.1.0.55.

1. Initialization of the API.

Flashphoner.init() code

Context object is passed to method init() for initialization.

Flashphoner.init(this);

2. Request the permission to use microphone

code

        mMicCheckBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mMicCheckBox.isChecked()) {
                    ActivityCompat.requestPermissions(ScreenSharingActivity.this,
                            new String[]{Manifest.permission.RECORD_AUDIO},
                            PUBLISH_REQUEST_CODE);
                }
            }
        });

3. Choose the microphone

code

        mMicSpinner = (Spinner) findViewById(R.id.spinner_mic);
        ArrayAdapter<MediaDevice> arrayAdapter = new ArrayAdapter<MediaDevice>(this, android.R.layout.simple_spinner_item, Flashphoner.getMediaDevices().getAudioList());
        arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mMicSpinner.setAdapter(arrayAdapter);

4. Session creation

Flashphoner.createSession() code

SessionOptions is passed to the method with the following parameters

  • WCS server URL
  • SurfaceViewRenderer localRenderer to display local video
  • SurfaceViewRenderer remoteRenderer to display video published
                    SessionOptions sessionOptions = new SessionOptions(url);
                    sessionOptions.setLocalRenderer(localRender);
                    sessionOptions.setRemoteRenderer(remoteRender);

                    /**
                     * Session for connection to WCS server is created with method createSession().
                     */
                    session = Flashphoner.createSession(sessionOptions);

5. Connection to the server

Session.connect() code

session.connect(new Connection());

6. Receiving the event confirming successful connection.

session.onConnected() code

@Override
public void onConnected(final Connection connection) {
   runOnUiThread(new Runnable() {
       @Override
       public void run() {
           mStartButton.setText(R.string.action_stop);
           mStartButton.setTag(R.string.action_stop);
           mStartButton.setEnabled(true);
           mStatusView.setText(connection.getStatus());
           ...
       }
   });
}

7. Video stream creation

session.createStream() code

                                    StreamOptions streamOptions = new StreamOptions(streamName);
                                    VideoConstraints videoConstraints = new VideoConstraints();
                                    DisplayMetrics metrics = getResources().getDisplayMetrics();
                                    videoConstraints.setResolution(metrics.widthPixels, metrics.heightPixels);
                                    videoConstraints.setVideoFps(metrics.densityDpi);
                                    streamOptions.getConstraints().setVideoConstraints(videoConstraints);
                                    streamOptions.getConstraints().updateAudio(mMicCheckBox.isChecked());

                                    /**
                                     * Stream is created with method Session.createStream().
                                     */
                                    publishStream = session.createStream(streamOptions);
                                    ...
                                    startScreenCapture();

8. Prepare to capture device screen

code

    private void startScreenCapture() {
        mMediaProjectionManager = (MediaProjectionManager) getSystemService(
                Context.MEDIA_PROJECTION_SERVICE);
        Intent permissionIntent = mMediaProjectionManager.createScreenCaptureIntent();
        startActivityForResult(permissionIntent, REQUEST_CODE_CAPTURE_PERM);
    }

9. Start foreground service, capture the screen and publish the stream

startService(), setVideoCapturer(), Stream.publish() code

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (REQUEST_CODE_CAPTURE_PERM == requestCode && resultCode == RESULT_OK) {
            serviceIntent = new Intent(this, ScreenSharingService.class);
            startService(serviceIntent);
            videoCapturer = new ScreenCapturerAndroid(data, new MediaProjection.Callback() {
                @Override
                public void onStop() {
                    super.onStop();
                }
            });
            WebRTCMediaProvider.getInstance().setVideoCapturer(videoCapturer);

            /**
             * Method Stream.publish() is called to publish stream.
             */
            publishStream.publish();
            Log.i(TAG, "Permission has been granted by user");
            ...
        }
    }

10. Receiving the event confirming the successful stream publishing

StreamStatusEvent PUBLISHING code

On receiving this event preview stream is created with Session.createStream() and Stream.play() is invoked to play it.

                                    publishStream.on(new StreamStatusEvent() {
                                        @Override
                                        public void onStreamStatus(final Stream stream, final StreamStatus streamStatus) {
                                            runOnUiThread(new Runnable() {
                                                @Override
                                                public void run() {
                                                    if (StreamStatus.PUBLISHING.equals(streamStatus)) {

                                                        /**
                                                         * The options for the stream to play are set.
                                                         * The stream name is passed when StreamOptions object is created.
                                                         */
                                                        StreamOptions streamOptions = new StreamOptions(streamName);
                                                        streamOptions.getConstraints().updateAudio(mMicCheckBox.isChecked());

                                                        /**
                                                         * Stream is created with method Session.createStream().
                                                         */
                                                        playStream = session.createStream(streamOptions);
                                                        ...
                                                        playStream.play();
                                                    } else {
                                                        Log.e(TAG, "Can not publish stream " + stream.getName() + " " + streamStatus);
                                                    }
                                                    mStatusView.setText(streamStatus.toString());
                                                }
                                            });
                                        }
                                    });

11. Session disconnection.

Session.disconnect() code

mStartButton.setEnabled(false);

/**
  * Connection to WCS server is closed with method Session.disconnect().
  */
session.disconnect();

12. Starting foreground service

Service.onCreate(), startForeground() code

    @Override
    public void onCreate() {
        super.onCreate();

        NotificationChannel chan =
                new NotificationChannel(
                        CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_NONE);
        NotificationManager manager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        manager.createNotificationChannel(chan);

        final int notificationId = (int) System.currentTimeMillis();
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, CHANNEL_ID);
        Notification notification =
                notificationBuilder
                        .setSmallIcon(R.drawable.service_icon)
                        .setOngoing(true)
                        .setShowWhen(true)
                        .setContentTitle("ScreenSharingService is running in the foreground")
                        .setPriority(NotificationManager.IMPORTANCE_MIN)
                        .setCategory(Notification.CATEGORY_SERVICE)
                        .build();
        NotificationManager notificationManager
                = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(NOTIFICATION_ID, notification);

        startForeground(notificationId, notification);
    }

13. Stopping foreground service

Service.onDestroy(), stopForeground() code

    @Override
    public void onDestroy() {
        stopForeground(true);
        super.onDestroy();
    }
  • No labels