Android如何在使用SurfaceView和MediaPlayer播放视频时使用/显示MediaController?

8

我需要使用MediaPlayer来播放视频,而不是VideoView。在Xml布局中有一个SurfaceView,在Activity中有一个MediaPlayer和一个MediaController。

我找不到一种方法来将MediaController与SurfaceView和MediaPlayer一起使用。使用VideoView非常简单,但无法弄清楚如何与MediaPlayer一起使用。

我在网上找到了一些示例,但它们都是关于播放音频而不是视频的。

这是surfaceCreated方法,我在其中创建MediaPlayer。

@Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDisplay(mSurfaceHolder);
            mMediaPlayer.setDataSource(this, Uri.parse(mUrl));
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.prepare();
            mMediaController = new MediaController(this);

        } catch (Exception e) {
            Log.e(TAG, "MediaPlayer Prepare: " + e.getMessage());
        }
    }

并且这个MediaPlayer的onPrepared方法

@Override
    public void onPrepared(MediaPlayer mp) {

        mVideoWidth = mp.getVideoWidth();
        mVideoHeight = mp.getVideoHeight();
        mSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
        startVideoPlayback();

        mMediaController.setMediaPlayer(this);              

        handler.post(new Runnable() {

            public void run() {
                mMediaController.setEnabled(true);
                mMediaController.show();
            }
        });    
    }

上述代码在SurfaceView上没有显示MediaController。
我该如何实现呢?
提前感谢。
1个回答

16

为此,您需要实现活动

OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener,
OnVideoSizeChangedListener, SurfaceHolder.Callback, MediaPlayerControl

请查看下方的工作代码

package com.example.demo;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.MediaController;
import android.widget.MediaController.MediaPlayerControl;
import android.widget.ProgressBar;

public class MainActivity extends Activity implements  OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener,
OnVideoSizeChangedListener, SurfaceHolder.Callback, MediaPlayerControl{
    String url = "your video url";
    MediaPlayer mMediaPlayer ;
    SurfaceView mSurfaceView ;
    SurfaceHolder holder ;
    private ConstantAnchorMediaController controller = null;
    ProgressBar progressBar1 ;
    MediaController mcontroller ;
    Handler handler ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        progressBar1 = (ProgressBar)findViewById(R.id.progressBar1);
        SurfaceView v = (SurfaceView) findViewById(R.id.surface); 
        handler = new Handler();
        holder = v.getHolder(); 
        holder.addCallback(this);
        playVideo();

    }
    private void playVideo() {
        try {
            mcontroller = new MediaController(this);
            mMediaPlayer = MediaPlayer.create(this, Uri.parse(url));
            mMediaPlayer.setOnBufferingUpdateListener(this);
            mMediaPlayer.setOnCompletionListener(this);
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.setScreenOnWhilePlaying(true);
            mMediaPlayer.setOnVideoSizeChangedListener(this);
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
         mcontroller.show();
         return false;
    }
    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        // TODO Auto-generated method stub
    }
    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        mMediaPlayer.setDisplay(holder); 
        try {
            mMediaPlayer.start();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        // TODO Auto-generated method stub
        progressBar1.setVisibility(View.GONE);
        mcontroller.setMediaPlayer(this);
        mcontroller.setAnchorView(findViewById(R.id.surface));
        mcontroller.setEnabled(true);

        handler.post(new Runnable() {
            public void run() {
                mcontroller.show();
            }
        });
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        // TODO Auto-generated method stub
    }
    public void start() {
        mMediaPlayer.start();
    }

    public void pause() {
        mMediaPlayer.pause();
    }

    public int getDuration() {
        return mMediaPlayer.getDuration();
    }

    public int getCurrentPosition() {
        return mMediaPlayer.getCurrentPosition();
    }

    public void seekTo(int i) {
        mMediaPlayer.seekTo(i);
    }

    public boolean isPlaying() {
        return mMediaPlayer.isPlaying(); 
    }

    public int getBufferPercentage() {
        return 0;
    }

    public boolean canPause() {
        return true;
    }

    public boolean canSeekBackward() {
        return true;
    }

    public boolean canSeekForward() {
        return true;
    }
}

它并不启动应用程序,只显示应用程序已停止。 在代码方面没有显示任何错误。 - Lily
1
@Lily 下载可工作演示 - http://paragchauhan2010.blogspot.com/2013/10/mediacontroller-with-surfaceview.html - Parag Chauhan
我尝试了一下,仍然出现同样的问题,应用程序无法启动,只显示应用程序已停止。有什么建议吗? - Lily
这是出现在日志cat上的消息:“:E/AndroidRuntime(20047):java.lang.RuntimeException:无法实例化活动ComponentInfo {com.example.mediaplayer_surf / com.example.mediaplayer_surf.MainActivity}:java.lang.ClassNotFoundException:在路径上找不到类“com.example.mediaplayer_surf.MainActivity”的/data/app/com.example.mediaplayer_surf-2.apk” 然后还有其他不适合在此处的消息。 - Lily
我已经多次确认一切都正常。您能否提供源代码作为安卓应用程序,以确保设置正确? 我尝试下载您的源代码,但压缩文件可能无法正常工作。 非常感谢您的帮助。 - Lily
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接