summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/interface-changes.rst1
-rw-r--r--DOCS/man/options.rst8
-rw-r--r--audio/out/ao.c6
-rw-r--r--audio/out/ao.h1
-rw-r--r--options/options.c1
-rw-r--r--options/options.h1
-rw-r--r--player/audio.c10
7 files changed, 24 insertions, 4 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 2bdf8e25d9..6efd5a5105 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -20,6 +20,7 @@ Interface changes
::
--- mpv 0.12.0 ---
+ - add --audio-fallback-to-null option
- replace vf_format outputlevels suboption with "video-output-levels" global
property/option; also remove "colormatrix-output-range" property
- vo_opengl: remove sharpen3/sharpen5 scale filters, add sharpen sub-option
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 783fe665e0..2d11020be1 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -917,6 +917,14 @@ Audio
Currently not implemented for most AOs.
+``--audio-fallback-to-null=<yes|no>``
+ If no audio device can be opened, behave as if ``--ao=null`` was given. This
+ is useful in combination with ``--audio-device``: instead of causing an
+ error if the selected device does not exist, the client API user (or a
+ Lua script) could let playback continue normally, and check the
+ ``current-ao`` and ``audio-device-list`` properties to make high-level
+ decisions about how to continue.
+
``--ao=<driver1[:suboption1[=value]:...],driver2,...[,]>``
Specify a priority list of audio output drivers to be used. For
interactive use one would normally specify a single one to use, but in
diff --git a/audio/out/ao.c b/audio/out/ao.c
index 23c3987cb3..6330ec9d48 100644
--- a/audio/out/ao.c
+++ b/audio/out/ao.c
@@ -240,6 +240,7 @@ static void split_ao_device(void *tmp, char *opt, char **out_ao, char **out_dev)
}
struct ao *ao_init_best(struct mpv_global *global,
+ bool ao_null_fallback,
struct input_ctx *input_ctx,
struct encode_lavc_context *encode_lavc_ctx,
int samplerate, int format, struct mp_chmap channels)
@@ -282,6 +283,11 @@ struct ao *ao_init_best(struct mpv_global *global,
}
}
+ if (ao_null_fallback) {
+ MP_TARRAY_APPEND(tmp, ao_list, ao_num,
+ (struct m_obj_settings){.name = "null"});
+ }
+
for (int n = 0; n < ao_num; n++) {
struct m_obj_settings *entry = &ao_list[n];
bool probing = n + 1 != ao_num;
diff --git a/audio/out/ao.h b/audio/out/ao.h
index baf10ace19..e8e64e33eb 100644
--- a/audio/out/ao.h
+++ b/audio/out/ao.h
@@ -72,6 +72,7 @@ struct encode_lavc_context;
struct mp_audio;
struct ao *ao_init_best(struct mpv_global *global,
+ bool ao_null_fallback,
struct input_ctx *input_ctx,
struct encode_lavc_context *encode_lavc_ctx,
int samplerate, int format, struct mp_chmap channels);
diff --git a/options/options.c b/options/options.c
index 02ee782f75..7c04342384 100644
--- a/options/options.c
+++ b/options/options.c
@@ -383,6 +383,7 @@ const m_option_t mp_opts[] = {
OPT_SETTINGSLIST("ao-defaults", ao_defs, 0, &ao_obj_list),
OPT_STRING("audio-device", audio_device, 0),
OPT_STRING("audio-client-name", audio_client_name, 0),
+ OPT_FLAG("audio-fallback-to-null", ao_null_fallback, 0),
OPT_CHOICE("force-window", force_vo, 0,
({"no", 0}, {"yes", 1}, {"immediate", 2})),
OPT_FLAG("ontop", vo.ontop, M_OPT_FIXED),
diff --git a/options/options.h b/options/options.h
index 2a4bb8302d..75156043b3 100644
--- a/options/options.h
+++ b/options/options.h
@@ -81,6 +81,7 @@ typedef struct MPOpts {
struct m_obj_settings *audio_driver_list, *ao_defs;
char *audio_device;
char *audio_client_name;
+ int ao_null_fallback;
int force_vo;
int softvol;
float mixer_init_volume;
diff --git a/player/audio.c b/player/audio.c
index 92c4bbae19..4bcf69a00f 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -260,11 +260,15 @@ void reinit_audio_chain(struct MPContext *mpctx)
}
if (!mpctx->ao) {
+ bool spdif_fallback = af_fmt_is_spdif(afs->output.format) &&
+ mpctx->d_audio->spdif_passthrough;
+ bool ao_null_fallback = opts->ao_null_fallback && !spdif_fallback;
+
mp_chmap_remove_useless_channels(&afs->output.channels,
&opts->audio_output_channels);
mp_audio_set_channels(&afs->output, &afs->output.channels);
- mpctx->ao = ao_init_best(mpctx->global, mpctx->input,
+ mpctx->ao = ao_init_best(mpctx->global, ao_null_fallback, mpctx->input,
mpctx->encode_lavc_ctx, afs->output.rate,
afs->output.format, afs->output.channels);
@@ -283,9 +287,7 @@ void reinit_audio_chain(struct MPContext *mpctx)
if (!mpctx->ao) {
// If spdif was used, try to fallback to PCM.
- if (af_fmt_is_spdif(afs->output.format) &&
- mpctx->d_audio->spdif_passthrough)
- {
+ if (spdif_fallback) {
mpctx->d_audio->spdif_passthrough = false;
if (!audio_init_best_codec(mpctx->d_audio))
goto init_error;