Browse Source

feat: add audio call

one-file
konenet 4 years ago
parent
commit
4785290b46
  1. 114
      src/chat/Panel.jsx
  2. 5
      src/chat/common/constant/Constant.jsx

114
src/chat/Panel.jsx

@ -28,6 +28,7 @@ import InfiniteScroll from 'react-infinite-scroll-component'; @@ -28,6 +28,7 @@ import InfiniteScroll from 'react-infinite-scroll-component';
import moment from 'moment';
import { axiosGet, axiosPostBody } from './util/Request';
import * as Params from './common/param/Params'
import * as Constant from './common/constant/Constant'
import UserInfo from './component/UserInfo'
import protobuf from './proto/proto'
@ -115,6 +116,7 @@ class Panel extends React.Component { @@ -115,6 +116,7 @@ class Panel extends React.Component {
super(props)
this.state = {
isRecord: false,
onlineType: 1, // 线 12
user: {},
comments: [],
submitting: false,
@ -305,7 +307,7 @@ class Panel extends React.Component { @@ -305,7 +307,7 @@ class Panel extends React.Component {
}
// webrtc
if (messagePB.type === "webrtc") {
if (messagePB.type === Constant.MESSAGE_TRANS_TYPE) {
this.dealWebRtcMessage(messagePB);
return;
}
@ -368,7 +370,7 @@ class Panel extends React.Component { @@ -368,7 +370,7 @@ class Panel extends React.Component {
to: this.state.toUser,
messageType: this.state.messageType,
content: JSON.stringify(candidate),
type: "webrtc",
type: Constant.MESSAGE_TRANS_TYPE,
}
let message = protobuf.lookup("protocol.Message")
const messagePB = message.create(data)
@ -383,8 +385,13 @@ class Panel extends React.Component { @@ -383,8 +385,13 @@ class Panel extends React.Component {
*/
peer.ontrack = (e) => {
if (e && e.streams) {
if (this.state.onlineType === 1) {
let remoteVideo = document.getElementById("remoteVideo");
remoteVideo.srcObject = e.streams[0];
} else {
let remoteAudio = document.getElementById("audioPhone");
remoteAudio.srcObject = e.streams[0];
}
}
};
}
@ -407,11 +414,26 @@ class Panel extends React.Component { @@ -407,11 +414,26 @@ class Panel extends React.Component {
if (!this.checkMediaPermisssion()) {
return;
}
let preview = document.getElementById("preview1");
let preview
let video = false;
if (messagePB.contentType === Constant.VIDEO_ONLINE) {
preview = document.getElementById("preview1");
video = true
this.setState({
onlineType: 1,
})
} else {
preview = document.getElementById("audioPhone");
this.setState({
onlineType: 2,
})
}
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true,
video: video,
}).then((stream) => {
preview.srcObject = stream;
stream.getTracks().forEach(track => {
@ -428,13 +450,13 @@ class Panel extends React.Component { @@ -428,13 +450,13 @@ class Panel extends React.Component {
fromUsername: localStorage.username,
from: this.state.fromUser,
to: this.state.toUser,
messageType: this.state.messageType,
messageType: messagePB.contentType,
content: JSON.stringify(answer),
type: "webrtc",
type: Constant.MESSAGE_TRANS_TYPE,
}
let message = protobuf.lookup("protocol.Message")
const messagePB = message.create(data)
socket.send(message.encode(messagePB).finish())
const messagePBNew = message.create(data)
socket.send(message.encode(messagePBNew).finish())
})
});
});
@ -464,6 +486,10 @@ class Panel extends React.Component { @@ -464,6 +486,10 @@ class Panel extends React.Component {
* @returns 媒体权限是否开启
*/
checkMediaPermisssion = () => {
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia; //
if (!navigator || !navigator.mediaDevices) {
message.error("获取摄像头权限失败!")
return false;
@ -1023,16 +1049,13 @@ class Panel extends React.Component { @@ -1023,16 +1049,13 @@ class Panel extends React.Component {
* 开启视频电话
*/
startVideoOnline = () => {
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia; //
if (!this.checkMediaPermisssion()) {
return;
}
let preview = document.getElementById("preview1");
this.setState({
onlineType: 1,
isRecord: true,
rtcType: 'offer'
})
@ -1056,8 +1079,9 @@ class Panel extends React.Component { @@ -1056,8 +1079,9 @@ class Panel extends React.Component {
from: this.state.fromUser,
to: this.state.toUser,
messageType: this.state.messageType,
contentType: Constant.VIDEO_ONLINE,
content: JSON.stringify(offer),
type: "webrtc",
type: Constant.MESSAGE_TRANS_TYPE,
}
let message = protobuf.lookup("protocol.Message")
const messagePB = message.create(data)
@ -1081,10 +1105,20 @@ class Panel extends React.Component { @@ -1081,10 +1105,20 @@ class Panel extends React.Component {
this.recorder.stop()
this.recorder = null
}
let preview = document.getElementById("preview1");
let preview1 = document.getElementById("preview1");
if (preview1 && preview1.srcObject && preview1.srcObject.getTracks()) {
preview1.srcObject.getTracks().forEach((track) => track.stop());
}
let preview = document.getElementById("preview");
if (preview && preview.srcObject && preview.srcObject.getTracks()) {
preview.srcObject.getTracks().forEach((track) => track.stop());
}
let audioPhone = document.getElementById("audioPhone");
if (audioPhone && audioPhone.srcObject && audioPhone.srcObject.getTracks()) {
audioPhone.srcObject.getTracks().forEach((track) => track.stop());
}
this.dataChunks = []
if (this.interval) {
@ -1101,6 +1135,52 @@ class Panel extends React.Component { @@ -1101,6 +1135,52 @@ class Panel extends React.Component {
})
}
/**
* 开启语音电话
*/
startAudioOnline = () => {
if (!this.checkMediaPermisssion()) {
return;
}
this.setState({
onlineType: 2,
isRecord: true,
rtcType: 'offer'
})
navigator.mediaDevices
.getUserMedia({
audio: true,
video: false,
}).then((stream) => {
stream.getTracks().forEach(track => {
peer.addTrack(track, stream);
});
// offer
peer.createOffer()
.then(offer => {
peer.setLocalDescription(offer);
let data = {
fromUsername: localStorage.username,
from: this.state.fromUser,
to: this.state.toUser,
messageType: this.state.messageType, // 1. 2.
contentType: Constant.AUDIO_ONLINE, //
content: JSON.stringify(offer),
type: Constant.MESSAGE_TRANS_TYPE, //
}
let message = protobuf.lookup("protocol.Message")
const messagePB = message.create(data)
socket.send(message.encode(messagePB).finish())
});
});
this.setState({
mediaPanelDrawerVisible: true
})
}
/**
* 屏幕共享
@ -1282,11 +1362,10 @@ class Panel extends React.Component { @@ -1282,11 +1362,10 @@ class Panel extends React.Component {
<Tooltip title="语音聊天">
<Button
shape="circle"
onClick={this.startVideoOnline}
onClick={this.startAudioOnline}
style={{ marginRight: 10 }}
icon={<PhoneOutlined />}
// disabled={toUser === ''}
disabled
disabled={toUser === ''}
/>
</Tooltip>
<Tooltip title="视频聊天">
@ -1384,6 +1463,7 @@ class Panel extends React.Component { @@ -1384,6 +1463,7 @@ class Panel extends React.Component {
<img id="receiver" width={this.state.currentScreen.width} height="auto" alt="" />
<canvas id="canvas" width={this.state.currentScreen.width} height={this.state.currentScreen.height} />
<audio id="audioPhone" autoPlay controls />
</Drawer>
</>
);

5
src/chat/common/constant/Constant.jsx

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
export const AUDIO_ONLINE = 6; //
export const VIDEO_ONLINE = 7; //
export const MESSAGE_TRANS_TYPE = "webrtc"; // heatbeat,线webrtc
Loading…
Cancel
Save