diff --git a/DOCS/interface-changes/audio-set-media-role.txt b/DOCS/interface-changes/audio-set-media-role.txt new file mode 100644 index 0000000000000..60b74eb33fe8a --- /dev/null +++ b/DOCS/interface-changes/audio-set-media-role.txt @@ -0,0 +1 @@ +add --audio-set-media-role, disabled by default. This effectively changes the behavior for ao_pipewire diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index dd69902ededf7..53af9a1d27307 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -2387,6 +2387,14 @@ Audio if you want to force a different audio profile (e.g. with PulseAudio), or to set your own application name when using libmpv. +``--audio-set-media-role=`` + If enabled, mpv will set the appropriate media role on supported audio + servers to indicate whether mpv is playing a video or an audio-only file. + This is disabled by default since per media role volumes have often caused + unexpected and confusing behavior. + + Default: no. + ``--audio-buffer=`` Set the audio output minimum buffer. The audio device might actually create a larger buffer if it pleases. If the device creates a smaller buffer, diff --git a/audio/out/ao.c b/audio/out/ao.c index ee76b702ea580..91402fff1536b 100644 --- a/audio/out/ao.c +++ b/audio/out/ao.c @@ -145,6 +145,8 @@ const struct m_sub_options ao_conf = { {"audio-client-name", OPT_STRING(audio_client_name), .flags = UPDATE_AUDIO}, {"audio-buffer", OPT_DOUBLE(audio_buffer), .flags = UPDATE_AUDIO, M_RANGE(0, 10)}, + {"audio-set-media-role", OPT_BOOL(audio_set_media_role), + .flags = UPDATE_AUDIO}, {0} }, .size = sizeof(OPT_BASE_STRUCT), @@ -180,6 +182,7 @@ static struct ao *ao_alloc(bool probing, struct mpv_global *global, .log = mp_log_new(ao, log, name), .def_buffer = opts->audio_buffer, .client_name = talloc_strdup(ao, opts->audio_client_name), + .set_media_role = opts->audio_set_media_role }; talloc_free(opts); ao->priv = m_config_group_from_desc(ao, ao->log, global, &desc, name); diff --git a/audio/out/ao.h b/audio/out/ao.h index 8fde69cb37210..ce044fdc473a7 100644 --- a/audio/out/ao.h +++ b/audio/out/ao.h @@ -79,6 +79,7 @@ struct ao_opts { char *audio_device; char *audio_client_name; double audio_buffer; + bool audio_set_media_role; }; struct ao *ao_init_best(struct mpv_global *global, diff --git a/audio/out/ao_audiotrack.c b/audio/out/ao_audiotrack.c index 7bce2d42638cc..f483ccc8e8d8b 100644 --- a/audio/out/ao_audiotrack.c +++ b/audio/out/ao_audiotrack.c @@ -304,10 +304,12 @@ static int AudioTrack_New(struct ao *ao) MP_JNI_EXCEPTION_LOG(ao); tmp = MP_JNI_CALL_OBJECT(attr_builder, AudioAttributesBuilder.setUsage, AudioAttributes.USAGE_MEDIA); MP_JNI_LOCAL_FREEP(&tmp); - jint content_type = (ao->init_flags & AO_INIT_MEDIA_ROLE_MUSIC) ? - AudioAttributes.CONTENT_TYPE_MUSIC : AudioAttributes.CONTENT_TYPE_MOVIE; - tmp = MP_JNI_CALL_OBJECT(attr_builder, AudioAttributesBuilder.setContentType, content_type); - MP_JNI_LOCAL_FREEP(&tmp); + if (ao->set_media_role) { + jint content_type = (ao->init_flags & AO_INIT_MEDIA_ROLE_MUSIC) ? + AudioAttributes.CONTENT_TYPE_MUSIC : AudioAttributes.CONTENT_TYPE_MOVIE; + tmp = MP_JNI_CALL_OBJECT(attr_builder, AudioAttributesBuilder.setContentType, content_type); + MP_JNI_LOCAL_FREEP(&tmp); + } jobject attr = MP_JNI_CALL_OBJECT(attr_builder, AudioAttributesBuilder.build); MP_JNI_LOCAL_FREEP(&attr_builder); diff --git a/audio/out/ao_pipewire.c b/audio/out/ao_pipewire.c index 9900cb7a31da2..4ffe1b8657c17 100644 --- a/audio/out/ao_pipewire.c +++ b/audio/out/ao_pipewire.c @@ -577,7 +577,6 @@ static int init(struct ao *ao) struct pw_properties *props = pw_properties_new( PW_KEY_MEDIA_TYPE, "Audio", PW_KEY_MEDIA_CATEGORY, "Playback", - PW_KEY_MEDIA_ROLE, ao->init_flags & AO_INIT_MEDIA_ROLE_MUSIC ? "Music" : "Movie", PW_KEY_NODE_NAME, ao->client_name, PW_KEY_NODE_DESCRIPTION, ao->client_name, PW_KEY_APP_NAME, ao->client_name, @@ -588,6 +587,10 @@ static int init(struct ao *ao) NULL ); + if (ao->set_media_role) + pw_properties_set(props, PW_KEY_MEDIA_ROLE, + ao->init_flags & AO_INIT_MEDIA_ROLE_MUSIC ? "Music" : "Movie"); + if (pipewire_init_boilerplate(ao) < 0) goto error_props; diff --git a/audio/out/ao_pulse.c b/audio/out/ao_pulse.c index 1b29be09eea84..6b9b141d99af0 100644 --- a/audio/out/ao_pulse.c +++ b/audio/out/ao_pulse.c @@ -405,6 +405,11 @@ static int init(struct ao *ao) } (void)pa_proplist_sets(proplist, PA_PROP_MEDIA_ICON_NAME, ao->client_name); + if (ao->set_media_role) + (void)pa_proplist_sets(proplist, PA_PROP_MEDIA_ROLE, + ao->init_flags & AO_INIT_MEDIA_ROLE_MUSIC + ? "music" : "video"); + if (!(format = pa_format_info_new())) goto unlock_and_fail; diff --git a/audio/out/internal.h b/audio/out/internal.h index 2fecf86f2603d..85fa7775759ce 100644 --- a/audio/out/internal.h +++ b/audio/out/internal.h @@ -55,6 +55,9 @@ struct ao { // Application name to report to the audio API. char *client_name; + // Whether mpv should set the media role to the audio server + bool set_media_role; + // Used during init: if init fails, redirect to this ao char *redirect;