Skip to content

MultiplePlayer

dengchu817 edited this page Jan 16, 2018 · 6 revisions

多播放器

使用场景

譬如两个主播之间连麦,主播A和主播B仍是两路独立的直播流,并且这两路流的音频是一样,为了更好的观看,我们需要将这两路流同步播放,不至于两主播之间的对话完全对不上。

多播放器的功能

创建多个播放器,将多路直播流同步播放,这些播放器中只有一个主播放器,其他都是从播放器,主播放器正常播放,从播放器会同步到主播放器,当主播放器暂停或卡顿时,从播放器也会停止播放

接口说明

退出播放时,必须先释放从播放器,最后释放主播放器

KSYMediaPlayer层接口

/**
 * 设置从播放器内的主播放器
 * @param player 主播放器
 */
public void addMasterClock(KSYMediaPlayer player);

KSYTextureView层接口

/**
 * 设置从播放器内的主播放器
 * @param videoView 主播放器
 */
public void addMasterClock(KSYTextureView videoView);

使用条件

支持版本: v2.2.0及以上版本
多播放器同步建议: 多路直播流的音频需要一致

使用示例

KSYMediaPlayer示例

首先在你的布局中添加2个SurfaceView

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <SurfaceView
            android:id="@+id/player_master"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>

        <SurfaceView
            android:id="@+id/player_slave"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>
    </LinearLayout>

初始化播放器,mMasterPlayer为主播放器,mSlavePlayer为从播放器

protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_multiple_player);

        mMasterSurfaceView = (SurfaceView) findViewById(R.id.player_master);
        mSlaveSurfaceView = (SurfaceView) findViewById(R.id.player_slave);
        initPlayers();
        initViews();
    }

 private void initPlayers() {
        mMasterPlayer = new KSYMediaPlayer.Builder(this).build();
        mSlavePlayer = new KSYMediaPlayer.Builder(this).build();
        
        mMasterPlayer.shouldAutoPlay(false);
        mMasterPlayer.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(IMediaPlayer mp) {
                if (mMasterPlayer != null)
                    mMasterPlayer.start();
            }
        });
        try {
            mMasterPlayer.setDataSource(mDataSource);
            mMasterPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }

        mSlavePlayer.shouldAutoPlay(false);
        mSlavePlayer.addMasterClock(mMasterPlayer);
        mSlavePlayer.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(IMediaPlayer mp) {
                if (mSlavePlayer != null) {
                    mSlavePlayer.start();
                    mSlavePlayer.setPlayerMute(1);
                }
            }
        });
        try {
            mSlavePlayer.setDataSource(mDataSource1);
            mSlavePlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void initViews() {
        mMasterSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {

            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
                if (mMasterPlayer != null)
                    mMasterPlayer.setSurface(surfaceHolder.getSurface());
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                if (mMasterPlayer != null)
                    mMasterPlayer.setSurface(null);
            }
        });

        mSlaveSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {

            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
                if (mSlavePlayer != null)
                    mSlavePlayer.setSurface(surfaceHolder.getSurface());
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                if (mSlavePlayer != null)
                    mSlavePlayer.setSurface(null);
            }
        });
    }

KSYTextureView示例

在你的布局中添加2个KSYTextureView

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        < KSYTextureView
            android:id="@+id/player_master"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>

        < KSYTextureView
            android:id="@+id/player_slave"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>
    </LinearLayout>

初始化播放器,mMasterVideoView为主播放器,mSlaveVideoView为从播放器

protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_multiple_player);

        mMasterVideoView = (KSYTextureView) findViewById(R.id.player_master);
        mMasterVideoView.shouldAutoPlay(false);
        mMasterVideoView.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(IMediaPlayer mp) {
                if (mMasterVideoView != null)
                   mMasterVideoView.start();
            }
        });
        try{
            mMasterVideoView.setDataSource(mDataSource);
        }catch(IOException e) {
            e.printStackTrace();
        }
        mMasterVideoView.prepareAsync();

        mSlaveVideoView = (KSYTextureView) findViewById(R.id.player_slave);
        mSlaveVideoView.shouldAutoPlay(false);
        mSlaveVideoView.getMediaPlayer().addMasterClock(mMasterVideoView.getMediaPlayer());
        mSlaveVideoView.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(IMediaPlayer mp) {
                if (mSlaveVideoView != null)
                   mSlaveVideoView.start();
            }
        });
        try{
            mSlaveVideoView.setDataSource(mDataSource1);
        }catch(IOException e) {
            e.printStackTrace();
        }
        mSlaveVideoView.prepareAsync();
    }
Clone this wiki locally