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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } |
| static char * | app = "MP3Player" |
| static struct ast_module_info * | ast_module_info = &__mod_info |
Silly application to play an MP3 file -- uses mpg123.
Definition in file app_mp3.c.
| #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().
| static int load_module | ( | void | ) | [static] |
Definition at line 234 of file app_mp3.c.
References ast_register_application_xml, and mp3_exec().
00235 { 00236 return ast_register_application_xml(app, mp3_exec); 00237 }
| static int mp3_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 120 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(), f, ast_frame::frametype, LOG_WARNING, mp3play(), ast_frame::offset, timed_read(), and ast_channel::writeformat.
Referenced by load_module().
00121 { 00122 int res=0; 00123 int fds[2]; 00124 int ms = -1; 00125 int pid = -1; 00126 int owriteformat; 00127 int timeout = 2000; 00128 struct timeval next; 00129 struct ast_frame *f; 00130 struct myframe { 00131 struct ast_frame f; 00132 char offset[AST_FRIENDLY_OFFSET]; 00133 short frdata[160]; 00134 } myf = { 00135 .f = { 0, }, 00136 }; 00137 00138 if (ast_strlen_zero(data)) { 00139 ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n"); 00140 return -1; 00141 } 00142 00143 if (pipe(fds)) { 00144 ast_log(LOG_WARNING, "Unable to create pipe\n"); 00145 return -1; 00146 } 00147 00148 ast_stopstream(chan); 00149 00150 owriteformat = chan->writeformat; 00151 res = ast_set_write_format(chan, AST_FORMAT_SLINEAR); 00152 if (res < 0) { 00153 ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); 00154 return -1; 00155 } 00156 00157 res = mp3play((char *)data, fds[1]); 00158 if (!strncasecmp((char *)data, "http://", 7)) { 00159 timeout = 10000; 00160 } 00161 /* Wait 1000 ms first */ 00162 next = ast_tvnow(); 00163 next.tv_sec += 1; 00164 if (res >= 0) { 00165 pid = res; 00166 /* Order is important -- there's almost always going to be mp3... we want to prioritize the 00167 user */ 00168 for (;;) { 00169 ms = ast_tvdiff_ms(next, ast_tvnow()); 00170 if (ms <= 0) { 00171 res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata), timeout); 00172 if (res > 0) { 00173 myf.f.frametype = AST_FRAME_VOICE; 00174 myf.f.subclass = AST_FORMAT_SLINEAR; 00175 myf.f.datalen = res; 00176 myf.f.samples = res / 2; 00177 myf.f.mallocd = 0; 00178 myf.f.offset = AST_FRIENDLY_OFFSET; 00179 myf.f.src = __PRETTY_FUNCTION__; 00180 myf.f.delivery.tv_sec = 0; 00181 myf.f.delivery.tv_usec = 0; 00182 myf.f.data.ptr = myf.frdata; 00183 if (ast_write(chan, &myf.f) < 0) { 00184 res = -1; 00185 break; 00186 } 00187 } else { 00188 ast_debug(1, "No more mp3\n"); 00189 res = 0; 00190 break; 00191 } 00192 next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000)); 00193 } else { 00194 ms = ast_waitfor(chan, ms); 00195 if (ms < 0) { 00196 ast_debug(1, "Hangup detected\n"); 00197 res = -1; 00198 break; 00199 } 00200 if (ms) { 00201 f = ast_read(chan); 00202 if (!f) { 00203 ast_debug(1, "Null frame == hangup() detected\n"); 00204 res = -1; 00205 break; 00206 } 00207 if (f->frametype == AST_FRAME_DTMF) { 00208 ast_debug(1, "User pressed a key\n"); 00209 ast_frfree(f); 00210 res = 0; 00211 break; 00212 } 00213 ast_frfree(f); 00214 } 00215 } 00216 } 00217 } 00218 close(fds[0]); 00219 close(fds[1]); 00220 00221 if (pid > -1) 00222 kill(pid, SIGKILL); 00223 if (!res && owriteformat) 00224 ast_set_write_format(chan, owriteformat); 00225 00226 return res; 00227 }
| static int mp3play | ( | char * | filename, | |
| int | fd | |||
| ) | [static] |
Definition at line 67 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().
00068 { 00069 int res; 00070 00071 res = ast_safe_fork(0); 00072 if (res < 0) 00073 ast_log(LOG_WARNING, "Fork failed\n"); 00074 if (res) { 00075 return res; 00076 } 00077 if (ast_opt_high_priority) 00078 ast_set_priority(0); 00079 00080 dup2(fd, STDOUT_FILENO); 00081 ast_close_fds_above_n(STDERR_FILENO); 00082 00083 /* Execute mpg123, but buffer if it's a net connection */ 00084 if (!strncasecmp(filename, "http://", 7)) { 00085 /* Most commonly installed in /usr/local/bin */ 00086 execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00087 /* But many places has it in /usr/bin */ 00088 execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00089 /* As a last-ditch effort, try to use PATH */ 00090 execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00091 } 00092 else { 00093 /* Most commonly installed in /usr/local/bin */ 00094 execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00095 /* But many places has it in /usr/bin */ 00096 execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00097 /* As a last-ditch effort, try to use PATH */ 00098 execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00099 } 00100 /* Can't use ast_log since FD's are closed */ 00101 fprintf(stderr, "Execute of mpg123 failed\n"); 00102 _exit(0); 00103 }
| static int timed_read | ( | int | fd, | |
| void * | data, | |||
| int | datalen, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 105 of file app_mp3.c.
References ast_log(), ast_poll, and LOG_NOTICE.
Referenced by mp3_exec().
00106 { 00107 int res; 00108 struct pollfd fds[1]; 00109 fds[0].fd = fd; 00110 fds[0].events = POLLIN; 00111 res = ast_poll(fds, 1, timeout); 00112 if (res < 1) { 00113 ast_log(LOG_NOTICE, "Poll timed out/errored out with %d\n", res); 00114 return -1; 00115 } 00116 return read(fd, data, datalen); 00117 00118 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 229 of file app_mp3.c.
References ast_unregister_application().
00230 { 00231 return ast_unregister_application(app); 00232 }
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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static] |
struct ast_module_info* ast_module_info = &__mod_info [static] |
1.6.2