如何在Android中以不同的视图在一个布局中同时播放多个视频文件

如何在Android中以不同的视图在一个布局中同时播放多个视频文件,android,android-ndk,surfaceview,android-videoview,android-mediaplayer,Android,Android Ndk,Surfaceview,Android Videoview,Android Mediaplayer,在安卓系统中,我创建了一个三个面视图并排的布局,我想用不同的媒体播放器同时播放一个视频文件。但我面临的一个问题是,三个人都不能同时播放这段视频。他们中的一个或两个停止了显示。 如果我直接使用video view而不是Media Player类,问题仍然是一样的。 任何人都可以帮忙。问题出在哪里?它给出错误曲面创建失败本机错误。我尝试了不同的组合,比如一个文件在三个不同的视图中,三个文件在三个不同的视图中,但是问题还没有解决。 其他网站上的一些回复称,这取决于内核版本。 如果它取决于内核版本,请你

在安卓系统中,我创建了一个三个面视图并排的布局,我想用不同的媒体播放器同时播放一个视频文件。但我面临的一个问题是,三个人都不能同时播放这段视频。他们中的一个或两个停止了显示。 如果我直接使用video view而不是Media Player类,问题仍然是一样的。 任何人都可以帮忙。问题出在哪里?它给出错误曲面创建失败本机错误。我尝试了不同的组合,比如一个文件在三个不同的视图中,三个文件在三个不同的视图中,但是问题还没有解决。 其他网站上的一些回复称,这取决于内核版本。 如果它取决于内核版本,请你给我任何android网站上的android文档链接,它取决于内核版本。或者是可以玩的,请给我代码的步骤。这是错误日志-

04-10 19:23:37.995: E/ANDROID_DRM_TEST(2573): Client::notify In
04-10 19:23:37.995: V/AudioPolicyManager(2573): startOutput() output 1, stream 3,  session 131
04-10 19:23:37.995: V/AudioPolicyManager(2573): getDeviceForStrategy() from cache strategy 0, device 2
04-10 19:23:37.995: V/AudioPolicyManager(2573): getNewDevice() selected device 2
04-10 19:23:37.995: V/AudioPolicyManager(2573): setOutputDevice() output 1 device 2 delayMs 0
04-10 19:23:37.995: V/AudioPolicyManager(2573): setOutputDevice() setting same device 2 or null device for output 1
04-10 19:23:37.995: I/AudioFlinger(2573): start output streamType (0, 3) for 1
04-10 19:23:37.995: D/AudioHardwareYamaha(2573): AudioStreamOut::setParameters(keyValuePairs="start_output_streamtype=3")
04-10 19:23:38.010: W/SEC_Overlay(2689): overlay_setPosition(0) 0,0,200,397 => 0,0,200,397
04-10 19:23:38.010: I/SEC_Overlay(2689): overlay_setParameter param[4]=4
04-10 19:23:38.010: D/SEC_Overlay(2689): dst width, height have changed [w= 200, h= 397] -> [w=200, h= 397]
04-10 19:23:38.010: I/SEC_Overlay(2689): Nothing to do!
04-10 19:23:38.090: E/VideoMIO(2573): AndroidSurfaceOutput::setParametersSync()  VIDEO ROTATION 0
04-10 19:23:38.090: E/VideoMIO(2573): AndroidSurfaceOutput::setParametersSync()  VIDEO RENDERER 1
04-10 19:23:38.090: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48
04-10 19:23:38.090: E/SEC_Overlay(2689): Error - overlays already in use
04-10 19:23:38.090: D/VideoMIO(2573): Overlay create failed - retrying
04-10 19:23:38.195: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48
04-10 19:23:38.195: E/SEC_Overlay(2689): Error - overlays already in use
04-10 19:23:38.195: D/VideoMIO(2573): Overlay create failed - retrying
04-10 19:23:38.230: E/VideoMIO(2573): AndroidSurfaceOutput::setParametersSync()  VIDEO ROTATION 0
04-10 19:23:38.230: E/VideoMIO(2573): AndroidSurfaceOutput::setParametersSync()  VIDEO RENDERER 1
04-10 19:23:38.230: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48
04-10 19:23:38.230: E/SEC_Overlay(2689): Error - overlays already in use
04-10 19:23:38.230: D/VideoMIO(2573): Overlay create failed - retrying
04-10 19:23:38.295: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48
04-10 19:23:38.295: E/SEC_Overlay(2689): Error - overlays already in use
04-10 19:23:38.295: D/VideoMIO(2573): Overlay create failed - retrying
04-10 19:23:38.330: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48
04-10 19:23:38.330: E/SEC_Overlay(2689): Error - overlays already in use
04-10 19:23:38.330: D/VideoMIO(2573): Overlay create failed - retrying
04-10 19:23:38.395: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48
04-10 19:23:38.395: E/SEC_Overlay(2689): Error - overlays already in use
04-10 19:23:38.395: D/VideoMIO(2573): Overlay create failed - retrying
04-10 19:23:38.435: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48
04-10 19:23:38.435: E/SEC_Overlay(2689): Error - overlays already in use
04-10 19:23:38.435: D/VideoMIO(2573): Overlay create failed - retrying
04-10 19:23:38.495: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48
04-10 19:23:38.495: E/SEC_Overlay(2689): Error - overlays already in use
04-10 19:23:38.495: D/VideoMIO(2573): Overlay create failed - retrying
04-10 19:23:38.535: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48

您没有给出任何代码示例

根据我的经验,我发现你可以用片段(至少在我用过的设备上)来实现这一点。请记住,有一个针对旧设备的片段支持库


因此,基本上用线性布局或其他东西代替视频视图,然后使用片段事务将线性布局替换为具有视频视图的片段。

您没有给出太多关于您到底尝试了什么以及有问题的区域是什么的细节,所以我只是做了一个小测试,看看我是否能重现你所描述的任何东西

我没有任何结论性的发现,但至少可以确认我的Galaxy Nexus(Android 4.0.2)能够同时播放三个视频,没有任何问题。另一方面,我身边的一个旧三星Galaxy Spica(Android 2.1-update1)一次只能播放一个文件——它似乎总是第一个
SurfaceView

我通过为Android 3.0、2.3.3和2.2设置模拟器,进一步研究了不同的API级别。所有这些平台似乎都能够很好地处理多个视频文件在不同表面视图上的播放。我用一个运行2.1-update1的模拟器做了最后一次测试,有趣的是,与实际的手机不同,它也毫无问题地播放了测试用例。不过,我确实注意到布局的呈现方式有一些细微的差异

这种行为让我怀疑,您所追求的东西实际上没有任何软件限制,但它似乎取决于硬件是否支持同时播放多个视频文件。因此,对该场景的支持将因设备而异。从实证的角度来看,我肯定认为在更多的物理设备上测试这一假设会很有趣

有关实施的一些细节仅供参考:

  • 我设置了两个稍有不同的实现:一个基于单个
    活动中的三个
    MediaPlayer
    实例,另一个基于三个单独的片段,每个片段都有自己的
    MediaPlayer
    对象。(顺便说一下,我没有发现这两种实现的播放差异)
  • 一个位于
    assets
    文件夹中的单曲(感谢苹果),用于所有播放器的播放
  • 这两个实现的代码附在下面,主要基于谷歌的示例实现——我去掉了一些实际测试中不需要的代码。其结果绝不完整,也不适合在实时应用程序中使用

  • 基于活动的实施:

    public class MultipleVideoPlayActivity extends Activity implements
        OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {
    
        private static final String TAG = "MediaPlayer";
        private static final int[] SURFACE_RES_IDS = { R.id.video_1_surfaceview, R.id.video_2_surfaceview, R.id.video_3_surfaceview };
    
        private MediaPlayer[] mMediaPlayers = new MediaPlayer[SURFACE_RES_IDS.length];
        private SurfaceView[] mSurfaceViews = new SurfaceView[SURFACE_RES_IDS.length];
        private SurfaceHolder[] mSurfaceHolders = new SurfaceHolder[SURFACE_RES_IDS.length];
        private boolean[] mSizeKnown = new boolean[SURFACE_RES_IDS.length];
        private boolean[] mVideoReady = new boolean[SURFACE_RES_IDS.length];
    
        @Override public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
            setContentView(R.layout.multi_videos_layout);
    
            // create surface holders
            for (int i=0; i<mSurfaceViews.length; i++) {
                mSurfaceViews[i] = (SurfaceView) findViewById(SURFACE_RES_IDS[i]);
                mSurfaceHolders[i] = mSurfaceViews[i].getHolder();
                mSurfaceHolders[i].addCallback(this);
                mSurfaceHolders[i].setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
        }
    
        public void onBufferingUpdate(MediaPlayer player, int percent) {
            Log.d(TAG, "MediaPlayer(" + indexOf(player) + "): onBufferingUpdate percent: " + percent);
        }
    
        public void onCompletion(MediaPlayer player) {
            Log.d(TAG, "MediaPlayer(" + indexOf(player) + "): onCompletion called");
        }
    
        public void onVideoSizeChanged(MediaPlayer player, int width, int height) {
            Log.v(TAG, "MediaPlayer(" + indexOf(player) + "): onVideoSizeChanged called");
            if (width == 0 || height == 0) {
                Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
                return;
            }
    
            int index = indexOf(player);
            if (index == -1) return; // sanity check; should never happen
            mSizeKnown[index] = true;
            if (mVideoReady[index] && mSizeKnown[index]) {
                startVideoPlayback(player);
            }
        }
    
        public void onPrepared(MediaPlayer player) {
            Log.d(TAG, "MediaPlayer(" + indexOf(player) + "): onPrepared called");
    
            int index = indexOf(player);
            if (index == -1) return; // sanity check; should never happen
            mVideoReady[index] = true;
            if (mVideoReady[index] && mSizeKnown[index]) {
                startVideoPlayback(player);
            }
        }
    
        public void surfaceChanged(SurfaceHolder holder, int i, int j, int k) {
            Log.d(TAG, "SurfaceHolder(" + indexOf(holder) + "): surfaceChanged called");
        }
    
        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.d(TAG, "SurfaceHolder(" + indexOf(holder) + "): surfaceDestroyed called");
        }
    
    
        public void surfaceCreated(SurfaceHolder holder) {
            Log.d(TAG, "SurfaceHolder(" + indexOf(holder) + "): surfaceCreated called");
    
            int index = indexOf(holder);
            if (index == -1) return; // sanity check; should never happen
            try { 
                mMediaPlayers[index] = new MediaPlayer();
                AssetFileDescriptor afd = getAssets().openFd("sample.3gp");
                mMediaPlayers[index].setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
                mMediaPlayers[index].setDisplay(mSurfaceHolders[index]);
                mMediaPlayers[index].prepare();
                mMediaPlayers[index].setOnBufferingUpdateListener(this);
                mMediaPlayers[index].setOnCompletionListener(this);
                mMediaPlayers[index].setOnPreparedListener(this);
                mMediaPlayers[index].setOnVideoSizeChangedListener(this);
                mMediaPlayers[index].setAudioStreamType(AudioManager.STREAM_MUSIC);
            }
            catch (Exception e) { e.printStackTrace(); }
        }
    
        @Override protected void onPause() {
            super.onPause();
            releaseMediaPlayers();
        }
    
        @Override protected void onDestroy() {
            super.onDestroy();
            releaseMediaPlayers();
        }
    
        private void releaseMediaPlayers() {
            for (int i=0; i<mMediaPlayers.length; i++) {
                if (mMediaPlayers[i] != null) {
                    mMediaPlayers[i].release();
                    mMediaPlayers[i] = null;
                }
            }
        }
    
    
        private void startVideoPlayback(MediaPlayer player) {
            Log.v(TAG, "MediaPlayer(" + indexOf(player) + "): startVideoPlayback");
            player.start();
        }
    
        private int indexOf(MediaPlayer player) {
            for (int i=0; i<mMediaPlayers.length; i++) if (mMediaPlayers[i] == player) return i;
            return -1;  
        }
    
        private int indexOf(SurfaceHolder holder) {
            for (int i=0; i<mSurfaceHolders.length; i++) if (mSurfaceHolders[i] == holder) return i;
            return -1;  
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:orientation="vertical">
    
        <SurfaceView android:id="@+id/video_1_surfaceview"
            android:layout_width="fill_parent" android:layout_height="0dp"
            android:layout_weight="1" />
    
        <SurfaceView android:id="@+id/video_2_surfaceview"
            android:layout_width="fill_parent" android:layout_height="0dp"
            android:layout_weight="1" />
    
        <SurfaceView android:id="@+id/video_3_surfaceview"
            android:layout_width="fill_parent" android:layout_height="0dp"
            android:layout_weight="1" />
    
    </LinearLayout>
    
    public class MultipleVideoPlayFragmentActivity extends FragmentActivity {
    
        private static final String TAG = "MediaPlayer";
    
        @Override public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
            setContentView(R.layout.multi_videos_activity_layout);
        }
    
        public static class VideoFragment extends Fragment implements
            OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {
    
            private MediaPlayer mMediaPlayer;
            private SurfaceView mSurfaceView;
            private SurfaceHolder mSurfaceHolder;
            private boolean mSizeKnown;
            private boolean mVideoReady;
    
            @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                return inflater.inflate(R.layout.multi_videos_fragment_layout, container, false);
            }
    
            @Override public void onActivityCreated(Bundle savedInstanceState) {
                super.onActivityCreated(savedInstanceState);
                mSurfaceView = (SurfaceView) getView().findViewById(R.id.video_surfaceview);
                mSurfaceHolder = mSurfaceView.getHolder();
                mSurfaceHolder.addCallback(this);
                mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
    
            public void onBufferingUpdate(MediaPlayer player, int percent) {
                Log.d(TAG, "onBufferingUpdate percent: " + percent);
            }
    
            public void onCompletion(MediaPlayer player) {
                Log.d(TAG, "onCompletion called");
            }
    
            public void onVideoSizeChanged(MediaPlayer player, int width, int height) {
                Log.v(TAG, "onVideoSizeChanged called");
                if (width == 0 || height == 0) {
                    Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
                    return;
                }
    
                mSizeKnown = true;
                if (mVideoReady && mSizeKnown) {
                    startVideoPlayback();
                }
            }
    
            public void onPrepared(MediaPlayer player) {
                Log.d(TAG, "onPrepared called");
    
                mVideoReady = true;
                if (mVideoReady && mSizeKnown) {
                    startVideoPlayback();
                }
            }
    
            public void surfaceChanged(SurfaceHolder holder, int i, int j, int k) {
                Log.d(TAG, "surfaceChanged called");
            }
    
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.d(TAG, "surfaceDestroyed called");
            }
    
            public void surfaceCreated(SurfaceHolder holder) {
                Log.d(TAG, "surfaceCreated called");
    
                try { 
                    mMediaPlayer = new MediaPlayer();
                    AssetFileDescriptor afd = getActivity().getAssets().openFd("sample.3gp");
                    mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
                    mMediaPlayer.setDisplay(mSurfaceHolder);
                    mMediaPlayer.prepare();
                    mMediaPlayer.setOnBufferingUpdateListener(this);
                    mMediaPlayer.setOnCompletionListener(this);
                    mMediaPlayer.setOnPreparedListener(this);
                    mMediaPlayer.setOnVideoSizeChangedListener(this);
                    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                }
                catch (Exception e) { e.printStackTrace(); }
            }
    
            @Override public void onPause() {
                super.onPause();
                releaseMediaPlayer();
            }
    
            @Override public void onDestroy() {
                super.onDestroy();
                releaseMediaPlayer();
            }
    
            private void releaseMediaPlayer() {
                if (mMediaPlayer != null) {
                    mMediaPlayer.release();
                    mMediaPlayer = null;
                }
            }
    
            private void startVideoPlayback() {
                Log.v(TAG, "startVideoPlayback");
                mMediaPlayer.start();
            }
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:orientation="vertical">
    
        <fragment class="mh.so.video.MultipleVideoPlayFragmentActivity$VideoFragment"
            android:id="@+id/video_1_fragment" android:layout_width="fill_parent"
            android:layout_height="0dp" android:layout_weight="1" />
    
        <fragment class="mh.so.video.MultipleVideoPlayFragmentActivity$VideoFragment"
            android:id="@+id/video_2_fragment" android:layout_width="fill_parent"
            android:layout_height="0dp" android:layout_weight="1" />
    
        <fragment class="mh.so.video.MultipleVideoPlayFragmentActivity$VideoFragment"
            android:id="@+id/video_3_fragment" android:layout_width="fill_parent"
            android:layout_height="0dp" android:layout_weight="1" />
    
    </LinearLayout>
    
    <?xml version="1.0" encoding="utf-8"?>
    <SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/video_surfaceview" android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
    
    R.layout.多视频活动布局:

    public class MultipleVideoPlayActivity extends Activity implements
        OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {
    
        private static final String TAG = "MediaPlayer";
        private static final int[] SURFACE_RES_IDS = { R.id.video_1_surfaceview, R.id.video_2_surfaceview, R.id.video_3_surfaceview };
    
        private MediaPlayer[] mMediaPlayers = new MediaPlayer[SURFACE_RES_IDS.length];
        private SurfaceView[] mSurfaceViews = new SurfaceView[SURFACE_RES_IDS.length];
        private SurfaceHolder[] mSurfaceHolders = new SurfaceHolder[SURFACE_RES_IDS.length];
        private boolean[] mSizeKnown = new boolean[SURFACE_RES_IDS.length];
        private boolean[] mVideoReady = new boolean[SURFACE_RES_IDS.length];
    
        @Override public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
            setContentView(R.layout.multi_videos_layout);
    
            // create surface holders
            for (int i=0; i<mSurfaceViews.length; i++) {
                mSurfaceViews[i] = (SurfaceView) findViewById(SURFACE_RES_IDS[i]);
                mSurfaceHolders[i] = mSurfaceViews[i].getHolder();
                mSurfaceHolders[i].addCallback(this);
                mSurfaceHolders[i].setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
        }
    
        public void onBufferingUpdate(MediaPlayer player, int percent) {
            Log.d(TAG, "MediaPlayer(" + indexOf(player) + "): onBufferingUpdate percent: " + percent);
        }
    
        public void onCompletion(MediaPlayer player) {
            Log.d(TAG, "MediaPlayer(" + indexOf(player) + "): onCompletion called");
        }
    
        public void onVideoSizeChanged(MediaPlayer player, int width, int height) {
            Log.v(TAG, "MediaPlayer(" + indexOf(player) + "): onVideoSizeChanged called");
            if (width == 0 || height == 0) {
                Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
                return;
            }
    
            int index = indexOf(player);
            if (index == -1) return; // sanity check; should never happen
            mSizeKnown[index] = true;
            if (mVideoReady[index] && mSizeKnown[index]) {
                startVideoPlayback(player);
            }
        }
    
        public void onPrepared(MediaPlayer player) {
            Log.d(TAG, "MediaPlayer(" + indexOf(player) + "): onPrepared called");
    
            int index = indexOf(player);
            if (index == -1) return; // sanity check; should never happen
            mVideoReady[index] = true;
            if (mVideoReady[index] && mSizeKnown[index]) {
                startVideoPlayback(player);
            }
        }
    
        public void surfaceChanged(SurfaceHolder holder, int i, int j, int k) {
            Log.d(TAG, "SurfaceHolder(" + indexOf(holder) + "): surfaceChanged called");
        }
    
        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.d(TAG, "SurfaceHolder(" + indexOf(holder) + "): surfaceDestroyed called");
        }
    
    
        public void surfaceCreated(SurfaceHolder holder) {
            Log.d(TAG, "SurfaceHolder(" + indexOf(holder) + "): surfaceCreated called");
    
            int index = indexOf(holder);
            if (index == -1) return; // sanity check; should never happen
            try { 
                mMediaPlayers[index] = new MediaPlayer();
                AssetFileDescriptor afd = getAssets().openFd("sample.3gp");
                mMediaPlayers[index].setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
                mMediaPlayers[index].setDisplay(mSurfaceHolders[index]);
                mMediaPlayers[index].prepare();
                mMediaPlayers[index].setOnBufferingUpdateListener(this);
                mMediaPlayers[index].setOnCompletionListener(this);
                mMediaPlayers[index].setOnPreparedListener(this);
                mMediaPlayers[index].setOnVideoSizeChangedListener(this);
                mMediaPlayers[index].setAudioStreamType(AudioManager.STREAM_MUSIC);
            }
            catch (Exception e) { e.printStackTrace(); }
        }
    
        @Override protected void onPause() {
            super.onPause();
            releaseMediaPlayers();
        }
    
        @Override protected void onDestroy() {
            super.onDestroy();
            releaseMediaPlayers();
        }
    
        private void releaseMediaPlayers() {
            for (int i=0; i<mMediaPlayers.length; i++) {
                if (mMediaPlayers[i] != null) {
                    mMediaPlayers[i].release();
                    mMediaPlayers[i] = null;
                }
            }
        }
    
    
        private void startVideoPlayback(MediaPlayer player) {
            Log.v(TAG, "MediaPlayer(" + indexOf(player) + "): startVideoPlayback");
            player.start();
        }
    
        private int indexOf(MediaPlayer player) {
            for (int i=0; i<mMediaPlayers.length; i++) if (mMediaPlayers[i] == player) return i;
            return -1;  
        }
    
        private int indexOf(SurfaceHolder holder) {
            for (int i=0; i<mSurfaceHolders.length; i++) if (mSurfaceHolders[i] == holder) return i;
            return -1;  
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:orientation="vertical">
    
        <SurfaceView android:id="@+id/video_1_surfaceview"
            android:layout_width="fill_parent" android:layout_height="0dp"
            android:layout_weight="1" />
    
        <SurfaceView android:id="@+id/video_2_surfaceview"
            android:layout_width="fill_parent" android:layout_height="0dp"
            android:layout_weight="1" />
    
        <SurfaceView android:id="@+id/video_3_surfaceview"
            android:layout_width="fill_parent" android:layout_height="0dp"
            android:layout_weight="1" />
    
    </LinearLayout>
    
    public class MultipleVideoPlayFragmentActivity extends FragmentActivity {
    
        private static final String TAG = "MediaPlayer";
    
        @Override public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
            setContentView(R.layout.multi_videos_activity_layout);
        }
    
        public static class VideoFragment extends Fragment implements
            OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {
    
            private MediaPlayer mMediaPlayer;
            private SurfaceView mSurfaceView;
            private SurfaceHolder mSurfaceHolder;
            private boolean mSizeKnown;
            private boolean mVideoReady;
    
            @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                return inflater.inflate(R.layout.multi_videos_fragment_layout, container, false);
            }
    
            @Override public void onActivityCreated(Bundle savedInstanceState) {
                super.onActivityCreated(savedInstanceState);
                mSurfaceView = (SurfaceView) getView().findViewById(R.id.video_surfaceview);
                mSurfaceHolder = mSurfaceView.getHolder();
                mSurfaceHolder.addCallback(this);
                mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
    
            public void onBufferingUpdate(MediaPlayer player, int percent) {
                Log.d(TAG, "onBufferingUpdate percent: " + percent);
            }
    
            public void onCompletion(MediaPlayer player) {
                Log.d(TAG, "onCompletion called");
            }
    
            public void onVideoSizeChanged(MediaPlayer player, int width, int height) {
                Log.v(TAG, "onVideoSizeChanged called");
                if (width == 0 || height == 0) {
                    Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
                    return;
                }
    
                mSizeKnown = true;
                if (mVideoReady && mSizeKnown) {
                    startVideoPlayback();
                }
            }
    
            public void onPrepared(MediaPlayer player) {
                Log.d(TAG, "onPrepared called");
    
                mVideoReady = true;
                if (mVideoReady && mSizeKnown) {
                    startVideoPlayback();
                }
            }
    
            public void surfaceChanged(SurfaceHolder holder, int i, int j, int k) {
                Log.d(TAG, "surfaceChanged called");
            }
    
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.d(TAG, "surfaceDestroyed called");
            }
    
            public void surfaceCreated(SurfaceHolder holder) {
                Log.d(TAG, "surfaceCreated called");
    
                try { 
                    mMediaPlayer = new MediaPlayer();
                    AssetFileDescriptor afd = getActivity().getAssets().openFd("sample.3gp");
                    mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
                    mMediaPlayer.setDisplay(mSurfaceHolder);
                    mMediaPlayer.prepare();
                    mMediaPlayer.setOnBufferingUpdateListener(this);
                    mMediaPlayer.setOnCompletionListener(this);
                    mMediaPlayer.setOnPreparedListener(this);
                    mMediaPlayer.setOnVideoSizeChangedListener(this);
                    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                }
                catch (Exception e) { e.printStackTrace(); }
            }
    
            @Override public void onPause() {
                super.onPause();
                releaseMediaPlayer();
            }
    
            @Override public void onDestroy() {
                super.onDestroy();
                releaseMediaPlayer();
            }
    
            private void releaseMediaPlayer() {
                if (mMediaPlayer != null) {
                    mMediaPlayer.release();
                    mMediaPlayer = null;
                }
            }
    
            private void startVideoPlayback() {
                Log.v(TAG, "startVideoPlayback");
                mMediaPlayer.start();
            }
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:orientation="vertical">
    
        <fragment class="mh.so.video.MultipleVideoPlayFragmentActivity$VideoFragment"
            android:id="@+id/video_1_fragment" android:layout_width="fill_parent"
            android:layout_height="0dp" android:layout_weight="1" />
    
        <fragment class="mh.so.video.MultipleVideoPlayFragmentActivity$VideoFragment"
            android:id="@+id/video_2_fragment" android:layout_width="fill_parent"
            android:layout_height="0dp" android:layout_weight="1" />
    
        <fragment class="mh.so.video.MultipleVideoPlayFragmentActivity$VideoFragment"
            android:id="@+id/video_3_fragment" android:layout_width="fill_parent"
            android:layout_height="0dp" android:layout_weight="1" />
    
    </LinearLayout>
    
    <?xml version="1.0" encoding="utf-8"?>
    <SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/video_surfaceview" android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
    
    
    
    R.layout.多视频片段布局:

    public class MultipleVideoPlayActivity extends Activity implements
        OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {
    
        private static final String TAG = "MediaPlayer";
        private static final int[] SURFACE_RES_IDS = { R.id.video_1_surfaceview, R.id.video_2_surfaceview, R.id.video_3_surfaceview };
    
        private MediaPlayer[] mMediaPlayers = new MediaPlayer[SURFACE_RES_IDS.length];
        private SurfaceView[] mSurfaceViews = new SurfaceView[SURFACE_RES_IDS.length];
        private SurfaceHolder[] mSurfaceHolders = new SurfaceHolder[SURFACE_RES_IDS.length];
        private boolean[] mSizeKnown = new boolean[SURFACE_RES_IDS.length];
        private boolean[] mVideoReady = new boolean[SURFACE_RES_IDS.length];
    
        @Override public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
            setContentView(R.layout.multi_videos_layout);
    
            // create surface holders
            for (int i=0; i<mSurfaceViews.length; i++) {
                mSurfaceViews[i] = (SurfaceView) findViewById(SURFACE_RES_IDS[i]);
                mSurfaceHolders[i] = mSurfaceViews[i].getHolder();
                mSurfaceHolders[i].addCallback(this);
                mSurfaceHolders[i].setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
        }
    
        public void onBufferingUpdate(MediaPlayer player, int percent) {
            Log.d(TAG, "MediaPlayer(" + indexOf(player) + "): onBufferingUpdate percent: " + percent);
        }
    
        public void onCompletion(MediaPlayer player) {
            Log.d(TAG, "MediaPlayer(" + indexOf(player) + "): onCompletion called");
        }
    
        public void onVideoSizeChanged(MediaPlayer player, int width, int height) {
            Log.v(TAG, "MediaPlayer(" + indexOf(player) + "): onVideoSizeChanged called");
            if (width == 0 || height == 0) {
                Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
                return;
            }
    
            int index = indexOf(player);
            if (index == -1) return; // sanity check; should never happen
            mSizeKnown[index] = true;
            if (mVideoReady[index] && mSizeKnown[index]) {
                startVideoPlayback(player);
            }
        }
    
        public void onPrepared(MediaPlayer player) {
            Log.d(TAG, "MediaPlayer(" + indexOf(player) + "): onPrepared called");
    
            int index = indexOf(player);
            if (index == -1) return; // sanity check; should never happen
            mVideoReady[index] = true;
            if (mVideoReady[index] && mSizeKnown[index]) {
                startVideoPlayback(player);
            }
        }
    
        public void surfaceChanged(SurfaceHolder holder, int i, int j, int k) {
            Log.d(TAG, "SurfaceHolder(" + indexOf(holder) + "): surfaceChanged called");
        }
    
        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.d(TAG, "SurfaceHolder(" + indexOf(holder) + "): surfaceDestroyed called");
        }
    
    
        public void surfaceCreated(SurfaceHolder holder) {
            Log.d(TAG, "SurfaceHolder(" + indexOf(holder) + "): surfaceCreated called");
    
            int index = indexOf(holder);
            if (index == -1) return; // sanity check; should never happen
            try { 
                mMediaPlayers[index] = new MediaPlayer();
                AssetFileDescriptor afd = getAssets().openFd("sample.3gp");
                mMediaPlayers[index].setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
                mMediaPlayers[index].setDisplay(mSurfaceHolders[index]);
                mMediaPlayers[index].prepare();
                mMediaPlayers[index].setOnBufferingUpdateListener(this);
                mMediaPlayers[index].setOnCompletionListener(this);
                mMediaPlayers[index].setOnPreparedListener(this);
                mMediaPlayers[index].setOnVideoSizeChangedListener(this);
                mMediaPlayers[index].setAudioStreamType(AudioManager.STREAM_MUSIC);
            }
            catch (Exception e) { e.printStackTrace(); }
        }
    
        @Override protected void onPause() {
            super.onPause();
            releaseMediaPlayers();
        }
    
        @Override protected void onDestroy() {
            super.onDestroy();
            releaseMediaPlayers();
        }
    
        private void releaseMediaPlayers() {
            for (int i=0; i<mMediaPlayers.length; i++) {
                if (mMediaPlayers[i] != null) {
                    mMediaPlayers[i].release();
                    mMediaPlayers[i] = null;
                }
            }
        }
    
    
        private void startVideoPlayback(MediaPlayer player) {
            Log.v(TAG, "MediaPlayer(" + indexOf(player) + "): startVideoPlayback");
            player.start();
        }
    
        private int indexOf(MediaPlayer player) {
            for (int i=0; i<mMediaPlayers.length; i++) if (mMediaPlayers[i] == player) return i;
            return -1;  
        }
    
        private int indexOf(SurfaceHolder holder) {
            for (int i=0; i<mSurfaceHolders.length; i++) if (mSurfaceHolders[i] == holder) return i;
            return -1;  
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:orientation="vertical">
    
        <SurfaceView android:id="@+id/video_1_surfaceview"
            android:layout_width="fill_parent" android:layout_height="0dp"
            android:layout_weight="1" />
    
        <SurfaceView android:id="@+id/video_2_surfaceview"
            android:layout_width="fill_parent" android:layout_height="0dp"
            android:layout_weight="1" />
    
        <SurfaceView android:id="@+id/video_3_surfaceview"
            android:layout_width="fill_parent" android:layout_height="0dp"
            android:layout_weight="1" />
    
    </LinearLayout>
    
    public class MultipleVideoPlayFragmentActivity extends FragmentActivity {
    
        private static final String TAG = "MediaPlayer";
    
        @Override public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
            setContentView(R.layout.multi_videos_activity_layout);
        }
    
        public static class VideoFragment extends Fragment implements
            OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {
    
            private MediaPlayer mMediaPlayer;
            private SurfaceView mSurfaceView;
            private SurfaceHolder mSurfaceHolder;
            private boolean mSizeKnown;
            private boolean mVideoReady;
    
            @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                return inflater.inflate(R.layout.multi_videos_fragment_layout, container, false);
            }
    
            @Override public void onActivityCreated(Bundle savedInstanceState) {
                super.onActivityCreated(savedInstanceState);
                mSurfaceView = (SurfaceView) getView().findViewById(R.id.video_surfaceview);
                mSurfaceHolder = mSurfaceView.getHolder();
                mSurfaceHolder.addCallback(this);
                mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
    
            public void onBufferingUpdate(MediaPlayer player, int percent) {
                Log.d(TAG, "onBufferingUpdate percent: " + percent);
            }
    
            public void onCompletion(MediaPlayer player) {
                Log.d(TAG, "onCompletion called");
            }
    
            public void onVideoSizeChanged(MediaPlayer player, int width, int height) {
                Log.v(TAG, "onVideoSizeChanged called");
                if (width == 0 || height == 0) {
                    Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
                    return;
                }
    
                mSizeKnown = true;
                if (mVideoReady && mSizeKnown) {
                    startVideoPlayback();
                }
            }
    
            public void onPrepared(MediaPlayer player) {
                Log.d(TAG, "onPrepared called");
    
                mVideoReady = true;
                if (mVideoReady && mSizeKnown) {
                    startVideoPlayback();
                }
            }
    
            public void surfaceChanged(SurfaceHolder holder, int i, int j, int k) {
                Log.d(TAG, "surfaceChanged called");
            }
    
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.d(TAG, "surfaceDestroyed called");
            }
    
            public void surfaceCreated(SurfaceHolder holder) {
                Log.d(TAG, "surfaceCreated called");
    
                try { 
                    mMediaPlayer = new MediaPlayer();
                    AssetFileDescriptor afd = getActivity().getAssets().openFd("sample.3gp");
                    mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
                    mMediaPlayer.setDisplay(mSurfaceHolder);
                    mMediaPlayer.prepare();
                    mMediaPlayer.setOnBufferingUpdateListener(this);
                    mMediaPlayer.setOnCompletionListener(this);
                    mMediaPlayer.setOnPreparedListener(this);
                    mMediaPlayer.setOnVideoSizeChangedListener(this);
                    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                }
                catch (Exception e) { e.printStackTrace(); }
            }
    
            @Override public void onPause() {
                super.onPause();
                releaseMediaPlayer();
            }
    
            @Override public void onDestroy() {
                super.onDestroy();
                releaseMediaPlayer();
            }
    
            private void releaseMediaPlayer() {
                if (mMediaPlayer != null) {
                    mMediaPlayer.release();
                    mMediaPlayer = null;
                }
            }
    
            private void startVideoPlayback() {
                Log.v(TAG, "startVideoPlayback");
                mMediaPlayer.start();
            }
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:orientation="vertical">
    
        <fragment class="mh.so.video.MultipleVideoPlayFragmentActivity$VideoFragment"
            android:id="@+id/video_1_fragment" android:layout_width="fill_parent"
            android:layout_height="0dp" android:layout_weight="1" />
    
        <fragment class="mh.so.video.MultipleVideoPlayFragmentActivity$VideoFragment"
            android:id="@+id/video_2_fragment" android:layout_width="fill_parent"
            android:layout_height="0dp" android:layout_weight="1" />
    
        <fragment class="mh.so.video.MultipleVideoPlayFragmentActivity$VideoFragment"
            android:id="@+id/video_3_fragment" android:layout_width="fill_parent"
            android:layout_height="0dp" android:layout_weight="1" />
    
    </LinearLayout>
    
    <?xml version="1.0" encoding="utf-8"?>
    <SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/video_surfaceview" android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
    
    
    

    更新:虽然它已经存在了一段时间,但我认为值得指出的是,谷歌展示了一项功能,“将两个视频流同时解码为两个TextureView。”。不确定它扩展到两个以上视频文件的效果如何,但与原始问题相关。

    试试这个

    public class CustomPictureActivity extends Activity {
    /** Called when the activity is first created. */
    VideoView vd1,vd2;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        vd1=(VideoView) findViewById(R.id.v1);
        vd2=(VideoView) findViewById(R.id.v2);
        vd1.setVideoURI(Uri.parse("/mnt/sdcard/file.mp4"));
        vd1.setMediaController(new MediaController(this));
        vd1.requestFocus();
        vd1.start();
    
        vd2.setVideoURI(Uri.parse("/mnt/sdcard/android.mp4"));
        vd2.setMediaController(new MediaController(this));
        vd2.requestFocus();
        vd2.start();
    }
    
    }

    xml应该是这样的

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >
    
    <VideoView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.5" 
        android:id="@+id/v1"/>
    
    <VideoView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.5" 
        android:id="@+id/v2"/>
    
    </LinearLayout>
    

    我找到了一个解决方案。只需将/system/build.prop替换为以下build.prop-

    建筑道具

    # begin build properties
    # autogenerated by buildinfo.sh
    ro.build.id=GINGERBREAD
    ro.build.display.id=GINGERBREAD.EG14
    ro.build.version.incremental=EG14
    ro.build.version.sdk=10
    ro.build.version.codename=REL
    ro.build.version.release=2.3.4
    ro.build.date=Thu Jul 14 12:16:01 KST 2011
    ro.build.date.utc=1310613361
    ro.build.type=user
    ro.build.user=se.infra
    ro.build.host=SEI-28
    ro.build.tags=release-keys
    ro.product.model=SHW-M250S
    ro.product.brand=samsung
    ro.product.name=SHW-M250S
    ro.product.device=SHW-M250S
    ro.product.board=SHW-M250S
    ro.product.cpu.abi=armeabi-v7a
    # Samsung Specific Properties
    ro.build.PDA=M250S.EG14.1208
    ro.build.hidden_ver=M250S.EG14.1208
    ro.b uild.changelist=380592
    ro.product.cpu.abi2=armeabi
    ro.product.manufacturer=samsung
    ro.product.locale.language=ko
    ro.product.locale.region=KR
    ro.wifi.channels=
    ro.board.platform=s5pc210
    # ro.build.product is obsolete; use ro.product.device
    ro.build.product=SHW-M250S
    # Do not try to parse ro.build.description or .fingerprint
    ro.build.description=SHW-M250S-user 2.3.4 GINGERBREAD EG14 release-keys
    ro.build.fingerprint=samsung/SHW-M250S/SHW-M250S:2.3.4/GINGERBREAD/EG14:user/release-keys
    # Samsung Specific Properties
    ro.build.PDA=M250S.EG14.1208
    ro.build.hidden_ver=M250S.EG14.1208
    ro.build.changelist=380592
    ro.build.fota_ver=SSNT11GINGEREG14
    ro.tether.denied=false
    ro.flash.resolution=1080
    # end build properties
    #
    # system.prop for asop5000
    #
    
    rild.libpath=/system/lib/libsec-ril.so
    rild.libargs=-d /dev/ttyS0
    ro.sf.lcd_density=240
    dalvik.vm.heapsize=64m
    
    # Samsung USB default mode
    persist.service.usb.setting=2
    
    #
    # ADDITIONAL_BUILD_PROPERTIES
    #
    ro.setupwizard.mode=OPTIONAL
    ro.com.google.gmsversion=2.3_r4
    media.stagefright.enable-player=true
    media.stagefright.enable-meta=true
    media.stagefright.enable-scan=true
    media.stagefright.enable-http=true
    media.stagefright.enable-rtsp=true
    ro.com.google.clientidbase=android-samsung
    ro.com.google.clientidbase.ms=android-skt-kr
    ro.com.google.clientidbase.am=android-skt-kr
    ro.com.google.clientidbase.gmm=android-samsung
    ro.com.google.clientidbase.yt=android-samsung
    ro.url.legal=http://www.google.com/intl/%s/mobile/android/basic/phone-legal.html
    ro.url.legal.android_privacy=http://www.google.com/intl/%s/mobile/android/basic/privacy.html
    ro.com.google.locationfeatures=1
    keyguard.no_require_sim=true
    ro.config.ringtone=Over_the_horizon.ogg
    ro.config.notification_sound=Sherbet.ogg
    ro.config.alarm_alert=Good_Morning.ogg
    ro.config.media_sound=Over_the_horizon.ogg
    ro.opengles.version=131072
    ro.csc.sales_code=MSK
    ro.secdevenc=true
    ro.wtldatapassword=true
    net.bt.name=Android
    dalvik.vm.stack-trace-file=/data/anr/traces.txt
    
    首先,将您的三星Galaxy s-II与usb连接,然后键入命令提示符以安装您的系统-

    cmd:> adb remount
    
    然后替换文件并重新启动设备-

    cmd:> adb shell
    #reboot
    
    我注意到,默认情况下,该设备使用opencore框架而不是libstagefright。opencore也有一些问题,这就是为什么中堂错误会抛出。但是libstagefright已经在android版本2.3中实现。查看build.prop文件,stagefright已禁用。这是启用libstagefright框架并确实支持libstagefright框架的最佳解决方案。您还可以播放MPEG-2TS文件,它支持同时播放多个视频文件而不会出现任何问题。
    试试看,尽情享受。

    看看这段代码,它就行了

    video1=(VideoView)findViewById(R.id.myvideoview);
        video1.setVideoURI(Uri.parse("android.resource://" +getPackageName()+ "/"+R.raw.sample));
        video1.setMediaController(new MediaController(this));
        video1.requestFocus();
    video2=(VideoView)findViewById(R.id.myvideview);
    video2.setVideoURI(Uri.parse("android.resource://" +getPackageName()+ "/"+R.raw.sample1));
    video2.setMediaController(new MediaController(this));
    video2.requestFocus();
    
    Thread view1=new Thread(new Runnable() {
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_DISPLAY);
            video1.start();
        }
    });
    
    Thread view2=new Thread(new Runnable() {
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_DISPLAY);
            video2.start();
        }
    });
    

    但这取决于您的设备是否支持多
    视频视图。如果它不支持,它会给你错误,因为
    这个视频不能播放错误(1,-110)

    是什么让你认为这是可能的?如果可能的话,如何给我一些代码步骤。如果不可能,请说明原因。因为我不能同时播放所有文件。只有一个视频可以顺利播放。请提供代码您是否在Galaxy S-II v2.3.3上试用过。我遇到了上面提到的问题。如果它取决于设备或内核版本,您能否提供一份官方文档。@SuvamRoy:不,对不起,我没有Galaxy SII可供测试。我只能向您提供我的上述实证分析。由于不同的仿真器似乎不会遇到您描述的问题,我非常确定limitati