Open Source Training Seminar FreePBX Paid Support

Ticket #529 (assigned Feature Requests: None)

Opened 3 years ago

Last modified 3 months ago

Module to play specific audio files from the web on demand

Reported by: caribou7 Assigned to: nobody (accepted)
Priority: minor Milestone: Cut Line
Component: Web interface Version: Eventually
Keywords: Cc:
Confirmation: Unreviewed SVN Revision (if applicable):
Backend Engine: All Backend Engine Version:

Description (Last modified by wiseoldowl)

I would like to see a module that allows you to define certain extensions or codes (e.g. *30) so that they will do the following:

- Play ringing tone to the caller

- Download an audio file from a specific fixed location OR extract the location URL from a "podcast" XML file and download that audio file (but, in the case of a podcast file, don't download the file again if we already have it from a previous call and it hasn't been updated - just play the one we previously downloaded).

- When a new file is completely downloaded, call sox to convert the file to a format asterisk is capable of playing (if necessary)

- answer the call (stop the ringing tone)

- play the file to the caller

- hangup

- Delete the file, unless it's a podcast file in which case save it (until a newer one is available to overwrite it) because someone else may want to hear it.

When I first started playing with Asterisk, I did it this way (this does NOT work anymore, because of some change in how Asterisk 2.7 handles shell scripts):

In extensions_custom.conf:

exten => *30,1,ringing
exten => *30,2,System(/var/lib/asterisk/batch/getmsnbc.sh)
exten => *30,3,Wait(1)
exten => *30,4,Answer
exten => *30,5,MP3Player(/tmp/msnbc.mp3)
exten => *30,6,Hangup

Then in getmsnbc.sh (don't laugh too hard, it was my first Linux script and it took me hours to write, but in the end it worked, although it probably does some things that don't need to be done):

if [ -a /var/lib/asterisk/batch/msnbc.xml ]
then
mv -f /var/lib/asterisk/batch/msnbc.xml
/var/lib/asterisk/batch/msnbc2.xml
fi
/usr/bin/curl -s
http://podcast.msnbc.com/audio/podcast/MSNBC-Headlines.xml
> /var/lib/asterisk/batch/msnbc.xml
if cmp -s /var/lib/asterisk/batch/msnbc.xml
/var/lib/asterisk/batch/msnbc2.xml
then
exit 0
else
grep -m 1  "http://podcast.msnbc.com/audio/podcast/vh"
/var/lib/asterisk/batch/msnbc.xml | sed 's/^[
\t]*<link>/\/usr\/bin\/curl -s /;s/<\/link>/ >
\/tmp\/msnbc.mp3\nexit 0\n/' >
/var/lib/asterisk/batch/msnbcurl.sh
chmod 744 /var/lib/asterisk/batch/msnbcurl.sh
/var/lib/asterisk/batch/msnbcurl.sh
fi
exit 0

Yes, this really did write a second shell script, then jumped into it. Sorry but as I say, this was my first attempt at trying to make a shell script. In Asterisk@Home 2.4 it would execute both scripts, and only then return to exten => *30,3,Wait(1) But in 2.7 it seems to fire off the shell script and continue blindly on, without waiting for the script to finish. The scripts themselves still work, but A@H doesn't wait for them to finish.

So, in the module it should ask for these things:

The extension number you want to assign this to (could be a * code also)

The full path and filename of the audio file or podcast (xml format) file.

Select ("radio button") whether it's a direct link to an audio file or a podcast XML file (if this can't be determined automatically - note that podcasts do not always use a file with an XML extension, so you can't necessarily go by extension)

And, for XML-format files, the XML tag containing the path to the actual file. This could be a little tricky because, for example, in this case you're looking for the tag "<enclosure url=" but the data you want is INSIDE the tag, such as this:

<enclosure
url="http://podcast.msnbc.com/audio/podcast/vh-03-25-2006-161811.mp3"
length="108239" type="audio/mpeg"/>

Point is, you need some way to explicitly declare where to look in the file for the URL of the file to download and play. I am led to believe "<enclosure url=" is a normal tag for a podcast BUT I can imagine that in some other cases the desired URL would be bracketed by specific tags (not part of the tag itself). Also there may be times when you might want to extract a URL from a regular HTML page.

Bonus points for allowing playback of formats other than MP3. TRIPLE bonus points if you manage to play the dreaded WMA format and its ilk.

Note we are NOT talking about playing STREAMING audio here, though that could certainly be another option. These are for things like one or two minute newscasts, weather reports or whatever. Just an idea (since it's much easier to pick up a phone and punch in a few digits than to go to a computer, fire up a web browser, find what you want to listen to, and try to launch it).

Change History

01/06/07 21:29:46 changed by wiseoldowl

  • description changed.

This is funny - I actually have an agi script that gets this very same podcast, and also one for CNN, that I found in a blog post and slightly modified. It's probably not the world's best approach either, but it's got to be better than the shell script approach. The drawback is that it uses perl (actually pperl, "persistent perl", but I think regular perl works just as well), so you have to make sure the necessary perl modules (in the first few lines) are installed. I'll put the CNN one here because it does include a call to lame (not sox) to do the audio conversion:

#!/usr/bin/pperl

use XML::Simple;
use Asterisk::AGI;
use LWP::Simple;

$AGI = new Asterisk::AGI;
$xml = new XML::Simple;
$noext = "/tmp/newscnn";
$resampled = $noext . ".mp3";

$AGI->verbose("Getting XML file\n",1);
$data = $xml->XMLin(get("http://www.cnn.com/services/podcasting/newscast/rss.xml"));
$url = $data->{channel}->{item}->[0]->{link};
$AGI->verbose("Extracted URL $url from XML file",1);
$url =~ m#(?:.*/)(.*)$#;
$podcast = "/tmp/" . $1;
if ((-s $podcast) && (-s $resampled))
{
  $AGI->verbose("$podcast already exists - skipping download\n",1);
}
else
{
  system("rm /tmp/CNN-News*.mp3");
  $AGI->verbose("Getting $url\n",1);
  getstore("$url", "$podcast") or die "Could not retrieve podcast";
  $AGI->verbose("$podcast retrived\n",1);
  system("lame --silent --mp3input --scale 2 --abr 32 -m m -h $podcast $resampled")==0 or die "Could not convert file";
  $AGI->verbose("$pd converted to $resampled\n",1);
}
$AGI->answer;
$AGI->exec('Playback',$noext);
$AGI->hangup;
exit;

The above code is saved under the name /var/lib/asterisk/agi-bin/msnbcnews.agi and then gets called (e.g. from extension_custom.conf) using something like this:

exten => _.,1,Ringing
exten => _.,n,AGI(cnnnews.agi)
exten => _.,n,Hangup

This code was obtained (with the exception of minor changes) from a three-part blog series here, here, and here. I'm sure that if this were ever to be included in FreePBX the developers would probably want to rewrite it in PHP and make it more generic, but this at least gives a logic path to follow, and may be useful to someone as is.

01/06/07 21:32:56 changed by wiseoldowl

  • description changed.

Description change was unintentional, I typed wiki formatting codes in the wrong box (and have removed them, so the description should be as it was after I post this).

01/06/07 21:39:21 changed by wiseoldowl

  • description changed.

Ack! One more try at restoring the original formatting by the OP.

07/24/08 17:44:43 changed by ryppn

  • confirmation set to Unreviewed.
  • engine_version changed.
  • svn_rev changed.
  • milestone set to Cut Line.
Donate



Support
Download
Develop
Forums
News
Documentation
Paid Support
About

Paid Ads