Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Example for receive a call and record it #80

Closed
xyc0815 opened this issue Nov 3, 2022 · 10 comments
Closed

Example for receive a call and record it #80

xyc0815 opened this issue Nov 3, 2022 · 10 comments
Assignees
Labels
discussion help wanted Extra attention is needed question Issue is asking a question

Comments

@xyc0815
Copy link
Collaborator

xyc0815 commented Nov 3, 2022

I try to record the call. For this I use this part in the callback function answer

        print("+++++++++++++++++  Get Audio from caller and write file")
        w = wave.open('test_wave.wav', 'wb')
        w.setparams((1, 16 // 8, 8000, 0, 'NONE', 'NONE'))
        while call.state == CallState.ANSWERED:
            data = call.read_audio()
            #print(data)
            w.writeframesraw(data)
        w.close()

This writes a wav file, but I only get is very noisy. I think the parameters in setparams a not right. But I don't know what to set here.

@xyc0815 xyc0815 added help wanted Extra attention is needed discussion labels Nov 3, 2022
@tayler6000 tayler6000 added the question Issue is asking a question label Nov 3, 2022
@tayler6000 tayler6000 self-assigned this Nov 3, 2022
@lo-hei
Copy link

lo-hei commented Nov 8, 2022

Are you sure that you receive 2 Bytes = 16 Bit? Normally you will get 8 Bit = 1 Byte. It worked for me, and the saved audio-file is totally okay.

My Code:

    w = wave.open('test_wave.wav', 'wb')
    w.setnchannels(1)
    w.setsampwidth(8 // 8) # 8 Bit = 1 Byte
    w.setframerate(8000)
    w.close

@tayler6000
Copy link
Owner

That's correct, PCMU/A is 8 bit

@xyc0815
Copy link
Collaborator Author

xyc0815 commented Nov 17, 2022

Thanks, sometimes the right solution is so easy. It works for me too.

@Koshkodav
Copy link

This code works, recording is permanently. How can i stop recording by time or (will be better) by silent in channel?

w = wave.open('test_wave.wav', 'wb')
w.setnchannels(1)
w.setsampwidth(8 // 8)
w.setframerate(8000)

while call.state == CallState.ANSWERED:
    data = call.read_audio()
    w.writeframesraw(data)
w.close()
call.hangup()

@tayler6000
Copy link
Owner

You could probably do something like:

if data != b"\x80" * len(data):
    w.writeframes(data)

@TipsTricksMore
Copy link

TipsTricksMore commented Feb 9, 2023

I'm trying to record a few seconds of a certain part in a call. However, I can't even get a simple recording to work properly...

I want to save a recording as a .wav file.
If I'm using: data = call.read_audio(blocking=False) it starts to produce an multiple hour long .wav file that's pretty large (+ 200Mb) and does not even contain any audio...
When I'm using data = call.read_audio(blocking=True) it spits out a 365kb file with 0 seconds...

What am I missing here?

from pyVoIP.VoIP import VoIPPhone, InvalidStateError, CallState
import time
import wave


# ACCOUNT DATA:
SIP_IP = 'pbx.easybell.de'
SIP_Port = 5060
SIP_Username = 'placeholder'
SIP_Password = 'placeholder'
myIP = 'placeholder'

def answer(call):
    w = wave.open('test_wave.wav', 'wb')
    w.setnchannels(1)
    w.setsampwidth(2)
    w.setsampwidth(8 // 8)
    w.setframerate(8000)
    call.answer()

    while call.state == CallState.ANSWERED:
        print("recording start")
        data = call.read_audio(blocking=False)
        w.writeframesraw(data)
    w.close()
    print("recording saved")


if __name__ == "__main__":
    phone = VoIPPhone(SIP_IP, SIP_Port, SIP_Username, SIP_Password, myIP=myIP, callCallback=answer)
    phone.start()
    input('Press enter to disable the phone')
    phone.stop()

@Koshkodav
Copy link

Koshkodav commented Feb 10, 2023

I'm trying to record a few seconds of a certain part in a call.
...

>     while call.state == CallState.ANSWERED:
>         print("recording start")
>         data = call.read_audio(blocking=False)

Don't use print() in the function answer(). If you need logging then use recording into a file. Parameter "blocking" better left by default.

@tayler6000
Copy link
Owner

@TipsTricksMore, definitely heed what @Koshkodav said about blocking. But I think your problem is you don't want to be using writeframesraw, if I recall correctly, that does not increase the frame counter in the wav file so it thinks you haven't added any data when you have. But yeah, if you set blocking to false it's going to add a TON of empty sound in between packets.

@PraveenChordia
Copy link

PraveenChordia commented Mar 30, 2023

w = wave.open('test_wave.wav', 'wb')
w.setnchannels(1)
w.setsampwidth(2)
w.setsampwidth(8 // 8)
w.setframerate(8000)

call.answer()
while call.state == CallState.ANSWERED:
  data = call.read_audio(blocking=False)
  if data != b"\x80" * len(data):
      w.writeframesraw(data)

w.close()
call.hangup()

I am getting only a 0-sec file what am I doing wrong?
I am not receiving any audio from another side I don't know why.
Any suggestions

@tayler6000
Copy link
Owner

I believe the issue you are having is the writeframesraw call. Per the Python documentation writeframesraw does not increment the frames counter in the wav file. You should use writeframes instead.

Repository owner locked and limited conversation to collaborators May 9, 2023
@tayler6000 tayler6000 converted this issue into discussion #130 May 9, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
discussion help wanted Extra attention is needed question Issue is asking a question
Projects
None yet
Development

No branches or pull requests

6 participants