diff --git a/firebaseai/src/LiveSession.cs b/firebaseai/src/LiveSession.cs
index 52030a7d..38719b4d 100644
--- a/firebaseai/src/LiveSession.cs
+++ b/firebaseai/src/LiveSession.cs
@@ -141,29 +141,71 @@ public async Task SendAsync(
}
///
- /// Send realtime input to the server.
+ /// Sends realtime input (media chunks) to the server.
///
- /// A list of media chunks to send.
- /// A token to cancel the send operation.
- public async Task SendMediaChunksAsync(
+ /// The list of media chunks to send.
+ [Obsolete("Use SendAudio, SendVideo, or SendText instead")]
+ public Task SendMediaChunksAsync(
List mediaChunks,
CancellationToken cancellationToken = default) {
- if (mediaChunks == null) return;
+ if (mediaChunks == null) return Task.CompletedTask;
+
+ return SendRealtimeInputAsync(cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// Sends audio data to the server.
+ ///
+ /// The audio data to send.
+ public Task SendAudioAsync(ModelContent.InlineDataPart audio, CancellationToken cancellationToken = default) {
+ return SendRealtimeInputAsync(audio: audio, cancellationToken: cancellationToken);
+ }
+ ///
+ /// Sends video data to the server.
+ ///
+ /// The video data to send.
+ public Task SendVideoAsync(ModelContent.InlineDataPart video, CancellationToken cancellationToken = default) {
+ return SendRealtimeInputAsync(video: video, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// Sends text data to the server.
+ ///
+ /// The text data to send.
+ public Task SendTextAsync(string text, CancellationToken cancellationToken = default) {
+ return SendRealtimeInputAsync(text: text, cancellationToken: cancellationToken);
+ }
+
+ private Task SendRealtimeInputAsync(
+ ModelContent.InlineDataPart? audio = null,
+ ModelContent.InlineDataPart? video = null,
+ string text = null,
+ CancellationToken cancellationToken = default) {
// Prepare the message payload.
Dictionary jsonDict = new() {
{
- "realtimeInput", new Dictionary() {
- {
- // InlineDataPart inherits from Part, so this conversion should be safe.
- "mediaChunks", mediaChunks.Select(mc => (mc as ModelContent.Part).ToJson()["inlineData"]).ToList()
- }
- }
+ "realtimeInput", new Dictionary()
}
};
+
+ var realtimeInputDict = (Dictionary)jsonDict["realtimeInput"];
+
+ if (audio.HasValue) {
+ realtimeInputDict["audio"] = (audio.Value as ModelContent.Part).ToJson()["inlineData"];
+ }
+
+ if (video.HasValue) {
+ realtimeInputDict["video"] = (video.Value as ModelContent.Part).ToJson()["inlineData"];
+ }
+
+ if (!string.IsNullOrEmpty(text)) {
+ realtimeInputDict["text"] = text;
+ }
+
var byteArray = Encoding.UTF8.GetBytes(Json.Serialize(jsonDict));
- await InternalSendBytesAsync(new ArraySegment(byteArray), cancellationToken);
+ return InternalSendBytesAsync(new ArraySegment(byteArray), cancellationToken);
}
private static byte[] ConvertTo16BitPCM(float[] samples) {
@@ -189,7 +231,7 @@ private static byte[] ConvertTo16BitPCM(float[] samples) {
/// A token to cancel the send operation.
public Task SendAudioAsync(float[] audioData, CancellationToken cancellationToken = default) {
ModelContent.InlineDataPart inlineDataPart = new("audio/pcm", ConvertTo16BitPCM(audioData));
- return SendMediaChunksAsync(new List(new []{inlineDataPart}), cancellationToken);
+ return SendAudioAsync(inlineDataPart, cancellationToken);
}
///