This is a feature heavily inspired by the mpv player. At the moment, methods for adjusting volume in ffplay are rather clumsy: either one needs to set it system-wide, or one needs to set it via the volume filter.
This patch adds key bindings identical to the mpv defaults for muting/unmuting and increasing/decreasing the volume interactively without any introduction of external dependencies. Key repeats have been introduced simply because they improve usability in my experience for volume, brightness, and other such controls by speeding up the time taken to go from 0 to max intensity. As a side benefit, this enables rapid seeking through a file via left/right keys. TODO: doc update, possible mouse button bindings (mpv has this). Signed-off-by: Ganesh Ajjanagadde <gajjanaga...@gmail.com> --- ffplay.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/ffplay.c b/ffplay.c index d302793..4f3322b 100644 --- a/ffplay.c +++ b/ffplay.c @@ -73,6 +73,9 @@ const int program_birth_year = 2003; /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */ #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30 +/* Step size for volume control */ +#define SDL_VOLUME_STEP 2 + /* no AV sync correction is done if below the minimum AV sync threshold */ #define AV_SYNC_THRESHOLD_MIN 0.04 /* AV sync correction is done if above the maximum AV sync threshold */ @@ -246,6 +249,8 @@ typedef struct VideoState { unsigned int audio_buf1_size; int audio_buf_index; /* in bytes */ int audio_write_buf_size; + int audio_volume; + int muted; struct AudioParams audio_src; #if CONFIG_AVFILTER struct AudioParams audio_filter_src; @@ -1348,6 +1353,25 @@ static void toggle_pause(VideoState *is) is->step = 0; } +static void toggle_mute(VideoState *is) +{ + is->muted = !is->muted; +} + +static void update_volume(VideoState *is, int sign, int step) +{ + if (sign > 0) { + is->audio_volume += step; + if (is->audio_volume > SDL_MIX_MAXVOLUME) + is->audio_volume = SDL_MIX_MAXVOLUME; + } + else { + is->audio_volume -= step; + if (is->audio_volume < 0) + is->audio_volume = 0; + } +} + static void step_to_next_frame(VideoState *is) { /* if the stream is paused unpause it, then step */ @@ -2447,7 +2471,10 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len) len1 = is->audio_buf_size - is->audio_buf_index; if (len1 > len) len1 = len; - memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1); + if (is->muted) + SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, 0); + else + SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume); len -= len1; stream += len1; is->audio_buf_index += len1; @@ -2634,6 +2661,8 @@ static int stream_component_open(VideoState *is, int stream_index) is->audio_src = is->audio_tgt; is->audio_buf_size = 0; is->audio_buf_index = 0; + is->audio_volume = SDL_MIX_MAXVOLUME; + is->muted = 0; /* init averaging filter */ is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB); @@ -3311,6 +3340,17 @@ static void event_loop(VideoState *cur_stream) case SDLK_SPACE: toggle_pause(cur_stream); break; + case SDLK_m: + toggle_mute(cur_stream); + break; + case SDLK_ASTERISK: + case SDLK_0: + update_volume(cur_stream, 1, SDL_VOLUME_STEP); + break; + case SDLK_SLASH: + case SDLK_9: + update_volume(cur_stream, -1, SDL_VOLUME_STEP); + break; case SDLK_s: // S: Step to next frame step_to_next_frame(cur_stream); break; @@ -3740,6 +3780,8 @@ int main(int argc, char **argv) SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); SDL_EventState(SDL_USEREVENT, SDL_IGNORE); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + if (av_lockmgr_register(lockmgr)) { av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n"); do_exit(NULL); -- 2.5.3 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel