4 * @file gmyth/gmyth_vlc.c
6 * @brief <p> GMythVLC library provides functions that
7 * interact with a VLC server running telnet interface.
9 * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
10 * @author Artur Duque de Souza <artur.souza@indt.org.br>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "gmyth_vlc.h"
35 #include "gmyth_debug.h"
36 #include "gmyth_socket.h"
41 static int _socket_send(int socket, gchar * msg);
42 static int _socket_recv(int socket, gchar * buf);
44 /** Primitive function to send a message through the socket
47 * @param msg the message itself
48 * @return 0 if success
51 _socket_send(int socket, gchar * msg)
53 size_t size = strlen(msg) + 2; // (\n + \0)
54 gchar *final = (gchar *) g_malloc0(sizeof(gchar) * size);
56 g_snprintf(final, size, "%s\n", msg);
58 if (send(socket, final, strlen(final), 0) == -1)
59 perror("GMyth_VLC: send error");
66 /** Primitive function to receive a message through the socket
69 * @param buf Buffer to put the message
70 * @return 0 if success
73 _socket_recv(int socket, gchar * buf)
77 if ((numbytes = recv(socket, buf, BUFFER - 1, 0)) == -1) {
78 perror("GMyth_VLC: recv error");
82 buf[numbytes - 1] = '\0';
87 /** Function that adds options to the output media
89 * @param vlc structure with options for vlc
90 * @param output the number of the output media
91 * @param kind the type of option we'll change
92 * @param the params for the option
93 * @return 0 if success
96 gmyth_vlc_setup_output(GMythVlc * vlc, int output, gchar * kind,
101 size_t size = strlen(opts) + 25;
102 gchar *msg = g_malloc0(sizeof(gchar) * size);
104 g_snprintf(msg, size, "setup output%d %s %s", output, kind, opts);
106 ret = _socket_send(vlc->sockfd, msg);
113 /** Function to clean the playlist
115 * @param vlc structure with options for vlc
116 * @param output the number of the output media
117 * @param file the file we want to insert in the playlist
118 * @return 0 if success
121 gmyth_vlc_clean_playlist(GMythVlc * vlc)
123 return _socket_send(vlc->sockfd, "del all");
127 /** Function to control the playlist
129 * @param vlc structure with options for vlc
130 * @param output the number of the output media
131 * @param command play, stop or pause(just for vod)
132 * @return 0 if success
135 gmyth_vlc_control_input(GMythVlc * vlc, int output, gchar * command)
138 gchar *msg = g_malloc0(sizeof(gchar) * size);
140 g_snprintf(msg, size, "control output%d %s", output, command);
142 int ret = _socket_send(vlc->sockfd, msg);
150 /** Function to insert an item in the playlist
152 * @param vlc structure with options for vlc
153 * @param output the number of the output media
154 * @param file the file we want to insert in the playlist
155 * @return 0 if success
158 gmyth_vlc_create_input(GMythVlc * vlc, int output, gchar * file)
160 return gmyth_vlc_setup_output(vlc, output, "input", file);
164 /** Function to create a channel in vlc
166 * @param vlc structure with options for vlc
167 * @param type the type of channel (broadcast, vod...)
169 * @return 0 if success
172 gmyth_vlc_create_channel(GMythVlc * vlc, gchar * type, int port,
177 gchar *msg = (gchar *) g_malloc0(sizeof(gchar) * size);
179 g_snprintf(msg, size, "new output%d %s enabled loop", vlc->n_outputs,
182 ret = _socket_send(vlc->sockfd, msg);
185 gmyth_vlc_setup_output(vlc, vlc->n_outputs, "option",
190 msg = (gchar *) g_malloc0(sizeof(gchar) * size);
193 // Best transcode option for N800 (MP1V)
194 g_snprintf(msg, size, "#transcode{vcodec=mp1v,vb=384,"
195 "fps=25.0,scale=1,acodec=mpga,"
196 "ab=64,channels=1}:duplicate{dst="
197 "std{access=http,mux=mpeg1,dst=" ":%d}}", port);
199 // Best transcode option for N800 (THEORA)
200 g_snprintf(msg, size, "#transcode{vcodec=theo,vb=384,"
201 "fps=25.0,scale=1,acodec=vorb,"
202 "ab=64,channels=1}:duplicate{dst="
203 "std{access=http,mux=ogg,dst=" ":%d}}", port);
205 ret = gmyth_vlc_setup_output(vlc, vlc->n_outputs, "output", msg);
216 /** Function to connect to vlc on the backend
218 * @param vlc structure with options for vlc
219 * @param backend_info infos about the backend
220 * @param passwd the password for telnet interface
221 * @return 0 if success
224 gmyth_vlc_connect(GMythVlc * vlc, GMythBackendInfo * backend_info,
225 gchar * passwd, int port)
229 if ((vlc->he = gethostbyname(backend_info->hostname)) == NULL) {
230 herror("GMyth_VLC: gethostbyname error");
234 if ((vlc->sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
235 perror("GMyth_VLC: socket error");
239 vlc->their_addr.sin_family = AF_INET;
240 vlc->their_addr.sin_port = htons(port);
241 vlc->their_addr.sin_addr = *((struct in_addr *) vlc->he->h_addr);
242 memset(&(vlc->their_addr.sin_zero), '\0', 8);
244 if (connect(vlc->sockfd, (struct sockaddr *) &(vlc->their_addr),
245 sizeof(struct sockaddr)) == -1) {
246 perror("GMyth_VLC: connect error. Check VLC's telnet interface");
249 // Receive the Password's Prompt
250 numbytes = _socket_recv(vlc->sockfd, vlc->buf);
252 // Send the Password. We don't have to
253 // care about passwords being sent in plain text
254 // because telnet protocol does it.
255 _socket_send(vlc->sockfd, passwd);
257 // Receive the Welcome msg
258 numbytes = _socket_recv(vlc->sockfd, vlc->buf);
260 if (strncmp(vlc->buf, "\r\nWrong password.", 17) == 0) {
261 perror("Gmyth_VLC: passwd error. Check your passwd");
270 /** Function to disconnect from vlc
272 * @param vlc structure with options for vlc
273 * @param backend_info infos about the backend
274 * @return 0 if success
277 gmyth_vlc_disconnect(GMythVlc * vlc)
282 ret = gmyth_vlc_clean_playlist(vlc);
289 return close(vlc->sockfd);