stream: implement some HTTP specific options for stream_lavf

The "http:" protocol has been switched to use ffmpeg's HTTP
implementation some time ago. One problem with this was that many HTTP
specific options stopped working, because they were obviously
implemented for the internal HTTP implementation only.

Add the missing things. Note that many options will work for ffmpeg
only, as Libav's HTTP implementation is missing these. They will
silently be ignored on Libav.

Some options we can't fix:
--ipv4-only-proxy, --prefer-ipv4, --prefer-ipv6
    As far as I can see, not even libavformat internals distinguish
    between ipv4 and ipv6.
--user, --passwd
    ffmpeg probably supports specifying these in the URL directly.
This commit is contained in:
wm4 2013-01-24 16:05:52 +01:00
parent 570271c776
commit dd96c11d5e
9 changed files with 61 additions and 30 deletions

View File

@ -495,15 +495,11 @@
(network only)
Support cookies when making HTTP requests. Disabled by default.
*WARNING*: works with the deprecated ``mp_http://`` protocol only.
--cookies-file=<filename>
(network only)
Read HTTP cookies from <filename>. The file is
assumed to be in Netscape format.
*WARNING*: works with the deprecated ``mp_http://`` protocol only.
--correct-pts, --no-correct-pts
Switches mpv to a mode where timestamps for video frames are
calculated differently and video filters which add new frames or modify
@ -824,8 +820,6 @@
--http-header-fields=<field1,field2>
Set custom HTTP fields when accessing HTTP stream.
*WARNING*: works with the deprecated ``mp_http://`` protocol only.
*EXAMPLE*:
``mpv --http-header-fields='Field1: value1','Field2: value2' http://localhost:1234``
@ -1677,8 +1671,6 @@
--referrer=<string>
Specify a referrer path or URL for HTTP requests.
*WARNING*: works with the deprecated ``mp_http://`` protocol only.
--reuse-socket
(udp:// only)
Allows a socket to be reused by other processes as soon as it is closed.
@ -2272,8 +2264,6 @@
--user-agent=<string>
Use <string> as user agent for HTTP streaming.
*WARNING*: works with the deprecated ``mp_http://`` protocol only.
-v
Increment verbosity level, one level for each ``-v`` found on the command
line.

View File

@ -48,19 +48,6 @@ extern int field_dominance;
/* from dec_audio, currently used for ac3surround decoder only */
extern int fakemono;
/* defined in network.c */
extern char *network_username;
extern char *network_password;
extern int network_bandwidth;
extern char *network_useragent;
extern char *network_referrer;
extern int network_cookies_enabled;
extern char *cookies_file;
extern int network_prefer_ipv4;
extern int network_ipv4_only_proxy;
extern int reuse_socket;
extern int dvd_speed; /* stream/stream_dvd.c */
/* defined in demux: */

View File

@ -45,8 +45,6 @@
#include "demux/asfguid.h"
extern int network_bandwidth;
static int asf_http_streaming_start(stream_t *stream, int *demuxer_type);
static int asf_read_wrapper(int fd, void *buffer, int len, streaming_ctrl_t *stream_ctrl) {

View File

@ -261,3 +261,24 @@ cookies_set(HTTP_header_t * http_hdr, const char *domain, const char *url)
http_set_field(http_hdr, buf);
free(buf);
}
// Return a cookies string as expected by lavf (libavformat/http.c). The format
// is like a Set-Cookie header (http://curl.haxx.se/rfc/cookie_spec.html),
// separated by newlines.
char *cookies_lavf(void)
{
if (!cookie_list)
cookie_list = load_cookies();
struct cookie_list_type *list = cookie_list;
char *res = talloc_strdup(NULL, "");
while (list) {
res = talloc_asprintf_append_buffer(res,
"%s=%s; path=%s; domain=%s; %s\n", list->name, list->value,
list->path, list->domain, list->secure ? "secure" : "");
list = list->next;
}
return res;
}

View File

@ -28,5 +28,6 @@
void cookies_set(HTTP_header_t * http_hdr, const char *hostname,
const char *url);
char *cookies_lavf(void);
#endif /* MPLAYER_COOKIES_H */

View File

@ -45,8 +45,6 @@
#include <libavutil/avutil.h>
extern int network_bandwidth;
typedef struct {
unsigned metaint;
unsigned metapos;

View File

@ -63,6 +63,18 @@ extern const mime_struct_t mime_type_table[];
extern char **network_http_header_fields;
extern char *network_username;
extern char *network_password;
extern int network_bandwidth;
extern char *network_useragent;
extern char *network_referrer;
extern int network_cookies_enabled;
extern char *cookies_file;
extern int network_prefer_ipv4;
extern int network_ipv4_only_proxy;
extern int reuse_socket;
streaming_ctrl_t *streaming_ctrl_new(void);
int streaming_bufferize( streaming_ctrl_t *streaming_ctrl, char *buffer, int size);

View File

@ -27,6 +27,9 @@
#include "core/m_struct.h"
#include "demux/demux.h"
#include "network.h"
#include "cookies.h"
static int fill_buffer(stream_t *s, char *buffer, int max_len)
{
AVIOContext *avio = s->priv;
@ -97,6 +100,7 @@ static int open_f(stream_t *stream, int mode, void *opts, int *file_format)
int flags = 0;
AVIOContext *avio = NULL;
int res = STREAM_ERROR;
AVDictionary *dict = NULL;
void *temp = talloc_new(NULL);
if (mode == STREAM_READ)
@ -137,7 +141,28 @@ static int open_f(stream_t *stream, int mode, void *opts, int *file_format)
filename = talloc_asprintf(temp, "mmsh://%.*s", BSTR_P(b_filename));
}
int err = avio_open(&avio, filename, flags);
#ifdef CONFIG_NETWORKING
// HTTP specific options (other protocols ignore them)
if (network_useragent)
av_dict_set(&dict, "user-agent", network_useragent, 0);
if (network_cookies_enabled)
av_dict_set(&dict, "cookies", talloc_steal(temp, cookies_lavf()), 0);
char *cust_headers = talloc_strdup(temp, "");
if (network_referrer) {
cust_headers = talloc_asprintf_append(cust_headers, "Referer: %s\r\n",
network_referrer);
}
if (network_http_header_fields) {
for (int n = 0; network_http_header_fields[n]; n++) {
cust_headers = talloc_asprintf_append(cust_headers, "%s\r\n",
network_http_header_fields[n]);
}
}
if (strlen(cust_headers))
av_dict_set(&dict, "headers", cust_headers, 0);
#endif
int err = avio_open2(&avio, filename, flags, NULL, &dict);
if (err < 0) {
if (err == AVERROR_PROTOCOL_NOT_FOUND)
mp_msg(MSGT_OPEN, MSGL_ERR, "[ffmpeg] Protocol not found. Make sure"
@ -178,6 +203,7 @@ static int open_f(stream_t *stream, int mode, void *opts, int *file_format)
res = STREAM_OK;
out:
av_dict_free(&dict);
talloc_free(temp);
return res;
}

View File

@ -60,8 +60,6 @@ udp_streaming_start (stream_t *stream)
static int
udp_stream_open (stream_t *stream, int mode, void *opts, int *file_format)
{
extern int network_bandwidth;
mp_msg (MSGT_OPEN, MSGL_INFO, "STREAM_UDP, URL: %s\n", stream->url);
stream->streaming_ctrl = streaming_ctrl_new ();
if (!stream->streaming_ctrl)