Re: PJSUA2 - Python3 Create Recorder fails with error Wrong number or type of arguments for overloaded function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As I could not get any clue from here for Audio recorder, I tried to create virtual sound device using pulse audio and pipe that to a wave file. It worked. But now I am unable to route the audio to both speaker and this virtual device. How can I do it?

                ep.audDevManager().setPlaybackDev(self.acc.callerVoiceRecorderDeviceID);
                am.startTransmit(ep.audDevManager().getPlaybackDevMedia())
               
                ep.audDevManager().setPlaybackDev(self.acc.speakerDeviceID);
                am.startTransmit(ep.audDevManager().getPlaybackDevMedia())

self.acc.callerVoiceRecorderDeviceID points to virtual device ID and self.acc.speakerDeviceID points to speaker.

What I observed is voice is getting directed to second device and not to first one. Log shows

18:22:05.081           pjsua_call.c  Answering call 0: code=200
18:22:05.081          pjsua_media.c  ...Call 0: updating media..
18:22:05.081          pjsua_media.c  .....Media stream call00:0 is destroyed
18:22:05.082            pjsua_aud.c  ....Audio channel update..
18:22:05.082          strm0x235ef88  .....VAD temporarily disabled
18:22:05.082          strm0x235ef88  .....Encoder stream started
18:22:05.082          strm0x235ef88  .....Decoder stream started
18:22:05.082          pjsua_media.c  ....Audio updated, stream #0: PCMU (sendrecv)
18:22:05.082            pjsua_aud.c  ...Set sound device: capture=-1, playback=3
18:22:05.082            pjsua_aud.c  ...Conf connect: 1 --> 0
18:22:05.082            pjsua_aud.c  ....Set sound device: capture=-1, playback=3
18:22:05.082            pjsua_aud.c  .....Opening sound device (speaker + mic) PCM@16000/1/20ms
18:22:05.090            ec0x2371c80  ......AEC created, clock_rate=16000, channel=1, samples per frame=320, tail length=200 ms, latency=0 ms
18:22:05.090           conference.c  ....Port 1 (sip:192.168.1.3) transmitting to port 0 (default)
18:22:05.090            pjsua_aud.c  ...Set sound device: capture=-1, playback=2
18:22:05.090            pjsua_aud.c  .....Closing CallerVoice sound playback device and default sound capture device
18:22:05.110            pjsua_aud.c !....Opening sound device (speaker + mic) PCM@16000/1/20ms
18:22:05.119            ec0x238ff80  .....AEC created, clock_rate=16000, channel=1, samples per frame=320, tail length=200 ms, latency=0 ms
18:22:05.120            pjsua_aud.c  ...Conf connect: 1 --> 0
18:22:05.120           pjsua_core.c !....TX 928 bytes Response msg 200/INVITE/cseq=4969 (tdta0x237ab38) to UDP 192.168.1.3:5060:

When I switch from playback 3 (virtual) to 2 (speaker), it disconnects 3 as per log. How can I send caller voice to two sinks?

As I am running it inside a docker and both sinks are actually virtual devices created thru pulse audio. I am trying to use one for full audio recording and another one for caller audio monitoring. Full code, if it helps is below. As per this code, full audio recording works (both caller voice and outgoing wave file being played). I am looking for another recorder in paralllel which will only record caller audio.


------------------------------------

import pjsua2 as pj
#import time
# Subclass to extend the Account and get notifications etc.
#from concurrent.futures import ProcessPoolExecutor

# Call class
class Call(pj.Call):
   
    """
    High level Python Call object, derived from pjsua2's Call object.
    """
   
    def __init__(self, acc, peer_uri='', chat=None, call_id = pj.PJSUA_INVALID_ID):
        pj.Call.__init__(self, acc, call_id)
        self.acc = acc
        self._onhold_ = False
        self.am=None
        self.recorder=None
        self.connected=False
        self.canConnectPlayer=False

    def onCallState(self, prm):
        ci = self.getInfo()
        connected = ci.state == pj.PJSIP_INV_STATE_CONFIRMED
        if(connected==True):
            self.connected=True
            print("########################################## Call connected")
        if(ci.state==pj.PJSIP_INV_STATE_DISCONNECTED):
            self.connected=False
            self.am=None
            self.canConnectPlayer=False
            print(">>>>>>>>>>>>>>>>>>>>>>> Call disconnected")



    def onCallMediaState(self, prm):
        ci = self.getInfo()
        for mi in ci.media:
            if mi.type == pj.PJMEDIA_TYPE_AUDIO and \
              (mi.status == pj.PJSUA_CALL_MEDIA_ACTIVE or \
               mi.status == pj.PJSUA_CALL_MEDIA_REMOTE_HOLD):
             
                m = self.getMedia(mi.index)
                am = pj.AudioMedia.typecastFromMedia(m)
                # connect ports
                #ep.audDevManager().getCaptureDevMedia().startTransmit(am)
               
                ep.audDevManager().setPlaybackDev(self.acc.callerVoiceRecorderDeviceID);
                am.startTransmit(ep.audDevManager().getPlaybackDevMedia())
               
                ep.audDevManager().setPlaybackDev(self.acc.fullRecorderDeviceID);
                am.startTransmit(ep.audDevManager().getPlaybackDevMedia())


                self.am=am
                self.canConnectPlayer=True

                if mi.status == pj.PJSUA_CALL_MEDIA_REMOTE_HOLD and not self.onhold:
                    #self.chat.addMessage(None, "'%s' sets call onhold" % (self.peerUri))
                    self._onhold_ = True
                elif mi.status == pj.PJSUA_CALL_MEDIA_ACTIVE and self.onhold:
                    #self.chat.addMessage(None, "'%s' sets call active" % (self.peerUri))
                    self._onhold_ = False
        #raise Exception('onCallMediaState done!')        
                   
class Account(pj.Account):

    def __init__(self, ep=None):
        pj.Account.__init__(self)
        self.ep=ep
        self.c=None
        self.acceptCall=False;
        self.inCall=False;
        self.call_id=None
        self.callerVoiceRecorderDeviceID=None
        self.fullRecorderDeviceID=None

    def onRegState(self, prm):
        print ("***OnRegState: " + prm.reason)
    def onIncomingCall(self, prm):
        self.call_id==prm.callId
        self.acceptCall=True

        self.c = Call(self, call_id=prm.callId)
       
        ci = self.c.getInfo()
        msg = "Incoming call  from  '%s'" % (ci.remoteUri)
        print(msg)
           
        self.inCall=True


# pjsua2 test function
def pjsua2_test():
    # Create and initialize the library
    global ep
    ep_cfg = pj.EpConfig()
    ep_cfg.uaConfig.threadCnt = 0
    ep_cfg.uaConfig.mainThreadOnly = False
    ep = pj.Endpoint()
    ep.libCreate()
    ep.libInit(ep_cfg)

    # Create SIP transport. Error handling sample is shown
    sipTpConfig = pj.TransportConfig();
    sipTpConfig.port = 12345;
    tp=ep.transportCreate(pj.PJSIP_TRANSPORT_UDP, sipTpConfig);
    # Start the library
    ep.libStart();

    acfg = pj.AccountConfig();

    acfg.idUri = "sip:192.168.1.11:12345";

    # Create the account
    acc = Account(ep);
    acc.create(acfg)
    #Get device list and collect device IDs of two virtual devices created
    ep.audDevManager().refreshDevs();
    devList=ep.audDevManager().enumDev()
    fullRecorderDeviceID=0
    devID=0
    for dev in devList:
        print(dev.name)
        if(dev.name=="FullRecorder"):
            acc.fullRecorderDeviceID=devID
           
        if(dev.name=="CallerVoice"):
            acc.callerVoiceRecorderDeviceID=devID

        devID=devID+1
       
           
    while True:
        ep.libHandleEvents(10)
        if(acc.acceptCall==True):
            acc.acceptCall=False;
            call_prm = pj.CallOpParam()
            call_prm.statusCode = 200
            acc.c.answer(call_prm)
            if(acc.c.canConnectPlayer==True and acc.c.am!=None ):
                acc.c.canConnectPlayer=False
                player=pj.AudioMediaPlayer()
                #Play welcome message
                fn=u'/PJSUA2/example/welcomeFull.wav'
                player.createPlayer(fn, pj.PJMEDIA_FILE_NO_LOOP);
                # This will connect the sound device/mic to the call audio media
                player.startTransmit( acc.c.am);
                player.startTransmit( ep.audDevManager().getPlaybackDevMedia());

    ep.libDestroy()
    del ep;

#
# main()
#
if __name__ == "__main__":
    #recorder=pj.AudioMediaRecorder()
    #recorder.createRecorder("123.wav");
    pjsua2_test();

 
-----------------------------------

Thanks
Sekar



From: Sekar S
Sent: Saturday, January 19, 2019 8:33 PM
To: pjsip@xxxxxxxxxxxxxxx
Subject: PJSUA2 - Python3 Create Recorder fails with error Wrong number or type of arguments for overloaded function
 
Hi all,
Even a simple 3 line code is giving  error. Can anyone help on this? Where can I get any kind of help

import pjsua2 as pj
recorder=pj.AudioMediaRecorder()
recorder.createRecorder('file.wav');

    return _pjsua2.AudioMediaRecorder_createRecorder(self, file_name, enc_type, max_size, options)
NotImplementedError: Wrong number or type of arguments for overloaded function 'AudioMediaRecorder_createRecorder'.
  Possible C/C++ prototypes are:
    pj::AudioMediaRecorder::createRecorder(pj::string const &,unsigned int,pj_ssize_t,unsigned int)
    pj::AudioMediaRecorder::createRecorder(pj::string const &,unsigned int,pj_ssize_t)
    pj::AudioMediaRecorder::createRecorder(pj::string const &,unsigned int)
    pj::AudioMediaRecorder::createRecorder(pj::string const &)


I tried trunk,2.8 and 2.7 and same error is observed. I tried to compare createPlayer code and create recorder code in generated SWIG / h files in python folders and could not find any difference. However, create player works, but create recorder doesn't. Am I only person having this issue with Python3? Is it working for anyone else?

Any help or guidance will be highly appreciated.

Sekar

_______________________________________________
Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@xxxxxxxxxxxxxxx
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux