Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio Issue with mjSIP - RTP Stream Not Working #31

Open
eddyslarez opened this issue Feb 12, 2025 · 0 comments
Open

Audio Issue with mjSIP - RTP Stream Not Working #31

eddyslarez opened this issue Feb 12, 2025 · 0 comments

Comments

@eddyslarez
Copy link

I hope you're doing well. First, let me thank you for your work on mjSIP — it's an impressive project, and I'm excited to use it in my application. However, I'm encountering an issue with the audio functionality, and I was hoping you could provide some guidance.

Here’s the problem I’m facing:

When attempting to set up audio streams, I’m seeing the following logs:

yaml
Copiar
Editar
[2025-02-12 12:42:45] INFO: [org.mjsip.media.RtpStreamSender]: Created RTP stream sender: UDP:null:16001 --> 37.328.82.6:25890
[2025-02-12 12:42:45] INFO: [org.mjsip.media.RtpStreamReceiver]: Created RTP stream receiver: UDP:null:16001 <-- null
It seems like the RTP stream is not being initialized properly, as the null values appear in the logs for both the sender and receiver. As a result, I’m unable to hear any audio during calls.

I've verified the configuration settings and ensured the network connection is stable, but I’m still unable to resolve the issue.

Would you have any suggestions or pointers on how to debug or fix this problem? Are there additional settings I need to adjust to get the RTP stream working correctly?

I appreciate your time and any guidance you can provide.

Best regards,

class DesktopMediaAgent {
fun createMediaAgent(direction: FlowSpec.Direction = FlowSpec.Direction.FULL_DUPLEX): MediaAgent {
val streamerFactory = createStreamerFactory(direction)
val mediaDescs = createMediaDescriptors()
return MediaAgent(mediaDescs, streamerFactory).apply {
configureAudioDevices()
}
}

private fun createStreamerFactory(direction: FlowSpec.Direction): DefaultStreamerFactory {
    val audioTransmitter = if (direction.doSend()) {
        JavaxAudioInput(true, false) // sync=true, noConversion=false for better compatibility
    } else null

    
    val audioReceiver = if (direction.doReceive()) {
        JavaxAudioOutput(false) 
    } else null


    val options = StreamerOptions.builder()
        .setSymmetricRtp(true)
        .setRandomEarlyDrop(0)
        .setSequenceCheck(true)
        .setSilencePadding(true)
        .setSsrcCheck(true)
        .setSyncAdjust(0)
        .setRtp(true)
        .build()

    return DefaultStreamerFactory(options, audioReceiver, audioTransmitter)
}

private fun createMediaDescriptors(): Array<MediaDesc> {

    val pcmaSpec = MediaSpec(8, "PCMA", 8000, 1, 160)  
    val pcmuSpec = MediaSpec(0, "PCMU", 8000, 1, 160)  

    return arrayOf(
        MediaDesc(
            "audio",
            0, 
            "RTP/AVP",
            arrayOf(pcmaSpec, pcmuSpec)
        )
    )
}

private fun configureAudioDevices() {
    try {
        val mixer = AudioSystem.getMixer(null)
        mixer.open()

        mixer.sourceLines.forEach { line ->
            if (line is DataLine) {
                try {
                    line.open()
                    if (line.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
                        val gainControl = line.getControl(FloatControl.Type.MASTER_GAIN) as FloatControl
                        gainControl.value = gainControl.maximum * 0.75f
                    }
                    line.close()
                } catch (e: Exception) {
                    println("[WARN] Failed to configure audio line: ${e.message}")
                }
            }
        }

        mixer.targetLines.forEach { line ->
            if (line is DataLine) {
                try {
                    line.open()
                    if (line.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
                        val gainControl = line.getControl(FloatControl.Type.MASTER_GAIN) as FloatControl
                        gainControl.value = gainControl.maximum * 0.8f
                    }
                    line.close()
                } catch (e: Exception) {
                    println("[WARN] Failed to configure audio line: ${e.message}")
                }
            }
        }

        mixer.close()
    } catch (e: Exception) {
        println("[ERROR] Failed to configure audio devices: ${e.message}")
    }
}

}

private fun setupUAConfig(username: String, password: String, domain: String) {
val sipConfig = SipConfig().apply {
normalize()
serverInfo = "-SIP-Client/1.0"
uaInfo = "-SIP-UA/1.0"
hostPort = 5065

        setViaAddrIPv4(IpAddress.getLocalHostAddress(AddressType.IP4).hostAddress)
    }

    uaConfig = UAConfig().apply {
        setDisplayName(username)
        setUser(username)
        setAuthUser(username)
        setAuthPasswd(password)

        setProxy(domain)
        setRegistrar(SipURI(domain, 5060))

        val localIpAddress = sipConfig.getViaAddr(AddressType.IP4)
        setMediaAddr(localIpAddress)

        setUaAddress(domain)

        setRegister(true)
        setExpires(3600)
        setKeepAliveTime(60000)

        setNoOffer(false)
        setUaServer(true)
        setOptionsServer(true)
        setNullServer(false)

        setRecvOnly(false)
        setSendOnly(false)
        setJavaxSoundSync(true)

        normalize(sipConfig)
    }

    sipProvider = SipProvider(sipConfig, scheduler).also { provider ->
        userAgent = UserAgent(provider, portPool, uaConfig, createUserAgentListener())
        provider.addPromiscuousListener(userAgent)
        provider.addPromiscuousListener(createSipListener())
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant