diff --git a/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/AndroidMediaPlayer.java b/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/AndroidMediaPlayer.java index a7b348af02b1194a91679a684d813138f6bad310..ed41536f71b96929c11ac5b0ec1df181cbf09f4a 100644 --- a/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/AndroidMediaPlayer.java +++ b/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/AndroidMediaPlayer.java @@ -200,6 +200,11 @@ public class AndroidMediaPlayer extends SimpleMediaPlayer { attachInternalListeners(); } + @Override + public void setVolume(float leftVolume, float rightVolume) { + mInternalMediaPlayer.setVolume(leftVolume, rightVolume); + } + @Override public MediaInfo getMediaInfo() { if (sMediaInfo == null) { diff --git a/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/IMediaPlayer.java b/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/IMediaPlayer.java index 4cfce1eb3499d04b1c712bf703946d8426959b70..8406c6753b5bc2664d04ac6665944a67d27a16ff 100644 --- a/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/IMediaPlayer.java +++ b/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/IMediaPlayer.java @@ -65,6 +65,8 @@ public interface IMediaPlayer { public abstract void reset(); + public abstract void setVolume(float leftVolume, float rightVolume); + public abstract MediaInfo getMediaInfo(); public abstract void setLogEnabled(boolean enable); diff --git a/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/IjkMediaPlayer.java b/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/IjkMediaPlayer.java index a7dfe43c6fe7bfd0ce6109516376ba8eaca30089..8507630a48d3f96728b13a6bdb631b98900a5db3 100644 --- a/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/IjkMediaPlayer.java +++ b/android/ijkmediaplayer/src/tv/danmaku/ijk/media/player/IjkMediaPlayer.java @@ -400,6 +400,8 @@ public final class IjkMediaPlayer extends SimpleMediaPlayer { private native void _reset(); + public native void setVolume(float leftVolume, float rightVolume); + @Override public MediaInfo getMediaInfo() { MediaInfo mediaInfo = new MediaInfo(); diff --git a/ijkmedia/ijkplayer/android/ijkplayer_android.c b/ijkmedia/ijkplayer/android/ijkplayer_android.c index 9d7b80eac68a69faebb30b9a0c9b44fe7883db2d..ba78dba005b7cab2c49021703b88202d4d698435 100644 --- a/ijkmedia/ijkplayer/android/ijkplayer_android.c +++ b/ijkmedia/ijkplayer/android/ijkplayer_android.c @@ -69,3 +69,19 @@ void ijkmp_android_set_surface(JNIEnv *env, IjkMediaPlayer *mp, jobject android_ pthread_mutex_unlock(&mp->mutex); MPTRACE("ijkmp_set_android_surface(surface=%p)=void", (void*)android_surface); } + +void ijkmp_android_set_volume(JNIEnv *env, IjkMediaPlayer *mp, float left, float right) +{ + if (!mp) + return; + + MPTRACE("ijkmp_android_set_volume(%f, %f)", left, right); + pthread_mutex_lock(&mp->mutex); + + if (mp && mp->ffplayer && mp->ffplayer->aout) { + SDL_AoutSetStereoVolume(mp->ffplayer->aout, left, right); + } + + pthread_mutex_unlock(&mp->mutex); + MPTRACE("ijkmp_android_set_volume(%f, %f)=void", left, right); +} diff --git a/ijkmedia/ijkplayer/android/ijkplayer_android.h b/ijkmedia/ijkplayer/android/ijkplayer_android.h index fd6753e7272217caf2059d473601e0035bac80ae..5acfea5775c031405c0a30da53ae883fcf4bd0c2 100644 --- a/ijkmedia/ijkplayer/android/ijkplayer_android.h +++ b/ijkmedia/ijkplayer/android/ijkplayer_android.h @@ -31,4 +31,6 @@ IjkMediaPlayer *ijkmp_android_create(int(*msg_loop)(void*)); void ijkmp_android_set_surface(JNIEnv *env, IjkMediaPlayer *mp, jobject android_surface); +void ijkmp_android_set_volume(JNIEnv *env, IjkMediaPlayer *mp, float left, float right); + #endif diff --git a/ijkmedia/ijkplayer/android/ijkplayer_jni.c b/ijkmedia/ijkplayer/android/ijkplayer_jni.c index 1ce925e60569cbe9f4437ee3647d8eb7e912e366..4b47d16c1d39b716a0058d9ae743eb55fc50db7a 100644 --- a/ijkmedia/ijkplayer/android/ijkplayer_jni.c +++ b/ijkmedia/ijkplayer/android/ijkplayer_jni.c @@ -263,6 +263,19 @@ IjkMediaPlayer_reset(JNIEnv *env, jobject thiz) ijkmp_dec_ref_p(&mp); } +static void +IjkMediaPlayer_setVolume(JNIEnv *env, jobject thiz, jfloat leftVolume, jfloat rightVolume) +{ + MPTRACE("IjkMediaPlayer_setVolume"); + IjkMediaPlayer *mp = jni_get_media_player(env, thiz); + JNI_CHECK_GOTO(mp, env, NULL, "mpjni: setVolume: null mp", LABEL_RETURN); + + ijkmp_android_set_volume(env, mp, leftVolume, rightVolume); + + LABEL_RETURN: + ijkmp_dec_ref_p(&mp); +} + static void IjkMediaPlayer_setAvFormatOption(JNIEnv *env, jobject thiz, jobject name, jobject value) { @@ -445,23 +458,24 @@ static JNINativeMethod g_methods[] = { "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V", (void *) IjkMediaPlayer_setDataSourceAndHeaders }, - { "_setVideoSurface", "(Landroid/view/Surface;)V", (void *) IjkMediaPlayer_setVideoSurface }, - { "prepareAsync", "()V", (void *) IjkMediaPlayer_prepareAsync }, - { "_start", "()V", (void *) IjkMediaPlayer_start }, - { "_stop", "()V", (void *) IjkMediaPlayer_stop }, - { "seekTo", "(J)V", (void *) IjkMediaPlayer_seekTo }, - { "_pause", "()V", (void *) IjkMediaPlayer_pause }, - { "isPlaying", "()Z", (void *) IjkMediaPlayer_isPlaying }, - { "getCurrentPosition", "()J", (void *) IjkMediaPlayer_getCurrentPosition }, - { "getDuration", "()J", (void *) IjkMediaPlayer_getDuration }, - { "_release", "()V", (void *) IjkMediaPlayer_release }, - { "_reset", "()V", (void *) IjkMediaPlayer_reset }, - { "native_init", "()V", (void *) IjkMediaPlayer_native_init }, - { "native_setup", "(Ljava/lang/Object;)V", (void *) IjkMediaPlayer_native_setup }, - { "native_finalize", "()V", (void *) IjkMediaPlayer_native_finalize }, + { "_setVideoSurface", "(Landroid/view/Surface;)V", (void *) IjkMediaPlayer_setVideoSurface }, + { "prepareAsync", "()V", (void *) IjkMediaPlayer_prepareAsync }, + { "_start", "()V", (void *) IjkMediaPlayer_start }, + { "_stop", "()V", (void *) IjkMediaPlayer_stop }, + { "seekTo", "(J)V", (void *) IjkMediaPlayer_seekTo }, + { "_pause", "()V", (void *) IjkMediaPlayer_pause }, + { "isPlaying", "()Z", (void *) IjkMediaPlayer_isPlaying }, + { "getCurrentPosition", "()J", (void *) IjkMediaPlayer_getCurrentPosition }, + { "getDuration", "()J", (void *) IjkMediaPlayer_getDuration }, + { "_release", "()V", (void *) IjkMediaPlayer_release }, + { "_reset", "()V", (void *) IjkMediaPlayer_reset }, + { "setVolume", "(FF)V", (void *) IjkMediaPlayer_setVolume }, + { "native_init", "()V", (void *) IjkMediaPlayer_native_init }, + { "native_setup", "(Ljava/lang/Object;)V", (void *) IjkMediaPlayer_native_setup }, + { "native_finalize", "()V", (void *) IjkMediaPlayer_native_finalize }, { "_setAvFormatOption", "(Ljava/lang/String;Ljava/lang/String;)V", (void *) IjkMediaPlayer_setAvFormatOption }, - { "_setAvCodecOption", "(Ljava/lang/String;Ljava/lang/String;)V", (void *) IjkMediaPlayer_setAvCodecOption }, + { "_setAvCodecOption", "(Ljava/lang/String;Ljava/lang/String;)V", (void *) IjkMediaPlayer_setAvCodecOption }, }; JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) diff --git a/ijkmedia/ijksdl/android/android_audiotrack.c b/ijkmedia/ijksdl/android/android_audiotrack.c index 15d8d43be725330f76797691c02b0950b35bc0d5..dacb7c258cf7de0a43239419b3b2653980b16eed 100644 --- a/ijkmedia/ijksdl/android/android_audiotrack.c +++ b/ijkmedia/ijksdl/android/android_audiotrack.c @@ -263,6 +263,11 @@ static int audiotrack_set_stereo_volume(JNIEnv *env, SDL_AndroidAudioTrack *atra return retval; } +void sdl_audiotrack_set_volume(JNIEnv *env, SDL_AndroidAudioTrack *atrack, float left_volume, float right_volume) +{ + audiotrack_set_stereo_volume(env, atrack, left_volume, right_volume); +} + SDL_AndroidAudioTrack *sdl_audiotrack_new_from_spec(JNIEnv *env, SDL_AndroidAudioTrack_Spec *spec) { assert(spec); diff --git a/ijkmedia/ijksdl/android/android_audiotrack.h b/ijkmedia/ijksdl/android/android_audiotrack.h index 4e91d3690901a5fc017efde530a646e5fef0aa28..fe065d0ac51333d914386382bc3873e8b0018ee0 100644 --- a/ijkmedia/ijksdl/android/android_audiotrack.h +++ b/ijkmedia/ijksdl/android/android_audiotrack.h @@ -93,6 +93,7 @@ int sdl_audiotrack_get_min_buffer_size(SDL_AndroidAudioTrack* atrack); void sdl_audiotrack_play(JNIEnv *env, SDL_AndroidAudioTrack *atrack); void sdl_audiotrack_pause(JNIEnv *env, SDL_AndroidAudioTrack *atrack); void sdl_audiotrack_flush(JNIEnv *env, SDL_AndroidAudioTrack *atrack); +void sdl_audiotrack_set_volume(JNIEnv *env, SDL_AndroidAudioTrack *atrack, float left_volume, float right_volume); void sdl_audiotrack_stop(JNIEnv *env, SDL_AndroidAudioTrack *atrack); void sdl_audiotrack_release(JNIEnv *env, SDL_AndroidAudioTrack *atrack); int sdl_audiotrack_reserve_buffer(JNIEnv *env, SDL_AndroidAudioTrack *atrack, int len); diff --git a/ijkmedia/ijksdl/android/ijksdl_aout_android_audiotrack.c b/ijkmedia/ijksdl/android/ijksdl_aout_android_audiotrack.c index 359e5acdc1019f35fcc51985343748c29ca0f231..7bab6f7345faee6dba34c65c24316a192b8cafc1 100644 --- a/ijkmedia/ijksdl/android/ijksdl_aout_android_audiotrack.c +++ b/ijkmedia/ijksdl/android/ijksdl_aout_android_audiotrack.c @@ -50,6 +50,10 @@ typedef struct SDL_Aout_Opaque { volatile bool pause_on; volatile bool abort_request; + volatile bool need_set_volume; + volatile float left_volume; + volatile float right_volume; + SDL_Thread *audio_tid; SDL_Thread _audio_tid; } SDL_Aout_Opaque; @@ -85,6 +89,10 @@ int aout_thread_n(JNIEnv *env, SDL_Aout *aout) opaque->need_flush = 0; sdl_audiotrack_flush(env, atrack); } + if (opaque->need_set_volume) { + opaque->need_set_volume = 0; + sdl_audiotrack_set_volume(env, atrack, opaque->left_volume, opaque->right_volume); + } SDL_UnlockMutex(opaque->wakeup_mutex); audio_cblk(userdata, buffer, copy_size); @@ -201,6 +209,18 @@ void aout_flush_audio(SDL_Aout *aout) SDL_UnlockMutex(opaque->wakeup_mutex); } +void aout_set_volume(SDL_Aout *aout, float left_volume, float right_volume) +{ + SDL_Aout_Opaque *opaque = aout->opaque; + SDL_LockMutex(opaque->wakeup_mutex); + SDLTRACE("aout_flush_audio()"); + opaque->left_volume = left_volume; + opaque->right_volume = right_volume; + opaque->need_set_volume = 1; + SDL_CondSignal(opaque->wakeup_cond); + SDL_UnlockMutex(opaque->wakeup_mutex); +} + void aout_close_audio(SDL_Aout *aout) { SDL_Aout_Opaque *opaque = aout->opaque; @@ -249,6 +269,7 @@ SDL_Aout *SDL_AoutAndroid_CreateForAudioTrack() aout->open_audio = aout_open_audio; aout->pause_audio = aout_pause_audio; aout->flush_audio = aout_flush_audio; + aout->set_volume = aout_set_volume; aout->close_audio = aout_close_audio; return aout; diff --git a/ijkmedia/ijksdl/ijksdl_aout.c b/ijkmedia/ijksdl/ijksdl_aout.c index a9d7ab6c2dcf421aadcca3a532bf504c4cd18cba..730f4ff3c563368703ab3997bdce4535829ef1ee 100644 --- a/ijkmedia/ijksdl/ijksdl_aout.c +++ b/ijkmedia/ijksdl/ijksdl_aout.c @@ -44,6 +44,12 @@ void SDL_AoutFlushAudio(SDL_Aout *aout) aout->flush_audio(aout); } +void SDL_AoutSetStereoVolume(SDL_Aout *aout, float left_volume, float right_volume) +{ + if (aout && aout->set_volume) + aout->set_volume(aout, left_volume, right_volume); +} + void SDL_AoutCloseAudio(SDL_Aout *aout) { if (aout && aout->close_audio) diff --git a/ijkmedia/ijksdl/ijksdl_aout.h b/ijkmedia/ijksdl/ijksdl_aout.h index d24b49301cf860861857020cd12eba9723f9bc0c..f402eb3db12aef5779ac7bd064c955ec1e7e3ce5 100644 --- a/ijkmedia/ijksdl/ijksdl_aout.h +++ b/ijkmedia/ijksdl/ijksdl_aout.h @@ -37,12 +37,14 @@ typedef struct SDL_Aout { int (*open_audio)(SDL_Aout *aout, SDL_AudioSpec *desired, SDL_AudioSpec *obtained); void (*pause_audio)(SDL_Aout *aout, int pause_on); void (*flush_audio)(SDL_Aout *aout); + void (*set_volume)(SDL_Aout *aout, float left, float right); void (*close_audio)(SDL_Aout *aout); } SDL_Aout; int SDL_AoutOpenAudio(SDL_Aout *aout, SDL_AudioSpec *desired, SDL_AudioSpec *obtained); void SDL_AoutPauseAudio(SDL_Aout *aout, int pause_on); void SDL_AoutFlushAudio(SDL_Aout *aout); +void SDL_AoutSetStereoVolume(SDL_Aout *aout, float left_volume, float right_volume); void SDL_AoutCloseAudio(SDL_Aout *aout); void SDL_AoutFree(SDL_Aout *aout); void SDL_AoutFreeP(SDL_Aout **paout);