4 * Copyright (C) Joey Parrish
6 * This file is part of MPlayer, a free movie player.
8 * MPlayer is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
13 * MPlayer is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with MPlayer; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * If you have a tivo with the vstream server installed, (and most tivo
25 * hackers do,) then you can connect to it and stream ty files using
26 * this module. The url syntax is tivo://host/fsid or tivo://host/list
27 * to list the available recordings and their fsid's.
28 * This module depends on libvstream-client, which is available from
29 * http://armory.nicewarrior.org/projects/vstream-client .
36 #include <sys/types.h>
54 #include <vstream-client.h>
56 void vstream_error(const char *format
, ...) {
60 vsnprintf(buf
, 1024, format
, va
);
62 mp_msg(MSGT_STREAM
, MSGL_ERR
, buf
);
65 static struct stream_priv_s
{
68 } stream_priv_dflts
= {
73 #define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
75 static const m_option_t stream_opts_fields
[] = {
76 {"hostname", ST_OFF(host
), CONF_TYPE_STRING
, 0, 0 ,0, NULL
},
77 {"filename", ST_OFF(fsid
), CONF_TYPE_STRING
, 0, 0 ,0, NULL
},
78 { NULL
, NULL
, 0, 0, 0, 0, NULL
}
81 static struct m_struct_st stream_opts
= {
83 sizeof(struct stream_priv_s
),
88 static int fill_buffer(stream_t
*s
, char* buffer
, int max_len
){
89 struct stream_priv_s
* p
= (struct stream_priv_s
*)s
->priv
;
90 int len
= vstream_load_chunk(p
->fsid
, buffer
, max_len
, s
->pos
);
91 if (len
<= 0) return 0;
95 static int seek(stream_t
*s
,off_t newpos
) {
100 static int control(struct stream_st
*s
,int cmd
,void* arg
) {
101 return STREAM_UNSUPPORTED
;
104 static void close_s(struct stream_st
*s
) {
107 static int open_s(stream_t
*stream
, int mode
, void* opts
, int* file_format
) {
109 struct stream_priv_s
* p
= (struct stream_priv_s
*)opts
;
111 if(mode
!= STREAM_READ
)
112 return STREAM_UNSUPPORTED
;
115 mp_msg(MSGT_OPEN
, MSGL_ERR
, "We need a host name (ex: tivo://hostname/fsid)\n");
116 m_struct_free(&stream_opts
, opts
);
120 if(!p
->fsid
|| strlen(p
->fsid
) == 0) {
121 mp_msg(MSGT_OPEN
, MSGL_ERR
, "We need an fsid (ex: tivo://hostname/fsid)\n");
122 m_struct_free(&stream_opts
, opts
);
126 f
= connect2Server(p
->host
, VSERVER_PORT
, 1);
129 mp_msg(MSGT_OPEN
, MSGL_ERR
, "Connection to %s failed\n", p
->host
);
130 m_struct_free(&stream_opts
, opts
);
135 vstream_set_socket_fd(f
);
137 if (!strcmp(p
->fsid
, "list")) {
138 vstream_list_streams(0);
140 } else if (!strcmp(p
->fsid
, "llist")) {
141 vstream_list_streams(1);
145 if (vstream_start()) {
146 mp_msg(MSGT_OPEN
, MSGL_ERR
, "Cryptic internal error #1\n");
147 m_struct_free(&stream_opts
, opts
);
150 if (vstream_startstream(p
->fsid
)) {
151 mp_msg(MSGT_OPEN
, MSGL_ERR
, "Cryptic internal error #2\n");
152 m_struct_free(&stream_opts
, opts
);
156 stream
->start_pos
= 0;
157 stream
->end_pos
= vstream_streamsize();
158 mp_msg(MSGT_OPEN
, MSGL_DBG2
, "Tivo stream size is %d\n", stream
->end_pos
);
161 stream
->fill_buffer
= fill_buffer
;
162 stream
->control
= control
;
164 stream
->close
= close_s
;
165 stream
->type
= STREAMTYPE_VSTREAM
;
170 const stream_info_t stream_info_vstream
= {
178 1 // Url is an option string