MediaPlayer: "Attempt to call getDuration without ..."

All your problems with Audio, Video and Images.

MediaPlayer: "Attempt to call getDuration without ..."

Postby chris_abyi » Sat Feb 26, 2011 4:46 am

Hi!

I'm stuck with the following problem since a whole day already and I would really appreciate any help and advice:
I created a playback-class for an mp3 player which takes commands from play/pause/back and forward buttons. Furthermore, it provides a progressBar to see the current progress of the track.

I'm using a AsyncTask for controlling the Progressbar. To avoid any clashes with the MediaPlayer, I cancel the task when the "back"-button (forward yet not implemented) is hit, then reset the mediaplayer, set the new file path and prepare it again. Nevertheless, I sometimes get the following error message which causes the whole application (but especially the progressBar) not to work anymore: Error (-38,0): Attempt to call getDuration without a valid mediaplayer.

I was seeking for cause already a long time but I got no luck. I also tried to build better checks into the asyncTask to cancel it fast, so it doesn't conflict with the resetting mediaPlayer. Unfortunately, I do not know if this works or not. Here's the source: Any suggestions how-to handle both the AsyncTask and the MediaPlayer?

Code: Select all

    //Play or resume
    private void play(){
       
       String path = playlist.get(playPointer).getAbsolutePath();
       
       if(!paused){
          try {
            mPlayer.reset();
             mPlayer.setDataSource(path);
            mPlayer.prepare();
            
            //start the thread to control the progressBar
            updateProgress = new UpdateProgress();
            updateProgress.execute();
            
         } catch (Exception e){
            e.printStackTrace();
         }
       }
      mPlayer.start();
      paused=false;
      
      //Switch to paused-icon
      ((ImageButton)findViewById(R.id.btn_play)).setImageResource(R.drawable.sel_playback_pause);
    }
    private void back(){
       
       if(mPlayer!=null){
          updateProgress.cancel(true);
          int position = mPlayer.getCurrentPosition()/1000;
          
          //If playing current track less than 5 seconds yet, switch to previous track. Else, stay with this one and just restart.
          if(position<5){
             if(playPointer==0){
                playPointer = (playlist.size()-1);
             }else{
                playPointer--;
             }
          }
          play();
       }
    }
   
   private class UpdateProgress extends AsyncTask<Void,Integer,Void>{
      
       // can use UI thread here 
      protected void onPreExecute() { 
         mProgress.setProgress(0);
         mProgress.setMax(100);
         tv_Progress.setText("00:00");
      } 

      //Done in worker thread (separate from UI thread)
      protected Void doInBackground(Void...args) {
         
         int progress = 0;
         int position = 0;
         int duration = 0;
         int timeLeftMs = 0;
         int timeLeftSec = 0;
         int leftMinutes = 0;
         int leftSeconds = 0;
         
         do{
            
            if(!this.isCancelled()){
               try{
                  position = mPlayer.getCurrentPosition();
                  duration = mPlayer.getDuration();
                   Thread.sleep(500);
               }catch(Exception e){
                  e.printStackTrace();
               }
            }
            
            //Calculating the current progress
            progress = Math.round(((float)position/(float)duration)*100);
            
            //Calculating the remaining playing time
            timeLeftMs = duration-position;
             timeLeftSec = timeLeftMs/1000;
             leftMinutes = timeLeftSec/60;
             leftSeconds = timeLeftSec%60;

             this.publishProgress(progress, leftMinutes, leftSeconds);
         }while (progress<100 && !this.isCancelled());
         
         return null;
      }
      
      //Using the UI thread here
      protected void onProgressUpdate(Integer...progress){
         
         //Update progress bar
         mProgress.setProgress(progress[0]);
         
         //progress[1]=leftMinutes, progress[2]=leftSeconds, formatting;
          String minString=Integer.toString(progress[1]);
          String secString=Integer.toString(progress[2]);
          if(progress[1]<10){
             minString="0"+progress[1];
          }
          if(progress[2]<10){
             secString="0"+progress[2];
          }
          
          //Update progress label
         tv_Progress.setText("-"+minString+":"+secString);
      }
      
      protected void onPostExecute(Void args){
         mProgress.setProgress(0);
         tv_Progress.setText("00:00");
      }
      
   }
}


Thank you very much for your help!

Chris
chris_abyi
Freshman
Freshman
 
Posts: 3
Joined: Fri Feb 25, 2011 3:19 pm

Top

Return to Multimedia Problems

Who is online

Users browsing this forum: No registered users and 10 guests