...
Ниже представлен пример аудиочата в приложении
Поля ввода
- 'WCS URL', где
wss://demo.flashphoner.com:8443/
- адрес WCS-сервера - 'Login', где
bob
- имя пользователя - 'Room', где
room1
- имя "комнаты" чата
Работа с кодом примера
Для разбора кода возьмем класс AudioChatActivity.java примера audio chat, который доступен для скачивания в соответствующей сборке 1.1.0.61.
В отличии от прямого подключения к серверу методом createSession()
, для управления подключением к серверу и конференции используется объект RoomManager
. Соединение с сервером установливается при создании объекта RoomManager
, а для присоединения к конфренции вызывается метод RoomManager.join(),
При присоединении к новой "комнате" методом RoomManager.join()
, создается объект Room для работы с этой "комнатой". Для работы с участниками конференции используются объекты Participant.
Все события, происходящие в "комнате" (присоединение/выход пользователя, отправленные сообщения), транслируются другим участникам, подключенным к этой "комнате".
Например, в следующем коде подключаемся к "комнате" и запрашиваем список других участников:
Code Block |
---|
|
room = roomManager.join(roomOptions);
room.on(new RoomEvent() {
public void onState(final Room room) {
for (final Participant participant : room.getParticipants()) {
...
}
...
}
...
}); |
1. Инициализация API
Flashphoner.init()
code
Code Block |
---|
|
Flashphoner.init(this); |
...
Code Block |
---|
|
renderer = new SurfaceViewRenderer(this); |
3. Подключение к серверу
Flashphoner.createRoomManager()
code
Методу передается объект RoomManagerOptions со следующими параметрами
- URL WCS-сервера
- имя пользователя для присоединения к чат-комнате
Code Block |
---|
|
RoomManagerOptions roomManagerOptions = new RoomManagerOptions(mWcsUrlView.getText().toString(), mLoginView.getText().toString());
/**
* RoomManager object is created with method createRoomManager().
* Connection session is created when RoomManager object is created.
*/
roomManager = Flashphoner.createRoomManager(roomManagerOptions); |
4. Получение от сервера события, подтверждающего успешное соединение.
RoomManager.onConnected()
code
Code Block |
---|
|
@Override
public void onConnected(final Connection connection) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mConnectButton.setText(R.string.action_disconnect);
mConnectButton.setTag(R.string.action_disconnect);
mConnectButton.setEnabled(true);
mConnectStatus.setText(connection.getStatus());
mJoinButton.setEnabled(true);
}
});
} |
5. Присоединение к конференции.
RoomManager.join()
code
Методу RoomManager.join()
передается объект RoomOptions
с именем комнаты конференции
Code Block |
---|
|
RoomOptions roomOptions = new RoomOptions();
roomOptions.setName(mJoinRoomView.getText().toString());
/**
* The participant joins a audio chat room with method RoomManager.join().
* RoomOptions object is passed to the method.
* Room object is created and returned by the method.
*/
room = roomManager.join(roomOptions); |
6. Получение от сервера события, подтверждающего успешное присоединение к конференции
Room.onState()
code
При получении данного события количество и состав других участников определяется с помощью метода Room.getParticipants()
. Если количество участников более 2, текущий участник выходит из комнаты.
Если текущий участник остается в комнате, запускается проигрывание потока от другого участника при помощи Participant.play()
Code Block |
---|
|
if (room.getParticipants().size() >= 2) {
room.leave(null);
runOnUiThread(
new Runnable() {
@Override
public void run() {
mJoinStatus.setText("Room is full");
mJoinButton.setEnabled(true);
}
}
);
return;
}
final StringBuffer chatState = new StringBuffer("participants: ");
/**
* Iterating through the collection of the other participants returned by method Room.getParticipants().
* There is corresponding Participant object for each participant.
*/
for (final Participant participant : room.getParticipants()) {
/**
* A player view is assigned to each of the other participants in the room.
*/
chatState.append(participant.getName()).append(",");
runOnUiThread(
new Runnable() {
@Override
public void run() {
participant.play(renderer);
mParticipantName.setText(participant.getName());
}
}
);
} |
7. Публикация аудиопотока
Room.publish()
code
Методу передаются ограничения, указывающие, что публиковаться должно только аудио
Code Block |
---|
|
case PUBLISH_REQUEST_CODE: {
if (grantResults.length == 0 ||
grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission has been denied by user");
} else {
/**
* Stream is created and published with method Room.publish().
*/
StreamOptions streamOptions = new StreamOptions();
streamOptions.setConstraints(new Constraints(true, false));
stream = room.publish(null, streamOptions);
...
Log.i(TAG, "Permission has been granted by user");
}
} |
8. Получение от сервера события, сигнализирующего о присоединении к конференции другого участника
Room.onJoined()
code
Code Block |
---|
|
@Override
public void onJoined(final Participant participant) {
/**
* When a new participant joins the room, a player view is assigned to that participant.
*/
runOnUiThread(
new Runnable() {
@Override
public void run() {
mParticipantName.setText(participant.getName());
addMessageHistory(participant.getName(), "joined");
}
}
);
} |
9. Получение от сервера события, сигнализирующего о публикации видеопотока другим участником
Room.onPublished()
code
При получении данного события поток, опубликованный участником, воспроизводится с помощью метода Participant.play()
. Этому методу передается SurfaceViewRenderer
, в котором будет проигрываться аудио
Code Block |
---|
|
@Override
public void onPublished(final Participant participant) {
/**
* When one of the other participants starts publishing, playback of the stream published by that participant is started.
*/
runOnUiThread(
new Runnable() {
@Override
public void run() {
participant.play(renderer);
}
}
);
} |
10. Получение от сервера события, сигнализирующего об отправке сообщения другим участником
Room.onMessage()
code
Code Block |
---|
|
@Override
public void onMessage(final Message message) {
/**
* When one of the participants sends a text message, the received message is added to the messages log.
*/
runOnUiThread(
new Runnable() {
@Override
public void run() {
addMessageHistory(message.getFrom(), message.getText());
}
}
);
} |
11. Отправка сообщения другому участнику
Participant.sendMessage()
code
Code Block |
---|
|
mSendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
String text = mMessage.getText().toString();
if (!"".equals(text)) {
for (Participant participant : room.getParticipants()) {
participant.sendMessage(text);
}
addMessageHistory(mLoginView.getText().toString(), text);
mMessage.setText("");
}
}
}); |
12. Остановка публикации аудиопотока при нажатии Unpublish.
Room.unpublish()
code
Code Block |
---|
|
@Override
public void onClick(View view) {
if (mPublishButton.getTag() == null || Integer.valueOf(R.string.action_publish).equals(mPublishButton.getTag())) {
ActivityCompat.requestPermissions(AudioChatActivity.this,
new String[]{Manifest.permission.RECORD_AUDIO},
PUBLISH_REQUEST_CODE);
} else {
mPublishButton.setEnabled(false);
/**
* Stream is unpublished with method Room.unpublish().
*/
room.unpublish();
}
...
} |
13. Выход из комнаты при нажатии Leave
Room.leave()
code
Методу передается обработчик ответа REST хука, используемого при выходе из комнаты
Code Block |
---|
|
room.leave(new RestAppCommunicator.Handler() {
@Override
public void onAccepted(Data data) {
runOnUiThread(action);
}
@Override
public void onRejected(Data data) {
runOnUiThread(action);
}
}); |
14. Закрытие соединения
RoomManager.disconnect()
code
Code Block |
---|
|
mConnectButton.setEnabled(false);
/**
* Connection to WCS server is closed with method RoomManager.disconnect().
*/
roomManager.disconnect(); |
15. Включение/выключение аудио для публикуемого потока.
Stream.unmuteAudio()
, Stream.muteAudio()
code
Code Block |
---|
|
mMuteAudio = (Switch) findViewById(R.id.mute_audio);
mMuteAudio.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
stream.muteAudio();
} else {
stream.unmuteAudio();
}
}
}); |