Stream to an icecast server via ICES (see contrib/asterisk-ices.xml). More...
#include "asterisk.h"
#include <signal.h>
#include <fcntl.h>
#include <sys/time.h>
#include "asterisk/paths.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 | path_BIN "/usr/bin/" |
#define | path_LOCAL "/usr/local/bin/" |
Functions | |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Encode and Stream via icecast and ices") | |
static int | ices_exec (struct ast_channel *chan, const char *data) |
static int | icesencode (char *filename, int fd) |
static int | load_module (void) |
static int | unload_module (void) |
Variables | |
static char * | app = "ICES" |
Stream to an icecast server via ICES (see contrib/asterisk-ices.xml).
Definition in file app_ices.c.
#define path_BIN "/usr/bin/" |
Definition at line 71 of file app_ices.c.
Referenced by icesencode().
#define path_LOCAL "/usr/local/bin/" |
Definition at line 72 of file app_ices.c.
Referenced by icesencode().
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Encode and Stream via icecast and ices" | ||||
) |
static int ices_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 111 of file app_ices.c.
References ast_channel::_state, ast_answer(), ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_debug, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_read_format(), AST_STATE_UP, ast_stopstream(), ast_strlen_zero(), ast_waitfor(), ast_frame::data, ast_frame::datalen, errno, f, ast_flags::flags, ast_frame::frametype, icesencode(), LOG_WARNING, ast_frame::ptr, and ast_channel::readformat.
Referenced by load_module().
00112 { 00113 int res = 0; 00114 int fds[2]; 00115 int ms = -1; 00116 int pid = -1; 00117 int flags; 00118 int oreadformat; 00119 struct ast_frame *f; 00120 char filename[256]=""; 00121 char *c; 00122 00123 if (ast_strlen_zero(data)) { 00124 ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n"); 00125 return -1; 00126 } 00127 00128 if (pipe(fds)) { 00129 ast_log(LOG_WARNING, "Unable to create pipe\n"); 00130 return -1; 00131 } 00132 flags = fcntl(fds[1], F_GETFL); 00133 fcntl(fds[1], F_SETFL, flags | O_NONBLOCK); 00134 00135 ast_stopstream(chan); 00136 00137 if (chan->_state != AST_STATE_UP) 00138 res = ast_answer(chan); 00139 00140 if (res) { 00141 close(fds[0]); 00142 close(fds[1]); 00143 ast_log(LOG_WARNING, "Answer failed!\n"); 00144 return -1; 00145 } 00146 00147 oreadformat = chan->readformat; 00148 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00149 if (res < 0) { 00150 close(fds[0]); 00151 close(fds[1]); 00152 ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); 00153 return -1; 00154 } 00155 if (((char *)data)[0] == '/') 00156 ast_copy_string(filename, (char *) data, sizeof(filename)); 00157 else 00158 snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_CONFIG_DIR, (char *)data); 00159 /* Placeholder for options */ 00160 c = strchr(filename, '|'); 00161 if (c) 00162 *c = '\0'; 00163 res = icesencode(filename, fds[0]); 00164 if (res >= 0) { 00165 pid = res; 00166 for (;;) { 00167 /* Wait for audio, and stream */ 00168 ms = ast_waitfor(chan, -1); 00169 if (ms < 0) { 00170 ast_debug(1, "Hangup detected\n"); 00171 res = -1; 00172 break; 00173 } 00174 f = ast_read(chan); 00175 if (!f) { 00176 ast_debug(1, "Null frame == hangup() detected\n"); 00177 res = -1; 00178 break; 00179 } 00180 if (f->frametype == AST_FRAME_VOICE) { 00181 res = write(fds[1], f->data.ptr, f->datalen); 00182 if (res < 0) { 00183 if (errno != EAGAIN) { 00184 ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno)); 00185 res = -1; 00186 ast_frfree(f); 00187 break; 00188 } 00189 } 00190 } 00191 ast_frfree(f); 00192 } 00193 } 00194 close(fds[0]); 00195 close(fds[1]); 00196 00197 if (pid > -1) 00198 kill(pid, SIGKILL); 00199 if (!res && oreadformat) 00200 ast_set_read_format(chan, oreadformat); 00201 00202 return res; 00203 }
static int icesencode | ( | char * | filename, | |
int | fd | |||
) | [static] |
Definition at line 76 of file app_ices.c.
References ast_close_fds_above_n(), ast_debug, ast_log(), ast_opt_high_priority, ast_safe_fork(), ast_set_priority(), LOG_WARNING, path_BIN, path_LOCAL, and SENTINEL.
Referenced by ices_exec().
00077 { 00078 int res; 00079 00080 res = ast_safe_fork(0); 00081 if (res < 0) 00082 ast_log(LOG_WARNING, "Fork failed\n"); 00083 if (res) { 00084 return res; 00085 } 00086 00087 if (ast_opt_high_priority) 00088 ast_set_priority(0); 00089 dup2(fd, STDIN_FILENO); 00090 ast_close_fds_above_n(STDERR_FILENO); 00091 00092 /* Most commonly installed in /usr/local/bin 00093 * But many places has it in /usr/bin 00094 * As a last-ditch effort, try to use PATH 00095 */ 00096 execl(path_LOCAL "ices2", "ices", filename, SENTINEL); 00097 execl(path_BIN "ices2", "ices", filename, SENTINEL); 00098 execlp("ices2", "ices", filename, SENTINEL); 00099 00100 ast_debug(1, "Couldn't find ices version 2, attempting to use ices version 1.\n"); 00101 00102 execl(path_LOCAL "ices", "ices", filename, SENTINEL); 00103 execl(path_BIN "ices", "ices", filename, SENTINEL); 00104 execlp("ices", "ices", filename, SENTINEL); 00105 00106 ast_log(LOG_WARNING, "Execute of ices failed, could not find command.\n"); 00107 close(fd); 00108 _exit(0); 00109 }
static int load_module | ( | void | ) | [static] |
Definition at line 210 of file app_ices.c.
References ast_register_application_xml, and ices_exec().
00211 { 00212 return ast_register_application_xml(app, ices_exec); 00213 }
static int unload_module | ( | void | ) | [static] |
Definition at line 205 of file app_ices.c.
References ast_unregister_application().
00206 { 00207 return ast_unregister_application(app); 00208 }
char* app = "ICES" [static] |
Definition at line 74 of file app_ices.c.