Skip to content

Commit ac0eeb2

Browse files
v-pivamshiVinothini Dharmaraj
andauthored
Added get recording result api. (Azure#47692)
* added get call recording api and Interrupt Hold Audio flag in play options. * added live test. * record the live test. * added live test. * Fixing the Analyze * skipping the recording result live test due to current latency to get the recording result is 2 mints * updaitng the test to test chunks --------- Co-authored-by: Vinothini Dharmaraj <[email protected]>
1 parent d493d2d commit ac0eeb2

File tree

4 files changed

+151
-2
lines changed

4 files changed

+151
-2
lines changed

sdk/communication/Azure.Communication.CallAutomation/api/Azure.Communication.CallAutomation.net8.0.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,8 @@ protected CallRecording() { }
526526
public virtual Azure.Response DownloadTo(System.Uri sourceLocation, string destinationPath, Azure.Communication.CallAutomation.ContentTransferOptions transferOptions = default(Azure.Communication.CallAutomation.ContentTransferOptions), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
527527
public virtual System.Threading.Tasks.Task<Azure.Response> DownloadToAsync(System.Uri sourceLocation, System.IO.Stream destinationStream, Azure.Communication.CallAutomation.ContentTransferOptions transferOptions = default(Azure.Communication.CallAutomation.ContentTransferOptions), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
528528
public virtual System.Threading.Tasks.Task<Azure.Response> DownloadToAsync(System.Uri sourceLocation, string destinationPath, Azure.Communication.CallAutomation.ContentTransferOptions transferOptions = default(Azure.Communication.CallAutomation.ContentTransferOptions), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
529+
public virtual Azure.Response<Azure.Communication.CallAutomation.RecordingResult> GetRecording(string recordingId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
530+
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Communication.CallAutomation.RecordingResult>> GetRecordingAsync(string recordingId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
529531
public virtual Azure.Response<Azure.Communication.CallAutomation.RecordingStateResult> GetState(string recordingId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
530532
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Communication.CallAutomation.RecordingStateResult>> GetStateAsync(string recordingId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
531533
public virtual Azure.Response Pause(string recordingId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }

sdk/communication/Azure.Communication.CallAutomation/api/Azure.Communication.CallAutomation.netstandard2.0.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,8 @@ protected CallRecording() { }
526526
public virtual Azure.Response DownloadTo(System.Uri sourceLocation, string destinationPath, Azure.Communication.CallAutomation.ContentTransferOptions transferOptions = default(Azure.Communication.CallAutomation.ContentTransferOptions), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
527527
public virtual System.Threading.Tasks.Task<Azure.Response> DownloadToAsync(System.Uri sourceLocation, System.IO.Stream destinationStream, Azure.Communication.CallAutomation.ContentTransferOptions transferOptions = default(Azure.Communication.CallAutomation.ContentTransferOptions), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
528528
public virtual System.Threading.Tasks.Task<Azure.Response> DownloadToAsync(System.Uri sourceLocation, string destinationPath, Azure.Communication.CallAutomation.ContentTransferOptions transferOptions = default(Azure.Communication.CallAutomation.ContentTransferOptions), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
529+
public virtual Azure.Response<Azure.Communication.CallAutomation.RecordingResult> GetRecording(string recordingId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
530+
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Communication.CallAutomation.RecordingResult>> GetRecordingAsync(string recordingId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
529531
public virtual Azure.Response<Azure.Communication.CallAutomation.RecordingStateResult> GetState(string recordingId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
530532
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Communication.CallAutomation.RecordingStateResult>> GetStateAsync(string recordingId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
531533
public virtual Azure.Response Pause(string recordingId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }

sdk/communication/Azure.Communication.CallAutomation/src/CallRecording.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,50 @@ public virtual Response Resume(string recordingId, CancellationToken cancellatio
367367
}
368368
}
369369

370+
/// <summary> Get recording result. This includes the download URLs for the recording chunks. </summary>
371+
/// <param name="recordingId"> The recording id. </param>
372+
/// <param name="cancellationToken"> The cancellation token to use. </param>
373+
/// <exception cref="ArgumentNullException"> <paramref name="recordingId"/> is null. </exception>
374+
public virtual Response<RecordingResult> GetRecording(string recordingId, CancellationToken cancellationToken = default)
375+
{
376+
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(CallRecording)}.{nameof(GetRecording)}");
377+
scope.Start();
378+
try
379+
{
380+
return _callRecordingRestClient.GetRecordingResult(
381+
recordingId: recordingId,
382+
cancellationToken: cancellationToken
383+
);
384+
}
385+
catch (Exception ex)
386+
{
387+
scope.Failed(ex);
388+
throw;
389+
}
390+
}
391+
392+
/// <summary> Get recording result. This includes the download URLs for the recording chunks. </summary>
393+
/// <param name="recordingId"> The recording id. </param>
394+
/// <param name="cancellationToken"> The cancellation token to use. </param>
395+
/// <exception cref="ArgumentNullException"> <paramref name="recordingId"/> is null. </exception>
396+
public virtual async Task<Response<RecordingResult>> GetRecordingAsync(string recordingId, CancellationToken cancellationToken = default)
397+
{
398+
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(CallRecording)}.{nameof(GetRecording)}");
399+
scope.Start();
400+
try
401+
{
402+
return await _callRecordingRestClient.GetRecordingResultAsync(
403+
recordingId: recordingId,
404+
cancellationToken: cancellationToken
405+
).ConfigureAwait(false);
406+
}
407+
catch (Exception ex)
408+
{
409+
scope.Failed(ex);
410+
throw;
411+
}
412+
}
413+
370414
/// <summary>
371415
/// The <see cref="DownloadStreamingAsync(Uri, HttpRange, CancellationToken)"/>
372416
/// operation downloads the recording's content.

sdk/communication/Azure.Communication.CallAutomation/tests/CallRecordings/CallRecordingAutomatedLiveTests.cs

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
// Licensed under the MIT License.
33

44
using System;
5-
using System.Collections.Generic;
65
using System.Threading.Tasks;
7-
using System.Xml;
86
using Azure.Communication.CallAutomation.Tests.Infrastructure;
97
using Azure.Core.TestFramework;
108
using Microsoft.AspNetCore.Http;
@@ -405,5 +403,108 @@ public async Task StartRecordingWithCallConnectionIdTest()
405403
await CleanUpCall(client, callConnectionId, uniqueId);
406404
}
407405
}
406+
407+
[Ignore(reason: "Skipping this currently getrecording api taking more than 2 mints to get the recording result")]
408+
[RecordedTest]
409+
public async Task GetRecordingTest()
410+
{
411+
/* Test case: ACS to ACS call
412+
* 1. create a CallAutomationClient.
413+
* 2. create a call from source to one ACS target.
414+
* 3. get updated call properties and check for the connected state.
415+
* 4. start recording the call with channel affinity
416+
* 5. stop recording the call
417+
* 6. get call recording
418+
* 7. hang up the call.
419+
* 8. once call is hung up, verify disconnected event
420+
*/
421+
// create caller and receiver
422+
CommunicationUserIdentifier target = await CreateIdentityUserAsync().ConfigureAwait(false);
423+
CommunicationUserIdentifier user = await CreateIdentityUserAsync().ConfigureAwait(false);
424+
CallAutomationClient client = CreateInstrumentedCallAutomationClientWithConnectionString(user);
425+
CallAutomationClient targetClient = CreateInstrumentedCallAutomationClientWithConnectionString(target);
426+
string? callConnectionId = null, uniqueId = null;
427+
428+
try
429+
{
430+
try
431+
{
432+
// setup service bus
433+
uniqueId = await ServiceBusWithNewCall(user, target);
434+
435+
// create call and assert response
436+
var createCallOptions = new CreateCallOptions(new CallInvite(target), new Uri(TestEnvironment.DispatcherCallback + $"?q={uniqueId}"));
437+
CreateCallResult response = await client.CreateCallAsync(createCallOptions).ConfigureAwait(false);
438+
callConnectionId = response.CallConnectionProperties.CallConnectionId;
439+
Assert.IsNotEmpty(response.CallConnectionProperties.CallConnectionId);
440+
441+
// wait for incomingcall context
442+
string? incomingCallContext = await WaitForIncomingCallContext(uniqueId, TimeSpan.FromSeconds(20));
443+
Assert.IsNotNull(incomingCallContext);
444+
445+
// answer the call
446+
var answerCallOptions = new AnswerCallOptions(incomingCallContext, new Uri(TestEnvironment.DispatcherCallback));
447+
var answerResponse = await targetClient.AnswerCallAsync(answerCallOptions);
448+
Assert.AreEqual(answerResponse.GetRawResponse().Status, StatusCodes.Status200OK);
449+
450+
// wait for callConnected
451+
var connectedEvent = await WaitForEvent<CallConnected>(callConnectionId, TimeSpan.FromSeconds(20));
452+
Assert.IsNotNull(connectedEvent);
453+
Assert.IsTrue(connectedEvent is CallConnected);
454+
Assert.IsTrue(((CallConnected)connectedEvent!).CallConnectionId == callConnectionId);
455+
456+
// test get properties
457+
Response<CallConnectionProperties> properties = await response.CallConnection.GetCallConnectionPropertiesAsync().ConfigureAwait(false);
458+
Assert.AreEqual(CallConnectionState.Connected, properties.Value.CallConnectionState);
459+
460+
// try start recording unmixed audio with channel affinity
461+
var startRecordingOptions =
462+
new StartRecordingOptions(new ServerCallLocator(properties.Value.ServerCallId))
463+
{
464+
RecordingChannel = RecordingChannel.Unmixed,
465+
RecordingContent = RecordingContent.Audio,
466+
RecordingFormat = RecordingFormat.Wav,
467+
RecordingStateCallbackUri = new Uri(TestEnvironment.DispatcherCallback),
468+
};
469+
startRecordingOptions.AudioChannelParticipantOrdering.Add(user);
470+
startRecordingOptions.AudioChannelParticipantOrdering.Add(target);
471+
var startRecordingResponse = await client.GetCallRecording().StartAsync(startRecordingOptions);
472+
Assert.AreEqual(StatusCodes.Status200OK, startRecordingResponse.GetRawResponse().Status);
473+
Assert.NotNull(startRecordingResponse.Value.RecordingId);
474+
475+
// try stop recording
476+
var stopRecordingResponse = await client.GetCallRecording().StopAsync(startRecordingResponse.Value.RecordingId);
477+
Assert.AreEqual(StatusCodes.Status204NoContent, stopRecordingResponse.Status);
478+
479+
// get call recording result
480+
var recordingResult = await client.GetCallRecording().GetRecordingAsync(startRecordingResponse.Value.RecordingId).ConfigureAwait(false);
481+
Assert.NotNull(recordingResult.Value);
482+
Assert.NotNull(recordingResult.Value.RecordingDurationMs);
483+
Assert.NotNull(recordingResult.Value.RecordingStorageInfo);
484+
Assert.NotNull(recordingResult.Value.RecordingStorageInfo.RecordingChunks);
485+
Assert.AreEqual(recordingResult.Value.RecordingId, startRecordingResponse.Value.RecordingId);
486+
487+
// try hangup
488+
await response.CallConnection.HangUpAsync(true).ConfigureAwait(false);
489+
var disconnectedEvent = await WaitForEvent<CallDisconnected>(callConnectionId, TimeSpan.FromSeconds(20));
490+
Assert.IsNotNull(disconnectedEvent);
491+
Assert.IsTrue(disconnectedEvent is CallDisconnected);
492+
Assert.IsTrue(((CallDisconnected)disconnectedEvent!).CallConnectionId == callConnectionId);
493+
callConnectionId = null;
494+
}
495+
catch (Exception)
496+
{
497+
throw;
498+
}
499+
}
500+
catch (Exception ex)
501+
{
502+
Assert.Fail($"Unexpected error: {ex}");
503+
}
504+
finally
505+
{
506+
await CleanUpCall(client, callConnectionId, uniqueId);
507+
}
508+
}
408509
}
409510
}

0 commit comments

Comments
 (0)