2024-09-07 21:07:10 +08:00

94 lines
2.9 KiB
Kotlin

import io.github.jaredmdobson.concentus.OpusApplication
import io.github.jaredmdobson.concentus.OpusDecoder
import io.github.jaredmdobson.concentus.OpusEncoder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.IOException
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.io.Serializable
import java.net.InetSocketAddress
import java.net.Socket
import javax.sound.sampled.AudioSystem
import kotlin.system.measureTimeMillis
class Client {
companion object {
@JvmStatic
fun main(args: Array<String>) {
Client().mainClient()
}
}
val bufferOut = ByteArray(BUFFER_SIZE)
val targetDataLine = AudioSystem.getTargetDataLine(AUDIO_FORMAT).also {
it.open(AUDIO_FORMAT, bufferOut.size)
it.start()
}
val bufferIn = ByteArray(BUFFER_SIZE)
val sourceDataLine = AudioSystem.getSourceDataLine(AUDIO_FORMAT).also {
it.open(AUDIO_FORMAT, bufferIn.size)
it.start()
}
val decoder = OpusDecoder(SAMPLE_RATE, CHANNELS)
val encoder = OpusEncoder(SAMPLE_RATE, CHANNELS, OpusApplication.OPUS_APPLICATION_AUDIO).also {
it.bitrate = OPUS_BITRATE
it.forceMode = OPUS_MODE
it.signalType = OPUS_SIGNAL_TYPE
it.complexity = OPUS_COMPLEXITY
}
fun mainClient() {
val socket = Socket()
val scope = CoroutineScope(Dispatchers.IO)
val t = measureTimeMillis {
socket.connect(InetSocketAddress(SERVER_HOST, SERVER_PORT))
}
"connect time $t".loge()
val out = ObjectOutputStream(socket.getOutputStream())
val inp = ObjectInputStream(socket.getInputStream())
val recordJob = scope.launch {
while (true) {
targetDataLine.read(bufferOut, 0, bufferOut.size)
try {
out.writeObject(encoder.encode(bufferOut))
out.flush()
} catch (e: Exception) {
e.printStackTrace()
System.exit(0)
}
}
}
val playJob = scope.launch {
while (true) {
try {
// if (`in`!!.available() > bufferIn.size * 2) {
// `in`!!.skip(`in`!!.available().toLong() - bufferIn.size)
// println("丢弃")
// }
// `in`!!.read(bufferIn, 0, bufferIn.size)
val dataPack = inp.readObject() as DataPack
decoder.decode(dataPack, bufferIn)
sourceDataLine.write(bufferIn, 0, bufferIn.size)
} catch (e: IOException) {
e.printStackTrace()
System.exit(0)
}
}
}
runBlocking {
recordJob.join()
playJob.join()
}
}
}