Android 媒体播放器 onSeekComplete 未被调用

问题描述 投票:0回答:2

我正在编写一个媒体播放器,可以播放直播和点播流。它大部分工作正常,但由于某种原因我无法让eekTo(int)正常工作。我的问题是,当我调用eekTo(int)时,我没有得到onSeekComplete回调。我在 onPrepared 回调中注册我的回调方法。

我应该注意,我也在使用 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();
    }

}
android media-player seek
2个回答
1
投票

设备实现 MediaPlayer 有时略有不同。检查您的 onInfo 监听器,看看您是否收到反馈。

编辑评论:
我只是自己尝试过,但它在我的应用程序中对我来说也不起作用。对我来说,解决这个问题的方法是,特别是如果您的媒体在搜索事件开始时已经在播放,如果您看到 currentPosition 再次增加,那么您就知道搜索已经完成。


0
投票

它有点旧,但问题仍然相关。 我找到的解决方案是运行一个循环来检查 MediaPlayer 当前是否正在播放,如果没有,我就释放它。

        mediaPlayer.start()
        while (mediaPlayer.isPlaying) {
            Thread.sleep(500)
        }
        mediaPlayer.release()

我不怕占用线程,因为我不在主线程上运行MediaPlayer。

© www.soinside.com 2019 - 2024. All rights reserved.