├── app ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── colors.xml │ │ │ └── themes.xml │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── mine_default_avatar.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── switch_camera.png │ │ │ ├── ic_launcher_round.png │ │ │ ├── video_chat_answer.png │ │ │ └── video_chat_hangup.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── xml │ │ │ └── network_security_config.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── values-night │ │ │ └── themes.xml │ │ ├── drawable │ │ │ ├── video_chat_hangup_selector.xml │ │ │ ├── video_chat_answer_selector.xml │ │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ │ ├── item_contact.xml │ │ │ ├── activity_contacts.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_video_call_send.xml │ │ │ └── activity_video_call_receive.xml │ │ └── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ ├── java │ │ └── com │ │ │ └── alick │ │ │ └── learnwebrtc │ │ │ ├── bean │ │ │ ├── Contact.kt │ │ │ ├── SdpBean.kt │ │ │ ├── RequestMsgBean.kt │ │ │ ├── IceCandidateBean.kt │ │ │ ├── response │ │ │ │ ├── base │ │ │ │ │ └── BaseResponse.kt │ │ │ │ ├── PeersResponse.kt │ │ │ │ ├── AddContactResponse.kt │ │ │ │ ├── AllContactResponse.kt │ │ │ │ ├── CreateRoomResponse.kt │ │ │ │ ├── RemoveContactResponse.kt │ │ │ │ ├── IceCandidateResponse.kt │ │ │ │ ├── SdpAnswerResponse.kt │ │ │ │ └── SdpOfferResponse.kt │ │ │ ├── RoomBean.kt │ │ │ └── request │ │ │ │ ├── base │ │ │ │ ├── BaseSignalRequest.kt │ │ │ │ └── BaseRequest.kt │ │ │ │ ├── GetAllContactRequest.kt │ │ │ │ ├── JoinRequest.kt │ │ │ │ ├── LeaveRequest.kt │ │ │ │ ├── RingRequest.kt │ │ │ │ ├── CancelRequest.kt │ │ │ │ ├── RejectRequest.kt │ │ │ │ ├── InviteRequest.kt │ │ │ │ ├── CreateRoomRequest.kt │ │ │ │ ├── SdpOfferRequest.kt │ │ │ │ ├── SdpAnswerRequest.kt │ │ │ │ ├── SendIceCandidateRequest.kt │ │ │ │ └── SendIceCandidateRemovedRequest.kt │ │ │ ├── http_api │ │ │ ├── BaseApiResponse.kt │ │ │ ├── GetAllRoomListResponse.kt │ │ │ └── ApiUtils.kt │ │ │ ├── utils │ │ │ ├── RoomIdUtils.kt │ │ │ ├── BLog.kt │ │ │ ├── MMKVUtils.kt │ │ │ ├── ToastUtils.kt │ │ │ ├── FilterUtils.java │ │ │ ├── AppHolder.java │ │ │ └── JsonUtils.java │ │ │ ├── core │ │ │ ├── sdp │ │ │ │ ├── CreateSdpObserver.kt │ │ │ │ └── SetSdpObserver.kt │ │ │ └── WebRTCEngine.kt │ │ │ ├── manager │ │ │ ├── AccountManager.kt │ │ │ ├── SignalManager.kt │ │ │ └── WebSocketManager.kt │ │ │ ├── App.kt │ │ │ ├── constant │ │ │ ├── Constant.kt │ │ │ ├── WebRtcConstant.kt │ │ │ └── RRType.kt │ │ │ ├── adapter │ │ │ └── ContactsAdapter.kt │ │ │ ├── widget │ │ │ └── ChatTimeTextView.kt │ │ │ ├── ContactsActivity.kt │ │ │ ├── MainActivity.kt │ │ │ ├── VideoCallReceiveActivity.kt │ │ │ ├── VideoCallSendActivity.kt │ │ │ └── BaseVideoCallActivity.kt │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── .idea ├── .gitignore ├── codeStyles │ ├── codeStyleConfig.xml │ └── Project.xml ├── vcs.xml ├── compiler.xml ├── dictionaries │ └── Administrator.xml ├── misc.xml ├── gradle.xml └── jarRepositories.xml ├── key └── alick.jks ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── README.md ├── gradle.properties ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | rootProject.name = "LearnWebRtc" -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /key/alick.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/key/alick.jks -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | LearnWebRtc 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/Contact.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean 2 | 3 | data class Contact(val account: String) 4 | -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/SdpBean.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean 2 | 3 | data class SdpBean(val description:String) -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/switch_camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-xxhdpi/switch_camera.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/video_chat_answer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-xxhdpi/video_chat_answer.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/video_chat_hangup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-xxhdpi/video_chat_hangup.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/mine_default_avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-xhdpi/mine_default_avatar.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wolongalick/LearnWebRtc/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/RequestMsgBean.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean 2 | 3 | data class RequestMsgBean(val msgType: String, val fromAccount: String) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/IceCandidateBean.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean 2 | 3 | open class IceCandidateBean(val label: Int, val id: String, val candidate: String) -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/http_api/BaseApiResponse.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.http_api 2 | 3 | open class BaseApiResponse(var data:Data?=null, val code:Int=0, val msg:String="") -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/dictionaries/Administrator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | capturer 5 | mmkv 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/response/base/BaseResponse.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.response.base 2 | 3 | open class BaseResponse( 4 | val msgType: String,val roomId:String="", val fromAccount: String = "", val data: Data? = null 5 | ) -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 18 13:48:45 CST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/RoomBean.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean 2 | 3 | data class RoomBean(val roomId: String,val creatorAccount:String) { 4 | var roomName: String = "" 5 | var roomSize: Int = 0 6 | val contactList: MutableList = mutableListOf() 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/base/BaseSignalRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request.base 2 | 3 | open class BaseSignalRequest( 4 | msgType: String, 5 | val roomId: String, 6 | val toAccount: String, 7 | data: Any? = null 8 | ) : BaseRequest(msgType, data) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/utils/RoomIdUtils.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.utils 2 | 3 | import java.util.* 4 | 5 | class RoomIdUtils { 6 | companion object{ 7 | fun createRoomId():String{ 8 | return UUID.randomUUID().toString() 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/GetAllContactRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.request.base.BaseRequest 4 | import com.alick.learnwebrtc.constant.RequestType 5 | 6 | class GetAllContactRequest(): BaseRequest(RequestType.All_CONTACT) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/response/PeersResponse.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.response 2 | 3 | import com.alick.learnwebrtc.bean.response.base.BaseResponse 4 | import com.alick.learnwebrtc.constant.ResponseType 5 | 6 | class PeersResponse() : BaseResponse(ResponseType.PEERS) { 7 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/response/AddContactResponse.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.response 2 | 3 | import com.alick.learnwebrtc.bean.Contact 4 | import com.alick.learnwebrtc.bean.response.base.BaseResponse 5 | 6 | 7 | class AddContactResponse(msgType: String) : BaseResponse(msgType) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/base/BaseRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request.base 2 | 3 | import com.alick.learnwebrtc.manager.AccountManager 4 | 5 | open class BaseRequest(val msgType: String, val data: Any? = null) { 6 | val fromAccount: String = AccountManager.getAccount() 7 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/response/AllContactResponse.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.response 2 | 3 | import com.alick.learnwebrtc.bean.Contact 4 | import com.alick.learnwebrtc.bean.response.base.BaseResponse 5 | 6 | class AllContactResponse(msgType: String) : BaseResponse>(msgType) -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/http_api/GetAllRoomListResponse.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.http_api 2 | 3 | import com.alick.learnwebrtc.bean.RoomBean 4 | 5 | /** 6 | * @author 崔兴旺 7 | * @description 8 | * @date 2021/6/27 13:36 9 | */ 10 | class GetAllRoomListResponse : BaseApiResponse>() -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/core/sdp/CreateSdpObserver.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.core.sdp 2 | 3 | import org.webrtc.SdpObserver 4 | 5 | abstract class CreateSdpObserver : SdpObserver { 6 | 7 | final override fun onSetSuccess() { 8 | 9 | } 10 | 11 | final override fun onSetFailure(p0: String?) { 12 | 13 | } 14 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/JoinRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.request.base.BaseSignalRequest 4 | import com.alick.learnwebrtc.constant.RequestType 5 | 6 | class JoinRequest(roomId: String, toAccount: String) : 7 | BaseSignalRequest(RequestType.JOIN, roomId, toAccount) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/LeaveRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.request.base.BaseSignalRequest 4 | import com.alick.learnwebrtc.constant.RequestType 5 | 6 | class LeaveRequest(roomId: String, toAccount: String) : 7 | BaseSignalRequest(RequestType.LEAVE, roomId, toAccount) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/RingRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.request.base.BaseSignalRequest 4 | import com.alick.learnwebrtc.constant.RequestType 5 | 6 | class RingRequest(roomId: String, toAccount: String) : 7 | BaseSignalRequest(RequestType.RING, roomId, toAccount) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/manager/AccountManager.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.manager 2 | 3 | import com.alick.learnwebrtc.constant.Constant 4 | import com.alick.learnwebrtc.utils.MMKVUtils 5 | 6 | object AccountManager { 7 | fun getAccount():String{ 8 | return MMKVUtils.getString(Constant.MMKV_KEY_ACCOUNT) 9 | } 10 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/CancelRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.request.base.BaseSignalRequest 4 | import com.alick.learnwebrtc.constant.RequestType 5 | 6 | class CancelRequest(roomId: String, toAccount: String) : 7 | BaseSignalRequest(RequestType.CANCEL, roomId, toAccount) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/RejectRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.request.base.BaseSignalRequest 4 | import com.alick.learnwebrtc.constant.RequestType 5 | 6 | class RejectRequest(roomId: String, toAccount: String) : 7 | BaseSignalRequest(RequestType.REJECT, roomId, toAccount) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/InviteRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.request.base.BaseSignalRequest 4 | import com.alick.learnwebrtc.constant.RequestType 5 | 6 | class InviteRequest(roomId: String, toAccount: String) : 7 | BaseSignalRequest(RequestType.INVITE, roomId, toAccount) { 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/response/CreateRoomResponse.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.response 2 | 3 | import com.alick.learnwebrtc.bean.RoomBean 4 | import com.alick.learnwebrtc.bean.response.base.BaseResponse 5 | import com.alick.learnwebrtc.constant.ResponseType 6 | 7 | class CreateRoomResponse : BaseResponse(ResponseType.CREATE_SUCCESS) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/response/RemoveContactResponse.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.response 2 | 3 | import com.alick.learnwebrtc.bean.Contact 4 | import com.alick.learnwebrtc.bean.response.base.BaseResponse 5 | import com.alick.learnwebrtc.constant.ResponseType 6 | 7 | 8 | class RemoveContactResponse: BaseResponse(ResponseType.REMOVE_CONTACT) { 9 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/core/sdp/SetSdpObserver.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.core.sdp 2 | 3 | import org.webrtc.SdpObserver 4 | import org.webrtc.SessionDescription 5 | 6 | abstract class SetSdpObserver : SdpObserver { 7 | final override fun onCreateSuccess(p0: SessionDescription?) { 8 | } 9 | 10 | final override fun onCreateFailure(p0: String?) { 11 | } 12 | 13 | 14 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/CreateRoomRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.request.base.BaseSignalRequest 4 | import com.alick.learnwebrtc.constant.RequestType 5 | import com.alick.learnwebrtc.utils.RoomIdUtils 6 | 7 | class CreateRoomRequest : BaseSignalRequest( 8 | RequestType.CREATE, 9 | RoomIdUtils.createRoomId(), 10 | "" 11 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/App.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc 2 | 3 | import android.app.Application 4 | import com.alick.learnwebrtc.utils.AppHolder 5 | import com.alick.learnwebrtc.utils.ToastUtils 6 | import com.tencent.mmkv.MMKV 7 | 8 | class App : Application() { 9 | override fun onCreate() { 10 | super.onCreate() 11 | AppHolder.init(this); 12 | MMKV.initialize(this) 13 | } 14 | } -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/SdpOfferRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.SdpBean 4 | import com.alick.learnwebrtc.bean.request.base.BaseSignalRequest 5 | import com.alick.learnwebrtc.constant.RequestType 6 | 7 | class SdpOfferRequest(roomId: String, toAccount: String, sdpBean: SdpBean) : BaseSignalRequest( 8 | RequestType.SDP_OFFER, roomId, 9 | toAccount,data = sdpBean 10 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/SdpAnswerRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.SdpBean 4 | import com.alick.learnwebrtc.bean.request.base.BaseSignalRequest 5 | import com.alick.learnwebrtc.constant.RequestType 6 | 7 | class SdpAnswerRequest(roomId: String, toAccount: String, sdpBean: SdpBean) : BaseSignalRequest( 8 | RequestType.SDP_ANSWER, roomId, 9 | toAccount, data = sdpBean 10 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/response/IceCandidateResponse.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.response 2 | 3 | import com.alick.learnwebrtc.bean.IceCandidateBean 4 | import com.alick.learnwebrtc.bean.response.base.BaseResponse 5 | 6 | class IceCandidateResponse( 7 | msgType: String, 8 | roomId: String , 9 | fromAccount: String , 10 | data: IceCandidateBean 11 | ) : BaseResponse(msgType, roomId, fromAccount, data) { 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/SendIceCandidateRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.IceCandidateBean 4 | import com.alick.learnwebrtc.bean.request.base.BaseSignalRequest 5 | import com.alick.learnwebrtc.constant.RequestType 6 | 7 | class SendIceCandidateRequest(roomId: String,toAccount: String, data: IceCandidateBean) : 8 | BaseSignalRequest(RequestType.CANDIDATE,roomId, toAccount, data) { 9 | 10 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/response/SdpAnswerResponse.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.response 2 | 3 | import com.alick.learnwebrtc.bean.SdpBean 4 | import com.alick.learnwebrtc.bean.response.base.BaseResponse 5 | import com.alick.learnwebrtc.constant.ResponseType 6 | 7 | class SdpAnswerResponse( 8 | roomId: String = "", 9 | fromAccount: String = "", 10 | data: SdpBean? = null 11 | ) : BaseResponse(ResponseType.SDP_ANSWER, roomId, fromAccount, data) { 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/response/SdpOfferResponse.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.response 2 | 3 | import com.alick.learnwebrtc.bean.SdpBean 4 | import com.alick.learnwebrtc.bean.response.base.BaseResponse 5 | import com.alick.learnwebrtc.constant.ResponseType 6 | 7 | class SdpOfferResponse( 8 | roomId: String = "", 9 | fromAccount: String = "", 10 | data: SdpBean? = null 11 | ) : BaseResponse(ResponseType.SDP_OFFER, roomId, fromAccount, data) { 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/utils/BLog.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.utils 2 | 3 | import android.util.Log 4 | 5 | class BLog { 6 | companion object { 7 | 8 | fun i(msg: String, tag: String = "alick") { 9 | Log.i(tag, msg) 10 | } 11 | 12 | fun d(msg: String, tag: String = "alick") { 13 | Log.d(tag, msg) 14 | } 15 | 16 | fun e(msg: String, tag: String = "alick") { 17 | Log.e(tag, msg) 18 | } 19 | } 20 | 21 | 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/bean/request/SendIceCandidateRemovedRequest.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.bean.request 2 | 3 | import com.alick.learnwebrtc.bean.IceCandidateBean 4 | import com.alick.learnwebrtc.bean.request.base.BaseSignalRequest 5 | import com.alick.learnwebrtc.constant.RequestType 6 | 7 | class SendIceCandidateRemovedRequest(roomId: String,toAccount: String, data: Data) : 8 | BaseSignalRequest(RequestType.REMOVE_CANDIDATES,roomId, toAccount, data) { 9 | 10 | data class Data(val type: String, val candidates: MutableList) 11 | 12 | } -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/utils/MMKVUtils.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.utils 2 | 3 | import com.tencent.mmkv.MMKV 4 | 5 | 6 | class MMKVUtils { 7 | companion object { 8 | private var kv: MMKV = MMKV.defaultMMKV() 9 | 10 | fun getString(key: String): String { 11 | return kv.getString(key, "") ?: "" 12 | } 13 | 14 | fun getInt(key: String): Int { 15 | return kv.getInt(key, 0) 16 | } 17 | 18 | fun setString(key: String, value: String) { 19 | kv.putString(key, value) 20 | } 21 | 22 | fun setInt(key: String, value: Int) { 23 | kv.putInt(key, value) 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/constant/Constant.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.constant 2 | 3 | class Constant { 4 | companion object { 5 | const val MMKV_KEY_OUTER_ADDRESS = "outer_address" 6 | const val MMKV_KEY_INNER_ADDRESS = "inner_address" 7 | const val MMKV_KEY_USING_ADDRESS = "using_address" 8 | const val MMKV_KEY_SELECT_ADDRESS_TYPE = "select_address_type" 9 | 10 | const val MMKV_VALUE_SELECT_ADDRESS_TYPE_OUTER="outer" 11 | const val MMKV_VALUE_SELECT_ADDRESS_TYPE_INNER="inner" 12 | 13 | 14 | const val MMKV_KEY_ACCOUNT = "account" 15 | 16 | const val DEFAULT_OUTER_ADDRESS="39.105.182.221:5001" 17 | const val DEFAULT_INNER_ADDRESS="192.168.129.162:5001" 18 | } 19 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LearnWebRtc 2 | 这是一个用于音视频通话的webrtc安卓端项目 3 | 4 | 服务端项目:https://github.com/wolongalick/LearnWebRtcServer 5 | 6 | # 联系人页面 7 | ![contacts.jpg](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cd3b30fd638749b98e53e8d427da803e~tplv-k3u1fbpfcp-watermark.image?) 8 | 9 | # 呼叫中 10 | ![callOut.jpg](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/389c2f01394d4a41bddab1332563ecb5~tplv-k3u1fbpfcp-watermark.image?) 11 | 12 | # 来电 13 | ![incomingTelegram.jpg](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3944f92d6b6d4321b0bd72598ad097a6~tplv-k3u1fbpfcp-watermark.image?) 14 | 15 | # 正在通话 16 | 17 | ![call.jpg](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/90b6631a44d245de83c95e381bc43047~tplv-k3u1fbpfcp-watermark.image?) 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/utils/ToastUtils.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.utils 2 | 3 | import android.os.Handler 4 | import android.os.Looper 5 | import android.widget.Toast 6 | 7 | object ToastUtils { 8 | private val mainHandler by lazy { 9 | Handler(Looper.getMainLooper()) 10 | } 11 | 12 | fun show(msg: String, isError: Boolean = true) { 13 | if (Looper.getMainLooper() == Looper.myLooper()) { 14 | Toast.makeText(AppHolder.getApp(), msg, Toast.LENGTH_SHORT).show() 15 | } else { 16 | mainHandler.post { 17 | Toast.makeText(AppHolder.getApp(), msg, Toast.LENGTH_SHORT).show() 18 | } 19 | } 20 | 21 | if (isError) { 22 | BLog.e(msg) 23 | } else { 24 | BLog.i(msg) 25 | } 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/alick/learnwebrtc/constant/WebRtcConstant.kt: -------------------------------------------------------------------------------- 1 | package com.alick.learnwebrtc.constant 2 | 3 | /** 4 | * WebRtc相关常量 5 | */ 6 | class WebRtcConstant { 7 | companion object{ 8 | const val AUDIO_ECHO_CANCELLATION_CONSTRAINT = "googEchoCancellation" //回音消除 9 | const val AUDIO_AUTO_GAIN_CONTROL_CONSTRAINT = "googAutoGainControl" //自动增益 10 | const val AUDIO_HIGH_PASS_FILTER_CONSTRAINT = "googHighpassFilter" //高通滤波器 11 | const val AUDIO_NOISE_SUPPRESSION_CONSTRAINT = "googNoiseSuppression" //降噪 12 | 13 | const val SDP_OFFER_TO_RECEIVE_AUDIO = "OfferToReceiveAudio" //提供接收音频 14 | const val SDP_OFFER_TO_RECEIVE_VIDEO = "OfferToReceiveVideo" //提供接收视频 15 | 16 | const val VIDEO_TRACK_ID = "ARDAMSv0" 17 | const val AUDIO_TRACK_ID = "ARDAMSa0" 18 | const val VIDEO_AUDIO_TRACK_ID = "ARDAMS" 19 | 20 | const val HD_VIDEO_WIDTH = 1280 21 | const val HD_VIDEO_HEIGHT = 720 22 | const val BPS_IN_KBPS = 1000 23 | 24 | const val VIDEO_TRACK_TYPE = "video" 25 | } 26 | } -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/video_chat_hangup_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/video_chat_answer_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | android.injected.testOnly=false -------------------------------------------------------------------------------- /app/src/main/res/layout/item_contact.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 22 | 23 |