Youtube视频播放与Android播放器

时间:2012-03-16 14:46:55

标签: android

我们如何使用Android媒体播放器播放youtube视频?

任何人都有想法,请解释我。

我必须使用Android默认媒体播放器播放网址:“http://www.youtube.com/embed/bIPcobKMB94?autoplay=1”。

当我使用Android媒体播放器播放此网址时,我收到了MediaPlayer错误(1,-2147483648)。

我在我的Android设备媒体播放器中播放该网址,但现在我无法在平板电脑中播放。有人帮帮我。 为什么我无法在平板电脑上播放该视频?

RTSP://v6.cache3.c.youtube.com/CiILENy73wIaGQnokCRYfXXPsBMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp

由于

3 个答案:

答案 0 :(得分:1)

嗯,Android部分非常简单。您只需要YouTube视频的原始URI并触发其意图:

    Uri uri = Uri.parse("http://<link-to-RAW-youtube-video>"); // i.e. mp4 version
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(uri, "video/*"); // important! otherwise you just download the video
    startActivity(intent); // called directly from an other activity as you see

如果用户安装了多个视频播放器,用户还可以选择要用于播放的视频播放器。

这里棘手的部分与Android无关,它是如何获取YouTube视频的原始URI。通常它们是从原始YouTube视频页面的源代码中提取的,但这是另一个主题。我尝试使用自解压URI到视频的mp4版本上面的代码,它在我的Android 4.0手机上工作得很好。

编辑:

你真的必须使用原始URI到YouTube视频,对于你的视频它将是:

http://o-o.preferred.ber01s04.v22.lscache2.c.youtube.com/videoplayback?sparams=cp%2Cid%2Cip%2Cipbits%2Citag%2Cratebypass%2Csource%2Cexpire&fexp=904550%2C919700%2C911614&itag=18&ip=77.0.0.0&signature=C721CE7543081FC0C805C86F5D3C4D9B34D77764.D4288106CF7A3153FF1574F2334161CBD1176535&sver=3&ratebypass=yes&source=youtube&expire=1332001847&key=yt1&ipbits=8&cp=U0hSR1BLT19JUUNOMl9IRVNJOmllRjJJYy1SSG92&id=6c83dca1b28c07de&title=AT%26T%20Samsung%20Captivate%20TV%20Commercial%20-%20Galaxy%20S%20Phone-360p

它很长但它会起作用:)

答案 1 :(得分:0)

我很难实现支持许多功能和格式的播放器。甚至VideoView也无法满足我的所有需求。最后,我最终编写了基于SurfaceView和MediaPlayer的自己的解决方案。这是源代码。对于本地3gp,本地mp4,http 3gp和youtube rtsp流,它在4.0.3和4.1.2上得到了验证。

请记住,目前,android上有效youtube视频的URI应如下所示:rtsp://v5.cache1.c.youtube.com/CjYLENy73wIaLQnhycnrJQ8qmRMYESARFEIJbXYtZ29vZ2xlSARSBXdhdGNoYPj_hYjnq6uUTQw=/0/0/0/video.3gp。你可以通过http://m.youtube.video获得它们。

活动的参数由Intent设置。有很多种选择。请参阅我的评论中提供的最新源代码。您可以删除与Sequencer,Scenario和Test类相关的代码。它们特定于我的程序(用于平台测试的自动化系统)

package my.package;

import java.io.IOException;
import java.lang.ref.WeakReference;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Point;
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.Build.VERSION;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.text.format.Time;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import my.package.Log;
import my.package.R;
import my.package.Scenario;
import my.package.Sequencer;
import my.package.Test;
import my.package.TestUtil;

/**
 * An activity to display local or remote video or play audio file.
 */
public class MediaPlayerActivity extends Activity implements
        OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener,
        OnVideoSizeChangedListener, OnErrorListener, SurfaceHolder.Callback {

    private static final String LOG_TAG = MediaPlayerActivity.class
            .getSimpleName();

    // Mandatory creation arguments passed by extras in starting Intent
    public static final String SEQUENCER = "sequencer"; //$NON-NLS-1$
    public static final String SCENARIO = "scenario"; //$NON-NLS-1$
    public static final String TEST = "test"; //$NON-NLS-1$
    public static final String SOURCE_URI = "uri"; //$NON-NLS-1$

    // Optional creation arguments passed by extras in starting Intent
    public static final String PAUSE_ON_BACKGROUND = "auto_pause"; //$NON-NLS-1$
    public static final String TIMEOUT = "timeout"; //$NON-NLS-1$
    public static final String LOOP = "loop"; //$NON-NLS-1$
    public static final String SCREEN_ON_WHILE_PLAYING = "screen_on_while_playing"; //$NON-NLS-1$

    // data arguments returned by Intent on finish
    public static final String REASON = "cause"; //$NON-NLS-1$
    public static final String EXCEPTION = "exception"; //$NON-NLS-1$

    // additional state bundle arguments.
    private static final String START_POSITION = "start"; //$NON-NLS-1$
    private static final String VIDEO_WIDTH = "video_width"; //$NON-NLS-1$
    private static final String VIDEO_HEIGHT = "video_height"; //$NON-NLS-1$

    private WeakReference<Sequencer> mSequencer = new WeakReference<Sequencer> (null);

    private WeakReference<Test> mTest = new WeakReference<Test> (null);

    /**
     * URI of the video/audio source.
     * 
     * This player supports a variety of videos and audio sources, either local
     * or remote.
     * <p>
     * An HTTP live streaming URI would be:
     * {@code httplive://xboodangx.api.channel.livestream.com/3.0/playlist.m3u8}
     * </p>
     * <p>
     * A local video file URI would be {@code file:///sdcard/spiderman.mp4}
     * </p>
     * <p>
     * A remote 3GPP format video URI would be
     * {@code http://commonsware.com/misc/test2.3gp}
     * </p>
     * <p>
     * And finally an RTP or RTSP video source URI would be
     * {@code rtsp://v4.cache1.c.youtube.com/CjYLENy73wIaLQk4RDShYkdS1BMYDSANFEIJbXYtZ29vZ2xlSARSBXdhdGNoYK-Cn8qh8J6-Tgw=/0/0/0/video.3gp}
     * </p>
     */
    private Uri mMediaURI;

    /**
     * Input: this flag is set to true if the video must be paused when the
     * activity is not visible any more. The video will resume when the activity
     * is visible again.
     */
    private boolean mPauseOnBackground;

    /**
     * Input: number of milliseconds until automatic shutdown, or -1 if no
     * timeout.
     */
    private long mTimeout;

    /**
     * Input: flag set to true to loop back to the beginning of the video when
     * reaching its end
     */
    private boolean mLoop;

    /**
     * The width of the video, obtained by
     * {@link #onVideoSizeChanged(MediaPlayer, int, int)}
     */
    private int mVideoWidth;

    /**
     * The height of the video, obtained by
     * {@link #onVideoSizeChanged(MediaPlayer, int, int)}
     */
    private int mVideoHeight;

    private MediaPlayer mMediaPlayer;

    private SurfaceView mPreview;

    private boolean mIsVideoSizeKnown = false;

    private boolean mMediaPrepared = false;

    /**
     * This member is set to position the video should start. It is set when
     * pausing the video and used when restoring the instance.
     */
    private int mStartPosition;

    private boolean mTimeoutSet;

    private boolean mScreenOnWhilePlaying;

    private SurfaceHolder mHolder;

    private static class ShutdownHandler extends Handler {

        WeakReference<MediaPlayerActivity> mActivity;

        public ShutdownHandler(MediaPlayerActivity activity) {
            mActivity = new WeakReference<MediaPlayerActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {

            MediaPlayerActivity activity = mActivity.get();
            if (activity != null) {
                activity.finishTest(Activity.RESULT_OK, null);
            } else {
                //Log.w(LOG_TAG, "no activity for shutdown");
            }
        }

    }

    public MediaPlayerActivity() {
        super();

        // These members are initialized in onCreate(Bundle) by the
        // starting Intent, the first time the activity is created, and restored
        // in the same method with the arguments in the saved instance bundle.
        mSequencer = new WeakReference<Sequencer> (null);
        mTest = new WeakReference<Test> (null);
        setSourceURI(null);
        setPauseOnBackground(false);
        setPlayTimeout(-1);
        setLooping(false);
        setScreenOnWhilePlaying(true);

        // Initialize internals.
        mIsVideoSizeKnown = false;
        mVideoWidth = mVideoHeight = 0; // unknown
        mMediaPrepared = false;
        mMediaPlayer = null;
        mPreview = null; // set in onCreate(Bundle)
        setStartPosition(0); // beginning of the video
        mTimeoutSet = false;
    }

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

        setContentView(R.layout.video_player);

        Intent intent = getIntent();
        if (savedInstanceState != null) {

            onRestoreInstanceState(savedInstanceState);

        } else if (intent != null) {

            Log.d(LOG_TAG, "Loading starting Intent extras...");

            // read starting Intent extras.
            _updateForeignReferences(intent);

            setSourceURI((Uri) intent.getParcelableExtra(SOURCE_URI));
            setPlayTimeout(intent.getLongExtra(TIMEOUT, -1L));
            setPauseOnBackground(intent.getBooleanExtra(PAUSE_ON_BACKGROUND,
                    false));
            setLooping(intent.getBooleanExtra(LOOP, false));
            setScreenOnWhilePlaying(intent.getBooleanExtra(SCREEN_ON_WHILE_PLAYING, true));
        }

        mTimeoutSet = false;

        _updateWidgets();
    }

    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        Log.d(LOG_TAG, "Restoring instance state...");

        // restore saved references
        _updateSavedForeignReferences(savedInstanceState);

        // restore saved inputs
        setSourceURI(Uri.parse(savedInstanceState.getString(SOURCE_URI)));
        setPlayTimeout(savedInstanceState.getLong(TIMEOUT));
        setPauseOnBackground(savedInstanceState.getBoolean(PAUSE_ON_BACKGROUND));
        setLooping(savedInstanceState.getBoolean(LOOP));
        setScreenOnWhilePlaying(savedInstanceState.getBoolean(SCREEN_ON_WHILE_PLAYING));

        // restore internals
        setStartPosition(savedInstanceState.getInt(START_POSITION, 0));
        mVideoWidth = savedInstanceState.getInt(VIDEO_WIDTH);
        mVideoHeight = savedInstanceState.getInt(VIDEO_HEIGHT); // unknown
        mIsVideoSizeKnown = (mVideoWidth > 0) && (mVideoHeight > 0);
    }

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

        if (mMediaPlayer == null) {
            try {
                _playMedia();
            } catch (Exception e) {
                _fail(e);
            }
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        Log.d(LOG_TAG, "Saving instance state");

        Sequencer sequencer = mSequencer.get();
        if (sequencer != null) {
            outState.putInt(SEQUENCER, sequencer.getPosition());
            Scenario scenario = sequencer.getScenario();
            if (scenario != null) {
                outState.putInt(SCENARIO, scenario.getScenarioId());
            }
        }

        Test test = mTest.get();
        if (test != null) {
            outState.putString(TEST, TestUtil.getTestPath(test, TestUtil.Path.Static));
        }

        if (getSourceURI() != null) {
            outState.putString(SOURCE_URI, getSourceURI().toString());
        }
        outState.putBoolean(LOOP, isLooping());
        outState.putBoolean(PAUSE_ON_BACKGROUND, isPausingOnBackground());
        outState.putLong(TIMEOUT, getPlayTimeout());
        outState.putBoolean(SCREEN_ON_WHILE_PLAYING, isScreenOnWhilePlaying());

        outState.putInt(START_POSITION, getStartPosition());
    }

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

        if (isPausingOnBackground()) {
            _pausePlayback();
        }
    }

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

        Log.d(LOG_TAG, "onStop");

        if (isPausingOnBackground()) {
            _releaseMediaPlayer();
        }
    }

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

        Log.d(LOG_TAG, "onDestroy");

        // TODO: It would be fine to fail the test if the activity was destroyed
        // if we didn't finished the test yet but there are far too many cases
        // and I failed to implement one working with all of them!
/*      if (!mInstanceSaved) {
        finishTest(Activity.RESULT_FIRST_USER, new Intent().putExtra(REASON,
                "Activity destroyed. Something certainly goes wrong there."));
        }
*/      
        _releaseMediaPlayer();
    }

    // Restore sequencer, scenario and test references from saved state.
    private void _updateSavedForeignReferences(Bundle savedInstanceState) {

        int sequencer = savedInstanceState.getInt(SEQUENCER, -1);
        int scenarioId = savedInstanceState.getInt(SCENARIO, -1);

        mSequencer = new WeakReference<Sequencer>(null);
        mTest = new WeakReference<Test>(null);

        if (scenarioId >= 0 && sequencer >= 0) {

            Scenario scenario = Controller.controller.getData().scenarios()
                    .getScenario(scenarioId);

            mSequencer = new WeakReference<Sequencer>(Controller.controller
                    .engine().getSequencerAt(sequencer));

            String testPath = savedInstanceState.getString(TEST);
            if (!TextUtils.isEmpty(testPath)) {
                mTest = new WeakReference<Test>(TestUtil.fromPath(
                        scenario.getRootTest(), testPath));
            }
        }
    }

    // Update sequencer, scenario and test references from starting Intent
    protected void _updateForeignReferences(Intent intent) {

        int scenarioId = intent.getIntExtra(MediaPlayerActivity.SCENARIO, -1);
        Scenario scenario = Controller.controller.getData().scenarios()
                .getScenario(scenarioId);
        int sequencer = intent.getIntExtra(MediaPlayerActivity.SEQUENCER, -1);

        mSequencer = new WeakReference<Sequencer>(null);
        mTest = new WeakReference<Test>(null);

        if (scenarioId >= 0 && sequencer >= 0) {

            mSequencer = new WeakReference<Sequencer>(Controller.controller
                    .engine().getSequencerAt(sequencer));

            String testPath = intent.getStringExtra(MediaPlayerActivity.TEST);
            if (!TextUtils.isEmpty(testPath)) {
                mTest = new WeakReference<Test>(TestUtil.fromPath(
                        scenario.getRootTest(), testPath));
            }
        }
    }

    /**
     * Terminate the test case and finish the activity at the same time.
     * <p>
     * The result code and data are passed to both the parent activity and the
     * {@link Test#terminate(int, Sequencer, Object)} method.
     * </p>
     * 
     * @param resultCode
     *            the result code. May be on of the Activity result code but
     *            also any other one having a meaning for the test and caller
     *            activity.
     * @param data
     *            extra result data. Can be null.
     */
    public void finishTest(int resultCode, Intent data) {

        Test test = mTest.get();
        Sequencer sequencer = mSequencer.get();
        if ((test != null) && (sequencer != null)) {
            test.terminate(resultCode, sequencer, data);

            // prevent any further call to finishTest.
            mTest = new WeakReference<Test> (null);
        }

        if (!isFinishing()) {
            setResult(Activity.RESULT_OK, data);
            finish();
        }
    }

    @SuppressWarnings("deprecation")
    private void _updateWidgets() {
        SurfaceView surface = (SurfaceView) findViewById(R.id.surface);
        mPreview = surface;

        SurfaceHolder holder = surface.getHolder();
        holder.addCallback(this);

        if (VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) {
            holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
    }

    public void onBufferingUpdate(MediaPlayer arg0, int percent) {
        Log.d(LOG_TAG, "onBufferingUpdate percent:" + percent);

        if (percent >= 100) {
            mMediaPlayer.setOnBufferingUpdateListener(null);
        }

        // no display so don't bother.
    }

    public void onCompletion(MediaPlayer player) {
        _releaseMediaPlayer();

        finishTest(Activity.RESULT_OK, null);
    }

    private void _rearmPlayer() {
        mVideoWidth = 0;
        mVideoHeight = 0;
        mMediaPrepared = false;
        mIsVideoSizeKnown = false;
    }

    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        if (mIsVideoSizeKnown) return; // further notifications are completely wrong!!

        Log.i(LOG_TAG, "Video size: " + width + "x" + height);

        mIsVideoSizeKnown = true;
        mVideoWidth = width;
        mVideoHeight = height;

        if (width > 0 && height > 0) {
            _fitSurfaceForVideo();
        } else {
            // audio only or video size unknown.
        }

        if (mMediaPrepared) {
            _startPlayback();
        }
    }

    @SuppressWarnings("deprecation")
    @SuppressLint("NewApi")
    private void _fitSurfaceForVideo() {

        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();

        if (VERSION.SDK_INT >= 13) {
            display.getSize(size);
        } else {
            size.x = display.getWidth();
            size.y = display.getHeight();
        }

        double ratioVideo = (double)mVideoWidth / mVideoHeight;
        double ratioScreen = (double)size.x / size.y;

        if (ratioScreen > ratioVideo) {
            // fit in height and scale the width to match the video ratio
            mVideoHeight = size.y;
            mVideoWidth = (int) (size.y / ratioVideo);
        } else {
            // fit in width and scale height to keep the video ratio
            mVideoWidth = size.x;
            mVideoHeight = (int) (size.x / ratioVideo);
        }
    }

    public void onPrepared(MediaPlayer mediaplayer) {
        mMediaPrepared = true;

        if (mIsVideoSizeKnown) {
            _startPlayback();
        }
    }

    private void _startPlayback() {

        SurfaceHolder holder = mPreview.getHolder();
        if (mVideoWidth > 0 && mVideoHeight > 0) {
            holder.setFixedSize(mVideoWidth, mVideoHeight);
        }

        if (mStartPosition > 0) {
            Log.i(LOG_TAG, String.format("Resume at %f seconds", mStartPosition / 1000.f));
            mMediaPlayer.seekTo(mStartPosition);
        } else {
            Log.i(LOG_TAG, "Start video");
        }

        if (!mTimeoutSet && (getPlayTimeout() > 0)) {

            // this is a constant time reference: deduce the time already played.
            long remaining = getPlayTimeout() - mStartPosition;

            Time time = new Time();
            time.setToNow();
            time.second += remaining / 1000;
            time.normalize(false);
            Log.i(LOG_TAG, "Will end the video on " + time.format2445());

            new ShutdownHandler(this).sendEmptyMessageDelayed(0, remaining);
            mTimeoutSet = true;
        }

        mMediaPlayer.start();
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        Log.d(LOG_TAG, String.format(
                "surfaceChanged called: format=%d, width=%d, height=%d",
                format, width, height));
    }

    public void surfaceDestroyed(SurfaceHolder surfaceholder) {
        Log.d(LOG_TAG, "surfaceDestroyed called");

        mHolder = null;

        if (mMediaPlayer != null) {
            mMediaPlayer.setDisplay(null);
        }
    }

    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(LOG_TAG, "surfaceCreated called");

        mHolder = holder;

        if (mMediaPlayer != null) {
            // surface created after the media player
            try {
                mMediaPlayer.setDisplay(holder);
                mMediaPlayer.setScreenOnWhilePlaying(isScreenOnWhilePlaying());
                mMediaPlayer.setOnCompletionListener(this);

                if (!mMediaPrepared) {
                    mMediaPlayer.setDataSource(this, mMediaURI);
                    mMediaPlayer.prepareAsync();
                }
            } catch (IllegalStateException e) {
                _fail(e);
            } catch (IllegalArgumentException e) {
                _fail(e);
            } catch (SecurityException e) {
                _fail(e);
            } catch (IOException e) {
                _fail(e);
            }
        }
    }

    private void _playMedia() throws IllegalArgumentException,
            SecurityException, IllegalStateException, IOException {

        Log.d(LOG_TAG, "_playMedia()");

        _rearmPlayer();

        /*
         * The video should be in a streamable mp4 or 3gpp format. The URI
         * scheme may be Http. Mediaplayer can only play
         * "progressive streamable contents" which basically means: 1. the movie
         * atom has to precede all the media data atoms. 2. The clip has to be
         * reasonably interleaved.
         */

        if (mMediaURI != null) {
            Log.i(LOG_TAG, "Source: " + mMediaURI);

            // Create a new media player and set the listeners
            if (mMediaPlayer != null) {
                mMediaPlayer.reset();
            } else {
                mMediaPlayer = new MediaPlayer();
            }

//          mMediaPlayer.setDataSource(this, mMediaURI);

            mMediaPlayer.setOnBufferingUpdateListener(this);
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.setLooping(isLooping());
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mMediaPlayer.setOnVideoSizeChangedListener(this);

            if (mHolder != null) {
                // surface created before the media player
                mMediaPlayer.setDisplay(mHolder);
                mMediaPlayer.setScreenOnWhilePlaying(isScreenOnWhilePlaying());
                mMediaPlayer.setOnCompletionListener(this);

                mMediaPlayer.setDataSource(this, mMediaURI);
                mMediaPlayer.prepareAsync();
            }
        } else {
            _fail("No video source defined");
        }
    }

    // fail due to exception
    private void _fail(Exception e) {

        Log.e(LOG_TAG, e);

        Intent data = new Intent();
        data.putExtra(EXCEPTION, e);
        finishTest(Activity.RESULT_FIRST_USER, data);
    }

    // fail due to generic error
    private void _fail(String text) {

        Log.e(LOG_TAG, text);

        Intent data = new Intent();
        data.putExtra(REASON, text);
        finishTest(Activity.RESULT_FIRST_USER, data);
    }

    private void _pausePlayback() {
        if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
            Log.i(LOG_TAG, "Pause playback");

            mMediaPlayer.pause();

            // retain position for use by onSaveInstanceState(Bundle)
            setStartPosition(mMediaPlayer.getCurrentPosition());
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();

        Intent data = new Intent();
        data.putExtra(REASON, "canceled by user");
        finishTest(Activity.RESULT_CANCELED, data);
    }

    private void _releaseMediaPlayer() {
        _stopPlayback();

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

        _rearmPlayer();
    }

    private void _stopPlayback() {
        if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
            _pausePlayback();

            Log.i(LOG_TAG, "stop video");
            mMediaPlayer.stop();
        }
    }

    public boolean isPausingOnBackground() {
        return mPauseOnBackground;
    }

    public void setPauseOnBackground(boolean pause) {
        Log.d(LOG_TAG, "Pausing on background: " + pause);
        this.mPauseOnBackground = pause;
    }

    public Uri getSourceURI() {
        return mMediaURI;
    }

    public void setSourceURI(Uri uri) {
        Log.d(LOG_TAG, "Media source: " + uri);
        this.mMediaURI = uri;
    }

    public long getPlayTimeout() {
        return mTimeout;
    }

    public void setPlayTimeout(long timeout) {
        Log.d(LOG_TAG, "Play length (ms): " + timeout);
        this.mTimeout = timeout;
    }

    public boolean isLooping() {
        return mLoop;
    }

    public void setLooping(boolean loop) {
        Log.d(LOG_TAG, "Is looping: " + loop);
        this.mLoop = loop;
    }

    public int getStartPosition() {
        int position = 0;

        if (mMediaPlayer != null) {
            position = mMediaPlayer.getCurrentPosition();
        }

        return position;
    }

    public void setStartPosition(int position) {
        Log.d(LOG_TAG, String.format("Start at %fs", position / 1000.));
        this.mStartPosition = position;
    }

    public boolean isScreenOnWhilePlaying() {
        return mScreenOnWhilePlaying;
    }

    public void setScreenOnWhilePlaying(boolean screenOnWhilePlaying) {
        Log.d(LOG_TAG, "Screen ON while playing: " + screenOnWhilePlaying);
        this.mScreenOnWhilePlaying = screenOnWhilePlaying;
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        _fail(String.format("Media player error: what=%d, extra=%d", what, extra));
        return true;
    }

}

包含SurfaceView的布局资源:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <SurfaceView
        android:id="@+id/surface"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</FrameLayout>

使用活动的一个例子:

Intent intent = new Intent(parent, MediaPlayerActivity.class);

intent.putExtra(MediaPlayerActivity.SOURCE_URI, this.getSourceURI());
intent.putExtra(MediaPlayerActivity.PAUSE_ON_BACKGROUND,
            this.getPauseOnBackground());

Scenario scenario = sequencer.getScenario();
intent.putExtra(MediaPlayerActivity.SCENARIO, scenario.getScenarioId());
intent.putExtra(MediaPlayerActivity.SEQUENCER, sequencer.getPosition());
intent.putExtra(MediaPlayerActivity.TEST, TestUtil.getTestPath(
        scenario.getCurrentTest(), TestUtil.Path.Static));

// timeout option
TimeSpan timeout = this.getTimeout();
if (!timeout.isNull()) {
    timeout.renew();

    intent.putExtra(MediaPlayerActivity.TIMEOUT, timeout.value());
}

intent.putExtra(MediaPlayerActivity.LOOP, this.isLooping());

startActivity(intent);

答案 2 :(得分:0)

@Sock您是否考虑过使用适用于Android的YouTube API。他们拥有出色的播放器视图,可以为您提供视频上的大量控制和事件监听功能。我最近发布了一个关于使用API​​的教程,如果它可能符合您的需求,请查看here