常规集成
api 'com.tencent.imsdk:imsdk-plus:5.6.1200'
ndk {
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
}
-keep class com.tencent.imsdk.** { *; }
package com.z.zplay;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMSDKConfig;
import com.tencent.imsdk.v2.V2TIMSDKListener;
import com.tencent.liteav.TXLiteAVCode;
import com.tencent.rtmp.TXLivebase;
import com.tencent.trtc.TRTCCloud;
import com.tencent.trtc.TRTCCloudListener;
import com.z.zplay.im.GenerateTestUserSig;
public class IApplication extends Application {
private static IApplication instance;
private static String TAG = "IApplication";
public static IApplication instance() {
return instance;
}
@Override
public void onCreate() {
super.onCreate();
instance = this;
initIM();
}
private void initIM() {
int sdkAppID = GenerateTestUserSig.SDKAPPID;
// 1. 从 IM 控制台获取应用 SDKAppID,详情请参考 SDKAppID。
// 2. 初始化 config 对象
V2TIMSDKConfig sdkConfig = new V2TIMSDKConfig();
// 3. 指定 log 输出级别,详情请参考 SDKConfig。
sdkConfig.setLogLevel(V2TIMSDKConfig.V2TIM_LOG_DEBUG);
// 4. 初始化 SDK 并设置 V2TIMSDKListener 的监听对象。
// initSDK 后 SDK 会自动连接网络,网络连接状态可以在 V2TIMSDKListener 回调里面监听。
V2TIMManager.getInstance().initSDK(this, sdkAppID, sdkConfig, new V2TIMSDKListener() {
// 5. 监听 V2TIMSDKListener 回调
@Override
public void onConnecting() {
// 正在连接到腾讯云服务器
Log.v(TAG,"onConnecting");
}
@Override
public void onConnectSuccess() {
// 已经成功连接到腾讯云服务器
Log.v(TAG,"onConnectSuccess");
}
@Override
public void onConnectFailed(int code, String error) {
// 连接腾讯云服务器失败
Log.v(TAG,"onConnectFailed");
}
@Override
public void onKickedOffline() {
//当前用户被踢下线
//此时可以 UI 提示用户“您已经在其他端登录了当前账号,是否重新登录?”
Log.v(TAG,"onKickedOffline");
}
@Override
public void onUserSigExpired() {
//登录票据已经过期
//请使用新签发的 UserSig 进行登录。
Log.v(TAG,"onUserSigExpired");
}
});
}
}
2.单聊、群聊
package com.z.zplay.im
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import com.king.zxing.util.CodeUtils
import com.tencent.imsdk.v2.*
import com.z.zplay.CaptureCustomActivity
import com.z.zplay.CopyUtils
import com.z.zplay.R
import com.z.zplay.ValueEvent
import com.z.zplay.imlives.TAnchorActivity
import com.z.zplay.imlives.TAudienceActivity
import kotlinx.android.synthetic.main.activity_imlogin.*
import kotlinx.android.synthetic.main.activity_imlogin.btn_scan
import kotlinx.android.synthetic.main.activity_main.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class IMLoginActivity : AppCompatActivity() {
val TAG = "IMLoginActivity"
var userID = ""
var userSig = ""
companion object {
val USER_ID = "userid"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_imlogin)
V2TIMManager.getInstance().addSimpleMsgListener(object : V2TIMSimpleMsgListener() {
override fun onRecvC2CTextMessage(
msgID: String?,
sender: V2TIMUserInfo?,
text: String?
) {
super.onRecvC2CTextMessage(msgID, sender, text)
Log.v(TAG, "发送者:" + sender?.userID)
Log.v(TAG, "消息id:$msgID,消息:$text")
tv_msg.text = text
}
override fun onRecvGroupTextMessage(
msgID: String?,
groupID: String?,
sender: V2TIMGroupMemberInfo?,
text: String?
) {
super.onRecvGroupTextMessage(msgID, groupID, sender, text)
Log.v(TAG, "发送者:" + sender?.userID)
Log.v(TAG, "消息id:$msgID,消息:$text")
tv_msg.text = text
}
override fun onRecvGroupCustomMessage(
msgID: String?,
groupID: String?,
sender: V2TIMGroupMemberInfo?,
customData: ByteArray?
) {
super.onRecvGroupCustomMessage(msgID, groupID, sender, customData)
Log.v(TAG, "发送者:" + sender?.userID)
Log.v(TAG, "消息id:$msgID,消息:${customData?.toString(Charsets.UTF_8)}")
tv_msg.text = customData?.toString(Charsets.UTF_8)
}
})
//登录
btn_login.setonClickListener {
userID = et_userid!!.text.toString()
userSig = GenerateTestUserSig.genTestUserSig(userID)
V2TIMManager.getInstance().login(userID, userSig, object : V2TIMCallback {
override fun onSuccess() {
Toast.makeText(this@IMLoginActivity, "登录成功", Toast.LENGTH_SHORT).show()
}
override fun onError(code: Int, desc: String) {
val log = "登录失败code:$code,desc:$desc"
Log.v("login", log)
Toast.makeText(this@IMLoginActivity, log, Toast.LENGTH_SHORT).show()
}
})
}
btn_to_live.setonClickListener {
var int = Intent(this@IMLoginActivity, TAnchorActivity::class.java)
int.putExtra(USER_ID,userID)
startActivity(int)
}
btn_look_live.setonClickListener {
var int = Intent(this@IMLoginActivity, TAudienceActivity::class.java)
int.putExtra(USER_ID,userID)
startActivity(int)
}
//单聊发送
btn_c2c.setonClickListener {
V2TIMManager.getInstance().sendC2CTextMessage(
et_msg.text.toString(),
et_to_user.text.toString(),
object : V2TIMValueCallback {
override fun onSuccess(t: V2TIMMessage?) {
Toast.makeText(this@IMLoginActivity, "发送消息成功", Toast.LENGTH_SHORT).show()
}
override fun onError(code: Int, desc: String?) {
Toast.makeText(this@IMLoginActivity, "发送消息失败", Toast.LENGTH_SHORT).show()
}
})
}
//创建群,Groupid设为null则由系统自动生成返回
btn_create_group.setonClickListener {
V2TIMManager.getInstance()
.createGroup("AVChatRoom", null, "篮球群", object : V2TIMValueCallback {
override fun onSuccess(t: String?) {
Log.v(TAG, "创建群成功:$t")
tv_group_id.text = t
et_join.setText(t)
var bitmap = CodeUtils.createQRCode(t, 200)
iv_code.setImageBitmap(bitmap)
}
override fun onError(code: Int, desc: String?) {
Log.v(TAG, "创建群失败:$code,$desc")
}
})
}
btn_scan.setonClickListener {
startActivity(Intent(this, CaptureCustomActivity::class.java))
}
tv_group_id.setonClickListener {
CopyUtils.clip(this, tv_group_id.text.toString())
}
//加入群
btn_join.setonClickListener {
V2TIMManager.getInstance().joinGroup(
et_join.text.toString(),
"大家好,我是" + et_userid.text.toString(),
object : V2TIMCallback {
override fun onSuccess() {
Toast.makeText(this@IMLoginActivity, "入群成功", Toast.LENGTH_SHORT).show()
}
override fun onError(code: Int, desc: String?) {
Toast.makeText(this@IMLoginActivity, "入群失败:$code,$desc", Toast.LENGTH_SHORT)
.show()
}
})
}
//发送群消息
btn_group.setonClickListener {
V2TIMManager.getInstance().sendGroupTextMessage(
et_msg.text.toString(),
et_join.text.toString(),
V2TIMMessage.V2TIM_PRIORITY_NORMAL,
object : V2TIMValueCallback {
override fun onSuccess(t: V2TIMMessage?) {
Toast.makeText(this@IMLoginActivity, "发送消息成功", Toast.LENGTH_SHORT).show()
}
override fun onError(code: Int, desc: String?) {
Toast.makeText(
this@IMLoginActivity,
"发送消息失败$code,$desc",
Toast.LENGTH_SHORT
).show()
}
})
}
//发送自定义群消息,比如点赞
btn_custom_group.setonClickListener {
var upmsg = "{ "command": "favor", "value": 101 }"
V2TIMManager.getInstance()
.sendGroupCustomMessage(upmsg.toByteArray(Charsets.UTF_8), et_join.text.toString(),
V2TIMMessage.V2TIM_PRIORITY_NORMAL,
object : V2TIMValueCallback {
override fun onSuccess(t: V2TIMMessage?) {
Toast.makeText(this@IMLoginActivity, "发送消息成功", Toast.LENGTH_SHORT)
.show()
}
override fun onError(code: Int, desc: String?) {
Toast.makeText(
this@IMLoginActivity,
"发送消息失败$code,$desc",
Toast.LENGTH_SHORT
).show()
}
})
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onValueEvent(event: ValueEvent) {
et_join.setText(event.value.toString())
}
override fun onStart() {
super.onStart()
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this)
}
}
override fun onDestroy() {
super.onDestroy()
if (EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().unregister(this)
}
}
}
GenerateTestUserSig可参考
或者腾讯的demo基本都有。
跑通直播模式
implementation 'com.tencent.liteav:LiteAVSDK_Professional:latest.release'
ndk {
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a"
}
主播页面
package com.z.zplay.zhibo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.tencent.liteav.TXLiteAVCode;
import com.tencent.rtmp.ui.TXCloudVideoView;
import com.tencent.trtc.TRTCCloud;
import com.tencent.trtc.TRTCCloudDef;
import com.tencent.trtc.TRTCCloudListener;
import com.z.zplay.R;
import com.z.zplay.im.GenerateTestUserSig;
import static com.tencent.trtc.TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FIT;
public class AnchorActivity extends AppCompatActivity {
private EditText et_userid;
private EditText et_roomid;
private Button btn_to_room;
private Button btn_exit;
private TRTCCloud mTRTCCloud;
private TXCloudVideoView pusher_tx_cloud_view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anchor);
initRTC();
et_userid = findViewById(R.id.et_userid);
et_roomid = findViewById(R.id.et_roomid);
btn_to_room = findViewById(R.id.btn_to_room);
btn_exit = findViewById(R.id.btn_exit);
pusher_tx_cloud_view = findViewById(R.id.pusher_tx_cloud_view);
btn_to_room.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TRTCCloudDef.TRTCParams params = new TRTCCloudDef.TRTCParams();
params.sdkAppId = GenerateTestUserSig.SDKAPPID;
params.userId = et_userid.getText().toString();
params.userSig = GenerateTestUserSig.genTestUserSig(params.userId);
params.roomId = Integer.parseInt(et_roomid.getText().toString());
//示例代码:发布本地的音视频流
mTRTCCloud.startLocalPreview(true, pusher_tx_cloud_view);
mTRTCCloud.setLocalViewFillMode(TRTC_VIDEO_RENDER_MODE_FIT);
//设置本地视频编码参数
TRTCCloudDef.TRTCVideoEncParam encParam = new TRTCCloudDef.TRTCVideoEncParam();
encParam.videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_960_540;
encParam.videoFps = 15;
encParam.videoBitrate = 1200;
encParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT;
mTRTCCloud.setVideoEncoderParam(encParam);
mTRTCCloud.startLocalAudio();
//但需要您通过 TRTCParams 中的 “role” 字段设定用户是“主播”(TRTCRoleAnchor)还是“观众”(TRTCRoleAudience)。
params.role = TRTCCloudDef.TRTCRoleAnchor;
//TRTCAppSceneLIVE (视频互动直播),此场景下,您必须通过 TRTCParams 中的 role 字段指定当前用户的角色
mTRTCCloud.enterRoom(params, TRTCCloudDef.TRTC_APP_SCENE_LIVE);
}
});
btn_exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mTRTCCloud.exitRoom();
}
});
}
private void initRTC() {
// 创建 trtcCloud 实例
mTRTCCloud = TRTCCloud.sharedInstance(getApplicationContext());
mTRTCCloud.setListener(new TRTCCloudListener() {
@Override
public void onEnterRoom(long result) {
if (result > 0) {
Toast.makeText(AnchorActivity.this, "进房成功,总计耗时" + result + "ms", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(AnchorActivity.this, "进房失败,错误码:" + result, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onExitRoom(int reason) {
//如果您的 App 中同时集成了多个音视频 SDK,请在收到onExitRoom回调后再启动其它音视频 SDK,否则可能会遇到硬件占用问题。
Toast.makeText(AnchorActivity.this, "退出房间" + reason, Toast.LENGTH_SHORT).show();
}
// 错误通知监听,错误通知意味着 SDK 不能继续运行
@Override
public void onError(int errCode, String errMsg, Bundle extraInfo) {
Toast.makeText(AnchorActivity.this, "onError: " + errMsg + "[" + errCode + "]", Toast.LENGTH_SHORT).show();
if (errCode == TXLiteAVCode.ERR_ROOM_ENTER_FAIL) {
mTRTCCloud.exitRoom();
}
}
});
}
}
观众页面
package com.z.zplay.zhibo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.tencent.liteav.TXLiteAVCode;
import com.tencent.rtmp.ui.TXCloudVideoView;
import com.tencent.trtc.TRTCCloud;
import com.tencent.trtc.TRTCCloudDef;
import com.tencent.trtc.TRTCCloudListener;
import com.z.zplay.R;
import com.z.zplay.im.GenerateTestUserSig;
public class AudienceActivity extends AppCompatActivity {
private TRTCCloud mTRTCCloud;
private EditText et_userid;
private EditText et_zb_userid;
private EditText et_roomid;
private Button btn_to_room;
private Button btn_exit;
private TXCloudVideoView tx_cloud_view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audience);
et_userid = findViewById(R.id.et_userid);
et_zb_userid = findViewById(R.id.et_zb_userid);
et_roomid = findViewById(R.id.et_roomid);
btn_to_room = findViewById(R.id.btn_to_room);
btn_exit = findViewById(R.id.btn_exit);
tx_cloud_view = findViewById(R.id.tx_cloud_view);
initRTC();
btn_to_room.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TRTCCloudDef.TRTCParams params = new TRTCCloudDef.TRTCParams();
params.sdkAppId = GenerateTestUserSig.SDKAPPID;
params.userId = et_userid.getText().toString();
params.userSig = GenerateTestUserSig.genTestUserSig(params.userId);
params.roomId = Integer.parseInt(et_roomid.getText().toString());
//但需要您通过 TRTCParams 中的 “role” 字段设定用户是“主播”(TRTCRoleAnchor)还是“观众”(TRTCRoleAudience)。
params.role = TRTCCloudDef.TRTCRoleAudience;
//TRTCAppSceneLIVE (视频互动直播),此场景下,您必须通过 TRTCParams 中的 role 字段指定当前用户的角色
mTRTCCloud.enterRoom(params, TRTCCloudDef.TRTC_APP_SCENE_LIVE);
}
});
btn_exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mTRTCCloud.exitRoom();
}
});
}
private void initRTC() {
// 创建 trtcCloud 实例
mTRTCCloud = TRTCCloud.sharedInstance(getApplicationContext());
mTRTCCloud.setListener(new TRTCCloudListener() {
@Override
public void onEnterRoom(long result) {
if (result > 0) {
Toast.makeText(AudienceActivity.this, "进房成功,总计耗时" + result + "ms", Toast.LENGTH_SHORT).show();
//mTRTCCloud.startRemoteView(et_userid.getText().toString(),tx_cloud_view);
mTRTCCloud.startRemoteView(et_zb_userid.getText().toString(), TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, tx_cloud_view);
//mTRTCCloud.startRemoteView(et_userid.getText().toString(),TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SMALL,tx_cloud_view);
//mTRTCCloud.startRemoteView(et_userid.getText().toString(),TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SUB,tx_cloud_view);
} else {
Toast.makeText(AudienceActivity.this, "进房失败,错误码:" + result, Toast.LENGTH_SHORT).show();
}
}
// 错误通知监听,错误通知意味着 SDK 不能继续运行
@Override
public void onError(int errCode, String errMsg, Bundle extraInfo) {
Toast.makeText(AudienceActivity.this, "onError: " + errMsg + "[" + errCode + "]", Toast.LENGTH_SHORT).show();
if (errCode == TXLiteAVCode.ERR_ROOM_ENTER_FAIL) {
mTRTCCloud.exitRoom();
}
}
});
}
}



