-
Notifications
You must be signed in to change notification settings - Fork 246
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及以上版本
多播放器同步建议: 多路直播流的音频需要一致
首先在你的布局中添加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);
}
});
}
在你的布局中添加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();
}