commit 28/07/2025
This commit is contained in:
@@ -2,6 +2,11 @@ package audio
|
||||
|
||||
import audio.Bass.BASS_STREAMPROC_END
|
||||
import audio.BassEnc.BASS_ENCODE_PCM
|
||||
import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import org.tinylog.Logger
|
||||
import java.io.PipedInputStream
|
||||
import java.io.PipedOutputStream
|
||||
@@ -76,7 +81,8 @@ class UDPReceiverToFile(listeningAddress: String, listeningPort: Int, val sampli
|
||||
var isReceiving = false
|
||||
if (isReady){
|
||||
|
||||
val thread1 = Thread{
|
||||
val scope = CoroutineScope(Dispatchers.Default)
|
||||
scope.launch(CoroutineName("UDPReceiverToFile UDP $senderIP $outputFilePath")) {
|
||||
Logger.info { "UDPReceiverToFile started, listening on ${socket?.localSocketAddress} , saving to $outputFilePath" }
|
||||
|
||||
PipedOutputStream(pipeIn).use { pipeOut ->
|
||||
@@ -100,11 +106,9 @@ class UDPReceiverToFile(listeningAddress: String, listeningPort: Int, val sampli
|
||||
}
|
||||
Logger.info { "UDPReceiverToFile ended" }
|
||||
}
|
||||
thread1.name = "UDPReceiverToFile Thread1 $senderIP $outputFilePath"
|
||||
thread1.isDaemon = true
|
||||
thread1.start()
|
||||
|
||||
val thread2 = Thread{
|
||||
|
||||
scope.launch(CoroutineName("UDPReceiverToFile BASS $senderIP $outputFilePath")) {
|
||||
bass.BASS_SetDevice(0) // Set to No Sound device, we are not playing audio
|
||||
val streamhandle = bass.BASS_StreamCreate(samplingrate, channel, 0, streamProc, null)
|
||||
if (streamhandle!=0){
|
||||
@@ -115,7 +119,7 @@ class UDPReceiverToFile(listeningAddress: String, listeningPort: Int, val sampli
|
||||
callback.accept(true, "UDPReceiverToFile started successfully, writing to $outputFilePath")
|
||||
while (isReceiving) {
|
||||
try {
|
||||
Thread.sleep(1000) // Sleep to avoid busy waiting
|
||||
delay(1000)
|
||||
} catch (e: InterruptedException) {
|
||||
Logger.error { "UDPReceiverToFile thread interrupted: ${e.message}" }
|
||||
break
|
||||
@@ -125,19 +129,18 @@ class UDPReceiverToFile(listeningAddress: String, listeningPort: Int, val sampli
|
||||
bass.BASS_StreamFree(streamhandle)
|
||||
Logger.info { "UDPReceiverToFile stopped writing to $outputFilePath" }
|
||||
callback.accept(false, "UDPReceiverToFile stopped successfully, written bytes: $bytesWritten")
|
||||
|
||||
} else {
|
||||
callback.accept(false, "Failed to start encoding: ${bass.BASS_ErrorGetCode()}")
|
||||
return@Thread
|
||||
}
|
||||
|
||||
} else {
|
||||
callback.accept(false, "Failed to create stream: ${bass.BASS_ErrorGetCode()}")
|
||||
return@Thread
|
||||
}
|
||||
}
|
||||
thread2.name = "UDPReceiverToFile Thread2 $senderIP $outputFilePath"
|
||||
thread2.isDaemon = true
|
||||
thread2.start()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
99
src/audio/UDPSenderFromFile.kt
Normal file
99
src/audio/UDPSenderFromFile.kt
Normal file
@@ -0,0 +1,99 @@
|
||||
package audio
|
||||
|
||||
import audio.Bass.BASS_STREAM_DECODE
|
||||
import codes.Somecodes.Companion.ValidFile
|
||||
import com.sun.jna.Memory
|
||||
import java.net.DatagramPacket
|
||||
import java.net.DatagramSocket
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.SocketAddress
|
||||
import java.util.function.BiConsumer
|
||||
import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Suppress("unused")
|
||||
class UDPSenderFromFile(val fileName: String, val bytesPerPackage: Int=1024, targetIP: Array<String>, targetPort: Int ) {
|
||||
val bass: Bass = Bass.Instance
|
||||
var filehandle: Int = 0
|
||||
var listSocketAddress = ArrayList<SocketAddress>()
|
||||
|
||||
var initialized: Boolean = false; private set
|
||||
var isRunning: Boolean = false; private set
|
||||
var bytesSent: Int = 0; private set
|
||||
|
||||
init {
|
||||
if (ValidFile(fileName)){
|
||||
bass.BASS_SetDevice(0)
|
||||
val handle = bass.BASS_StreamCreateFile(false, fileName, 0,0, BASS_STREAM_DECODE)
|
||||
if (handle!=0){
|
||||
// test buka file berhasil, tutup lagi
|
||||
bass.BASS_StreamFree(handle)
|
||||
if (targetPort>0 && targetPort<65535){
|
||||
if (targetIP.isNotEmpty()){
|
||||
var validIPs = true
|
||||
for(ip in targetIP){
|
||||
try{
|
||||
var so = InetSocketAddress(ip, targetPort)
|
||||
listSocketAddress.add(so)
|
||||
} catch (e : Exception){
|
||||
validIPs = false
|
||||
}
|
||||
}
|
||||
|
||||
if (validIPs){
|
||||
initialized = true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun Start(callback: BiConsumer<Boolean, String>){
|
||||
if (initialized){
|
||||
|
||||
val scope = CoroutineScope(Dispatchers.Default)
|
||||
scope.launch(CoroutineName("UDPSenderFromFile $fileName")) {
|
||||
try {
|
||||
val socket = DatagramSocket()
|
||||
bass.BASS_SetDevice(0) // Set to No Sound Device
|
||||
val handle = bass.BASS_StreamCreateFile(false, fileName, 0, 0, BASS_STREAM_DECODE)
|
||||
if (handle!=0){
|
||||
isRunning = true
|
||||
bytesSent = 0
|
||||
callback.accept(true,"UDPSenderFromFile started, sending $fileName to ${listSocketAddress.size} targets")
|
||||
while(isRunning){
|
||||
val buffer = Memory(bytesPerPackage.toLong())
|
||||
val bytesRead = bass.BASS_ChannelGetData(handle, buffer, bytesPerPackage)
|
||||
if (bytesRead > 0) {
|
||||
for(so in listSocketAddress){
|
||||
val bytes = buffer.getByteArray(0, bytesRead)
|
||||
socket.send(DatagramPacket(bytes, bytes.size, so))
|
||||
bytesSent += bytes.size
|
||||
}
|
||||
|
||||
} else isRunning = false
|
||||
}
|
||||
callback.accept(false,"UDPSenderFromFile finished sending $fileName")
|
||||
bass.BASS_StreamFree(handle)
|
||||
socket.close()
|
||||
} else callback.accept(false, "Failed to open file $fileName for reading")
|
||||
} catch (e : Exception){
|
||||
callback.accept(false, "Error in UDPSenderFromFile: ${e.message}")
|
||||
isRunning = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else callback.accept(false, "UDP Sender not initialized, check file and target IP/Port")
|
||||
|
||||
}
|
||||
|
||||
fun Stop(){
|
||||
isRunning = false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user