@@ -7,35 +7,51 @@ package aws.sdk.kotlin.e2etest
77import aws.sdk.kotlin.services.transcribestreaming.TranscribeStreamingClient
88import aws.sdk.kotlin.services.transcribestreaming.model.*
99import kotlinx.coroutines.Dispatchers
10+ import kotlinx.coroutines.delay
1011import kotlinx.coroutines.flow.Flow
1112import kotlinx.coroutines.flow.flow
1213import kotlinx.coroutines.flow.flowOn
1314import kotlinx.coroutines.runBlocking
1415import org.junit.jupiter.api.Test
1516import org.junit.jupiter.api.TestInstance
17+ import org.junit.jupiter.api.assertThrows
1618import java.io.File
1719import java.nio.file.Paths
1820import javax.sound.sampled.AudioSystem
1921import kotlin.test.assertTrue
22+ import kotlin.time.Duration
23+ import kotlin.time.Duration.Companion.seconds
2024
2125@TestInstance(TestInstance .Lifecycle .PER_CLASS )
2226class TranscribeStreamingIntegrationTest {
27+ private fun resource (path : String ): File {
28+ val url = this ::class .java.classLoader.getResource(path) ? : error(" failed to load test resource $path " )
29+ return Paths .get(url.toURI()).toFile()
30+ }
2331
2432 @Test
2533 fun testTranscribeEventStream (): Unit = runBlocking {
26- val url = this ::class .java.classLoader.getResource(" hello-kotlin-8000.wav" ) ? : error(" failed to load test resource" )
27- val audioFile = Paths .get(url.toURI()).toFile()
28-
34+ val file = resource(" hello-kotlin-8000.wav" )
35+ val audioStream = audioStreamFromFile(file)
2936 TranscribeStreamingClient { region = " us-west-2" }.use { client ->
30- val transcript = getTranscript(client, audioFile )
37+ val transcript = getTranscript(client, audioStream )
3138 assertTrue(transcript.startsWith(" Hello from" , true ), " full transcript: $transcript " )
3239 }
3340 }
41+
42+ @Test
43+ fun testTranscribeEventStreamWithLongPause (): Unit = runBlocking {
44+ val file = resource(" hello-kotlin-8000.wav" )
45+ val audioStream = audioStreamFromFile(file, 20 .seconds) // ~15 seconds should cause service to terminate stream
46+ TranscribeStreamingClient { region = " us-west-2" }.use { client ->
47+ assertThrows<BadRequestException > { getTranscript(client, audioStream) }
48+ }
49+ }
3450}
3551
3652private const val FRAMES_PER_CHUNK = 4096
3753
38- private fun audioStreamFromFile (file : File ): Flow <AudioStream > {
54+ private fun audioStreamFromFile (file : File , finalDelay : Duration ? = null ): Flow <AudioStream > {
3955 val format = AudioSystem .getAudioFileFormat(file)
4056 val ais = AudioSystem .getAudioInputStream(file)
4157 val bytesPerFrame = ais.format.frameSize
@@ -46,6 +62,10 @@ private fun audioStreamFromFile(file: File): Flow<AudioStream> {
4662 val frameBuffer = ByteArray (FRAMES_PER_CHUNK * bytesPerFrame)
4763 val rc = ais.read(frameBuffer)
4864 if (rc <= 0 ) {
65+ finalDelay?.let {
66+ println (" Artificially delaying for $finalDelay " )
67+ delay(it)
68+ }
4969 break
5070 }
5171
@@ -62,30 +82,32 @@ private fun audioStreamFromFile(file: File): Flow<AudioStream> {
6282 }.flowOn(Dispatchers .IO )
6383}
6484
65- private suspend fun getTranscript (client : TranscribeStreamingClient , audioFile : File ): String {
85+ private suspend fun getTranscript (client : TranscribeStreamingClient , audioStream : Flow < AudioStream > ): String {
6686 val req = StartStreamTranscriptionRequest {
6787 languageCode = LanguageCode .EnUs
6888 mediaSampleRateHertz = 8000
6989 mediaEncoding = MediaEncoding .Pcm
70- audioStream = audioStreamFromFile(audioFile)
90+ this . audioStream = audioStream
7191 }
7292
7393 val transcript = client.startStreamTranscription(req) { resp ->
7494 val fullMessage = StringBuilder ()
75- resp.transcriptResultStream?.collect { event ->
76- when (event) {
77- is TranscriptResultStream .TranscriptEvent -> {
78- event.value.transcript?.results?.forEach { result ->
79- val transcript = result.alternatives?.firstOrNull()?.transcript
80- println (" received TranscriptEvent: isPartial=${result.isPartial} ; transcript=$transcript " )
81- if (! result.isPartial) {
82- transcript?.let { fullMessage.append(it) }
95+ resp
96+ .transcriptResultStream
97+ ?.collect { event ->
98+ when (event) {
99+ is TranscriptResultStream .TranscriptEvent -> {
100+ event.value.transcript?.results?.forEach { result ->
101+ val transcript = result.alternatives?.firstOrNull()?.transcript
102+ println (" received TranscriptEvent: isPartial=${result.isPartial} ; transcript=$transcript " )
103+ if (! result.isPartial) {
104+ transcript?.let { fullMessage.append(it) }
105+ }
83106 }
84107 }
108+ else -> error(" unknown event $event " )
85109 }
86- else -> error(" unknown event $event " )
87110 }
88- }
89111 fullMessage.toString()
90112 }
91113
0 commit comments