94 lines
2.9 KiB
Kotlin
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()
|
|
}
|
|
}
|
|
}
|