2012-10-28 160 views
3

我正在編寫一個媒體播放器,將流媒體直播和點播流。這主要是工作,但由於某種原因,我無法得到seekTo(int)正常工作。我的問題是,當我打電話seekTo(int)我沒有得到我的onSeekComplete回調。我在我的onPrepared回調中註冊我的回調方法。Android媒體播放器onSeekComplete沒有被調用

我應該注意到我也在使用MediaController,並且已經使用MediaController註冊了我的MediaPlayer。當我通過錄制搜索欄尋找時,它會通過我的MediaController,並且在該場景中確實獲得了onSeekComplete回調。這是我的代碼。

package com.brockoli.android.hsdroid; 

import java.io.IOException; 

import android.app.Activity; 
import android.content.Intent; 
import android.graphics.Point; 
import android.media.AudioManager; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnSeekCompleteListener; 
import android.os.Bundle; 
import android.os.Handler; 
import android.util.Log; 
import android.view.Display; 
import android.view.MotionEvent; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.ViewGroup.LayoutParams; 
import android.widget.MediaController; 
import android.widget.MediaController.MediaPlayerControl; 
import android.widget.ProgressBar; 

public class VideoPlayerActivity extends Activity implements MediaPlayer.OnPreparedListener, 
                  MediaPlayer.OnVideoSizeChangedListener, 
                  SurfaceHolder.Callback, 
                  MediaController.MediaPlayerControl, 
                  OnSeekCompleteListener { 

    private MediaPlayer mp; 
    private MediaController mc; 
    private int width = 0; 
    private int height = 0; 
    private SurfaceView surface; 
    private SurfaceHolder holder; 
    private ProgressBar timeline = null; 
    private boolean isPaused = false; 
    private int mCurrentPosition = 0; 

    private Handler handler = new Handler(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.video_player); 

     if (getLastNonConfigurationInstance() != null) { 
      mCurrentPosition = (Integer) getLastNonConfigurationInstance();   
     } 

     mc = new MediaController(this); 

     surface = (SurfaceView) findViewById(R.id.surface_video); 
     holder = surface.getHolder(); 
     holder.addCallback(this); 

    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 

     isPaused = true; 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     width = getScreenWidth(); 
     height = setHeightBasedOnWidth(); 

     isPaused = false; 

    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 

     if (mp != null) { 
      mp.release(); 
      mp = null; 
     } 
    } 

    @Override 
    public Object onRetainNonConfigurationInstance() { 
     int currentPosition = 0; 
     if (mp != null && mp.isPlaying()) { 
      currentPosition = mp.getCurrentPosition(); 
     } 
     return currentPosition; 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     mc.show(); 
     return false; 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 

    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     Intent intent = this.getIntent(); 
     String url = intent.getStringExtra("STREAM_ID"); 

     playVideo(url); 

    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 

    } 

    @Override 
    public void onPrepared(MediaPlayer mediaPlayer) { 
     LayoutParams lp = surface.getLayoutParams(); 
     lp.width = width; 
     lp.height = height; 
     surface.setLayoutParams(lp); 
     if (width != 0 && height != 0) { 
      holder.setFixedSize(width, height); 
      mc.setMediaPlayer(this); 
      mc.setAnchorView(surface); 

      handler.post(new Runnable() { 

       @Override 
       public void run() { 
        mc.setEnabled(true); 
        mc.show(); 
       } 
      }); 

      Log.d("MEDIAPLAYER", "onPrepared start"); 
      mp.seekTo(mCurrentPosition); 
      //mediaPlayer.start(); 
     } 
    } 

    private void playVideo(String url) { 
      try { 
       if (mp == null) { 
        mp = new MediaPlayer(); 
        mp.setScreenOnWhilePlaying(true); 
        mp.setOnVideoSizeChangedListener(this); 
        mp.setOnSeekCompleteListener(this); 
       } else { 
        mp.stop(); 
        mp.reset(); 
       } 

       mp.setDataSource(url); 
       mp.setDisplay(holder); 
       mp.setAudioStreamType(AudioManager.STREAM_MUSIC); 
       mp.setOnPreparedListener(this); 
       mp.prepareAsync(); 
      } catch (IllegalStateException e) { 
       e.printStackTrace(); 
      } catch (IllegalArgumentException e) { 
       e.printStackTrace(); 
      } catch (SecurityException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
    } 

    @Override 
    public void onVideoSizeChanged(MediaPlayer mediaPlayer, int newWidth, int newHeight) { 
/*  if (width != 0 && height != 0) { 
      holder.setFixedSize(width, height); 
      //mp.seekTo(mCurrentPosition); 
      Log.d("MEDIAPLAYER", "onVideoSizeChanged start"); 
      //mediaPlayer.start(); 
     } 
*/  
    } 

    private Point getScreenSize() { 
     Display display = getWindowManager().getDefaultDisplay(); 
     Point size = new Point(); 
     display.getSize(size); 
     return size; 
    } 

    private int getScreenWidth() { 
     return getScreenSize().x; 
    } 

    private int getScreenHeight() { 
     return getScreenSize().y; 
    } 

    private int setHeightBasedOnWidth() { 
     if (getScreenWidth() > getScreenHeight()) { 
      return getScreenHeight(); 
     } 
     return (int) (getScreenWidth()/1.6); 
    } 

    @Override 
    public boolean canPause() { 
     return true; 
    } 

    @Override 
    public boolean canSeekBackward() { 
     return true; 
    } 

    @Override 
    public boolean canSeekForward() { 
     return true; 
    } 

    @Override 
    public int getBufferPercentage() { 
     return 0; 
    } 

    @Override 
    public int getCurrentPosition() { 
     return mp.getCurrentPosition(); 
    } 

    @Override 
    public int getDuration() { 
     return mp.getDuration(); 
    } 

    @Override 
    public boolean isPlaying() { 
     return mp.isPlaying(); 
    } 

    @Override 
    public void pause() { 
     mp.pause(); 
    } 

    @Override 
    public void seekTo(int pos) { 
     mp.seekTo(pos); 
    } 

    @Override 
    public void start() { 
     Log.d("MEDIAPLAYER", "MediaController start"); 
     mp.start(); 
    } 

    @Override 
    public void onSeekComplete(MediaPlayer mp) { 
     mp.start(); 
    } 

} 
+0

您是否檢查控件是否完全達到setOnSeekCompleteListener()調用? –

+0

我在setOnSeekCompleteListener()上設置了一個斷點,它確實打到了它。另外還應該注意,我一直關注內存中的媒體播放器對象,並可以看到onSeekCompleteListener成員被設置爲一個對象而不是null,這告訴我它確實設置了偵聽器。 – brockoli

回答

1

有時設備實施MediaPlayer有點不同。檢查你的onInfo監聽器,看看你是否得到反饋。

編輯點評:
我只是自己試了一下,並沒有在我的應用程序中工作。對我來說,解決這個問題的方法是,尤其是如果您的媒體在尋找活動開始時已經在玩,如果您看到當前位置再次增加,那麼您知道尋找已完成。

+0

我已經註冊onInfoListener回調在我註冊我的bufferListener,onSeekCompleteListener,onErrorListener等,並且也永遠不會被調用的地方。我試過也只是內聯它mp.setInfoListener(新MediaPlayer.OnInfoListener(){@覆蓋公共無效onInfo(...}仍然沒有運氣。真的不能看到我要去哪裏錯了。 – brockoli

+0

這不是你顯然,我在回家的路上讀了一篇關於你的情況的錯誤報告, – ajacian81

+0

嗯..好吧,我會嘗試編譯一個更低的API級別,當然這必須在某個時間點工作 – brockoli