MediaPlayer seekTo and accuracy - an odd problem

All your problems with Audio, Video and Images.

MediaPlayer seekTo and accuracy - an odd problem

Postby andyastrand » Sun Aug 08, 2010 10:33 am

Hi everyone,

Been working on an app for a bit now and thanks to forums like this I've worked through all my problems up till now. But this one (although not a show stopper) is irritating and I can't find anyone out there who has reported similar.

I've got a variety of mp3 files as assets (32kbps, constant bit rate) each mp3 holds multiple lines of dialog spoken by an actor. Then on my database I have the start position and duration (in milliseconds) of all of the lines.

A scheduler then associates each "actor" with their own MediaPlayer and plays the lines in a certain order and with a certain timing.

Method 1 - (and my initial implementation) would be for line 1 to do prepare/seek/start/<interval>/stop and then line 2 the same. However this seems to me to do a somewhat wasteful stop/prepare cycle and I assume this is moderately CPU intensive.

Method 2 - (my preferred solution) does prepare/seek/start/<interval>/pause and then for line 2 does seek/start/<interval>/pause. As a result I only prepare the file once.

Now method 1 works perfectly even with my somewhat cramped mp3 file. Line 3 starts at 12480ms and is 5300ms long and method 1 seeks to exactly the right place and plays it perfectly.

But method 2 has problems. The problem is that MediaPlayer.seekTo() seems inaccurate with this usage pattern. I ask it seek to 12480ms. In the OnSeekCompleteListener I call getCurrentPosition() and it reports being at that position. But when I call start() to resume playback in reality its about 200ms out.

I've tried making method 2 seek to 0ms and then seek to the place it wants but that doesn't seem to make any difference.

Has anyone got any suggestions? I can go back to method 1 but it does seem wasteful espectially as some of the mp3 files have around 200 lines of dialog and are quite long.

A code snippet of my debug code is below:

Just to add I'm currently using the emulator and testing with android v1.6, I'm going to try on 2.1 now.

Code: Select all
public class DebuggerSounds extends Activity
{
   private static final String TAG = "DebuggerSounds";
   public DebugListAdapter adapter;
   private MediaPlayer player;
   private Sound currentSound;

   private OnItemClickListener myDebugClickedHandler = new OnItemClickListener()
   {
      public void onItemClick(AdapterView parent, View v, int position, long id)
      {
         Sound sound = ( Sound ) v.getTag();
         playSound( sound );
      }
   };   
   
   @Override
   public void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.debugger_sounds);

      player = new MediaPlayer();
      player.setOnSeekCompleteListener( mySeekListener );
      
      ListView soundsListView = ( ListView ) findViewById( R.id.ListView );      
      
      adapter = new DebugListAdapter( this, Library.data.sounds );
      
      soundsListView.setTextFilterEnabled( false );
      soundsListView.setAdapter( adapter );
      soundsListView.setOnItemClickListener( myDebugClickedHandler );
   }

   // Will be connected with the buttons via XML

   public void myClickHandler(View view)
   {
      switch (view.getId())
      {
         case R.id.BackButton:
         {
            Intent intent = new Intent();
            setResult(RESULT_OK, intent);
            player.stop();
            finish();
            break;
         }
      }
   }

   private void playSound( Sound sound )
   {
      mHandler.removeMessages( 1 );

      if ( currentSound != null )
      {
         // checks if the mp3 file is the same as the one just played,
         // if it is then dont do a reset/prepare just start the seek process.
         // If I skipped this and just did the reset code below the seek would work right

         if ( currentSound.soundfile.equals( sound.soundfile ) )
         {
            currentSound = sound;
            player.seekTo( sound.start );
            return;
         }
      }

      // reset and reload the sound

      player.reset();
      currentSound = sound;
      
      try
      {
         AssetFileDescriptor afd = getAssets().openFd( sound.soundfile );
         player.setDataSource( afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength() );
         player.prepare();
         player.seekTo( 0 );
      }
      catch ( Exception e )
      {
         Log.e( TAG, "failed to set player data source" );
         return;
      }
   }

   public MediaPlayer.OnSeekCompleteListener mySeekListener = new OnSeekCompleteListener()
   {
      public void onSeekComplete( MediaPlayer mp )
      {
         // mp.getCurrentPosition() reports the right position at this point
         // BUT plays from the slightly the wrong position

         mp.start();
      
         Message msg = Message.obtain( mHandler, 1 );
         mHandler.sendMessageDelayed( msg, currentSound.duration );
      }
   };

   private Handler mHandler = new Handler()
   {
      @Override
      public void handleMessage(Message msg)
      {
         switch(msg.what)
         {
            case 1:
            {
               player.pause();
               break;
            }
         }
      }
   };
}
andyastrand
Freshman
Freshman
 
Posts: 2
Joined: Sun Aug 08, 2010 7:54 am

Top

Re: MediaPlayer seekTo and accuracy - an odd problem

Postby andyastrand » Sun Aug 08, 2010 10:52 am

Just checked and it's broken on 2.0 as well.
andyastrand
Freshman
Freshman
 
Posts: 2
Joined: Sun Aug 08, 2010 7:54 am

Re: MediaPlayer seekTo and accuracy - an odd problem

Postby blundell » Sun Aug 08, 2010 6:44 pm

Before you start cannibalising your code, I would recommend testing it on a real device as the emulators are a b*tch for Video Playback :-)
User avatar
blundell
Master Developer
Master Developer
 
Posts: 1610
Joined: Tue Nov 18, 2008 12:58 pm
Location: UK

Re: MediaPlayer seekTo and accuracy - an odd problem

Postby narfi » Thu Sep 02, 2010 1:34 pm

Hey, did you manage to solve the problem? I am in a similar situation, have exact same problems (after seekto). Please, if you found a solution, could you share (give advice or something?)

Thank you
narfi
Freshman
Freshman
 
Posts: 2
Joined: Thu Sep 02, 2010 1:12 pm

Re: MediaPlayer seekTo and accuracy - an odd problem

Postby raito_yagami » Thu Sep 09, 2010 2:25 pm

too long description ...
raito_yagami
Junior Developer
Junior Developer
 
Posts: 14
Joined: Mon Sep 06, 2010 5:48 pm

Top

Return to Multimedia Problems

Who is online

Users browsing this forum: No registered users and 12 guests