編輯:關於Android編程
1.由於粘貼了較大的代碼,造成內容比較長,可能會花費您較長的時間。
2.項目裡面沒有做權限判斷,所以如果發現有頁面發生崩潰可能是權限沒有打開,請打開權限後再進行嘗試。
3.錄制的GIF畫質好差,真實環境很好。
主播端 : /uploadfile/2016/0919/20160919100731416.gif
游客端 : /uploadfile/2016/0919/20160919100745416.gif
從github上Android" target="_blank">https://github.com/AnyRTC/RTMPCHybirdEngine-Android下載下來,導入AS,結構如下圖所示。

MainActivity.java
RTMPCHybird.Inst().Init(getApplicationContext());
RTMPCHybird.Inst().InitEngineWithAnyrtcInfo("你的開發者ID", "liveDemo", "LslMfUyvcW8hv6NgY0n8FOWf5t1K+YWpoMzRsqwkBiE", "d6ff4b7d1b549f497a0b94cf500fd549");
以上的四個參數可以在https://www.anyrtc.io注冊開發者賬號並創建一個應用可得,如下圖所示。你可以把它放在繼承Application的onCreate()方法中。

MainActivity.java
RTMPCHttpSDK.GetLiveList(this, RTMPCHybird.Inst().GetHttpAddr(), 你的開發者ID", "liveDemo", "d6ff4b7d1b549f497a0b94cf500fd549", mRTMPCHttpCallback);
private RTMPCHttpSDK.RTMPCHttpCallback mRTMPCHttpCallback = new RTMPCHttpSDK.RTMPCHttpCallback() {
@Override
public void OnRTMPCHttpOK(String strContent) {
mRecyclerViewUtils.endRefreshing();
try {
listLive.clear();
JSONObject liveJson = new JSONObject(strContent);
JSONArray liveList = liveJson.getJSONArray("LiveList");
JSONArray memberList = liveJson.getJSONArray("LiveMembers");
for (int i = 0; i < liveList.length(); i++) {
LiveItemBean bean = new LiveItemBean();
JSONObject itemJson = new JSONObject(liveList.getString(i));
bean.setmHosterId(itemJson.getString("hosterId"));
bean.setmRtmpPullUrl(itemJson.getString("rtmp_url"));
bean.setmHlsUrl(itemJson.getString("hls_url"));
bean.setmLiveTopic(itemJson.getString("topic"));
bean.setmAnyrtcId(itemJson.getString("anyrtcId"));
bean.setmMemNumber(memberList.getInt(i));
listLive.add(bean);
}
mAdapter.setDatas(listLive);
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void OnRTMPCHttpFailed(int code) {
}
};
以上代碼可以獲取所有正在直播列表名單
RTMPUrlHelper.java
public class RTMPUrlHelper {
/**
* rtmp 推流地址
*/
public static final String RTMP_PUSH_URL = "rtmp://192.168.7.207:1935/live/%s";
/**
* rtmp 拉流地址
*/
public static final String RTMP_PULL_URL = "rtmp://192.168.7.207:1935/live/%s";
/**
* hls 地址
*/
public static final String HLS_URL = "http://192.169.7.207/live/%s.m3u8";
/**
* 分享頁面url地址
*/
public static final String SHARE_WEB_URL = "http://123.59.68.21/rtmpc-demo/?%s";
}
PreStartLiveActivity.java
String anyrtcId = RTMPCHttpSDK.getRandomString(12);
String rtmpPushUrl = String.format(RTMPUrlHelper.RTMP_PUSH_URL, anyrtcId);
String rtmpPullUrl = String.format(RTMPUrlHelper.RTMP_PULL_URL, anyrtcId);
String hlsUrl = String.format(RTMPUrlHelper.HLS_URL, anyrtcId);
JSONObject item = new JSONObject();
try {
item.put("hosterId", "hostID");
item.put("rtmp_url", rtmpPullUrl);
item.put("hls_url", hlsUrl);
item.put("topic", topic);
item.put("anyrtcId", anyrtcId);
} catch (JSONException e) {
e.printStackTrace();
}
Bundle bundle = new Bundle();
bundle.putString("hosterId", "hostID");
bundle.putString("rtmp_url", rtmpPushUrl);
bundle.putString("hls_url", hlsUrl);
bundle.putString("topic", topic);
bundle.putString("andyrtcId", anyrtcId);
bundle.putString("userData", item.toString());
Intent intent = new Intent(this, HosterActivity.class);
intent.putExtras(bundle);
startActivity(intent);
HosterActivity.java
mHosterId = getIntent().getExtras().getString("hosterId");
mRtmpPushUrl = getIntent().getExtras().getString("rtmp_url");
mAnyrtcId = getIntent().getExtras().getString("andyrtcId");
mUserData = getIntent().getExtras().getString("userData");
mHlsUrl = getIntent().getExtras().getString("hls_url");
mTopic = getIntent().getExtras().getString("topic");
這裡的R.id.rl_rtmpc_videos表示打開手機攝像頭捕獲的像呈現的地方,如下圖所示。
HosterActivity.java
mVideoView = new RTMPCVideoView((RelativeLayout) findViewById(R.id.rl_rtmpc_videos), RTMPCHybird.Inst().Egl(), true);
mVideoView.setBtnCloseEvent(mBtnVideoCloseEvent);
mHosterKit = new RTMPCHosterKit(this, mHosterListener);
{
VideoRenderer render = mVideoView.OnRtcOpenLocalRender();
mHosterKit.SetVideoCapturer(render.GetRenderPointer(), true);
}

{
// Create and audio manager that will take care of audio routing,
// audio modes, audio device enumeration etc.
mRtmpAudioManager = RTMPAudioManager.create(this, new Runnable() {
// This method will be called each time the audio state (number
// and
// type of devices) has been changed.
@Override
public void run() {
onAudioManagerChangedState();
}
});
// Store existing audio settings and change audio mode to
// MODE_IN_COMMUNICATION for best possible VoIP performance.
mRtmpAudioManager.init();
mRtmpAudioManager.setAudioDevice(RTMPAudioManager.AudioDevice.SPEAKER_PHONE);
}
mStartRtmp = true;
/**
* 開始推流
*/
mHosterKit.StartPushRtmpStream(mRtmpPushUrl);
/**
* 建立RTC連線連接
*/
mHosterKit.OpenRTCLine(mAnyrtcId, mHosterId, mUserData);
mHosterKit = new RTMPCHosterKit(this, mHosterListener);
這句代碼是主播直播的回調接口,可以做連麥、取消連麥、接收消息和彈幕消息、實時觀看人數和人員上下線等。實用的操作一般再此實行。
HosterActivity.java
/**
* 主播回調信息接口
*/
private RTMPCAbstractHoster mHosterListener = new RTMPCAbstractHoster() {
/**
* rtmp連接成功
*/
@Override
public void OnRtmpStreamOKCallback() {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
((TextView) findViewById(R.id.txt_rtmp_connection_status)).setText(R.string.str_rtmp_connect_success);
}
});
}
/**
* rtmp 重連次數
* @param times 重連次數
*/
@Override
public void OnRtmpStreamReconnectingCallback(final int times) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
((TextView) findViewById(R.id.txt_rtmp_connection_status)).setText(String.format(getString(R.string.str_reconnect_times), times));
}
});
}
/**
* rtmp 推流狀態
* @param delayMs 推流延時
* @param netBand 推流碼流
*/
@Override
public void OnRtmpStreamStatusCallback(final int delayMs, final int netBand) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
((TextView) findViewById(R.id.txt_rtmp_status)).setText(String.format(getString(R.string.str_rtmp_status), delayMs, netBand));
}
});
}
/**
* rtmp推流失敗回調
* @param code
*/
@Override
public void OnRtmpStreamFailedCallback(int code) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
((TextView) findViewById(R.id.txt_rtmp_connection_status)).setTextColor(R.color.yellow);
((TextView) findViewById(R.id.txt_rtmp_connection_status)).setText(R.string.str_rtmp_connect_failed);
}
});
}
/**
* rtmp 推流關閉回調
*/
@Override
public void OnRtmpStreamClosedCallback() {
finish();
}
/**
* RTC 連接回調
* @param code 0: 連接成功
* @param strErr 原因
*/
@Override
public void OnRTCOpenLineResultCallback(final int code, String strErr) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
if (code == 0) {
((TextView) findViewById(R.id.txt_rtc_connection_status)).setText(R.string.str_rtc_connect_success);
} else {
((TextView) findViewById(R.id.txt_rtc_connection_status)).setTextColor(R.color.yellow);
((TextView) findViewById(R.id.txt_rtc_connection_status)).setText(R.string.str_rtmp_connect_failed);
}
}
});
}
/**
* 游客有申請連線回調
*
* @param strLivePeerID
* @param strCustomID
* @param strUserData
*/
@Override
public void OnRTCApplyToLineCallback(final String strLivePeerID, final String strCustomID, final String strUserData) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
ShowDialog(HosterActivity.this, strLivePeerID, strCustomID);
}
});
}
/**
* 視頻連線超過4人時回調
* @param strLivePeerID
* @param strCustomID
* @param strUserData
*/
@Override
public void OnRTCLineFullCallback(final String strLivePeerID, String strCustomID, String strUserData) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(HosterActivity.this, getString(R.string.str_connect_full), Toast.LENGTH_LONG).show();
mHosterKit.RejectRTCLine(strLivePeerID, true);
}
});
}
/**
* 游客掛斷連線回調
* @param strLivePeerID
*/
@Override
public void OnRTCCancelLineCallback(String strLivePeerID) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(HosterActivity.this, getString(R.string.str_line_disconnect), Toast.LENGTH_LONG).show();
}
});
}
/**
* RTC 連接關閉回調
* @param code 207:請去AnyRTC官網申請賬號,如有疑問請聯系客服!
* @param strReason
*/
@Override
public void OnRTCLineClosedCallback(final int code, String strReason) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
if (code == 207) {
Toast.makeText(HosterActivity.this, getString(R.string.str_apply_anyrtc_account), Toast.LENGTH_LONG).show();
finish();
}
}
});
}
/**
* 連線接通時的視頻圖像回調;
* @param strLivePeerID
*/
@Override
public void OnRTCOpenVideoRenderCallback(final String strLivePeerID) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
final VideoRenderer render = mVideoView.OnRtcOpenRemoteRender(strLivePeerID);
if (null != render) {
mHosterKit.SetRTCVideoRender(strLivePeerID, render.GetRenderPointer());
}
}
});
}
/**
* 連線關閉時的視頻圖像回調;
* @param strLivePeerID
*/
@Override
public void OnRTCCloseVideoRenderCallback(final String strLivePeerID) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
mHosterKit.SetRTCVideoRender(strLivePeerID, 0);
mVideoView.OnRtcRemoveRemoteRender(strLivePeerID);
}
});
}
/**
* 消息回調
* @param strCustomID 消息的發送者id
* @param strCustomName 消息的發送者昵稱
* @param strCustomHeader 消息的發送者頭像url
* @param strMessage 消息內容
*/
@Override
public void OnRTCUserMessageCallback(final String strCustomID, final String strCustomName, final String strCustomHeader, final String strMessage) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
addChatMessageList(new ChatMessageBean(strCustomID, strCustomName, "", strMessage));
}
});
}
/**
* 彈幕回調
* @param strCustomID 彈幕的發送者id
* @param strCustomName 彈幕的發送者昵稱
* @param strCustomHeader 彈幕的發送者頭像url
* @param strBarrage 彈幕的內容
*/
@Override
public void OnRTCUserBarrageCallback(final String strCustomID, final String strCustomName, final String strCustomHeader, final String strBarrage) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
addChatMessageList(new ChatMessageBean(strCustomID, strCustomName, "", strBarrage));
IDanmakuItem item = new DanmakuItem(HosterActivity.this, new SpannableString(strBarrage), mDanmakuView.getWidth(), 0, R.color.yellow_normol, 18, 1);
mDanmakuView.addItemToHead(item);
}
});
}
/**
* 直播觀看總人數回調
* @param totalMembers 觀看總人數
*/
@Override
public void OnRTCMemberListWillUpdateCallback(final int totalMembers) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
((TextView) findViewById(R.id.txt_watcher_number)).setText(String.format(getString(R.string.str_live_watcher_number), totalMembers));
}
});
}
/**
* 人員上下線回調
* @param strCustomID
* @param strUserData
*/
@Override
public void OnRTCMemberCallback(final String strCustomID, final String strUserData) {
HosterActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
JSONObject userData = new JSONObject(strUserData);
addChatMessageList(new ChatMessageBean(userData.getString("nickName"), "", userData.getString("headUrl"), ""));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
@Override
public void OnRTCMemberListUpdateDoneCallback() {
}
};
接下來就要說對應這些回調的方法了,這裡可以做關閉直播、直播分享、切換攝像頭和發送消息。
HosterActivity.java
public void OnBtnClicked(View btn) {
if (btn.getId() == R.id.btn_close) {
mStartRtmp = false;
mHosterKit.StopRtmpStream();
finish();
} else if (btn.getId() == R.id.btn_copy_hls) {
int index = mHlsUrl.lastIndexOf("/");
int lastIndex = mHlsUrl.lastIndexOf(".");
String shareUrl = String.format(RTMPUrlHelper.SHARE_WEB_URL, mHlsUrl.substring(index + 1, lastIndex));
mShareHelper.shareWeiXin(mTopic, shareUrl);
} else if (btn.getId() == R.id.btn_switch_camera) {
mHosterKit.SwitchCamera();
} else if (btn.getId() == R.id.btn_send_message) {
String message = editMessage.getText().toString();
editMessage.setText("");
if (message.equals("")) {
return;
}
if (mCheckBarrage.isChecked()) {
mHosterKit.SendBarrage(mNickname, "", message);
IDanmakuItem item = new DanmakuItem(HosterActivity.this, new SpannableString(message), mDanmakuView.getWidth(), 0, R.color.yellow_normol, 18, 1);
mDanmakuView.addItemToHead(item);
} else {
mHosterKit.SendUserMsg(mNickname, "", message);
}
addChatMessageList(new ChatMessageBean(mNickname, mNickname, "", message));
} else if (btn.getId() == R.id.iv_host_text) {
btnChat.clearFocus();
vaBottomBar.setDisplayedChild(1);
editMessage.requestFocus();
softKeyboardUtil.showKeyboard(HosterActivity.this, editMessage);
}
}
MainActivity.java
@Override
public void onItemChildClick(ViewGroup viewGroup, View view, int i) {
Intent it = new Intent(this, GuestActivity.class);
Bundle bundle = new Bundle();
bundle.putString("hls_url", listLive.get(i).getmHlsUrl());
bundle.putString("rtmp_url", listLive.get(i).getmRtmpPullUrl());
bundle.putString("anyrtcId", listLive.get(i).getmAnyrtcId());
bundle.putString("userData", new JSONObject().toString());
bundle.putString("topic", listLive.get(i).getmLiveTopic());
it.putExtras(bundle);
startActivity(it);
}
與主播端一樣,拿上個Activity傳過來的數據,其實這裡代碼與主播端的代碼基本上可以說是一模一樣,看完之後你應該會有我這樣的體會。
GuestActivity.java
mNickname = ((HybirdApplication)HybirdApplication.app()).getmNickname();
mRtmpPullUrl = getIntent().getExtras().getString("rtmp_url");
mAnyrtcId = getIntent().getExtras().getString("anyrtcId");
mHlsUrl = getIntent().getExtras().getString("hls_url");
mGuestId = mNickname;//getIntent().getExtras().getString("guestId");
mTopic = getIntent().getExtras().getString("topic");
mVideoView = new RTMPCVideoView((RelativeLayout) findViewById(R.id.rl_rtmpc_videos), RTMPCHybird.Inst().Egl(), false);
mVideoView.setBtnCloseEvent(mBtnVideoCloseEvent);
/**
* 初始化rtmp播放器
*/
mGuestKit = new RTMPCGuestKit(this, mGuestListener);
VideoRenderer render = mVideoView.OnRtcOpenLocalRender();
{
// Create and audio manager that will take care of audio routing,
// audio modes, audio device enumeration etc.
mRtmpAudioManager = RTMPAudioManager.create(this, new Runnable() {
// This method will be called each time the audio state (number
// and
// type of devices) has been changed.
@Override
public void run() {
onAudioManagerChangedState();
}
});
// Store existing audio settings and change audio mode to
// MODE_IN_COMMUNICATION for best possible VoIP performance.
mRtmpAudioManager.init();
mRtmpAudioManager.setAudioDevice(RTMPAudioManager.AudioDevice.SPEAKER_PHONE);
}
mUserData = new JSONObject();
try {
mUserData.put("nickName", mNickname);
mUserData.put("headUrl", "");
} catch (JSONException e) {
e.printStackTrace();
}
/**
* 開始播放rtmp流
*/
mGuestKit.StartRtmpPlay(mRtmpPullUrl, render.GetRenderPointer());
/**
* 開啟RTC連線連接
*/
mGuestKit.JoinRTCLine(mAnyrtcId, mGuestId, mUserData.toString());
mGuestKit = new RTMPCGuestKit(this, mGuestListener);
這句代碼是觀看直播的回調接口,可以做申請連麥、斷開連麥、接收消息和彈幕消息、實時觀看人數和人員上下線等。實用的操作一般再此實行。
GuestActivity.java
/**
* 觀看直播回調信息接口
*/
private RTMPCAbstractGuest mGuestListener = new RTMPCAbstractGuest() {
/**
* rtmp 連接成功
*/
@Override
public void OnRtmplayerOKCallback() {
}
/**
* rtmp 當前播放狀態
* @param cacheTime 當前緩存時間
* @param curBitrate 當前播放器碼流
*/
@Override
public void OnRtmplayerStatusCallback(int cacheTime, int curBitrate) {
}
/**
* rtmp 播放緩沖區時長
* @param time 緩沖時間
*/
@Override
public void OnRtmplayerCacheCallback(int time) {
}
/**
* rtmp 播放器關閉
* @param errcode
*/
@Override
public void OnRtmplayerClosedCallback(int errcode) {
}
/**
* 游客RTC 狀態回調
* @param code 回調響應碼:0:正常;101:主播未開啟直播;
* @param strReason 原因描述
*/
@Override
public void OnRTCJoinLineResultCallback(final int code, String strReason) {
GuestActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
if (code == 0) {
} else if (code == 101) {
Toast.makeText(GuestActivity.this, R.string.str_hoster_not_live, Toast.LENGTH_LONG).show();
mHandler.sendEmptyMessageDelayed(CLOSED, 2000);
}
}
});
}
/**
* 游客申請連線回調
* @param code 0:申請連線成功;-1:主播拒絕連線
*/
@Override
public void OnRTCApplyLineResultCallback(final int code) {
GuestActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
if (code == 0) {
VideoRenderer render = mVideoView.OnRtcOpenRemoteRender("LocalCameraRender");
mGuestKit.SetVideoCapturer(render.GetRenderPointer(), true);
} else if (code == -1) {
Toast.makeText(GuestActivity.this, R.string.str_hoster_refused, Toast.LENGTH_LONG).show();
mStartLine = false;
mBtnConnect.setText(R.string.str_connect_hoster);
}
}
});
}
/**
* 當與主播連線成功時,其他用戶連線回調
* @param strLivePeerID
* @param strCustomID
* @param strUserData
*/
@Override
public void OnRTCOtherLineOpenCallback(String strLivePeerID, String strCustomID, String strUserData) {
}
/**
* 其他用戶連線回調
* @param strLivePeerID
*/
@Override
public void OnRTCOtherLineCloseCallback(String strLivePeerID) {
}
/**
* 掛斷連線回調
*/
@Override
public void OnRTCHangupLineCallback() {
//主播連線斷開
GuestActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
mGuestKit.HangupRTCLine();
mVideoView.OnRtcRemoveRemoteRender("LocalCameraRender");
mStartLine = false;
mBtnConnect.setText(R.string.str_connect_hoster);
}
});
}
/**
* 主播已離開回調
* @param code
* @param strReason
*/
@Override
public void OnRTCLineLeaveCallback(int code, String strReason) {
//主播關閉直播
GuestActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(GuestActivity.this, R.string.str_hoster_leave, Toast.LENGTH_LONG).show();
mHandler.sendEmptyMessageDelayed(CLOSED, 2000);
}
});
}
/**
* 連線接通後回調
* @param strLivePeerID
*/
@Override
public void OnRTCOpenVideoRenderCallback(final String strLivePeerID) {
GuestActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
final VideoRenderer render = mVideoView.OnRtcOpenRemoteRender(strLivePeerID);
mGuestKit.SetRTCVideoRender(strLivePeerID, render.GetRenderPointer());
}
});
}
/**
* 連線關閉後圖像回調
* @param strLivePeerID
*/
@Override
public void OnRTCCloseVideoRenderCallback(final String strLivePeerID) {
GuestActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
mGuestKit.SetRTCVideoRender(strLivePeerID, 0);
mVideoView.OnRtcRemoveRemoteRender(strLivePeerID);
}
});
}
/**
* 消息回調
* @param strCustomID 消息的發送者id
* @param strCustomName 消息的發送者昵稱
* @param strCustomHeader 消息的發送者頭像url
* @param strMessage 消息內容
*/
@Override
public void OnRTCUserMessageCallback(final String strCustomID, final String strCustomName, final String strCustomHeader, final String strMessage) {
GuestActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
addChatMessageList(new ChatMessageBean(strCustomID, strCustomName, "", strMessage));
}
});
}
/**
* 彈幕回調
* @param strCustomID 彈幕的發送者id
* @param strCustomName 彈幕的發送者昵稱
* @param strCustomHeader 彈幕的發送者頭像url
* @param strBarrage 彈幕的內容
*/
@Override
public void OnRTCUserBarrageCallback(final String strCustomID, final String strCustomName, final String strCustomHeader, final String strBarrage) {
GuestActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
addChatMessageList(new ChatMessageBean(strCustomID, strCustomName, "", strBarrage));
IDanmakuItem item = new DanmakuItem(GuestActivity.this, new SpannableString(strBarrage), mDanmakuView.getWidth(), 0, R.color.yellow_normol, 18, 1);
mDanmakuView.addItemToHead(item);
}
});
}
/**
* 觀看直播的總人數回調
* @param totalMembers 觀看直播的總人數
*/
@Override
public void OnRTCMemberListWillUpdateCallback(final int totalMembers) {
GuestActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
((TextView) findViewById(R.id.txt_watcher_number)).setText(String.format(getString(R.string.str_live_watcher_number), totalMembers));
}
});
}
/**
* 人員上下線回調
* @param strCustomID
* @param strUserData
*/
@Override
public void OnRTCMemberCallback(final String strCustomID, final String strUserData) {
GuestActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
JSONObject userData = new JSONObject(strUserData);
addChatMessageList(new ChatMessageBean(userData.getString("nickName"), "", userData.getString("headUrl"), ""));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
@Override
public void OnRTCMemberListUpdateDoneCallback() {
}
};
接下來就要說對應這些回調的方法了,這裡可以做直播分享、申請連麥、斷開連麥和發送消息。
GuestActivity.java
public void OnBtnClicked(View btn) {
if(btn.getId() == R.id.btn_copy_hls) {
int index = mHlsUrl.lastIndexOf("/");
int lastIndex = mHlsUrl.lastIndexOf(".");
String shareUrl = String.format(RTMPUrlHelper.SHARE_WEB_URL, mHlsUrl.substring(index + 1, lastIndex));
mShareHelper.shareWeiXin(mTopic, shareUrl);
} else if (btn.getId() == R.id.btn_line) {
if (!mStartLine) {
JSONObject json = new JSONObject();
try {
json.put("guestId", mNickname);
} catch (JSONException e) {
e.printStackTrace();
}
/**
* 向主播申請連線
*/
mGuestKit.ApplyRTCLine(json.toString());
mStartLine = true;
mBtnConnect.setText(R.string.str_hangup_connect);
} else {
/**
* 掛斷連線
*/
mGuestKit.HangupRTCLine();
mVideoView.OnRtcRemoveRemoteRender("LocalCameraRender");
mStartLine = false;
mBtnConnect.setText(R.string.str_connect_hoster);
}
} else if (btn.getId() == R.id.btn_send_message) {
String message = editMessage.getText().toString();
editMessage.setText("");
if (message.equals("")) {
return;
}
if (mCheckBarrage.isChecked()) {
mGuestKit.SendBarrage(mNickname, "", message);
IDanmakuItem item = new DanmakuItem(GuestActivity.this, new SpannableString(message), mDanmakuView.getWidth(), 0, R.color.yellow_normol, 18, 1);
mDanmakuView.addItemToHead(item);
} else {
mGuestKit.SendUserMsg(mNickname, "", message);
}
addChatMessageList(new ChatMessageBean(mNickname, mNickname, "", message));
} else if (btn.getId() == R.id.iv_host_text) {
btnChat.clearFocus();
vaBottomBar.setDisplayedChild(1);
editMessage.requestFocus();
softKeyboardUtil.showKeyboard(GuestActivity.this, editMessage);
}
}
對於這個基於Anyrtc sdk的直播RTMPCHybirdEngine-Android核心的幾個類基本上介紹完成,我在此僅僅是大概介紹了幾點,可以讓你大概了解這個SDK的直播流程,方便您快速上手。
Android系統移植 http://source.android.com/devices/index.html
移植Android到不同的設備 Android允許提供不同的硬件平台和驅動支持Android的運行。硬件抽象層(Hardware Abstraction Layer)
Android中如何利用AIDL機制調用遠程服務
在Android中,每個應用程序都有自己的進程,當需要在不同的進程之間傳遞對象時,該如何實現呢?顯然, Java中是不支持跨進程內存共享的。因此要傳遞對象,需要把
微信朋友圈氣泡大字是怎麼做的 氣泡大字生成器
微信朋友圈氣泡大字是怎麼做的?近來,在微信朋友圈裡迅速出現了一種氣泡類型的大文字動態,在朋友圈裡可是新鮮得很啊,那麼這種氣泡大字是怎麼做的?小編特地了解到氣
androidstudio的UIautomaster界面自動化測試
Android測試支持庫包含 UI自動化模塊 ,它可以對Android應用進行自動黑盒測試。在API Level 18中引入了自動化模塊,它允許開發者在組成應用UI的控件