Skip to content

Commit

Permalink
Adding PlayAudio Api to Conversation Client (Out-Call) (#22021)
Browse files Browse the repository at this point in the history
* Added the PlayAudio Api for Out-call/ConversationClient

* Added test for the playAudio apis

* Fixed test caused due to merge coonflicts

* Minor fixes

Co-authored-by: Paresh Arvind Patil <papati@microsoft.com>
  • Loading branch information
Paresh-Arvind-Patil and Paresh Arvind Patil authored Jun 3, 2021
1 parent 07b7590 commit 32dd081
Show file tree
Hide file tree
Showing 14 changed files with 463 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@

import com.azure.communication.callingserver.implementation.AzureCommunicationCallingServerServiceImpl;
import com.azure.communication.callingserver.implementation.ConversationsImpl;
import com.azure.communication.callingserver.implementation.models.GetCallRecordingStateResponse;
import com.azure.communication.callingserver.implementation.models.StartCallRecordingResponse;
import com.azure.communication.callingserver.models.GetCallRecordingStateResult;
import com.azure.communication.callingserver.models.PlayAudioResponse;
import com.azure.communication.callingserver.implementation.converters.InviteParticipantsRequestConverter;
import com.azure.communication.callingserver.implementation.converters.JoinCallRequestConverter;
import com.azure.communication.callingserver.implementation.models.GetCallRecordingStateResponse;
import com.azure.communication.callingserver.implementation.models.InviteParticipantsRequest;
import com.azure.communication.callingserver.implementation.models.PlayAudioRequest;
import com.azure.communication.callingserver.implementation.models.StartCallRecordingRequest;
import com.azure.communication.callingserver.implementation.models.StartCallRecordingResponse;
import com.azure.communication.callingserver.models.GetCallRecordingStateResult;
import com.azure.communication.callingserver.models.JoinCallOptions;
import com.azure.communication.callingserver.models.JoinCallResponse;
import com.azure.communication.callingserver.models.StartCallRecordingResult;
Expand Down Expand Up @@ -469,6 +471,82 @@ Mono<Response<GetCallRecordingStateResult>> getRecordingStateWithResponse(String
}
}

/**
* Play audio in a call.
*
* @param conversationId The conversation id.
* @param audioFileUri The uri of the audio file .
* @param audioFileId Tne id for the media in the AudioFileUri, using which we cache the media resource.
* @param callbackUri The callback Uri to receive PlayAudio status notifications.
* @param operationContext The operation context.
* @return the response payload for play audio operation.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono<PlayAudioResponse> playAudio(String conversationId, String audioFileUri, String audioFileId, String callbackUri, String operationContext) {
try {
Objects.requireNonNull(conversationId, "'conversationId' cannot be null.");
Objects.requireNonNull(audioFileUri, "'audioFileUri' cannot be null.");

//Currently we do not support loop on the audio media for out-call, thus setting the loop to false
PlayAudioRequest playAudioRequest = new PlayAudioRequest().
setAudioFileUri(audioFileUri).setLoop(false).setAudioFileId(audioFileId).setCallbackUri(callbackUri).setOperationContext(operationContext);
return playAudio(conversationId, playAudioRequest);

} catch (RuntimeException ex) {
return monoError(logger, ex);
}
}

public Mono<PlayAudioResponse> playAudio(String conversationId, PlayAudioRequest request) {
try {
Objects.requireNonNull(conversationId, "'conversationId' cannot be null.");
Objects.requireNonNull(request, "'request' cannot be null.");

return this.conversationsClient.playAudioAsync(conversationId, request).flatMap(
(PlayAudioResponse response) -> {
return Mono.just(response);
});
} catch (RuntimeException ex) {
return monoError(logger, ex);
}
}
/**
* Play audio in a call.
*
* @param conversationId The conversation id.
* @param audioFileUri The uri of the audio file .
* @param audioFileId Tne id for the media in the AudioFileUri, using which we cache the media resource.
* @param callbackUri The callback Uri to receive PlayAudio status notifications.
* @param operationContext The operation context.
* @return the response payload for play audio operation.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono<Response<PlayAudioResponse>> playAudioWithResponse(String conversationId, String audioFileUri, String audioFileId, String callbackUri, String operationContext) {

//Currently we do not support loop on the audio media for out-call, thus setting the loop to false
PlayAudioRequest playAudioRequest = new PlayAudioRequest().
setAudioFileUri(audioFileUri).setLoop(false).setAudioFileId(audioFileId).setCallbackUri(callbackUri).setOperationContext(operationContext);
return playAudioWithResponse(conversationId, playAudioRequest, null);
}

Mono<Response<PlayAudioResponse>> playAudioWithResponse(String conversationId, PlayAudioRequest request, Context context) {
try {
Objects.requireNonNull(conversationId, "'conversationId' cannot be null.");
Objects.requireNonNull(request, "'request' cannot be null.");
return withContext(contextValue -> {
if (context != null) {
contextValue = context;
}
return this.conversationsClient.playAudioWithResponseAsync(conversationId, request).flatMap((
Response<PlayAudioResponse> response) -> {
return Mono.just(new SimpleResponse<>(response, response.getValue()));
});
});
} catch (RuntimeException ex) {
return monoError(logger, ex);
}
}

private StartCallRecordingRequest createStartCallRecordingRequest(URI recordingStateCallbackUri) {
StartCallRecordingRequest request = new StartCallRecordingRequest();
request.setRecordingStateCallbackUri(recordingStateCallbackUri.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

package com.azure.communication.callingserver;

import com.azure.communication.callingserver.implementation.models.PlayAudioRequest;
import com.azure.communication.callingserver.models.GetCallRecordingStateResult;
import com.azure.communication.callingserver.models.JoinCallOptions;
import com.azure.communication.callingserver.models.JoinCallResponse;
import com.azure.communication.callingserver.models.PlayAudioResponse;
import com.azure.communication.callingserver.models.StartCallRecordingResult;
import com.azure.communication.common.CommunicationIdentifier;
import com.azure.core.annotation.ReturnType;
Expand Down Expand Up @@ -236,4 +238,43 @@ public Response<GetCallRecordingStateResult> getRecordingStateWithResponse(Strin
String recordingId, Context context) {
return conversationAsyncClient.getRecordingStateWithResponse(conversationId, recordingId, context).block();
}

/**
* Play audio in a call.
*
* @param conversationId The conversation id.
* @param audioFileUri The media resource uri of the play audio request.
* @param audioFileId An id for the media in the AudioFileUri, using which we cache the media.
* @param callbackUri The callback Uri to receive PlayAudio status notifications.
* @param operationContext The value to identify context of the operation.
* @return the response payload for play audio operation.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public PlayAudioResponse playAudio(String conversationId, String audioFileUri, String audioFileId, String callbackUri, String operationContext) {

//Currently we do not support loop on the audio media for out-call, thus setting the loop to false
PlayAudioRequest playAudioRequest = new PlayAudioRequest().
setAudioFileUri(audioFileUri).setLoop(false).setAudioFileId(audioFileId).setCallbackUri(callbackUri).setOperationContext(operationContext);
return conversationAsyncClient.playAudio(conversationId, playAudioRequest).block();
}

/**
* Play audio in a call.
*
* @param conversationId The conversation id.
* @param audioFileUri The media resource uri of the play audio request.
* @param audioFileId An id for the media in the AudioFileUri, using which we cache the media.
* @param callbackUri The callback Uri to receive PlayAudio status notifications.
* @param operationContext The value to identify context of the operation.
* @param context A {@link Context} representing the request context.
* @return the response payload for play audio operation.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
public Response<PlayAudioResponse> playAudioWithResponse(String conversationId, String audioFileUri, String audioFileId, String callbackUri, String operationContext, Context context) {

//Currently we do not support loop on the audio media for out-call, thus setting the loop to false
PlayAudioRequest playAudioRequest = new PlayAudioRequest().
setAudioFileUri(audioFileUri).setLoop(false).setAudioFileId(audioFileId).setCallbackUri(callbackUri).setOperationContext(operationContext);
return conversationAsyncClient.playAudioWithResponse(conversationId, playAudioRequest, context).block();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

import java.net.URI;
import java.net.URISyntaxException;
import java.util.UUID;

import com.azure.communication.callingserver.models.CallRecordingState;
import com.azure.communication.callingserver.implementation.models.CommunicationErrorException;
import com.azure.communication.callingserver.models.GetCallRecordingStateResult;
import com.azure.communication.callingserver.models.PlayAudioResponse;
import com.azure.communication.callingserver.models.StartCallRecordingResult;
import com.azure.core.http.HttpClient;
import com.azure.core.http.rest.Response;
Expand All @@ -24,13 +26,13 @@
* test will not run in LIVE or RECORD as they cannot get their own conversationId.
*/
public class ConversationAsyncClientTests extends CallingServerTestBase {
private String conversationId = "aHR0cHM6Ly9jb252LXVzc2MtMDkuY29udi5za3lwZS5jb20vY29udi9LQTd3NzZVZk4wcUVKc1dOSFBwOHB3P2k9MTg5JmU9NjM3NTc4Mjc3MjE0Mzg0Njkz";
private String conversationId = "aHR0cHM6Ly9jb252LXVzZWEtMDcuY29udi5za3lwZS5jb20vY29udi85M0FnUnVMbGdVdUU2MWdxa1pnaHVBP2k9NTEmZT02Mzc1NzY1NzUwOTIzMTQ3OTU";

@ParameterizedTest
@MethodSource("com.azure.core.test.TestBase#getHttpClients")
public void runAllClientFunctionsAsync(HttpClient httpClient) throws URISyntaxException, InterruptedException {
ConversationClientBuilder builder = getConversationClientUsingConnectionString(httpClient);
ConversationAsyncClient conversationAsyncClient = setupAsyncClient(builder, "runAllClientFunctions");
ConversationAsyncClient conversationAsyncClient = setupAsyncClient(builder, "runAllClientFunctionsAsync");
String recordingId = "";
URI recordingStateCallbackUri = new URI("https://dev.skype.net:6448");

Expand All @@ -56,7 +58,7 @@ public void runAllClientFunctionsAsync(HttpClient httpClient) throws URISyntaxEx
@MethodSource("com.azure.core.test.TestBase#getHttpClients")
public void runAllClientFunctionsWithResponseAsync(HttpClient httpClient) throws URISyntaxException, InterruptedException {
ConversationClientBuilder builder = getConversationClientUsingConnectionString(httpClient);
ConversationAsyncClient conversationAsyncClient = setupAsyncClient(builder, "runAllClientFunctions");
ConversationAsyncClient conversationAsyncClient = setupAsyncClient(builder, "runAllClientFunctionsWithResponseAsync");
String recordingId = "";
URI recordingStateCallbackUri = new URI("https://dev.skype.net:6448");
System.out.println("conversationId: " + conversationId);
Expand All @@ -81,11 +83,53 @@ public void runAllClientFunctionsWithResponseAsync(HttpClient httpClient) throws
}
}

@ParameterizedTest
@MethodSource("com.azure.core.test.TestBase#getHttpClients")
public void runPlayAudioFunctionAsync(HttpClient httpClient) throws URISyntaxException, InterruptedException {
ConversationClientBuilder builder = getConversationClientUsingConnectionString(httpClient);
ConversationAsyncClient conversationAsyncClient = setupAsyncClient(builder, "runPlayAudioFunctionAsync");

var operationContext = "ac794123-3820-4979-8e2d-50c7d3e07b12";
String audioFileUri = "https://host.app/audio/bot-callcenter-intro.wav";
String callbackUri = "https://dev.skype.net:6448";

System.out.println("conversationId: " + conversationId);
try {
PlayAudioResponse playAudioResponse = conversationAsyncClient.playAudio(conversationId, audioFileUri, UUID.randomUUID().toString(), callbackUri, operationContext).block();
CallingServerTestUtils.validatePlayAudioResult(playAudioResponse, operationContext);

} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
throw e;
}
}

@ParameterizedTest
@MethodSource("com.azure.core.test.TestBase#getHttpClients")
public void runPlayAudioFunctionWithResponseAsync(HttpClient httpClient) throws URISyntaxException, InterruptedException {
ConversationClientBuilder builder = getConversationClientUsingConnectionString(httpClient);
ConversationAsyncClient conversationAsyncClient = setupAsyncClient(builder, "runPlayAudioFunctionWithResponseAsync");

var operationContext = "ac794123-3820-4979-8e2d-50c7d3e07b12";
String audioFileUri = "https://host.app/audio/bot-callcenter-intro.wav";
String callbackUri = "https://dev.skype.net:6448";

System.out.println("conversationId: " + conversationId);
try {
Response<PlayAudioResponse> playAudioResponse = conversationAsyncClient.playAudioWithResponse(conversationId, audioFileUri, UUID.randomUUID().toString(), callbackUri, operationContext).block();
CallingServerTestUtils.validatePlayAudioResponse(playAudioResponse, operationContext);

} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
throw e;
}
}

@ParameterizedTest
@MethodSource("com.azure.core.test.TestBase#getHttpClients")
public void startRecordingFailsAsync(HttpClient httpClient) throws URISyntaxException, InterruptedException {
ConversationClientBuilder builder = getConversationClientUsingConnectionString(httpClient);
ConversationAsyncClient conversationAsyncClient = setupAsyncClient(builder, "runAllClientFunctions");
ConversationAsyncClient conversationAsyncClient = setupAsyncClient(builder, "startRecordingFailsAsync");
var invalidConversationId = "aHR0cHM6Ly9jb252LXVzd2UtMDkuY29udi5za3lwZS5jb20vY29udi9EZVF2WEJGVVlFV1NNZkFXYno2azN3P2k9MTEmZT02Mzc1NzIyMjk0Mjc0NTI4Nzk=";
URI recordingStateCallbackUri = new URI("https://dev.skype.net:6448");
System.out.println("conversationId: " + invalidConversationId);
Expand Down
Loading

0 comments on commit 32dd081

Please sign in to comment.