davidliu
Committed by GitHub

Data stream helper methods (#732)

  1 +---
  2 +"client-sdk-android": patch
  3 +---
  4 +
  5 +Add sendText and sendFile helper methods to LocalParticipant for ease of use
  1 +---
  2 +"client-sdk-android": patch
  3 +---
  4 +
  5 +Add default name of "unknown" for StreamByteOptions to allow for no-arg construction
@@ -56,7 +56,7 @@ data class StreamBytesOptions( @@ -56,7 +56,7 @@ data class StreamBytesOptions(
56 /** 56 /**
57 * The name of the file being sent. 57 * The name of the file being sent.
58 */ 58 */
59 - val name: String, 59 + val name: String = "unknown",
60 /** 60 /**
61 * The total exact size in bytes, if known. 61 * The total exact size in bytes, if known.
62 */ 62 */
@@ -20,13 +20,18 @@ import androidx.annotation.CheckResult @@ -20,13 +20,18 @@ import androidx.annotation.CheckResult
20 import io.livekit.android.room.datastream.ByteStreamInfo 20 import io.livekit.android.room.datastream.ByteStreamInfo
21 import okio.Buffer 21 import okio.Buffer
22 import okio.FileSystem 22 import okio.FileSystem
  23 +import okio.Path.Companion.toOkioPath
23 import okio.Path.Companion.toPath 24 import okio.Path.Companion.toPath
24 import okio.Source 25 import okio.Source
25 import okio.source 26 import okio.source
  27 +import java.io.File
26 import java.io.InputStream 28 import java.io.InputStream
27 import java.util.Arrays 29 import java.util.Arrays
28 import kotlin.math.min 30 import kotlin.math.min
29 31
  32 +/**
  33 + * A stream sender for sending byte-based messages (e.g. files, images, etc.)
  34 + */
30 class ByteStreamSender( 35 class ByteStreamSender(
31 val info: ByteStreamInfo, 36 val info: ByteStreamInfo,
32 destination: StreamDestination<ByteArray>, 37 destination: StreamDestination<ByteArray>,
@@ -52,7 +57,19 @@ private val byteDataChunker: DataChunker<ByteArray> = { data: ByteArray, chunkSi @@ -52,7 +57,19 @@ private val byteDataChunker: DataChunker<ByteArray> = { data: ByteArray, chunkSi
52 } 57 }
53 58
54 /** 59 /**
  60 + * Reads the [file] and writes it to the data stream.
  61 + *
  62 + * @param file the file to read from
  63 + */
  64 +@CheckResult
  65 +suspend fun ByteStreamSender.writeFile(file: File): Result<Unit> {
  66 + return write(FileSystem.SYSTEM.source(file.toOkioPath()))
  67 +}
  68 +
  69 +/**
55 * Reads the file from [filePath] and writes it to the data stream. 70 * Reads the file from [filePath] and writes it to the data stream.
  71 + *
  72 + * @param filePath absolute path to the file
56 */ 73 */
57 @CheckResult 74 @CheckResult
58 suspend fun ByteStreamSender.writeFile(filePath: String): Result<Unit> { 75 suspend fun ByteStreamSender.writeFile(filePath: String): Result<Unit> {
@@ -29,6 +29,8 @@ import io.livekit.android.room.participant.Participant @@ -29,6 +29,8 @@ import io.livekit.android.room.participant.Participant
29 import io.livekit.android.util.LKLog 29 import io.livekit.android.util.LKLog
30 import livekit.LivekitModels.DataPacket 30 import livekit.LivekitModels.DataPacket
31 import livekit.LivekitModels.DataStream 31 import livekit.LivekitModels.DataStream
  32 +import java.io.File
  33 +import java.io.InputStream
32 import java.util.Collections 34 import java.util.Collections
33 import java.util.Date 35 import java.util.Date
34 import java.util.concurrent.atomic.AtomicLong 36 import java.util.concurrent.atomic.AtomicLong
@@ -38,6 +40,7 @@ interface OutgoingDataStreamManager { @@ -38,6 +40,7 @@ interface OutgoingDataStreamManager {
38 /** 40 /**
39 * Start sending a stream of text. Call [TextStreamSender.close] when finished sending. 41 * Start sending a stream of text. Call [TextStreamSender.close] when finished sending.
40 * 42 *
  43 + * @see [TextStreamSender.write]
41 * @throws StreamException if the stream failed to open. 44 * @throws StreamException if the stream failed to open.
42 */ 45 */
43 suspend fun streamText(options: StreamTextOptions = StreamTextOptions()): TextStreamSender 46 suspend fun streamText(options: StreamTextOptions = StreamTextOptions()): TextStreamSender
@@ -45,9 +48,45 @@ interface OutgoingDataStreamManager { @@ -45,9 +48,45 @@ interface OutgoingDataStreamManager {
45 /** 48 /**
46 * Start sending a stream of bytes. Call [ByteStreamSender.close] when finished sending. 49 * Start sending a stream of bytes. Call [ByteStreamSender.close] when finished sending.
47 * 50 *
  51 + * Extension functions are available for sending bytes from sources such as [InputStream] or [File].
  52 + *
  53 + * @see [ByteStreamSender.write]
  54 + * @see [ByteStreamSender.writeFile]
48 * @throws StreamException if the stream failed to open. 55 * @throws StreamException if the stream failed to open.
49 */ 56 */
50 suspend fun streamBytes(options: StreamBytesOptions): ByteStreamSender 57 suspend fun streamBytes(options: StreamBytesOptions): ByteStreamSender
  58 +
  59 + /**
  60 + * Send text through a data stream.
  61 + */
  62 + @CheckResult
  63 + suspend fun sendText(text: String, options: StreamTextOptions = StreamTextOptions()): Result<Unit> {
  64 + val sender = streamText(options)
  65 + val result = sender.write(text)
  66 +
  67 + if (result.isFailure) {
  68 + sender.close(result.exceptionOrNull()?.message ?: "Unknown error.")
  69 + } else {
  70 + sender.close()
  71 + }
  72 + return result
  73 + }
  74 +
  75 + /**
  76 + * Send a file through a data stream.
  77 + */
  78 + @CheckResult
  79 + suspend fun sendFile(file: File, options: StreamBytesOptions = StreamBytesOptions()): Result<Unit> {
  80 + val sender = streamBytes(options)
  81 + val result = sender.writeFile(file)
  82 +
  83 + if (result.isFailure) {
  84 + sender.close(result.exceptionOrNull()?.message ?: "Unknown error.")
  85 + } else {
  86 + sender.close()
  87 + }
  88 + return result
  89 + }
51 } 90 }
52 91
53 /** 92 /**