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