如何防止 VideoView/MediaPlayer 停止其他应用程序的音频?
How to prevent VideoView/MediaPlayer from stopping other apps' audio?
在一个屏幕上我有一个循环播放的背景视频(显示正常的 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 之前),来自其他应用程序的音乐播放停止。
我使用的视频本身没有声音。有没有办法在 "muted mode" 中设置 VideoView 或它使用的 MediaPlayer?即,告诉它根本不要播放音频,尤其是 不要干扰其他应用程序的音频。
在onPrepared()
中尝试了mp.setVolume(0, 0);
,但没有效果。
从 Android 个来源复制粘贴 VideoView
并注释掉这些行:
AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
例如,您可以将新名称命名为 class MutedVideoView
。
已接受的解决方案不保证所有 Android 版本的兼容性,并且是一个肮脏的 hack,而不是真正的解决方案。我已经尝试了所有形式的 hack 来使它正常工作,但 none 的效果令我满意。
虽然我想出了一个更好的解决方案 - 从 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()
调用之前)
在一个屏幕上我有一个循环播放的背景视频(显示正常的 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 之前),来自其他应用程序的音乐播放停止。
我使用的视频本身没有声音。有没有办法在 "muted mode" 中设置 VideoView 或它使用的 MediaPlayer?即,告诉它根本不要播放音频,尤其是 不要干扰其他应用程序的音频。
在onPrepared()
中尝试了mp.setVolume(0, 0);
,但没有效果。
从 Android 个来源复制粘贴 VideoView
并注释掉这些行:
AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
例如,您可以将新名称命名为 class MutedVideoView
。
已接受的解决方案不保证所有 Android 版本的兼容性,并且是一个肮脏的 hack,而不是真正的解决方案。我已经尝试了所有形式的 hack 来使它正常工作,但 none 的效果令我满意。
虽然我想出了一个更好的解决方案 - 从 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()
调用之前)