[Python] Why is onCallMediaState not triggered and audio file not playing in PJSUA2?

Discussão em 'Python' iniciado por Stack, Fevereiro 10, 2025.

  1. Stack

    Stack Membro Participativo

    I'm using PJSUA2 in Python to handle incoming SIP calls. The call is received and answered successfully, but the onCallMediaState callback is never triggered. Additionally, the audio file is not played.

    Here’s what happens:

    The SIP account registers successfully. Incoming call is received, and I answer it with statusCode = 200. onCallMediaState is expected to be triggered, but it never happens. Because onCallMediaState is not called, the audio file never starts playing. What I have tried: Ensuring the call is actually answered before expecting onCallMediaState to be triggered. Checking the media status inside onCallMediaState when manually calling it, but it doesn't seem to activate. Debugging SIP logs to verify if media negotiation is happening. Ensuring the audio file exists and is accessible.

    import pjsua2 as pj
    import time
    import os
    from colorama import Fore

    AUDIO_FILE = "./test.wav"

    if not os.path.exists(AUDIO_FILE):
    print(Fore.RED + f"Error: File {AUDIO_FILE} not found!" + Fore.RESET)
    exit(1)

    class Account(pj.Account):
    def __init__(self):
    super().__init__()
    self.call = None # Hold active call

    def onRegState(self, prm):
    print(Fore.RED + f"*** Registration State: {prm.code} - {prm.reason}" + Fore.RESET)

    def onIncomingCall(self, prm):
    self.call = pj.Call(self, prm.callId)
    call_prm = pj.CallOpParam()

    print(Fore.GREEN + "*** Incoming call received!" + Fore.RESET)

    # Ringing
    call_prm.statusCode = 180
    self.call.answer(call_prm)
    print(Fore.YELLOW + " Ringing..." + Fore.RESET)

    time.sleep(2)

    # Answer the call
    call_prm.statusCode = 200
    self.call.answer(call_prm)
    print(Fore.GREEN + "✅ Call answered." + Fore.RESET)

    def onCallMediaState(self, prm):
    print(Fore.GREEN + " Media state changed!" + Fore.RESET)

    if not self.call:
    print(Fore.RED + "⛔ No active call found!" + Fore.RESET)
    return

    ci = self.call.getInfo() # Get call info
    print(Fore.CYAN + f" Call Info: {ci}" + Fore.RESET)

    for mi in ci.media:
    print(Fore.CYAN + f" Media Type: {mi.type}, Status: {mi.status}" + Fore.RESET)
    if mi.type == pj.PJMEDIA_TYPE_AUDIO and mi.status == pj.PJSUA_CALL_MEDIA_ACTIVE:
    print(Fore.GREEN + f" Playing audio file: {AUDIO_FILE}" + Fore.RESET)

    try:
    # Create audio player
    self.player = pj.AudioMediaPlayer()
    self.player.createPlayer(AUDIO_FILE)

    # Get call audio media
    audioMedia = self.call.getAudioMedia(mi.index)

    # Transmit audio to the call
    self.player.startTransmit(audioMedia)

    print(Fore.GREEN + "✅ Audio is playing..." + Fore.RESET)

    # Play for 10 seconds then hang up
    time.sleep(10)
    self.call.hangup()
    print(Fore.RED + "*** Call ended." + Fore.RESET)

    except Exception as e:
    print(Fore.RED + f"Error processing media: {e}" + Fore.RESET)

    def pjsua2_test():
    ep_cfg = pj.EpConfig()
    ep = pj.Endpoint()
    ep.libCreate()
    ep.libInit(ep_cfg)

    sipTpConfig = pj.TransportConfig()
    sipTpConfig.port = 5060
    ep.transportCreate(pj.PJSIP_TRANSPORT_UDP, sipTpConfig)

    ep.libStart()
    print(Fore.RED + "*** PJSUA2 library started." + Fore.RESET)

    sip_domain = "***"
    sip_user = "***"
    sip_password = "***"

    acfg = pj.AccountConfig()
    acfg.idUri = f"sip:{sip_user}@{sip_domain}:5060"
    acfg.regConfig.registrarUri = f"sip:{sip_domain}:5060"

    cred = pj.AuthCredInfo("digest", "*", sip_user, 0, sip_password)
    acfg.sipConfig.authCreds.append(cred)

    acc = Account()
    acc.create(acfg)
    print(Fore.RED + "*** SIP account created." + Fore.RESET)

    time.sleep(60)

    ep.libDestroy()
    print(Fore.RED + "*** PJSUA2 library destroyed." + Fore.RESET)


    if __name__ == "__main__":
    pjsua2_test()


    I tried the following steps to debug the issue:

    Verified call registration – The SIP account registers successfully, and incoming calls are received. Checked call answering – The call is answered with statusCode = 200, and the call state seems to be active. Expected onCallMediaState to trigger – After answering, I expected onCallMediaState to be called automatically, but it never happens. Checked media negotiation – I enabled SIP logging to see if media negotiation happens, but I couldn’t find any obvious issues. Tried manually getting call info – I checked self.call.getInfo() inside onCallMediaState and printed media details, but it never enters that function. Ensured the audio file is accessible – The file exists and is in the correct format, but since onCallMediaState is never triggered, it doesn’t even attempt to play. I was expecting that once the call is answered, onCallMediaState would be triggered, allowing me to start playing an audio file. However, this function is never called, and no audio is transmitted.

    How can I ensure that media state is correctly activated after answering the call?

    Continue reading...

Compartilhe esta Página