Пример стримера для Android
Данный стример может использоваться для публикации WebRTC-видеопотока с Web Call Server.
На скриншоте ниже представлен пример во время публикации потока.
В URL в поле ввода
- 192.168.2.104 - адрес WCS-сервера
- test - имя потока
Слева отображается видео с камеры, справа воспроизводится опубликованный поток.
Работа с кодом примера
Для разбора кода возьмем класс StreamerActivity.java примера streamer, который доступен для скачивания в соответствующей сборке 1.0.1.38.
1. Инициализация API.
Flashphoner.init() код
При инициализации методу init() передается объект Сontext.
Code Block | ||
---|---|---|
| ||
Flashphoner.init(this); |
2. Создание сессии
Flashphoner.createSession() код
Методу передается объект SessionOptions со следующими параметрами
- URL WCS-сервера
- SurfaceViewRenderer localRenderer, который будет использоваться для отображения видео с камеры
- SurfaceViewRenderer remoteRenderer, который будет использоваться для воспроизведения опубликованного видеопотока
Code Block | ||
---|---|---|
| ||
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); |
3. Подключение к серверу.
Session.connect(). код
Code Block | ||
---|---|---|
| ||
session.connect(new Connection()); |
4. Получение от сервера события, подтверждающего успешное соединение.
session.onConnected() код
Code Block | ||
---|---|---|
| ||
@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()); /** * The options for the stream to publish are set. * The stream name is passed when StreamOptions object is created. */ StreamOptions streamOptions = new StreamOptions(streamName); /** * Stream is created with method Session.createStream(). */ publishStream = session.createStream(streamOptions); ... } }); } |
5. Создание видеопотока.
Session.createStream(), ActivityCompat.requestPermissions() код
При создании потока методу Session.createStream() передается объект StreamOptions с именем видеопотока
Code Block | ||
---|---|---|
| ||
StreamOptions streamOptions = new StreamOptions(streamName); /** * Stream is created with method Session.createStream(). */ publishStream = session.createStream(streamOptions); ... ActivityCompat.requestPermissions(StreamerActivity.this, new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA}, PUBLISH_REQUEST_CODE); |
6. Публикация потока
Stream.publish() код
Code Block | ||
---|---|---|
| ||
case PUBLISH_REQUEST_CODE: { if (grantResults.length == 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) { mStartButton.setEnabled(false); session.disconnect(); Log.i(TAG, "Permission has been denied by user"); } else { /** * Method Stream.publish() is called to publish stream. */ publishStream.publish(); Log.i(TAG, "Permission has been granted by user"); } } |
7. Получение от сервера события, подтверждающего успешную публикацию потока
StreamStatusEvent PUBLISHING код
При получении данного события создается превью-видеопоток при помощи Session.createStream() и вызывается Stream.play() для его воспроизведения.
Code Block | ||
---|---|---|
| ||
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); /** * Stream is created with method Session.createStream(). */ playStream = session.createStream(streamOptions); /** * Callback function for stream status change is added to display the status. */ playStream.on(new StreamStatusEvent() { @Override public void onStreamStatus(final Stream stream, final StreamStatus streamStatus) { runOnUiThread(new Runnable() { @Override public void run() { if (!StreamStatus.PLAYING.equals(streamStatus)) { Log.e(TAG, "Can not play stream " + stream.getName() + " " + streamStatus); } mStatusView.setText(streamStatus.toString()); } }); } }); /** * Method Stream.play() is called to start playback of the stream. */ playStream.play(); } else { Log.e(TAG, "Can not publish stream " + stream.getName() + " " + streamStatus); } mStatusView.setText(streamStatus.toString()); } }); } }); |
8. Закрытие соединения.
Session.disconnect() код
Code Block | ||
---|---|---|
| ||
mStartButton.setEnabled(false); /** * Connection to WCS server is closed with method Session.disconnect(). */ session.disconnect(); |
9. Получение события, подтверждающего разъединение.
session.onDisconnection() код
Code Block | ||
---|---|---|
| ||
@Override public void onDisconnection(final Connection connection) { runOnUiThread(new Runnable() { @Override public void run() { mStartButton.setText(R.string.action_start); mStartButton.setTag(R.string.action_start); mStartButton.setEnabled(true); mStatusView.setText(connection.getStatus()); } }); } |