Recorded files lost when user hangs up - php

I'm writing a voice application in which I want to save a recorded sound file.
My code is:
$file = $clientid.rand(5, 10);
$agi->stream_file("itc-Por-favor-indique-su-nombre-numero-de-telefono");
$sal = $agi->record_file($file,"WAV","0123456789#*",-1,NULL,true);
if ($sal['result'] > 0) {
$bodytext = "Reclamo de la mesa de ayuda, cliente no identificado por IVR.
\nNumero de Telefono: ".$agi->request['agi_callerid'];
}
Whenever I hang up during recording, the recording application can not execute and hangup the call.
Does anyone have any idea how to manage this record function while hanging up?

You need use 'k' option to instruct asterisk you want save file on hangup WITHOUT confirmation.
core show application Record
-= Info about application 'Record' =-
[Synopsis]
Record to a file.
[Description]
If filename contains '%d', these characters will be replaced with a number
incremented by one each time the file is recorded. Use 'core show file formats'
to see the available formats on your system User can press '#' to terminate the
recording and continue to the next priority. If the user hangs up during a
recording, all data will be lost and the application will terminate.
${RECORDED_FILE}: Will be set to the final filename of the recording.
${RECORD_STATUS}: This is the final status of the command
DTMF:A terminating DTMF was received ('#' or '*', depending upon option
't')
SILENCE:The maximum silence occurred in the recording.
SKIP:The line was not yet answered and the 's' option was specified.
TIMEOUT:The maximum length was reached.
HANGUP:The channel was hung up.
ERROR:An unrecoverable error occurred, which resulted in a WARNING to the
logs.
[Syntax]
Record(filename.format[,silence[,maxduration[,options]]])
[Arguments]
format
Is the format of the file type to be recorded (wav, gsm, etc).
silence
Is the number of seconds of silence to allow before returning.
maxduration
Is the maximum recording duration in seconds. If missing or 0 there is no
maximum.
options
a: Append to existing recording rather than replacing.
n: Do not answer, but record anyway if line not yet answered.
q: quiet (do not play a beep tone).
s: skip recording if the line is not yet answered.
t: use alternate '*' terminator key (DTMF) instead of default '#'
x: Ignore all terminator keys (DTMF) and keep recording until hangup.
k: Keep recorded file upon hangup.
y: Terminate recording if *any* DTMF digit is received.

Related

How to use $agi->get_data with multiple audio files

In Playback, Background, Read we can combine audio files with &, like file1&file2.
In PHPAgi instead of Read, I use $agi->get_data, but its look like accept only one file!
I also tried to play audio with Background before calling get_data:
$multipleAudioPath = 'file1&file2';
$agi->exec('Background', $multipleAudioPath);
$rawInput = $agi->get_data('blankAudioFile', $timeout, $digits);
But first character goes for breaking Background audio and didn't catch in get_data.
What can I do? Can I do it alone with $agi->get_data ? Or is there any other solution ?
You can use multiple files using Read asterisk command.
$agi->exec("Read","variable,filename&filename2")
[Syntax]
Read(variable[,filename[&filename2[&...]][,maxdigits[,options[,attempts[,timeout]]]]])
[Arguments]
variable
The input digits will be stored in the given <variable> name.
filename
file(s) to play before reading digits or tone with option i
maxdigits
Maximum acceptable number of digits. Stops reading after <maxdigits> have
been entered (without requiring the user to press the '#' key).
Defaults to '0' - no limit - wait for the user press the '#' key. Any value
below '0' means the same. Max accepted value is '255'.
options
s: to return immediately if the line is not up.
i: to play filename as an indication tone from your "indications.conf".
n: to read digits even if the line is not up.
attempts
If greater than '1', that many <attempts> will be made in the event no data
is entered.
timeout
The number of seconds to wait for a digit response. If greater than '0',
that value will override the default timeout. Can be floating point.
[See Also]
SendDTMF()
Other option is mix it together by SOX or via libsox.

Force a statement to visually write to a file slowly

I have a want to take a File.open('somefile', 'w+') and make it read a file, take one line of text at a time, and visually write it slowly in another file. The reason I ask this question is because I can find nothing that does this already in code, nor can I find anything that actually controls the speed of how fast a program writes on the computer. I know that this can be simulated in a program such as Adobe Aftereffects so long as you provide a cursor after a character and the visual effect doesn't take place too quickly, but I've got 4,000 lines of code that I want to iterate over and can't afford to do this manually. This effect can also be achieved with a Microsoft Macro, but this requires it to be manually entered into the macro with no option of copy and paste.
-solutions preferred in Python, Ruby, and PHP-
If I understood properly, what you are trying to achieve, here you go:
input = File.read('readfrom.txt', 'r')
File.open('writeto.txt', 'w+') do |f|
input.chars.each do |c|
f.print(c) # print 1 char
f.flush # flush the stream
sleep 1 # sleep
end
end
This is one quick and dirty way of doing it in Python.
from time import sleep
mystring= 'My short text with a newline here\nand then ensuing text'
dt = 0.2 #0.2 seconds
for ch in mystring:
with open('fn_out','w+') as f:
f.write(ch)
f.flush()
sleep(dt)
f.flush() will result in updating the file with the changes.
One could make this more elaborate by having a longer pause after each newline, or a variable timestep dt.
To watch the change one has to repeatedly reload the file, as pointed out by #Tom Lord so you could run something like this beforehand to watch it in the terminal:
watch -n 0.1 cat fn_out
After some serious testing, I have finally developed a piece of code that will do the very thing I want. Tom Lord gave me some new words to use in my search terms "simulate typing" and this led me to win32ole with its SendKeys function. Here is a code that will iterate over all the characters in a file and print them out exactly as they were saved while simulating typing. I will see about making this into a gem for future use.
require 'win32ole'
wsh = WIN32OLE.new("WScript.Shell")
wsh.Run("Notepad.exe")
while not wsh.AppActivate("Notepad")
sleep 1
end
def fileToArray(file)
x = []
File.foreach("#{file}") do |line|
x << line.split('')
end
return x.flatten!
end
tests = fileToArray("readfrom.txt")
x = 0
while x <= tests.length
send = tests[x]
wsh.SendKeys("#{send}")
x += 1
sleep 0.1
end

Pause-Continue reading large text file with php

I have the below PHP code. I want to be able to continue reading the text file from the point it stopped, and the text file is over 90mb.
Is it possible to continue reading from the point the script stopped running?
$in = fopen('email.txt','r');
while($kw = trim(fgets($in))) {
//my code
}
No, that's not easily possible without saving the current state from time to time.
However, instead of doing that you should better try to fix whatever causes your script to stop. set_time_limit(0); and ignore_user_abort(true); will most likely prevent your script from being stopped while it's running.
If you do want to be able to continue from some position, use ftell($in) to get the position and store it in a file/database from time to time. When starting the script you check if you have a stored position and then simply fseek($in, $offset); after opening the file.
If the script is executed from a browser and it takes enough time to make aborts likely, you could also consider splitting it in chunks and cleanly terminating the script with a redirect containing an argument where to continue. So your script would process e.g. 1000 lines and then be restarted with an offset of 1000 to process the next 1000 lines and so on.

Amazon Simple Queue Service (SQS)

I created a queue in SQS, added two messages (serialized PHP arrays: array('filename' => 0, ...) and array('filename' => 1, ...)). I'm using the newest version of amazon SDK for PHP from their git repo.
The problem is that when I use receive_message function with these options:
MaxNumberOfMessages = 10
VisibilityTimeout = 0 // other values doesn't change much
I get only the first message, repeated 10 times:
<ReceiveMessageResponse>
−
<ReceiveMessageResult>
−
<Message>
<MessageId>82523332-75e0-444d-ae8f-55ccd5580beb</MessageId>
−
<ReceiptHandle>
v5iiyMGi3b6RunVNVvjOQOV+ZDqRV7sNLzj5pUAEj1brIAkucpYiGaM8UIdOEis9Kouh4s+cAkSAd7MhbJKPGM6SdKYE993x2Lf/DwEbhkfmzRxOevzUsyJCrrVdTSTSx0cNUqqV6Cgr/Asi72t/UOhbdXhTp3kaCaZfd2weymg=
</ReceiptHandle>
<MD5OfBody>ced185420292fbd06b32ea6e35da3d21</MD5OfBody>
−
<Body>
a:3:{s:8:"priority";i:2;s:8:"filename";i:0;s:11:"task_ticket";s:0:"";}
</Body>
</Message>
−
<Message>
<MessageId>82523332-75e0-444d-ae8f-55ccd5580beb</MessageId>
−
<ReceiptHandle>
v5iiyMGi3b6RunVNVvjOQOV+ZDqRV7sNLzj5pUAEj1brIAkucpYiGaM8UIdOEis9Kouh4s+cAkSAd7MhbJKPGM6SdKYE993x2Lf/DwEbhkfmzRxOevzUsyJCrrVdTSTSx0cNUqqV6Cgr/Asi72t/UOhbdXhTp3kaCaZfd2weymg=
</ReceiptHandle>
<MD5OfBody>ced185420292fbd06b32ea6e35da3d21</MD5OfBody>
−
<Body>
a:3:{s:8:"priority";i:2;s:8:"filename";i:0;s:11:"task_ticket";s:0:"";}
</Body>
</Message>
...and so on, always with "filename";i:0
I'm 100% that there are only 2 messages in the queue (I deleted it and recreated to be sure) and yet I get only the first one, populated many times. This changes from time to time and sometimes I get the second one mixed in the list. If I leave VisibilityTimeout as default 3 (or other non-zero value) the first one disappears for a while (as expected) and then I get the second one repeated many times.
get_queue_size returns 2, which is true.
I also tried Amazon Scratchpad and just made API calls with the same results. So, is SQS broken or I'm doing something totally wrong?
I believe this is expected behavior because you have set VisibilityTimeout = 0. Typically you would set the timeout value to be the expected duration to process a message. You must call delete on a read message before the visibility timeout expires or the message will be automatically re-queued.
In more complex systems a separate thread might be used to extend the timeout period for a single message if the initial timeout was not long enough.
As it sounds like you are just starting, it's important that you write your message processing code to account for reading the same message multiple times. Not only can your message get re-queued automatically but SQS will occasionally return a duplicate message.

How can I tell what line a file resource is currently "on" in PHP?

Using PHP, it's possible to read off the contents of a file using fopen and fgets. Each time fgets is called, it returns the next line in the file.
How does fgets know what line to read? In other words, how does it know that it last read line 5, so it should return the contents of line 6 this time? Is there a way for me to access that line-number data?
(I know it's possible to do something similar by reading the entire contents of the file into an array with file, but I'd like to accomplish this with fopen.)
There is a "position" kept in memory for each file that is opened ; it is automatically updated each time you are reading a line/character/whatever from the file.
You can get this position with ftell, and modify it with fseek :
ftell — Returns the current position
of the file read/write pointer
fseek — Seeks on a file pointer
You can also use rewind to... rewind... the position of that pointer.
This is not getting you a position as a line number, but closer to a position as a character number (actually, you are getting the position as a number of bytes from the beginning of the file) ; when you have that, reading a line is just a metter of reading characters until yu hit an end of line character.
BTW : as far as I remember, these functions are coming from the C language -- PHP itself being written in C ;-)
Files are just a stream of data, read from the beginning to the end. The OS will remember the position you've read so far in that file. If needed, doing so in the application as well is fairly simple. The OS only cares about byte positions though, not lines.
Just imagine dealing out a deck of 52 card sequentially. You hand off the first card. Next time the 2. card. When you want to give out the 3. card , you don't need to start counting from the start again, or even remembering where you were you just hand out the next available card, and that'll be the third.
It might be a bit more work that's needed to read lines, since you'd want to buffer data read from the actual file for preformance sake, but it's not that much more to it than to record the offset of the last piece of data you handed out, find the next newline character and hand off all the data between those 2 points.
PHP nor the OS has no real need to keep the line number around, since all the system care about is "next line". If you want to know the line number, you keep a counter and increment it every time your app reads a line.
$lineno=0;
while (!feof($handle)) {
$buffer = fgets($handle, 4096);
lineno++; // keep track of the line number
...
}
i hav this old sample i hob its can help you :)
$File = file('path');
$array = array();
$linenr = 5;
foreach( $File AS $line_num => $line )
{
$array = array_push( $array , $line );
}
echo $array[($linenr-1)];
You could just call fgets and increment a var $line_number each time you call it. That would tell you the line it is on.

Categories