2015-01-23 20 views
12

Sto costruendo un'app che registra e riproduce video. Mi piacerebbe farlo senza influire sulla riproduzione della musica di sottofondo, cioè se inizio a riprodurre un video, non voglio mettere in pausa l'audio di altre app. Tuttavia, il Lollipop, classe VideoView di Android richiede automaticamente messa a fuoco audio quando il metodo privato VideoView.openVideo() si chiama:Disabilita la richiesta VideoView di Android Audio Focus durante la riproduzione di un video?

AudioManager am = (AudioManager) super.getSystemService(name); 
am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); 

Qualche suggerimento su come ottenere intorno a questo?

risposta

2

Ho risolto questo problema con una soluzione stupida copiando l'intero codice sorgente di android.widget.VideoView di Lollipop e rimuovendo la linea che hai menzionato.

Fai il tuo VideoView classe. non utilizzare extends VideoView poiché non è possibile sovrascrivere il metodo openVideo().

Non consiglio questo perché penso che sia una soluzione temporanea. VideoView cambiato molto tra 4,1-5,0 quindi questo può rendere RuntimeException sulla versione Android diverso Lollipop

Modifica

ho fatto approccio MediaPlayer + SurfaceView come pinxue ci ha detto; Rispetta le proporzioni all'interno di viewWidth e 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"); 
       } 
      } 
+1

Il codice sorgente per 'VideoView' usa un sacco di riferimenti a campi e metodi di' MediaPlayer' nascosti, come sei entrato in giro che quando si copiato per rendere la tua classe? –

+0

Sono stato stupido quella volta prima che pinxue ci dicesse MediaPlayer + SurfaceView. :/Ho appena cancellato tutto ciò che si verifica errori del compilatore su copia di VideoView Source .. la maggior parte di quelli erano riferimenti relativi ai sottotitoli di cui non ho bisogno. ..e ho lavorato bene per il mio scopo. Raccomando anche l'approccio di MediaPlayer + SurfaceView. – LaruYan

+0

Grazie per aver chiarito, ho finito per cancellare anche il codice di errore compilato.Ti capita di conoscere un buon tutorial per l'utilizzo dell'approccio di MediaPlayer + SurfaceView? Potrei andare in giro per passare ad esso alla fine. –

1

Si può usare al posto MediaPlayer + SurfaceView.

0

uso audioManager.abandonAudioFocus (null)

Se si guarda il codice VideoView si noterà che chiama il metodo audioManager.requestAudioFocus con null per l'OnAudioFocusChangeListener. Al momento della registrazione di un ascoltatore con l'AudioManager utilizza questo metodo per fare un ID per l'ascoltatore

private String getIdForAudioFocusListener(OnAudioFocusChangeListener l) { 
    if (l == null) { 
     return new String(this.toString()); 
    } else { 
     return new String(this.toString() + l.toString()); 
    } 
} 

che genera lo stesso ID ogni volta che si utilizza nullo. Quindi, se si chiama abandonAudioFocus con null rimuoverà qualsiasi ascoltatore che è stato aggiunto con NULL come il parametro per la

+0

Nobile tentativo, ma non ha funzionato per me nonostante provassi ogni variazione di questo. –

1

La soluzione accettata OnAudioFocusChangeListener non garantisce la compatibilità in tutte le versioni di Android ed è un hack sporco più che una vera soluzione. Ho provato tutte le forme di hack per farlo funzionare, ma nessuno ha funzionato per la mia soddisfazione.

Sono venuto su con una soluzione molto migliore anche se - passaggio da un VideoView ad un TextureView e caricarlo con un MediaPlayer. Non c'è alcuna differenza dal punto di vista dell'utente, basta l'interruzione dell'audio.

Ecco il mio caso d'uso per la riproduzione di un looping 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; 
    } 
} 
+1

Penso che questa dovrebbe essere la risposta accettata, ha fatto il trucco per me. – pillar15

Problemi correlati