Fri Jun 19 12:09:59 2009

Asterisk developer's documentation


app_mp3.c File Reference

Silly application to play an MP3 file -- uses mpg123. More...

#include "asterisk.h"
#include <sys/time.h>
#include <signal.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/frame.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/app.h"

Go to the source code of this file.

Defines

#define LOCAL_MPG_123   "/usr/local/bin/mpg123"
#define MPG_123   "/usr/bin/mpg123"

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int load_module (void)
static int mp3_exec (struct ast_channel *chan, void *data)
static int mp3play (char *filename, int fd)
static int timed_read (int fd, void *data, int datalen, int timeout)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Silly MP3 Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, }
static char * app = "MP3Player"
static struct ast_module_infoast_module_info = &__mod_info
static char * descrip
static char * synopsis = "Play an MP3 file or stream"


Detailed Description

Silly application to play an MP3 file -- uses mpg123.

Author:
Mark Spencer <markster@digium.com>

Definition in file app_mp3.c.


Define Documentation

#define LOCAL_MPG_123   "/usr/local/bin/mpg123"

Definition at line 44 of file app_mp3.c.

Referenced by mp3play(), and spawn_mp3().

#define MPG_123   "/usr/bin/mpg123"

Definition at line 45 of file app_mp3.c.

Referenced by mp3play(), and spawn_mp3().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 227 of file app_mp3.c.

static void __unreg_module ( void   )  [static]

Definition at line 227 of file app_mp3.c.

static int load_module ( void   )  [static]

Definition at line 222 of file app_mp3.c.

References ast_register_application, and mp3_exec().

00223 {
00224    return ast_register_application(app, mp3_exec, synopsis, descrip);
00225 }

static int mp3_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 110 of file app_mp3.c.

References ast_debug, AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, ast_log(), ast_read(), ast_samp2tv(), ast_set_write_format(), ast_stopstream(), ast_strlen_zero(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_waitfor(), ast_write(), chan, f, LOG_WARNING, mp3play(), ast_frame::offset, timed_read(), and ast_channel::writeformat.

Referenced by load_module().

00111 {
00112    int res=0;
00113    int fds[2];
00114    int ms = -1;
00115    int pid = -1;
00116    int owriteformat;
00117    int timeout = 2000;
00118    struct timeval next;
00119    struct ast_frame *f;
00120    struct myframe {
00121       struct ast_frame f;
00122       char offset[AST_FRIENDLY_OFFSET];
00123       short frdata[160];
00124    } myf;
00125    
00126    if (ast_strlen_zero(data)) {
00127       ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n");
00128       return -1;
00129    }
00130 
00131    if (pipe(fds)) {
00132       ast_log(LOG_WARNING, "Unable to create pipe\n");
00133       return -1;
00134    }
00135    
00136    ast_stopstream(chan);
00137 
00138    owriteformat = chan->writeformat;
00139    res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
00140    if (res < 0) {
00141       ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
00142       return -1;
00143    }
00144    
00145    res = mp3play((char *)data, fds[1]);
00146    if (!strncasecmp((char *)data, "http://", 7)) {
00147       timeout = 10000;
00148    }
00149    /* Wait 1000 ms first */
00150    next = ast_tvnow();
00151    next.tv_sec += 1;
00152    if (res >= 0) {
00153       pid = res;
00154       /* Order is important -- there's almost always going to be mp3...  we want to prioritize the
00155          user */
00156       for (;;) {
00157          ms = ast_tvdiff_ms(next, ast_tvnow());
00158          if (ms <= 0) {
00159             res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata), timeout);
00160             if (res > 0) {
00161                myf.f.frametype = AST_FRAME_VOICE;
00162                myf.f.subclass = AST_FORMAT_SLINEAR;
00163                myf.f.datalen = res;
00164                myf.f.samples = res / 2;
00165                myf.f.mallocd = 0;
00166                myf.f.offset = AST_FRIENDLY_OFFSET;
00167                myf.f.src = __PRETTY_FUNCTION__;
00168                myf.f.delivery.tv_sec = 0;
00169                myf.f.delivery.tv_usec = 0;
00170                myf.f.data.ptr = myf.frdata;
00171                if (ast_write(chan, &myf.f) < 0) {
00172                   res = -1;
00173                   break;
00174                }
00175             } else {
00176                ast_debug(1, "No more mp3\n");
00177                res = 0;
00178                break;
00179             }
00180             next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000));
00181          } else {
00182             ms = ast_waitfor(chan, ms);
00183             if (ms < 0) {
00184                ast_debug(1, "Hangup detected\n");
00185                res = -1;
00186                break;
00187             }
00188             if (ms) {
00189                f = ast_read(chan);
00190                if (!f) {
00191                   ast_debug(1, "Null frame == hangup() detected\n");
00192                   res = -1;
00193                   break;
00194                }
00195                if (f->frametype == AST_FRAME_DTMF) {
00196                   ast_debug(1, "User pressed a key\n");
00197                   ast_frfree(f);
00198                   res = 0;
00199                   break;
00200                }
00201                ast_frfree(f);
00202             } 
00203          }
00204       }
00205    }
00206    close(fds[0]);
00207    close(fds[1]);
00208    
00209    if (pid > -1)
00210       kill(pid, SIGKILL);
00211    if (!res && owriteformat)
00212       ast_set_write_format(chan, owriteformat);
00213    
00214    return res;
00215 }

static int mp3play ( char *  filename,
int  fd 
) [static]

Definition at line 57 of file app_mp3.c.

References ast_close_fds_above_n(), ast_log(), ast_opt_high_priority, ast_safe_fork(), ast_set_priority(), LOCAL_MPG_123, LOG_WARNING, and MPG_123.

Referenced by mp3_exec().

00058 {
00059    int res;
00060 
00061    res = ast_safe_fork(0);
00062    if (res < 0) 
00063       ast_log(LOG_WARNING, "Fork failed\n");
00064    if (res) {
00065       return res;
00066    }
00067    if (ast_opt_high_priority)
00068       ast_set_priority(0);
00069 
00070    dup2(fd, STDOUT_FILENO);
00071    ast_close_fds_above_n(STDERR_FILENO);
00072 
00073    /* Execute mpg123, but buffer if it's a net connection */
00074    if (!strncasecmp(filename, "http://", 7)) {
00075       /* Most commonly installed in /usr/local/bin */
00076        execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
00077       /* But many places has it in /usr/bin */
00078        execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
00079       /* As a last-ditch effort, try to use PATH */
00080        execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024",  "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
00081    }
00082    else {
00083       /* Most commonly installed in /usr/local/bin */
00084        execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
00085       /* But many places has it in /usr/bin */
00086        execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
00087       /* As a last-ditch effort, try to use PATH */
00088        execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
00089    }
00090    /* Can't use ast_log since FD's are closed */
00091    fprintf(stderr, "Execute of mpg123 failed\n");
00092    _exit(0);
00093 }

static int timed_read ( int  fd,
void *  data,
int  datalen,
int  timeout 
) [static]

Definition at line 95 of file app_mp3.c.

References ast_log(), ast_poll, and LOG_NOTICE.

Referenced by mp3_exec(), and NBScat_exec().

00096 {
00097    int res;
00098    struct pollfd fds[1];
00099    fds[0].fd = fd;
00100    fds[0].events = POLLIN;
00101    res = ast_poll(fds, 1, timeout);
00102    if (res < 1) {
00103       ast_log(LOG_NOTICE, "Poll timed out/errored out with %d\n", res);
00104       return -1;
00105    }
00106    return read(fd, data, datalen);
00107    
00108 }

static int unload_module ( void   )  [static]

Definition at line 217 of file app_mp3.c.

References ast_unregister_application().

00218 {
00219    return ast_unregister_application(app);
00220 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Silly MP3 Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static]

Definition at line 227 of file app_mp3.c.

char* app = "MP3Player" [static]

Definition at line 47 of file app_mp3.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 227 of file app_mp3.c.

char* descrip [static]

Initial value:

 
"  MP3Player(location): Executes mpg123 to play the given location,\n"
"which typically would be a filename or a URL. User can exit by pressing\n"
"any key on the dialpad, or by hanging up."

Definition at line 51 of file app_mp3.c.

char* synopsis = "Play an MP3 file or stream" [static]

Definition at line 49 of file app_mp3.c.


Generated on Fri Jun 19 12:09:59 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7