我正在開發一個應用程序,其中包括播放一些視頻文件(流媒體)。我想在一個活動中準備MediaPlayer,但在其他活動準備好後播放視頻,以便用戶可以瀏覽第一個活動的內容以殺死一些時間。這可能嗎?在一個活動中準備MediaPlayer的同步,在另一個活動中播放
有一個在應用類中定義的靜態MediaPlayer的,就像這樣:
public class EGDF_App extends Application {
private static MediaPlayer mediaPlayer = null;
public static MediaPlayer getMediaPlayer() {
if(mediaPlayer == null)
return new MediaPlayer();
else
return mediaPlayer;
}
}
我有一個文本(加載視頻)按鈕。當視頻準備就緒時,該文本會發生變化,當用戶點擊該文本時,會觸發以下活動。
的問題是,我得到的logcat以下錯誤:
09-06 20:43:34.606: D/ChapterPlayer(31999): surfaceCreated called
09-06 20:43:34.684: V/ChapterPlayer(31999): startVideoPlayback
09-06 20:43:34.684: E/MediaPlayer(31999): start called in state 1
09-06 20:43:34.684: E/MediaPlayer(31999): error (-38, 0)
09-06 20:43:34.684: D/ChapterPlayer(31999): surfaceChanged called
09-06 20:43:34.700: E/MediaPlayer(31999): Attempt to call getDuration without a valid mediaplayer
09-06 20:43:34.715: E/MediaPlayer(31999): Error (-38,0)
09-06 20:43:34.715: D/ChapterPlayer(31999): onCompletion called
09-06 20:43:34.751: E/MediaPlayer(31999): Attempt to call getDuration without a valid mediaplayer
這是包含在第一個活動代碼:
public void watchChapter(View view){
Log.i("Button", "Watch chapter button PRESSED");
Button b = (Button) view;
String loadChapter = getString(R.string.load_chapter_button_text);
String watchChapter = getString(R.string.watch_chapter_button_text);
if(((String) b.getText()).equals(loadChapter)){
prepareVideo(view);
}else if(((String) b.getText()).equals(watchChapter)){
Intent intent = new Intent(this,ChapterAsyncMediaPlayerActivity.class);
intent.putExtra(Constants.chapterVideoResParse, getIntent().getExtras().getString(Constants.chapterVideoResParse));
intent.putExtra("duration", String.valueOf(duration));
startActivity(intent);
}
}
private void prepareVideo(View view){
MediaPlayer mMediaPlayer;
String path;
final Button button = (Button) view;
String resource = extras.getString(Constants.chapterVideoResParse);
path = SecurityHandler.obtainURL(resource, this.getResources().openRawResource(R.raw.output), 10);
try {
// Gets the media player and set the listeners
mMediaPlayer = EGDF_App.getMediaPlayer();
mMediaPlayer.setDataSource(path);
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new OnPreparedListener(){
@Override
public void onPrepared(MediaPlayer mp) {
button.setText(getString(R.string.watch_chapter_button_text));
Log.i("MediaPlayer", "MediaPlayer ready");
duration = mp.getDuration();
Log.i("Video duration", String.valueOf(mp.getDuration()));
}
});
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
這是在第二個活動的代碼:
public class ChapterAsyncMediaPlayerActivity extends Activity implements
OnBufferingUpdateListener, OnCompletionListener,
OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback, MediaPlayerControl {
private static final String TAG = "ChapterPlayer";
private int mVideoWidth;
private int mVideoHeight;
private MediaPlayer mMediaPlayer;
private MediaController mController;
private SurfaceView mPreview;
private SurfaceHolder holder;
// private String path;
// private boolean mIsVideoSizeKnown = false;
private boolean mIsVideoReadyToBePlayed = false;
private Handler handler = new Handler();
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chapter_media_player);
mPreview = (SurfaceView) findViewById(R.id.mediaPlayerSurface);
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setKeepScreenOn(true);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mController.show();
return false;
}
private void playVideo() {
doCleanUp();
try {
// Create a new media player and set the listeners
mMediaPlayer = EGDF_App.getMediaPlayer();
// mMediaPlayer.setDataSource(path);
mMediaPlayer.setDisplay(holder);
// mMediaPlayer.prepareAsync();
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mController = new MediaController(this);
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
}
public void onPrepared(MediaPlayer mediaplayer) {
Log.d(TAG, "onPrepared called");
mIsVideoReadyToBePlayed = true;
mController.setMediaPlayer(this);
mController.setAnchorView(findViewById(R.id.mediaPlayerSurface));
handler.post(new Runnable(){
@Override
public void run() {
mController.setEnabled(true);
mController.show();
}
});
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
}
}
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
Log.d(TAG, "surfaceChanged called");
}
public void surfaceDestroyed(SurfaceHolder surfaceholder) {
Log.d(TAG, "surfaceDestroyed called");
}
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "surfaceCreated called");
playVideo();
mIsVideoReadyToBePlayed = true;
mController.setMediaPlayer(this);
mController.setAnchorView(findViewById(R.id.mediaPlayerSurface));
handler.post(new Runnable(){
@Override
public void run() {
mController.setEnabled(true);
mController.show();
}
});
if (mIsVideoReadyToBePlayed) {
startVideoPlayback();
}
}
@Override
protected void onPause() {
super.onPause();
mMediaPlayer.pause();
}
@Override
protected void onRestart() {
super.onPause();
mMediaPlayer.start();
}
@Override
protected void onDestroy() {
super.onDestroy();
releaseMediaPlayer();
doCleanUp();
}
private void releaseMediaPlayer() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
private void doCleanUp() {
mVideoWidth = 0;
mVideoHeight = 0;
mIsVideoReadyToBePlayed = false;
}
private void startVideoPlayback() {
Log.v(TAG, "startVideoPlayback");
holder.setFixedSize(mVideoWidth, mVideoHeight);
mMediaPlayer.start();
mMediaPlayer.setScreenOnWhilePlaying(true);
}
@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() {
if(mMediaPlayer != null)
return mMediaPlayer.getCurrentPosition();
else
return 0;
}
@Override
public int getDuration() {
if(mMediaPlayer != null)
return mMediaPlayer.getDuration();
else
return 0;
}
@Override
public boolean isPlaying() {
if(mMediaPlayer != null)
return mMediaPlayer.isPlaying();
else
return false;
}
@Override
public void pause() {
if(mMediaPlayer != null)
mMediaPlayer.pause();
}
@Override
public void seekTo(int pos) {
mMediaPlayer.seekTo(pos);
}
@Override
public void start() {
if(mMediaPlayer != null)
mMediaPlayer.start();
}
public void onBufferingUpdate(MediaPlayer arg0, int percent) {
Log.d(TAG, "onBufferingUpdate percent:" + percent);
}
public void onCompletion(MediaPlayer arg0) {
Log.d(TAG, "onCompletion called");
}
@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
Log.v(TAG, "onVideoSizeChanged called");
if (width == 0 || height == 0) {
Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
return;
}
mVideoWidth = width;
mVideoHeight = height;
if (mIsVideoReadyToBePlayed) {
startVideoPlayback();
}
}
}
我希望得到一些幫助或建議。謝謝!
我不確定是否所有的代碼都是相關的,但如果它不是試圖找到具體的代碼片斷,你認爲是導致錯誤,只是發佈這些。很難通過某人的整個項目來找到一個錯誤 –