Java通過WebSocket WebRTC實現視訊通話例項
阿新 • • 發佈:2019-01-09
package org.rtc.servlet; import java.io.IOException; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.rtc.room.WebRTCRoomManager; @WebServlet(urlPatterns = {"/room"}) public class WebRTCRoomServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String r = request.getParameter("r"); if(StringUtils.isEmpty(r)){ //如果房間為空,則生成一個新的房間號 r = String.valueOf(System.currentTimeMillis()); response.sendRedirect("room?r=" + r); }else{ Integer initiator = 1; String user = UUID.randomUUID().toString().replace("-", "");//生成一個使用者ID串 if(!WebRTCRoomManager.haveUser(r)){//第一次進入可能是沒有人的,所以就要等待連線,如果有人進入了帶這個房間好的頁面就會發起視訊通話的連線 initiator = 0;//如果房間沒有人則不傳送連線的請求 } WebRTCRoomManager.addUser(r, user);//向房間中新增一個使用者 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort() + request.getContextPath() +"/"; String roomLink = basePath + "room?r=" + r; String roomKey = r;//設定一些變數 request.setAttribute("initiator", initiator); request.setAttribute("roomLink", roomLink); request.setAttribute("roomKey", roomKey); request.setAttribute("user", user); request.getRequestDispatcher("index.jsp").forward(request, response); } } }
這個是進入房間前的處理,然而客戶端是怎麼發起視訊通話的呢?
function initialize() { console.log("Initializing; room=${roomKey}."); card = document.getElementById("card"); localVideo = document.getElementById("localVideo"); miniVideo = document.getElementById("miniVideo"); remoteVideo = document.getElementById("remoteVideo"); resetStatus(); openChannel(); getUserMedia(); } function getUserMedia() { try { navigator.webkitGetUserMedia({ 'audio' : true, 'video' : true }, onUserMediaSuccess, onUserMediaError); console.log("Requested access to local media with new syntax."); } catch (e) { try { navigator.webkitGetUserMedia("video,audio", onUserMediaSuccess, onUserMediaError); console .log("Requested access to local media with old syntax."); } catch (e) { alert("webkitGetUserMedia() failed. Is the MediaStream flag enabled in about:flags?"); console.log("webkitGetUserMedia failed with exception: " + e.message); } } } function onUserMediaSuccess(stream) { console.log("User has granted access to local media."); var url = webkitURL.createObjectURL(stream); localVideo.style.opacity = 1; localVideo.src = url; localStream = stream; // Caller creates PeerConnection. if (initiator) maybeStart(); } function maybeStart() { if (!started && localStream && channelReady) { setStatus("Connecting..."); console.log("Creating PeerConnection."); createPeerConnection(); console.log("Adding local stream."); pc.addStream(localStream); started = true; // Caller initiates offer to peer. if (initiator) doCall(); } } function doCall() { console.log("Sending offer to peer."); if (isRTCPeerConnection) { pc.createOffer(setLocalAndSendMessage, null, mediaConstraints); } else { var offer = pc.createOffer(mediaConstraints); pc.setLocalDescription(pc.SDP_OFFER, offer); sendMessage({ type : 'offer', sdp : offer.toSdp() }); pc.startIce(); } } function setLocalAndSendMessage(sessionDescription) { pc.setLocalDescription(sessionDescription); sendMessage(sessionDescription); } function sendMessage(message) { var msgString = JSON.stringify(message); console.log('發出資訊 : ' + msgString); path = 'message?r=${roomKey}' + '&u=${user}'; var xhr = new XMLHttpRequest(); xhr.open('POST', path, true); xhr.send(msgString); }
頁面載入完之後會呼叫initialize方法,initialize方法中呼叫了getUserMedia方法,這個方法是通過本地攝像頭獲取視訊的方法,在成功獲取視訊之後傳送連線請求,並在客戶端建立連線管道,最後通過sendMessage向另外一個客戶端傳送連線的請求,引數為當前通話的房間號和當前登陸人。