dia*_*ana 13 android audio-player android-videoview
我正在构建一个记录和播放视频的应用程序.我想在不影响背景音乐播放的情况下这样做,即如果我开始播放视频,我不想暂停其他应用的音频.但是,在Lollipop上,Android的VideoView类会在VideoView.openVideo()调用私有方法时自动请求音频焦点:
AudioManager am = (AudioManager) super.getSystemService(name);
am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
Run Code Online (Sandbox Code Playgroud)
有关如何绕过这个的任何建议?
从 Android SDK 26 开始,您可能想要使用VideoView和
if(Build.VERSION.SDK_INT >= Build.Version_CODES.O){
//set this BEFORE start playback
videoView.setAudioFocusRequest(AudioManager.AUDIOFOCUS_NONE)
}
Run Code Online (Sandbox Code Playgroud)
对于旧版本,这里描述了一种解决方法:https : //stackoverflow.com/a/31569930/993439
基本上,复制VideoView以下行的源代码并取消注释
AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
Run Code Online (Sandbox Code Playgroud)
android.widget.VideoView我通过复制Lollipop 的整个源代码并删除您提到的行来解决这个问题,这是一个愚蠢的解决方案。
创建您自己的VideoView课程。不要使用,extends VideoView因为您无法覆盖openVideo()方法。
我不推荐这样做,因为我认为这是一个临时解决方案。VideoView4.1-5.0 之间发生了很大变化,因此这可能会在 Lollipop 以外的 Android 版本上引发 RuntimeException
编辑
正如pinxue告诉我们的那样,我采用了MediaPlayer + SurfaceView的方法;viewWidth它尊重和内的纵横比viewHeight。
final String finalFilePath = filePath;
final SurfaceHolder surfaceHolder = sv.getHolder();
final MediaPlayer mediaPlayer = new MediaPlayer();
final LinearLayout.LayoutParams svLayoutParams = new LinearLayout.LayoutParams(viewWidth,viewHeight);
surfaceHolder.addCallback(new SurfaceHolder.Callback(){
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
if(isDebug) {
System.out.println("setting VideoPath to VideoView: "+finalFilePath);
}
mediaPlayer.setDataSource(finalFilePath);
}catch (IOException ioe){
if(isDebug){
ioe.printStackTrace();
}
//mediaPlayer = null;
}
mediaPlayer.setDisplay(surfaceHolder);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if(isDebug){
System.out.println("Video is starting...");
}
// for compatibility, we adjust size based on aspect ratio
if ( mp.getVideoWidth() * svLayoutParams.height < svLayoutParams.width * mp.getVideoHeight() ) {
//Log.i("@@@", "image too wide, correcting");
svLayoutParams.width = svLayoutParams.height * mp.getVideoWidth() / mp.getVideoHeight();
} else if ( mp.getVideoWidth() * svLayoutParams.height > svLayoutParams.width * mp.getVideoHeight() ) {
//Log.i("@@@", "image too tall, correcting");
svLayoutParams.height = svLayoutParams.width * mp.getVideoHeight() / mp.getVideoWidth();
}
sv.post(new Runnable(){
@Override
public void run() {
sv.setLayoutParams(svLayoutParams);
}
});
mp.start();
}
});
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if(isDebug){
System.out.println("surfaceChanged(holder, "+format+", "+width+", "+height+")");
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
try {
mediaPlayer.setDataSource("");
}catch (IOException ioe){
if(isDebug){
ioe.printStackTrace();
}
}
}
});
if(sv.post(new Runnable() {
@Override
public void run() {
sv.setLayoutParams(svLayoutParams);///
sv.setVisibility(View.VISIBLE);
}})){
if(isDebug) {
System.out.println("post Succeded");
}
}else{
if(isDebug) {
System.out.println("post Failed");
}
}
Run Code Online (Sandbox Code Playgroud)