【问题标题】:Youtube video play with android player用安卓播放器播放 Youtube 视频
【发布时间】:2012-04-02 02:56:44
【问题描述】:

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

谁有想法,请解释一下。

我必须使用 android 默认媒体播放器播放 URL:“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

谢谢

【问题讨论】:

  • 你的rstp stream 直播吗?它似乎不起作用

标签: android


【解决方案1】:

@Sock 您是否考虑过使用适用于 Android 的 YouTube API。他们有一个很棒的播放器视图,可以让您对视频进行大量控制和事件监听。我最近发布了一个关于使用 API 的教程,如果它可能满足您的需求,请查看 here

【讨论】:

    【解决方案2】:

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

    请记住,目前,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);
    

    【讨论】:

      【解决方案3】:

      嗯,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 手机上运行良好。

      编辑:

      您确实必须使用 YouTube 视频的原始 URI,对于您的视频,它将是:

      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

      它很长,但它会起作用:)

      【讨论】:

      • 亲爱的,我必须在我的应用程序中使用 android 媒体播放器播放 youtube 视频,而不是在应用程序之外...
      • 啊,好吧,我从您的原始帖子中不清楚这一点。但是,您的核心问题也已经在这里得到解答。您需要 YouTube 视频的 RAW URI。否则,您只需将网站处理到媒体播放器(即使是嵌入式版本)。我将您视频的链接添加到我的帖子中。我用 Chrome 扩展程序提取了它。
      • 如果有人用制表符播放此视频,请帮帮我。谢谢
      • @Sock: youtube 的http 视频网址在安卓平板电脑上运行良好
      • @Marcel Klein :感谢您的指导,我尝试了您给定的链接..但它说权限在网络浏览器上被拒绝...在 android 设备中...“无法播放此视频” ...您知道为什么会发生这种情况...如果有任何想法,请告诉我如何获取原始 uri?
      猜你喜欢
      • 2013-05-10
      • 1970-01-01
      • 1970-01-01
      • 2014-05-01
      • 2014-09-27
      • 2015-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多