title: MediaPlayer broken in android 6
body: <p>In our player we are using media player feature to render into a SurfaceTexture that is used in jni opengl layer to render dynamic textures.</p>
  
  <p>Everything run OK in android 4&amp;5, but not in android 6 (with the same code). </p>
  
  <p>The workflow is very easy.</p>
  
  <p>First thing is load movie from url</p>
  
  <pre><code>public void loadMovie(String moviePath){
      try {
          if(mediaPlayer == null) {
              mediaPlayer = new MediaPlayer(); 
  
              mediaPlayer.reset();
              mediaPlayer.setLooping(bIsLooping);
              mediaPlayer.setOnBufferingUpdateListener(this);
              mediaPlayer.setOnCompletionListener(this);
              mediaPlayer.setOnErrorListener(this);
              mediaPlayer.setOnInfoListener(this);
              mediaPlayer.setOnPreparedListener(this);
              mediaPlayer.setOnSeekCompleteListener(this);
              mediaPlayer.setOnTimedTextListener(this);
              mediaPlayer.setOnVideoSizeChangedListener(this); 
  
             surfaceTexture = new SurfaceTexture(texNumber);
             surfaceTexture.setOnFrameAvailableListener(this);
             surface = new Surface(surfaceTexture);
  
             mediaPlayer.setSurface(surface);   
          } 
  
          bIsLoaded = false;
  
          duration = 0.0f; 
          width = height = 0;
  
          mediaPlayer.reset();
  
          if (moviePath.startsWith("android.resource://")){
              mediaPlayer.setDataSource(activity, Uri.parse(moviePath));
          } else if (moviePath.contains("obb://")) {
              String obbFileEntry = moviePath.replace("obb://", "");
              int idx0 = obbFileEntry.indexOf("/");
              int idx1 = obbFileEntry.indexOf("/", idx0 + 1);
  
              int mainVersion = Integer.parseInt(obbFileEntry.substring(0,idx0));
              int patchVersion = Integer.parseInt(obbFileEntry.substring(1+idx0, idx1));
              obbFileEntry = obbFileEntry.substring(idx1 + 1);
  
              ZipResourceFile obbFile = APKExpansionSupport.getAPKExpansionZipFile(activity, mainVersion, patchVersion);
              AssetFileDescriptor assetFileDescriptor = obbFile.getAssetFileDescriptor(obbFileEntry);
              if (null != assetFileDescriptor) {
                  Log.d("[OFAndroidVideoPlayer]", "Playing media resource '" +  obbFileEntry + " packaged in obb expansion file( " + mainVersion + ", " + patchVersion + ")");
                  mediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());
              }
          } else if (moviePath.contains(".zip/")) { 
              String zipFilePath = moviePath.substring(0, moviePath.lastIndexOf(".zip") + ".zip".length());
              String zipFileEntry = moviePath.substring(zipFilePath.length() + 1);
  
              ZipResourceFile zipFile = new ZipResourceFile(zipFilePath);
  
              AssetFileDescriptor assetFileDescriptor = zipFile.getAssetFileDescriptor(zipFileEntry);
              if (null != assetFileDescriptor) {
                  Log.d("[OFAndroidVideoPlayer]", "Playing media resource '" +  zipFileEntry + " packaged in zip file: " + zipFilePath);
                  mediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());
              }
          } else {
              mediaPlayer.setDataSource(moviePath);
          }
  
          mediaPlayer.prepare(); 
  
          width = mediaPlayer.getVideoWidth();
          height = mediaPlayer.getVideoHeight();
          duration = mediaPlayer.getDuration();
  
          //setVolume(volume);
          this.mediaPath = moviePath;
      } catch(IllegalStateException e) {
          Log.e("[OFAndroidVideoPlayer]","Illegal state with " + moviePath + " (" + e.getMessage() + ")", e);
      } catch(IOException e) {
          Log.e("[OFAndroidVideoPlayer]","I/O exception with " + moviePath + " (" + e.getMessage() + ")", e);
          this.fixMediaPlayerIOExceptionCounter += 1;
  
          if (this.fixMediaPlayerIOExceptionCounter &lt; 2) {
              mediaPlayer.reset();
              mediaPlayer.release();
              mediaPlayer = null;
              loadMovie(moviePath);
          }
      } catch (Exception e) {
          Log.e("[OFAndroidVideoPlayer]","Couldn't load " + moviePath + " (" + e.getMessage() + ")", e);
      }       
  }
  </code></pre>
  
  <p>After register a mediaplayer listener we are to control when mediaplayer is ready</p>
  
  <pre><code>@Override
  public void onPrepared(MediaPlayer mp) {
      Log.d("[ofxAndroidVideo]","[onPrepared] Entering method.");
  
      duration = (0.1f &lt; duration)? duration: mediaPlayer.getDuration();
      width = (0 != width)? width: mediaPlayer.getVideoWidth();
      height = (0 != height)? height: mediaPlayer.getVideoHeight();
  
      bIsLoaded = true;
      if(bAutoResume) {
          setPositionMS(movieResumeTime);
          bAutoResume = false;
          play();
      }
  }
  </code></pre>
  
  <p>And update texture in surface texture loop</p>
  
  <pre><code>@Override
  public void onFrameAvailable(SurfaceTexture arg0) {
      synchronized(this){
          if(surfaceTexture != null) {
              surfaceTexture.updateTexImage();
          }
  }
  </code></pre>
  
  <p>What is the problem with android 6?.</p>
  
  <ul>
  <li>No listener callbacks are called after mediaplayer creation, prepare,..., IMHO seems like internal state of mediaplayer were wrong or broken o always in idle state and some internal working threads were not created/initialized.</li>
  </ul>
  
  <p>No error traces in logcat, all this is so frustating.</p>
  
  <p>Any idea? kabo</p>
  
  <p>Thanks in advanced</p>