How to handle audio stream in JsSIP?

9.3k Views Asked by At

I'm creating React application that use JsSIP library to answer calls made via VoIP SIP provider.

I've already created a page that have two buttons (Accept and Reject). It successfully register SIP client on SIP-server. It also successfully receive call and I can answer it. But I don't hear anything while answering call.

Registering JsSIP client (in willReceiveProps because I have information for connection after props changing):

const socketHost = 'wss://' + contactCenter.host + ':' + contactCenter.port
const socket = new JsSIP.WebSocketInterface(socketHost)
const configuration = {
    sockets: [socket],
    uri: 'sip:' + contactCenter.login + '@' + contactCenter.host,
    password: contactCenter.password,
    socketHost: socketHost,
}

const coolPhone = new JsSIP.UA(configuration)

coolPhone.on('connected', (e: any) => {
    const messages = ServiceContainer.get<MessageManagerInterface>(ServiceTypes.Messages)
    messages.addSuccess('SIP connected')
})

coolPhone.on('newRTCSession', (e: any) => {
    const messages = ServiceContainer.get<MessageManagerInterface>(ServiceTypes.Messages)
    messages.addAlert('New call')

    const session = e.session

    session.on('failed', this.resetLocalState)
    session.on('ended', this.resetLocalState)

    const numberRegexp = /\"(\d+)\"/
    const fromNumber = (numberRegexp.exec(e.request.headers.From[0].raw))[1]
    const toNumber = (numberRegexp.exec(e.request.headers.Contact[0].raw))[1].slice(1)

    this.setState({
        callReceived: true,
        callSession: session,
        fromNumber: fromNumber,
        toNumber: toNumber,
    })
})

coolPhone.start()

Method that handles answer button click:

private answerCall = () => {
    const messages = ServiceContainer.get<MessageManagerInterface>(ServiceTypes.Messages)
    messages.addSuccess('Call answered')

    const callOptions = {
        mediaConstraints: {
            audio: true, // only audio calls
            video: false
        },
        pcConfig: {
            iceServers: [
                { urls: ["stun:stun.l.google.com:19302"] }
            ],
            iceTransportPolicy: "all",
            rtcpMuxPolicy: "negotiate"
        }
    }

    this.state.callSession.answer(callOptions)

    this.state.callSession.connection.addEventListener('addstream', (event: any) => {
        console.log(event)
        this.audioElement.srcObject = event.stream
    })

    this.audioElement.play()

    this.setState({
        callAnswered: true,
        callReceived: false,
    })
}

What did I do wrong?

2

There are 2 best solutions below

3
On BEST ANSWER

I solved the problem.

The problem was in the position of this.audioElement.play() line.

I moved it to the callback on addstream event:

this.state.callSession.connection.addEventListener('addstream', (event: any) => {
    console.log(event)
    this.audioElement.srcObject = event.stream
    this.audioElement.play()
})

Now it works fine. Hope you also find it useful.

1
On

You can use react-sip npm library which simplifies usage of jssip inside React apps: https://www.npmjs.com/package/react-sip

You will just need to pass your connection settings as props to <SipProvider/>, which will be somewhere near the top of your react tree. This will allow you to perform basic start/stop/answer operations and watch the status of your call in the context!