3

ライブおよびオンデマンド ストリームをストリーミングするメディア プレーヤーを作成しています。ほとんど動作していますが、何らかの理由で seekTo(int) が正しく動作しません。私の問題は、 seekTo(int) を呼び出すと、 onSeekComplete コールバックが得られないことです。onPrepared コールバックにコールバック メソッドを登録します。

MediaController も使用しており、MediaPlayer を MediaController に登録したことに注意してください。シーク バーをテーピングしてシークすると、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();
    }

}
4

1 に答える 1

1

デバイスによって MediaPlayer の実装が少し異なる場合があります。onInfo リスナーをチェックして、フィードバックが得られているかどうかを確認してください。

コメントから編集:
自分で試してみたところ、アプリでもうまくいきませんでした。私にとっての回避策は、特に、シーク イベントが開始されたときにメディアが既に再生されていた場合、 currentPosition が再び増加しているのを見ると、シークが完了したことがわかります。

于 2012-10-30T11:09:20.537 に答える