Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding PlayAudio Api to Conversation Client (Out-Call) #22021

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