Skip to content

Commit

Permalink
Update SDK with V4 Media Features (#26196)
Browse files Browse the repository at this point in the history
This pull request updates the SDK with the remaining V4 Media features,
including:
- Media Streaming
- Play TTS
- Play SSML
- Recognize choices
- Recognize speech
  • Loading branch information
atazimsft authored Jun 15, 2023
1 parent 79e943f commit 54f342d
Show file tree
Hide file tree
Showing 9 changed files with 363 additions and 32 deletions.
13 changes: 11 additions & 2 deletions .vscode/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
"Rollup",
"rrggbb",
"Rtsp",
"reoffer",
"reoffer",
"rushx",
"soundex",
"southcentralus",
Expand Down Expand Up @@ -246,7 +246,9 @@
},
{
"filename": "sdk/formrecognizer/ai-form-recognizer/README.md",
"words": ["iddocument"]
"words": [
"iddocument"
]
},
{
"filename": "sdk/formrecognizer/ai-form-recognizer/review/**/*.md",
Expand Down Expand Up @@ -278,6 +280,13 @@
"riscv"
]
},
{
"filename": "sdk/communication/communication-call-automation/review/**/*.md",
"words": [
"ssml",
"Ssml"
]
},
{
"filename": "sdk/communication/communication-common/review/**/*.md",
"words": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,22 +158,27 @@ export type CallLocatorType = "serverCallLocator" | "groupCallLocator";
export class CallMedia {
constructor(callConnectionId: string, endpoint: string, credential: KeyCredential | TokenCredential, options?: CallAutomationApiClientOptionalParams);
cancelAllOperations(): Promise<void>;
play(playSource: FileSource, playTo: CommunicationIdentifier[], playOptions?: PlayOptions): Promise<void>;
playToAll(playSource: FileSource, playOptions?: PlayOptions): Promise<void>;
play(playSource: FileSource | TextSource | SsmlSource, playTo: CommunicationIdentifier[], playOptions?: PlayOptions): Promise<void>;
playToAll(playSource: FileSource | TextSource | SsmlSource, playOptions?: PlayOptions): Promise<void>;
// Warning: (ae-forgotten-export) The symbol "Tone" needs to be exported by the entry point index.d.ts
sendDtmf(tones: Tone[], targetParticipant: CommunicationIdentifier, sendDtmfOptions?: SendDtmfOptions): Promise<void>;
startContinuousDtmfRecognition(targetParticipant: CommunicationIdentifier, continuousDtmfRecognitionOptions?: ContinuousDtmfRecognitionOptions): Promise<void>;
startRecognizing(targetParticipant: CommunicationIdentifier, maxTonesToCollect: number, recognizeOptions: CallMediaRecognizeDtmfOptions): Promise<void>;
startRecognizing(targetParticipant: CommunicationIdentifier, maxTonesToCollect: number, recognizeOptions: CallMediaRecognizeDtmfOptions | CallMediaRecognizeChoiceOptions | CallMediaRecognizeSpeechOptions | CallMediaRecognizeSpeechOrDtmfOptions): Promise<void>;
stopContinuousDtmfRecognition(targetParticipant: CommunicationIdentifier, continuousDtmfRecognitionOptions?: ContinuousDtmfRecognitionOptions): Promise<void>;
}

// @public
export interface CallMediaRecognizeDtmfOptions extends CallMediaRecognizeOptions {
export interface CallMediaRecognizeChoiceOptions extends CallMediaRecognizeOptions {
choices: Choice[];
// (undocumented)
readonly kind: "callMediaRecognizeChoiceOptions";
}

// @public
export interface CallMediaRecognizeDtmfOptions extends CallMediaRecognizeOptions {
interToneTimeoutInSeconds?: number;
// (undocumented)
readonly kind: "callMediaRecognizeDtmfOptions";
// (undocumented)
stopDtmfTones?: DtmfTone[];
}

Expand All @@ -193,6 +198,22 @@ export interface CallMediaRecognizeOptions extends OperationOptions {
stopCurrentOperations?: boolean;
}

// @public
export interface CallMediaRecognizeSpeechOptions extends CallMediaRecognizeOptions {
endSilenceTimeoutInMs?: number;
// (undocumented)
readonly kind: "callMediaRecognizeSpeechOptions";
}

// @public
export interface CallMediaRecognizeSpeechOrDtmfOptions extends CallMediaRecognizeOptions {
endSilenceTimeoutInMs?: number;
interToneTimeoutInSeconds?: number;
// (undocumented)
readonly kind: "callMediaRecognizeSpeechOrDtmfOptions";
stopDtmfTones?: DtmfTone[];
}

// @public
export interface CallParticipant {
identifier?: CommunicationIdentifier;
Expand Down Expand Up @@ -240,6 +261,14 @@ export interface ChannelAffinity {
targetParticipant: CommunicationIdentifier;
}

// @public
export interface Choice {
label: string;
phrases: string[];
// (undocumented)
tone?: DtmfTone;
}

// @public
export interface ContinuousDtmfRecognitionOptions extends OperationOptions {
operationContext?: string;
Expand Down Expand Up @@ -335,6 +364,12 @@ export interface FileSource extends PlaySource {
url: string;
}

// @public
export enum Gender {
Female = "female",
Male = "male"
}

// @public
export type GetCallConnectionPropertiesOptions = OperationOptions;

Expand Down Expand Up @@ -811,6 +846,14 @@ export interface SendDtmfOptions extends OperationOptions {
operationContext?: string;
}

// @public
export interface SsmlSource extends PlaySource {
// (undocumented)
readonly kind: "ssmlSource";
// (undocumented)
ssmlText: string;
}

// @public
export interface StartRecordingOptions extends OperationOptions {
audioChannelParticipantOrdering?: CommunicationIdentifier[];
Expand All @@ -825,6 +868,20 @@ export interface StartRecordingOptions extends OperationOptions {
// @public
export type StopRecordingOptions = OperationOptions;

// @public
export interface TextSource extends PlaySource {
// (undocumented)
readonly kind: "textSource";
// (undocumented)
sourceLocale?: string;
// (undocumented)
text: string;
// (undocumented)
voiceGender?: Gender;
// (undocumented)
voiceName?: string;
}

// @public
export interface ToneInfo extends Omit<RestToneInfo, "sequenceId" | "tone"> {
sequenceId: number;
Expand Down
129 changes: 117 additions & 12 deletions sdk/communication/communication-call-automation/src/callMedia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
PlayRequest,
PlaySourceInternal,
FileSourceInternal,
TextSourceInternal,
SsmlSourceInternal,
KnownPlaySourceType,
RecognizeRequest,
KnownRecognizeInputType,
Expand All @@ -15,6 +17,7 @@ import {
ContinuousDtmfRecognitionRequest,
SendDtmfRequest,
Tone,
SpeechOptions,
} from "./generated/src";

import { CallMediaImpl } from "./generated/src/operations";
Expand All @@ -25,13 +28,16 @@ import {
serializeCommunicationIdentifier,
} from "@azure/communication-common";

import { FileSource } from "./models/models";
import { FileSource, TextSource, SsmlSource } from "./models/models";

import {
PlayOptions,
CallMediaRecognizeDtmfOptions,
CallMediaRecognizeChoiceOptions,
ContinuousDtmfRecognitionOptions,
SendDtmfOptions,
CallMediaRecognizeSpeechOptions,
CallMediaRecognizeSpeechOrDtmfOptions,
} from "./models/options";
import { KeyCredential, TokenCredential } from "@azure/core-auth";

Expand All @@ -55,8 +61,10 @@ export class CallMedia {
this.callMedia = new CallMediaImpl(this.callAutomationApiClient);
}

private createPlaySourceInternal(playSource: FileSource): PlaySourceInternal {
if (playSource.kind === "fileSource" || playSource.kind === undefined) {
private createPlaySourceInternal(
playSource: FileSource | TextSource | SsmlSource
): PlaySourceInternal {
if (playSource.kind === "fileSource") {
const fileSource: FileSourceInternal = {
uri: playSource.url,
};
Expand All @@ -65,6 +73,27 @@ export class CallMedia {
fileSource: fileSource,
playSourceId: playSource.playSourceId,
};
} else if (playSource.kind === "textSource") {
const textSource: TextSourceInternal = {
text: playSource.text,
sourceLocale: playSource.sourceLocale,
voiceGender: playSource.voiceGender,
voiceName: playSource.voiceName,
};
return {
sourceType: KnownPlaySourceType.Text,
textSource: textSource,
playSourceId: playSource.playSourceId,
};
} else if (playSource.kind === "ssmlSource") {
const ssmlSource: SsmlSourceInternal = {
ssmlText: playSource.ssmlText,
};
return {
sourceType: KnownPlaySourceType.Ssml,
ssmlSource: ssmlSource,
playSourceId: playSource.playSourceId,
};
}
throw new Error("Invalid play source");
}
Expand All @@ -77,7 +106,7 @@ export class CallMedia {
* @param playOptions - Additional attributes for play.
*/
public async play(
playSource: FileSource,
playSource: FileSource | TextSource | SsmlSource,
playTo: CommunicationIdentifier[],
playOptions: PlayOptions = { loop: false }
): Promise<void> {
Expand All @@ -103,7 +132,7 @@ export class CallMedia {
* @param playOptions - Additional attributes for play.
*/
public async playToAll(
playSource: FileSource,
playSource: FileSource | TextSource | SsmlSource,
playOptions: PlayOptions = { loop: false }
): Promise<void> {
const playRequest: PlayRequest = {
Expand All @@ -124,12 +153,13 @@ export class CallMedia {
private createRecognizeRequest(
targetParticipant: CommunicationIdentifier,
maxTonesToCollect: number,
recognizeOptions: CallMediaRecognizeDtmfOptions
recognizeOptions:
| CallMediaRecognizeDtmfOptions
| CallMediaRecognizeChoiceOptions
| CallMediaRecognizeSpeechOptions
| CallMediaRecognizeSpeechOrDtmfOptions
): RecognizeRequest {
if (
recognizeOptions.kind === "callMediaRecognizeDtmfOptions" ||
recognizeOptions.kind === undefined
) {
if (recognizeOptions.kind === "callMediaRecognizeDtmfOptions") {
const dtmfOptionsInternal: DtmfOptions = {
interToneTimeoutInSeconds: recognizeOptions.interToneTimeoutInSeconds
? recognizeOptions.interToneTimeoutInSeconds
Expand All @@ -154,8 +184,79 @@ export class CallMedia {
recognizeOptions: recognizeOptionsInternal,
operationContext: recognizeOptions.operationContext,
};
} else if (recognizeOptions.kind === "callMediaRecognizeChoiceOptions") {
const recognizeOptionsInternal: RecognizeOptions = {
interruptPrompt: recognizeOptions.interruptPrompt,
initialSilenceTimeoutInSeconds: recognizeOptions.initialSilenceTimeoutInSeconds
? recognizeOptions.initialSilenceTimeoutInSeconds
: 5,
targetParticipant: serializeCommunicationIdentifier(targetParticipant),
choices: recognizeOptions.choices,
};
return {
recognizeInputType: KnownRecognizeInputType.Choices,
playPrompt: recognizeOptions.playPrompt
? this.createPlaySourceInternal(recognizeOptions.playPrompt)
: undefined,
interruptCallMediaOperation: recognizeOptions.interruptCallMediaOperation,
recognizeOptions: recognizeOptionsInternal,
operationContext: recognizeOptions.operationContext,
};
} else if (recognizeOptions.kind === "callMediaRecognizeSpeechOptions") {
const speechOptions: SpeechOptions = {
endSilenceTimeoutInMs: recognizeOptions.endSilenceTimeoutInMs
? recognizeOptions.endSilenceTimeoutInMs
: 2,
};
const recognizeOptionsInternal: RecognizeOptions = {
interruptPrompt: recognizeOptions.interruptPrompt,
initialSilenceTimeoutInSeconds: recognizeOptions.initialSilenceTimeoutInSeconds
? recognizeOptions.initialSilenceTimeoutInSeconds
: 5,
targetParticipant: serializeCommunicationIdentifier(targetParticipant),
speechOptions: speechOptions,
};
return {
recognizeInputType: KnownRecognizeInputType.Speech,
playPrompt: recognizeOptions.playPrompt
? this.createPlaySourceInternal(recognizeOptions.playPrompt)
: undefined,
interruptCallMediaOperation: recognizeOptions.interruptCallMediaOperation,
recognizeOptions: recognizeOptionsInternal,
operationContext: recognizeOptions.operationContext,
};
} else if (recognizeOptions.kind === "callMediaRecognizeSpeechOrDtmfOptions") {
const dtmfOptionsInternal: DtmfOptions = {
interToneTimeoutInSeconds: recognizeOptions.interToneTimeoutInSeconds
? recognizeOptions.interToneTimeoutInSeconds
: 2,
maxTonesToCollect: maxTonesToCollect,
stopTones: recognizeOptions.stopDtmfTones,
};
const speechOptions: SpeechOptions = {
endSilenceTimeoutInMs: recognizeOptions.endSilenceTimeoutInMs
? recognizeOptions.endSilenceTimeoutInMs
: 2,
};
const recognizeOptionsInternal: RecognizeOptions = {
interruptPrompt: recognizeOptions.interruptPrompt,
initialSilenceTimeoutInSeconds: recognizeOptions.initialSilenceTimeoutInSeconds
? recognizeOptions.initialSilenceTimeoutInSeconds
: 5,
targetParticipant: serializeCommunicationIdentifier(targetParticipant),
speechOptions: speechOptions,
dtmfOptions: dtmfOptionsInternal,
};
return {
recognizeInputType: KnownRecognizeInputType.Speech,
playPrompt: recognizeOptions.playPrompt
? this.createPlaySourceInternal(recognizeOptions.playPrompt)
: undefined,
interruptCallMediaOperation: recognizeOptions.interruptCallMediaOperation,
recognizeOptions: recognizeOptionsInternal,
operationContext: recognizeOptions.operationContext,
};
}

throw new Error("Invalid recognizeOptions");
}

Expand All @@ -166,7 +267,11 @@ export class CallMedia {
public async startRecognizing(
targetParticipant: CommunicationIdentifier,
maxTonesToCollect: number,
recognizeOptions: CallMediaRecognizeDtmfOptions
recognizeOptions:
| CallMediaRecognizeDtmfOptions
| CallMediaRecognizeChoiceOptions
| CallMediaRecognizeSpeechOptions
| CallMediaRecognizeSpeechOrDtmfOptions
): Promise<void> {
return this.callMedia.recognize(
this.callConnectionId,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 54f342d

Please sign in to comment.