Skip to content

Commit 4d53658

Browse files
committed
stream_file: make appending:// URLs more useful
By exposing the two parameters that control the *timeout* as options. `--appending-max-retries` replaces the `MAX_RETRIES` constant. And `--appending-retry-timeout` replaces the `RETRY-TIMEOUT`. The options have the same default values as the removed constants. So nothing should change behavior wise. Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
1 parent d37405c commit 4d53658

File tree

6 files changed

+60
-8
lines changed

6 files changed

+60
-8
lines changed

DOCS/interface-changes.rst

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Interface changes
3131
::
3232

3333
--- mpv 0.40.0 ---
34+
- add `--appending-max-retries` and `--appending-retry-timeout` options
3435
--- mpv 0.39.0 ---
3536
- turn `--cover-art-whitelist` into a list option
3637
- reserve `user-data/osc` and `user-data/mpv` sub-paths for internal use

DOCS/man/mpv.rst

+4-1
Original file line numberDiff line numberDiff line change
@@ -1403,7 +1403,10 @@ PROTOCOLS
14031403
Play a local file, but assume it's being appended to. This is useful for
14041404
example for files that are currently being downloaded to disk. This will
14051405
block playback, and stop playback only if no new data was appended after
1406-
a timeout of about 2 seconds.
1406+
a timeout.
1407+
1408+
The timeout span depends on the values of ``--appending-max-retries`` and
1409+
``--appending-retry-timeout`` options.
14071410

14081411
Using this is still a bit of a bad idea, because there is no way to detect
14091412
if a file is actually being appended, or if it's still written. If you're

DOCS/man/options.rst

+18
Original file line numberDiff line numberDiff line change
@@ -7674,6 +7674,24 @@ Miscellaneous
76747674
Input file type for ``mf://`` (available: jpeg, png, tga, sgi). By default,
76757675
this is guessed from the file extension.
76767676

7677+
``--appending-max-retries=<max-retries>``
7678+
Number of retries to read newly appended data at the end of a file, before
7679+
assuming it's not being appended to anymore (default: 10).
7680+
7681+
.. warning::
7682+
7683+
Setting this to a high value could significantly slow-down media
7684+
loading/seeking.
7685+
7686+
``--appending-retry-timeout=<retry-timeout>``
7687+
Timeout in seconds between attempts to read newly appended data at the end
7688+
of a file (default: 0.2).
7689+
7690+
.. warning::
7691+
7692+
Setting this to a high value could significantly slow-down media
7693+
loading/seeking.
7694+
76777695
``--stream-dump=<destination-filename>``
76787696
Instead of playing a file, read its byte stream and write it to the given
76797697
destination file. The destination is overwritten. Can be useful to test

options/options.c

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ static void print_version(struct mp_log *log)
5858
}
5959

6060
extern const struct m_sub_options tv_params_conf;
61+
extern const struct m_sub_options stream_appending_conf;
6162
extern const struct m_sub_options stream_bluray_conf;
6263
extern const struct m_sub_options stream_cdda_conf;
6364
extern const struct m_sub_options stream_dvb_conf;
@@ -559,6 +560,7 @@ static const m_option_t mp_opts[] = {
559560

560561
// ------------------------- stream options --------------------
561562

563+
{"appending", OPT_SUBSTRUCT(stream_appending_opts, stream_appending_conf)},
562564
#if HAVE_DVDNAV
563565
{"dvd", OPT_SUBSTRUCT(dvd_opts, dvd_conf)},
564566
#endif

options/options.h

+1
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ typedef struct MPOpts {
345345
int w32_priority;
346346
bool media_controls;
347347

348+
struct appending_opts *stream_appending_opts;
348349
struct bluray_opts *stream_bluray_opts;
349350
struct cdda_opts *stream_cdda_opts;
350351
struct dvb_opts *stream_dvb_opts;

stream/stream_file.c

+34-7
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "common/msg.h"
3636
#include "misc/thread_tools.h"
3737
#include "stream.h"
38+
#include "options/m_config.h"
3839
#include "options/m_option.h"
3940
#include "options/path.h"
4041

@@ -85,6 +86,26 @@ typedef enum _FSINFOCLASS {
8586
#endif
8687
#endif
8788

89+
90+
struct appending_opts {
91+
double retry_timeout;
92+
int max_retries;
93+
};
94+
95+
#define OPT_BASE_STRUCT struct appending_opts
96+
const struct m_sub_options stream_appending_conf = {
97+
.opts = (const struct m_option[]) {
98+
{"retry-timeout", OPT_DOUBLE(retry_timeout), M_RANGE(0.1, 1.0)},
99+
{"max-retries", OPT_INT(max_retries), M_RANGE(2, 1000)},
100+
{0},
101+
},
102+
.size = sizeof(struct appending_opts),
103+
.defaults = &(const struct appending_opts){
104+
.retry_timeout = 0.2,
105+
.max_retries = 10,
106+
},
107+
};
108+
88109
struct priv {
89110
int fd;
90111
bool close;
@@ -93,12 +114,9 @@ struct priv {
93114
bool appending;
94115
int64_t orig_size;
95116
struct mp_cancel *cancel;
117+
struct appending_opts *opts;
96118
};
97119

98-
// Total timeout = RETRY_TIMEOUT * MAX_RETRIES
99-
#define RETRY_TIMEOUT 0.2
100-
#define MAX_RETRIES 10
101-
102120
static int64_t get_size(stream_t *s)
103121
{
104122
struct priv *p = s->priv;
@@ -129,13 +147,20 @@ static int fill_buffer(stream_t *s, void *buffer, int max_len)
129147
}
130148
#endif
131149

132-
for (int retries = 0; retries < MAX_RETRIES; retries++) {
150+
int max_retries = p->opts->max_retries;
151+
double retry_timeout = p->opts->retry_timeout;
152+
153+
for (int retries = 0; retries < max_retries; retries++) {
154+
int64_t size = get_size(s);
155+
156+
MP_DBG(s, "appending retry %d/%d @ pos %"PRId64"/%"PRId64" (timeout=%lf)\n",
157+
retries, max_retries, s->pos, size, retry_timeout);
158+
133159
int r = read(p->fd, buffer, max_len);
134160
if (r > 0)
135161
return r;
136162

137163
// Try to detect and handle files being appended during playback.
138-
int64_t size = get_size(s);
139164
if (p->regular_file && size > p->orig_size && !p->appending) {
140165
MP_WARN(s, "File is apparently being appended to, will keep "
141166
"retrying with timeouts.\n");
@@ -145,7 +170,7 @@ static int fill_buffer(stream_t *s, void *buffer, int max_len)
145170
if (!p->appending || p->use_poll)
146171
break;
147172

148-
if (mp_cancel_wait(p->cancel, RETRY_TIMEOUT))
173+
if (mp_cancel_wait(p->cancel, retry_timeout))
149174
break;
150175
}
151176

@@ -279,6 +304,8 @@ static int open_f(stream_t *stream, const struct stream_open_args *args)
279304
*p = (struct priv) {
280305
.fd = -1,
281306
};
307+
p->opts = mp_get_config_group(stream, stream->global,
308+
&stream_appending_conf);
282309
stream->priv = p;
283310
stream->is_local_fs = true;
284311

0 commit comments

Comments
 (0)