summaryrefslogtreecommitdiffstats
path: root/stream/stream_lavf.c
diff options
context:
space:
mode:
Diffstat (limited to 'stream/stream_lavf.c')
-rw-r--r--stream/stream_lavf.c51
1 files changed, 36 insertions, 15 deletions
diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
index 8bbfab8af8..a471c086e5 100644
--- a/stream/stream_lavf.c
+++ b/stream/stream_lavf.c
@@ -24,6 +24,8 @@
#include "common/msg.h"
#include "common/tags.h"
#include "common/av_common.h"
+#include "demux/demux.h"
+#include "misc/charset_conv.h"
#include "misc/thread_tools.h"
#include "stream.h"
#include "options/m_config.h"
@@ -37,12 +39,12 @@
#define OPT_BASE_STRUCT struct stream_lavf_params
struct stream_lavf_params {
char **avopts;
- int cookies_enabled;
+ bool cookies_enabled;
char *cookies_file;
char *useragent;
char *referrer;
char **http_header_fields;
- int tls_verify;
+ bool tls_verify;
char *tls_ca_file;
char *tls_cert_file;
char *tls_key_file;
@@ -56,9 +58,9 @@ const struct m_sub_options stream_lavf_conf = {
{"http-header-fields", OPT_STRINGLIST(http_header_fields)},
{"user-agent", OPT_STRING(useragent)},
{"referrer", OPT_STRING(referrer)},
- {"cookies", OPT_FLAG(cookies_enabled)},
+ {"cookies", OPT_BOOL(cookies_enabled)},
{"cookies-file", OPT_STRING(cookies_file), .flags = M_OPT_FILE},
- {"tls-verify", OPT_FLAG(tls_verify)},
+ {"tls-verify", OPT_BOOL(tls_verify)},
{"tls-ca-file", OPT_STRING(tls_ca_file), .flags = M_OPT_FILE},
{"tls-cert-file", OPT_STRING(tls_cert_file), .flags = M_OPT_FILE},
{"tls-key-file", OPT_STRING(tls_key_file), .flags = M_OPT_FILE},
@@ -73,7 +75,8 @@ const struct m_sub_options stream_lavf_conf = {
},
};
-static const char *const http_like[];
+static const char *const http_like[] =
+ {"http", "https", "mmsh", "mmshttp", "httproxy", NULL};
static int open_f(stream_t *stream);
static struct mp_tags *read_icy(stream_t *stream);
@@ -191,7 +194,7 @@ void mp_setup_av_network_options(AVDictionary **dict, const char *target_fmt,
char *file = opts->cookies_file;
if (file && file[0])
file = mp_get_user_path(temp, global, file);
- char *cookies = cookies_lavf(temp, log, file);
+ char *cookies = cookies_lavf(temp, global, log, file);
if (cookies && cookies[0])
av_dict_set(dict, "cookies", cookies, 0);
}
@@ -270,7 +273,7 @@ static int open_f(stream_t *stream)
for (int i = 0; i < sizeof(prefix) / sizeof(prefix[0]); i++)
if (!strncmp(filename, prefix[i], strlen(prefix[i])))
filename += strlen(prefix[i]);
- if (!strncmp(filename, "rtsp:", 5)) {
+ if (!strncmp(filename, "rtsp:", 5) || !strncmp(filename, "rtsps:", 6)) {
/* This is handled as a special demuxer, without a separate
* stream layer. demux_lavf will do all the real work. Note
* that libavformat doesn't even provide a protocol entry for
@@ -284,11 +287,18 @@ static int open_f(stream_t *stream)
}
// Replace "mms://" with "mmsh://", so that most mms:// URLs just work.
+ // Replace "dav://" or "webdav://" with "http://" and "davs://" or "webdavs://" with "https://"
bstr b_filename = bstr0(filename);
if (bstr_eatstart0(&b_filename, "mms://") ||
bstr_eatstart0(&b_filename, "mmshttp://"))
{
filename = talloc_asprintf(temp, "mmsh://%.*s", BSTR_P(b_filename));
+ } else if (bstr_eatstart0(&b_filename, "dav://") || bstr_eatstart0(&b_filename, "webdav://"))
+ {
+ filename = talloc_asprintf(temp, "http://%.*s", BSTR_P(b_filename));
+ } else if (bstr_eatstart0(&b_filename, "davs://") || bstr_eatstart0(&b_filename, "webdavs://"))
+ {
+ filename = talloc_asprintf(temp, "https://%.*s", BSTR_P(b_filename));
}
av_dict_set(&dict, "reconnect", "1", 0);
@@ -314,7 +324,7 @@ static int open_f(stream_t *stream)
if (err < 0) {
if (err == AVERROR_PROTOCOL_NOT_FOUND)
MP_ERR(stream, "Protocol not found. Make sure"
- " ffmpeg/Libav is compiled with networking support.\n");
+ " FFmpeg is compiled with networking support.\n");
goto out;
}
@@ -393,7 +403,21 @@ static struct mp_tags *read_icy(stream_t *s)
packet = bstr_cut(packet, i + head.len);
int end = bstr_find(packet, bstr0("\';"));
packet = bstr_splice(packet, 0, end);
+
+ bool allocated = false;
+ struct demux_opts *opts = mp_get_config_group(NULL, s->global, &demux_conf);
+ const char *charset = mp_charset_guess(s, s->log, packet, opts->meta_cp, 0);
+ if (charset && !mp_charset_is_utf8(charset)) {
+ bstr conv = mp_iconv_to_utf8(s->log, packet, charset, 0);
+ if (conv.start && conv.start != packet.start) {
+ allocated = true;
+ packet = conv;
+ }
+ }
mp_tags_set_bstr(res, bstr0("icy-title"), packet);
+ talloc_free(opts);
+ if (allocated)
+ talloc_free(packet.start);
}
av_opt_set(avio, "icy_metadata_packet", "-", AV_OPT_SEARCH_CHILDREN);
@@ -404,16 +428,14 @@ done:
return res;
}
-static const char *const http_like[] =
- {"http", "https", "mmsh", "mmshttp", "httproxy", NULL};
-
const stream_info_t stream_info_ffmpeg = {
.name = "ffmpeg",
.open = open_f,
.protocols = (const char *const[]){
- "rtmp", "rtsp", "http", "https", "mms", "mmst", "mmsh", "mmshttp", "rtp",
- "httpproxy", "rtmpe", "rtmps", "rtmpt", "rtmpte", "rtmpts", "srtp",
- "gopher", "data",
+ "rtmp", "rtsp", "rtsps", "http", "https", "mms", "mmst", "mmsh", "mmshttp",
+ "rtp", "httpproxy", "rtmpe", "rtmps", "rtmpt", "rtmpte", "rtmpts", "srt",
+ "rist", "srtp", "gopher", "gophers", "data", "ipfs", "ipns", "dav",
+ "davs", "webdav", "webdavs",
NULL },
.can_write = true,
.stream_origin = STREAM_ORIGIN_NET,
@@ -433,4 +455,3 @@ const stream_info_t stream_info_ffmpeg_unsafe = {
.stream_origin = STREAM_ORIGIN_UNSAFE,
.can_write = true,
};
-