android拉流设计,Android七牛拉流基础设置干货

private PLVideoTextureView mVideoView; //播放器

private MediaController mMediaController = null; //控制器

private int mIsLiveStreaming = 1;

private boolean mIsActivityPaused = true;

private boolean llSuccess = false; //拉流成功

/* 七牛设置 str -------------------------------------------------------*/

/**

* 设置基本七牛基本信息-->开始拉流

*/

public void startLL() {

mIsLiveStreaming = 1; // 1 = 直播 / 0 = 点播

int codec = AVOptions.MEDIA_CODEC_AUTO; //解码方式 sw = 软解 / hw = 硬解 / auto = 自动

setOptions(codec);

// You can mirror the display 预览画面反转

// mVideoView.setMirror(true);

// You can also use a custom `MediaController` widget

mMediaController = new MediaController(this, false, mIsLiveStreaming == 1);

mVideoView.setMediaController(mMediaController);

//mVideoView.setDisplayOrientation(PLVideoTextureView.ASPECT_RATIO_FIT_PARENT); //default-->ASPECT_RATIO_FIT_PARENT 画面旋转

mVideoView.setDisplayAspectRatio(PLVideoView.ASPECT_RATIO_PAVED_PARENT); //画面预览模式

mVideoView.setOnInfoListener(new PLMediaPlayer.OnInfoListener() { //播放器状态监听

@Override

public boolean onInfo(PLMediaPlayer plMediaPlayer, int i, int i1) {

switch (i) {

case PLMediaPlayer.MEDIA_INFO_UNKNOWN:

logger("未知消息");

break;

case PLMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START: //加载成功,正在播放

logger("第一帧视频已成功渲染");

llSuccess = true;

break;

case PLMediaPlayer.MEDIA_INFO_BUFFERING_START:

logger("开始缓冲");

break;

case PLMediaPlayer.MEDIA_INFO_BUFFERING_END:

logger("停止缓冲");

break;

case PLMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED:

logger("获取到视频的播放角度");

break;

case PLMediaPlayer.MEDIA_INFO_AUDIO_RENDERING_START:

logger("第一帧音频已成功播放");

break;

}

return false;

}

});

mVideoView.setOnCompletionListener(new PLMediaPlayer.OnCompletionListener() { //直播结束监听

@Override

public void onCompletion(PLMediaPlayer plMediaPlayer) {

}

});

mVideoView.setOnErrorListener(new PLMediaPlayer.OnErrorListener() { //直播错误监听

@Override

public boolean onError(PLMediaPlayer plMediaPlayer, int i) {

boolean isNeedReconnect = false; //是否需要重新连接

boolean customReturn = false;

switch (i) {

case PLMediaPlayer.ERROR_CODE_INVALID_URI:

logger("Invalid URL !无效的 URL");

break;

case PLMediaPlayer.ERROR_CODE_404_NOT_FOUND:

logger("404 resource not found !播放资源不存在");

break;

case PLMediaPlayer.ERROR_CODE_CONNECTION_REFUSED:

logger("Connection refused !服务器拒绝连接");

break;

case PLMediaPlayer.ERROR_CODE_CONNECTION_TIMEOUT:

logger("Connection timeout !连接超时");

isNeedReconnect = true;

break;

case PLMediaPlayer.ERROR_CODE_EMPTY_PLAYLIST:

logger("Empty playlist !空的播放列表");

break;

case PLMediaPlayer.ERROR_CODE_STREAM_DISCONNECTED:

logger("Stream disconnected !与服务器连接断开");

isNeedReconnect = true;

break;

case PLMediaPlayer.ERROR_CODE_IO_ERROR:

logger("Network IO Error !网络异常");

isNeedReconnect = true;

break;

case PLMediaPlayer.ERROR_CODE_UNAUTHORIZED:

logger("Unauthorized Error !");

break;

case PLMediaPlayer.ERROR_CODE_PREPARE_TIMEOUT:

logger("Prepare timeout !未授权,播放一个禁播的流");

// TODO: 2017/2/16 如果主播正常断开连接,第二次及之后所有的提示将会提示这个提示

liveEnd2();

customReturn = true;

//isNeedReconnect = true;

break;

case PLMediaPlayer.ERROR_CODE_READ_FRAME_TIMEOUT:

// TODO: 2017/2/16 如果主播正常断开连接,第一次提示这个提示

logger("Read frame timeout !读取数据超时");

isNeedReconnect = true;

break;

case PLMediaPlayer.ERROR_CODE_HW_DECODE_FAILURE:

setOptions(AVOptions.MEDIA_CODEC_SW_DECODE);

isNeedReconnect = true;

break;

case PLMediaPlayer.MEDIA_ERROR_UNKNOWN:

logger("未知错误");

break;

default:

logger("unknown error !未知错误");

break;

}

// Todo pls handle the error status here, reconnect or call finish()

if (isNeedReconnect) {

sendReconnectMessage();

} else {

// TODO: 2017/3/19 直播错误,请手动重连...

if (!customReturn)

liveEnd();

}

// Return true means the error has been handled

// If return false, then `onCompletion` will be called

//如果返回true-->错误已被处理 / 返回false-->setOnCompletionListener上交给国家

return true;

}

});

mVideoView.setVideoPath(mLLAddress);

mVideoView.start();

}

/**

* 设置播放器参数

*/

private void setOptions(int codecType) {

AVOptions options = new AVOptions();

// the unit of timeout is ms

options.setInteger(AVOptions.KEY_PREPARE_TIMEOUT, 10 * 1000);

options.setInteger(AVOptions.KEY_GET_AV_FRAME_TIMEOUT, 10 * 1000);

options.setInteger(AVOptions.KEY_PROBESIZE, 128 * 1024);

// Some optimization with buffering mechanism when be set to 1

options.setInteger(AVOptions.KEY_LIVE_STREAMING, mIsLiveStreaming);

if (mIsLiveStreaming == 1) {

options.setInteger(AVOptions.KEY_DELAY_OPTIMIZATION, 1);

}

// 1 -> hw codec enable, 0 -> disable [recommended]

options.setInteger(AVOptions.KEY_MEDIACODEC, codecType);

// whether start play automatically after prepared, default value is 1

options.setInteger(AVOptions.KEY_START_ON_PREPARED, 0);

mVideoView.setAVOptions(options);

}

/**

* 发送重连消息

*/

private void sendReconnectMessage() {

showToast(getStr(R.string.reconnection));

mHandler.removeCallbacksAndMessages(null);

mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_ID_RECONNECTING), 500);

}

/**

* 重连 同时对当前流是否可用做出判断

*/

private static final int MESSAGE_ID_RECONNECTING = 0x01;

protected Handler mHandler = new Handler(Looper.getMainLooper()) {

@Override

public void handleMessage(Message msg) {

if (msg.what != MESSAGE_ID_RECONNECTING) {

return;

}

if (mIsActivityPaused) { // TODO: 2017/2/16 同时可以增加后台确认当前主播是否在直播 (暂不使用)

return;

}

if (!NetworkUtils.isAvailableByPing()) {

sendReconnectMessage();

return;

}

mVideoView.setVideoPath(mLLAddress);

mVideoView.start();

}

};

/* 七牛设置 end ---------------------------------*/

@Override

protected void onPause() {

super.onPause();

mVideoView.pause();

mIsActivityPaused = true;

}

@Override

protected void onResume() {

super.onResume();

mIsActivityPaused = false;

mVideoView.start();

}

@Override

protected void onDestroy() {

super.onDestroy();

mVideoView.stopPlayback();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值