Android 如何防止VideoView/MediaPlayer停止其他应用程序';音频

Android 如何防止VideoView/MediaPlayer停止其他应用程序';音频,android,audio,android-mediaplayer,android-videoview,Android,Audio,Android Mediaplayer,Android Videoview,在一个屏幕中,我有一个循环的背景视频(上面显示正常的UI元素),使用VideoView实现,如下所示: String resPath = "android.resource://" + getPackageName() + "/" + R.raw.bg_video; videoView.setVideoURI(Uri.parse(resPath)); // Hide controls: MediaController controller = new MediaController(getAc

在一个屏幕中,我有一个循环的背景视频(上面显示正常的UI元素),使用VideoView实现,如下所示:

String resPath = "android.resource://" + getPackageName() + "/" + R.raw.bg_video;
videoView.setVideoURI(Uri.parse(resPath));

// Hide controls:
MediaController controller = new MediaController(getActivity());
controller.setVisibility(View.GONE);
videoView.setMediaController(controller);

// Use looping:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.setLooping(true);
    }
});

videoView.start();
这个视频效果很好。唯一的问题是,当显示此视图时(如果使用例如ViewPager,甚至在显示之前),其他应用程序的音乐播放停止

我正在使用的视频本身没有声音。有没有办法将VideoView或它使用的MediaPlayer设置为“静音模式”?也就是说,告诉它不要做音频,尤其是不要弄乱其他应用程序的音频


尝试
mp.setVolume(0,0)
onPrepared()
中,但它没有效果。

从Android源代码复制粘贴
VideoView
,并注释掉以下行:

AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
例如,您可以将新类命名为
MutedVideoView


要点如下:

公认的解决方案不能保证所有Android版本之间的兼容性,它是一种肮脏的黑客行为,而不是真正的解决方案。我已经尝试过各种形式的黑客来让它工作,但没有一种能让我满意

不过我想出了一个更好的解决方案——从
VideoView
切换到
TextureView
,并用
MediaPlayer
加载它。从用户的角度来看,没有什么不同,只是没有更多的音频中断

下面是我玩MP4循环的用例:

private TextureView _introVideoTextureView;
private MediaPlayer _introMediaPlayer;

...

@Override
public void onCreate(...) {
    _introVideoTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
           try {
               destoryIntroVideo();

               _introMediaPlayer = MediaPlayer.create(SignInActivity.this, R.raw.intro_video);
               _introMediaPlayer.setSurface(new Surface(surfaceTexture));
               _introMediaPlayer.setLooping(true);
               _introMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
               _introMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mediaPlayer) {
                        mediaPlayer.start();
                    }
                });

            } catch (Exception e) {
                System.err.println("Error playing intro video: " + e.getMessage());
            }
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {}

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {}
    });
}

@Override
public void onDestroy() {
    super.onDestroy();

    destoryIntroVideo();
}

private void destoryIntroVideo() {
    if (_introMediaPlayer != null) {
        _introMediaPlayer.stop();
        _introMediaPlayer.release();
        _introMediaPlayer = null;
    }
}
这对我很有用:

videoView.setAudioFocusRequest(AudioManager.AUDIOFOCUS_NONE);

(在
.setVideUri()
调用之前)

我还没有尝试过,但我相信你的答案将涉及到浏览并播放流的静音/独奏设置。因为它是来自其他应用程序的音乐,所以您需要在调用
prepare()
@ab之前将音频流设置为不同的值。helly:是的,我有时间时会发布一个答案。@Jonik,您能发布答案吗?@Ana:事实上,我最终得到的结果基本上与您的答案相同。尽管感觉很难看,从Android源代码复制粘贴
VideoView
,并注释掉
requestAudioFocus
调用。我如何编译复制的VideoView类。它抱怨“无法解析符号”:导入android.media.Metadata;导入android.media.controller;导入android.media.subtitrack.RenderingWidget;导入android.media.TtmlRenderer;导入android.media.webvtrenderer;我采用的解决方案(早在2015年)与此基本相同。“难看但它能用。”在Android源粘贴的
VideoView
副本中,我还不得不注释掉一些出于某种原因没有编译的字幕和元数据相关代码。有没有办法通过反射来实现这一点?这在api级别26及更高版本中提供,对于操作系统低于26的设备,您是否找到了API级别低于26的其他答案?