|
| 1 | +--- |
| 2 | +title: Include file - C# |
| 3 | +description: C# Audio Streaming quickstart |
| 4 | +services: azure-communication-services |
| 5 | +author: Alvin |
| 6 | +ms.service: azure-communication-services |
| 7 | +ms.subservice: call-automation |
| 8 | +ms.date: 07/15/2024 |
| 9 | +ms.topic: include |
| 10 | +ms.topic: Include file |
| 11 | +ms.author: alvinhan |
| 12 | +--- |
| 13 | + |
| 14 | +## Prerequisites |
| 15 | +- An Azure account with an active subscription, for details see [Create an account for free.](https://azure.microsoft.com/free/) |
| 16 | +- An Azure Communication Services resource. See [Create an Azure Communication Services resource](../../../quickstarts/create-communication-resource.md?tabs=windows&pivots=platform-azp). |
| 17 | +- A new web service application created using the [Call Automation SDK](../../../quickstarts/call-automation/callflows-for-customer-interactions.md). |
| 18 | +- The latest [.NET library](https://dotnet.microsoft.com/download/dotnet-core) for your operating system. |
| 19 | +- A websocket server that can receive media streams. |
| 20 | + |
| 21 | +## Set up a websocket server |
| 22 | +Azure Communication Services requires your server application to set up a WebSocket server to stream audio in real-time. WebSocket is a standardized protocol that provides a full-duplex communication channel over a single TCP connection. |
| 23 | +You can optionally use Azure services Azure WebApps that allows you to create an application to receive audio streams over a websocket connection. Follow this [quickstart](https://azure.microsoft.com/blog/introduction-to-websockets-on-windows-azure-web-sites/). |
| 24 | + |
| 25 | +## Establish a call |
| 26 | +Establish a call and provide streaming details |
| 27 | + |
| 28 | +``` C# |
| 29 | +MediaStreamingOptions mediaStreamingOptions = new MediaStreamingOptions( |
| 30 | + new Uri("<WEBSOCKET URL>"), |
| 31 | + MediaStreamingContent.Audio, |
| 32 | + MediaStreamingAudioChannel.Mixed, |
| 33 | + MediaStreamingTransport.Websocket, |
| 34 | + false); |
| 35 | + |
| 36 | + var createCallOptions = new CreateCallOptions(callInvite, callbackUri) |
| 37 | + { |
| 38 | + CallIntelligenceOptions = new CallIntelligenceOptions() { CognitiveServicesEndpoint = new Uri(cognitiveServiceEndpoint) }, |
| 39 | + MediaStreamingOptions = mediaStreamingOptions, |
| 40 | + }; |
| 41 | + |
| 42 | + CreateCallResult createCallResult = await callAutomationClient.CreateCallAsync(createCallOptions); |
| 43 | +``` |
| 44 | + |
| 45 | +## Start audio streaming |
| 46 | +How to start audio streaming: |
| 47 | +``` C# |
| 48 | +StartMediaStreamingOptions options = new StartMediaStreamingOptions() |
| 49 | + { |
| 50 | + OperationCallbackUri = new Uri(callbackUriHost), |
| 51 | + OperationContext = "startMediaStreamingContext" |
| 52 | + }; |
| 53 | + await callMedia.StartMediaStreamingAsync(options); |
| 54 | +``` |
| 55 | +When Azure Communication Services receives the URL for your WebSocket server, it creates a connection to it. Once Azure Communication Services successfully connects to your WebSocket server and streaming is started, it will send through the first data packet, which contains metadata about the incoming media packets. |
| 56 | + |
| 57 | +The metadata packet will look like this: |
| 58 | +``` code |
| 59 | +{ |
| 60 | + "kind": <string> // What kind of data this is, e.g. AudioMetadata, AudioData. |
| 61 | + "audioMetadata": { |
| 62 | + "subscriptionId": <string>, // unique identifier for a subscription request |
| 63 | + "encoding":<string>, // PCM only supported |
| 64 | + "sampleRate": <int>, // 16000 default |
| 65 | + "channels": <int>, // 1 default |
| 66 | + "length": <int> // 640 default |
| 67 | + } |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | + |
| 72 | +## Stop audio streaming |
| 73 | +How to stop audio streaming |
| 74 | +``` C# |
| 75 | +StopMediaStreamingOptions stopOptions = new StopMediaStreamingOptions() |
| 76 | + { |
| 77 | + OperationCallbackUri = new Uri(callbackUriHost) |
| 78 | + }; |
| 79 | + await callMedia.StopMediaStreamingAsync(stopOptions); |
| 80 | +``` |
| 81 | + |
| 82 | +## Handling audio streams in your websocket server |
| 83 | +The sample below demonstrates how to listen to audio streams using your websocket server. |
| 84 | + |
| 85 | +``` C# |
| 86 | +HttpListener httpListener = new HttpListener(); |
| 87 | +httpListener.Prefixes.Add("http://localhost:80/"); |
| 88 | +httpListener.Start(); |
| 89 | + |
| 90 | +while (true) |
| 91 | +{ |
| 92 | + HttpListenerContext httpListenerContext = await httpListener.GetContextAsync(); |
| 93 | + if (httpListenerContext.Request.IsWebSocketRequest) |
| 94 | + { |
| 95 | + WebSocketContext websocketContext; |
| 96 | + try |
| 97 | + { |
| 98 | + websocketContext = await httpListenerContext.AcceptWebSocketAsync(subProtocol: null); |
| 99 | + } |
| 100 | + catch (Exception ex) |
| 101 | + { |
| 102 | + return; |
| 103 | + } |
| 104 | + WebSocket webSocket = websocketContext.WebSocket; |
| 105 | + try |
| 106 | + { |
| 107 | + while (webSocket.State == WebSocketState.Open || webSocket.State == WebSocketState.CloseSent) |
| 108 | + { |
| 109 | + byte[] receiveBuffer = new byte[2048]; |
| 110 | + var cancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(60)).Token; |
| 111 | + WebSocketReceiveResult receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), cancellationToken); |
| 112 | + if (receiveResult.MessageType != WebSocketMessageType.Close) |
| 113 | + { |
| 114 | + var data = Encoding.UTF8.GetString(receiveBuffer).TrimEnd('\0'); |
| 115 | + try |
| 116 | + { |
| 117 | + var eventData = JsonConvert.DeserializeObject<AudioBaseClass>(data); |
| 118 | + if (eventData != null) |
| 119 | + { |
| 120 | + if(eventData.kind == "AudioMetadata") |
| 121 | + { |
| 122 | + //Process audio metadata |
| 123 | + } |
| 124 | + else if(eventData.kind == "AudioData") |
| 125 | + { |
| 126 | + //Process audio data |
| 127 | + var byteArray = eventData.audioData.data; |
| 128 | + //use audio byteArray as you want |
| 129 | + } |
| 130 | + } |
| 131 | + } |
| 132 | + catch { } |
| 133 | + } |
| 134 | + } |
| 135 | + } |
| 136 | + catch (Exception ex) { } |
| 137 | + } |
| 138 | +} |
| 139 | +``` |
0 commit comments