Java使用websocket和WebRTC實現視訊通話
最近這段時間折騰了一下WebRTC,這兩天終於是抽了時間把WebRTC搞定了,去年就想弄的,但是確實沒時間。看了網上的https://apprtc.appspot.com/的例子(可能需要翻牆訪問),這個例子是部署在Google App Engine上的應用程式,依賴與GAE的環境,後臺的語言是python,而且還依賴Google App Engine Channel API,所以無法在本地執行,也無法擴充套件。費了一番功夫研讀了例子的python端的原始碼,決定用Java實現,Tomcat7之後開始支援WebSocket,打算用WebSocket代替Google App Engine Channel API實現前後臺的通訊,在整個例子中Java+WebSocket起到的作用是負責客戶端之間的通訊,並不負責視訊的傳輸,視訊的傳輸依賴於WebRTC。
首先WebRTC,這個可以百度一下,大概就是一個音訊和視訊通訊技術,可以跨平臺,只要能用瀏覽器的基本都可以使用,當然要你的瀏覽器支援。
這裡引用了google的js庫:channel.js。不過還是下載下來放到本地伺服器吧,因為很多地方訪問google.com很吃力啊。最開始就是這個js沒有載入完鬱悶了很久,還一直以為是程式碼寫錯了。
另外在進入頁面的時候,注意初始化頁面js中的一個引數:initiator:如果是建立人這個引數設為false;如果是加入的時候這個設定為true。為true的時候,才會發起視訊通話的請求。
實現
對於前端JS程式碼及用到的物件大家可以去檢視詳細的程式碼介紹,我就貼一個連線的方法。首先建立一個客戶端實時獲取狀態的連線,在GAE的例子上是通過GAE Channel API實現,我在這裡用WebSocket實現,程式碼:
function openChannel() {
console.log("開啟websocket");
socket = new WebSocket("ws://192.168.1.158:8080/WebRTC/acgist.video/${requestScope.uid}");
socket.onopen = onChannelOpened;
socket.onmessage = onChannelMessage;
socket.onclose = onChannelClosed;
socket.onerror = onChannelError();
}
服務端程式碼很簡單,就是收到使用者的請求,傳送給另外一個使用者就可以了,這裡處理的其實是使用者WebRTC的一些資訊,並不是去傳輸視訊,如下:
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
/**
* @author 李智
* @date 2017/3/11
*
* WebRTC視訊通話
*/
@ServerEndpoint("/acgist.video/{uid}")
public class AcgistVideo {
// 最大通話數量
private static final int MAX_COUNT = 10;
private static final long MAX_TIME_OUT = 1 * 60 * 1000;
// 使用者和使用者的對話對映
private static final Map<String, String> user_user = Collections.synchronizedMap(new HashMap<String, String>());
// 使用者和websocket的session對映
private static final Map<String, Session> sessions = Collections.synchronizedMap(new HashMap<String, Session>());
/**
* 開啟websocket
* @param session websocket的session
* @param uid 開啟使用者的UID
*/
@OnOpen
public void onOpen(Session session, @PathParam("uid")String uid) {
session.setMaxIdleTimeout(MAX_TIME_OUT);
sessions.put(uid, session);
}
/**
* websocket關閉
* @param session 關閉的session
* @param uid 關閉的使用者標識
*/
@OnClose
public void onClose(Session session, @PathParam("uid")String uid) {
remove(session, uid);
}
/**
* 收到訊息
* @param message 訊息內容
* @param session 傳送訊息的session
* @param uid
*/
@OnMessage
public void onMessage(String message, Session session, @PathParam("uid")String uid) {
try {
if(uid != null && user_user.get(uid) != null && AcgistVideo.sessions.get(user_user.get(uid)) != null) {
Session osession = sessions.get(user_user.get(uid)); // 被呼叫的session
if(osession.isOpen())
osession.getAsyncRemote().sendText(new String(message.getBytes("utf-8")));
else
this.nowaiting(osession);
} else {
this.nowaiting(session);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 沒有人在等待
* @param session 傳送訊息的session
*/
private void nowaiting(Session session) {
session.getAsyncRemote().sendText("{\"type\" : \"nowaiting\"}");
}
/**
* 是否可以繼續建立通話房間
* @return 可以:true;不可以false;
*/
public static boolean canCreate() {
return sessions.size() <= MAX_COUNT;
}
/**
* 判斷是否可以加入
* @param oid 被申請對話的ID
* @return 如果能加入返回:true;否則返回false;
*/
public static boolean canJoin(String oid) {
return !(oid != null && user_user.containsKey(oid) && user_user.get(oid) != null);
}
/**
* 新增視訊物件
* @param uid 申請對話的ID
* @param oid 被申請對話的ID
* @return 是否是建立者:如果沒有申請對話ID為建立者,否則為為加入者。建立者返回:true;加入者返回:false;
*/
public static boolean addUser(String uid, String oid) {
if(oid != null && !oid.isEmpty()) {
AcgistVideo.user_user.put(uid, oid);
AcgistVideo.user_user.put(oid, uid);
return false;
} else {
AcgistVideo.user_user.put(uid, null);
return true;
}
}
/**
* 移除聊天使用者
* @param session 移除的session
* @param uid 移除的UID
*/
private static void remove(Session session, String uid) {
String oid = user_user.get(uid);
if(oid != null) user_user.put(oid, null); // 設定對方無人聊天
sessions.remove(uid); // 異常session
user_user.remove(uid); // 移除自己
try {
if(session != null && session.isOpen()) session.close(); // 關閉session
} catch (IOException e) {
e.printStackTrace();
}
}
}
自己測試的時候搞個公用的stun伺服器弄一弄就好了。不過人多的時候會延遲很就是了,成功截圖就不放了,人醜家貧。
相關推薦
Java使用websocket和WebRTC實現視訊通話
最近這段時間折騰了一下WebRTC,這兩天終於是抽了時間把WebRTC搞定了,去年就想弄的,但是確實沒時間。看了網上的https://apprtc.appspot.com/的例子(可能需要翻牆訪問),這個例子是部署在Google App Engine上的應用程式
Java通過WebSocket WebRTC實現視訊通話例項
package org.rtc.servlet; import java.io.IOException; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.annotation.WebSe
Java+WebSocket+WebRTC實現視訊通話例項
function initialize() { console.log("Initializing; room=${roomKey}."); card = document.getElementById("card"); localVideo = document.getElementById("local
基於socket.io即時通訊IM實現,webRTC實現視訊通話
Socket.io-FLSocketIM-iOS 基於Socket.io iOS即時通訊客戶端 iOS IM Client based on Socket.io 實現功能 文字傳送 圖片傳送(從相簿選取,或者拍攝) 短視
iOS WebRTC語音視訊通話實現與demo
pod install AppRTC 從那裡你可以看到在這個回購ARTCVideoChatViewController類。以下步驟詳細具體更改您將需要在您的應用程式新增視訊聊天。 Initialize SSL Peer ConnectionWebRTC可以通過SSL安全通訊。這是必需的,如果你想測試在ht
ffmpeg和mencoder實現視訊轉碼
最近研究了一下視訊轉碼的問題,參考了部落格https://blog.csdn.net/wdy_2099/article/details/71453602?utm_source=blogxgwz3 具體內容這裡不再說了,安裝可參考https://www.cnblogs.com/new-ass/p/7704
使用Resiprocate 部署 WebRTC IM 視訊通話平臺
為什麼選用SIP協議來部署WebRTC 通訊系統? 1,互通性,基於sip 協議有大量的軟硬體裝置,例如: ip 話機,軟電話,ip攝像頭等等,MCU 裝置等。 2,穩定性,sip 協議歷史悠久,且大量的公司使用它開發ip 通訊系統,文件豐富,功能強大。 3,支援與電話系統
iOS下WebRTC音視訊通話(一)
在iOS下做IM功能時,難免都會涉及到音訊通話和視訊通話。QQ中的QQ電話和視訊通話效果就非常好,但是如果你沒有非常深厚的技術,也沒有那麼大的團隊,很難做到QQ那麼快速和穩定的通話效果。 但是利用WebRTC技術,即使一個人也能夠實現效果不錯的音視訊通話。本篇
100行Javascript程式碼實現視訊通話
視訊聊天室 上一篇文章通過JavaScript呼叫AnyChat實現視訊聊天室 簡單地講述瞭如何通過AnyChat做視訊聊天室。通過學習,我自己也做了個簡單的小例子,幾十行JavaScript指令碼就能輕鬆實現視訊通話;也不用去下載指定的什麼瀏覽器,因為IE、firefo
AnyChatSDK 實現視訊通話
package com.bairuitech.main; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.app.Dialog; import android.
x-lite asterisk 成功實現視訊通話
首先,在此感謝asterisk協會的各位大牛們,沒有他們的幫助,我也不可能在這麼短的時間內實現,x-lite+asterisk音視訊通話。在此將實現的過程記錄如下,分享給asterisk的愛好者們。 1. 修改asterisk伺服器的sip.co
FreeSwitch 1.9.0 安裝配置及使用MySQL管理賬戶,並實現視訊通話
最近因為專案上的需要入手了FreeSwitch。 之前嘗試過Asterisk,但個人感覺對H264的支援不是特別友好,所以用才選擇了FreeSwitch。 安裝FreeSwitch前的準備工作: 1、VMare上安裝一個CentOS的虛擬機器 安裝CentOS 7:
使用SurfaceView和MediaPlayer實現視訊做為背景
場景:像我們在Uber應用開場,看到一一段視訊作為開始,這樣子讓使用者很快投入應用使用的場景中去,這種以視訊作為開場的應用,我們是不是覺得很高大上呢,哈哈,其實是使用了SerfaceView去載入一段小視訊,然後使用mediaplayer進行播放,然後迴圈。 先上圖吧。
利用MediaExtractor和MediaMuxer實現視訊剪下
客戶要在android手機上做個能視訊剪下的app,由於視訊源只是MP4,所以就想到了用MediaExtractor和MediaMuxer來實現功能,直接上程式碼。 public class VideoDecoder { private final
如何結合 CallKit 和 Agora SDK 實現視訊 VoIP 通話應用
作者簡介:龔宇華,聲網Agora.io 首席 iOS 研發工程師,負責 iOS 端移動應用產品設計和技術架構。 CallKit 是蘋果在 iOS10 中推出的,專為 VoIP 通話場景設計的系統框架,在 iOS 上為 VoIP 通話提供了系統級的支援。 在 iOS10 以前,VoI
基於socketio實現webrtc視訊通話的流程
按照發起方A往下走流程,呼叫requestServerCreateRoom方法,在這個方法裡建立socket連線,將發起方A和接收方B的使用者id傳遞給伺服器,傳送事件為“videoChat”。伺服器接收到videoChat事件,按照請求生成房間,並將房間號返回給發起方A。發起方A收到房間號後,執行conne
使用WebRTC實現電腦與手機通過瀏覽器進行視訊通話
最近一直在研究WebRTC,做了一個小專案:www.meet58.com,這個專案利用WebRTC、WebSocket可以讓各種裝置只通過瀏覽器進行視訊聊天,無論是電腦、手機或者是平板。下面就是手機和電腦進行視訊通話的截圖:PC端手機端這個專案目前只有簡單的視訊通
Android藍芽socket實現視訊實時傳輸,以及圖片和文字傳輸
目標 兩臺手機裝置之間能夠正常進行藍芽配對(藍芽模組兒和硬體掛鉤,所以需要兩臺真機) socket實現藍芽文字傳輸 實現圖片傳輸 實現實時視訊傳輸 程式碼下載:https://download.csdn.net/download/m0_37781149/10434336
vue專案利用vue-video-player實現視訊相容IOS和安卓放大播放
首先,圖片和視訊混合一起,預設圖片製作poster點選彈窗手機播放器 <template> <div class="look-v"> <section class="view-wrap" v-if="accObj"> <div c
使用opencv實現視訊分解圖片和圖片合成視屏
# 視訊分解成圖片 import cv2 cap = cv2.VideoCapture("22.mp4") # 獲取開啟的控制代碼 isOpened = cap.isOpened # 判斷是否開啟 print(isOpened) fps = cap.get(cv2.CAP_PROP_FPS) w