【m】远端视频开发
This commit is contained in:
@@ -15,9 +15,9 @@ const defaultStreamHeight = 720;
|
||||
|
||||
class CallStateManager {
|
||||
constructor() {
|
||||
let renderstreaming; // WebRTC连接管理实例
|
||||
let useWebSocket; // 是否使用WebSocket信令
|
||||
let connectionId; // 连接ID
|
||||
const renderstreaming=null; // WebRTC连接管理实例
|
||||
const useWebSocket=null; // 是否使用WebSocket信令
|
||||
const connectionId=null; // 连接ID
|
||||
// 核心状态
|
||||
this.state = {
|
||||
session: {
|
||||
@@ -33,9 +33,6 @@ class CallStateManager {
|
||||
|
||||
// 监听器数组
|
||||
this.listeners = [];
|
||||
|
||||
// 初始化
|
||||
//this.init();
|
||||
}
|
||||
|
||||
// 订阅状态变化
|
||||
@@ -52,20 +49,19 @@ class CallStateManager {
|
||||
}
|
||||
|
||||
// 初始化
|
||||
init() {
|
||||
async init() {
|
||||
// 启动通话时长计时器
|
||||
this.durationInterval = setInterval(() => {
|
||||
this.state.session.duration++;
|
||||
this.notify({ type: 'DURATION_UPDATE', duration: this.state.session.duration });
|
||||
}, 1000);
|
||||
// 初始化配置
|
||||
this.setupConfig();
|
||||
await this.setupConfig();
|
||||
// 获取本地摄像头视频流
|
||||
this.getLocalStream();
|
||||
|
||||
await this.getLocalStream();
|
||||
|
||||
// 模拟远端音频活动 (实际应由 WebRTC VAD 检测触发)
|
||||
this.simulateRemoteActivity();
|
||||
//this.simulateRemoteActivity();
|
||||
|
||||
// 模拟网络质量变化
|
||||
this.simulateNetworkChange();
|
||||
@@ -176,26 +172,46 @@ class CallStateManager {
|
||||
async setUp(connectionId) {
|
||||
//TODO
|
||||
this.connectionId = connectionId; // 获取连接ID
|
||||
codecPreferences.disabled = true; // 禁用编解码器选择
|
||||
|
||||
// 确保本地流已经初始化
|
||||
if (!this.state.localStream) {
|
||||
console.log('Local stream not available, waiting for initialization...');
|
||||
// 等待localStream初始化
|
||||
await new Promise((resolve) => {
|
||||
const checkStream = () => {
|
||||
if (this.state.localStream) {
|
||||
resolve();
|
||||
} else {
|
||||
setTimeout(checkStream, 100);
|
||||
}
|
||||
};
|
||||
checkStream();
|
||||
});
|
||||
}
|
||||
|
||||
// 创建信令实例
|
||||
const signaling = useWebSocket ? new WebSocketSignaling() : new Signaling();
|
||||
const signaling = this.useWebSocket ? new WebSocketSignaling() : new Signaling();
|
||||
const config = getRTCConfiguration(); // 获取RTC配置
|
||||
this.renderstreaming = new RenderStreaming(signaling, config); // 创建WebRTC连接管理实例
|
||||
|
||||
// 连接建立回调
|
||||
this.renderstreaming.onConnect = () => {
|
||||
const tracks = this.state.localStream.getTracks(); // 获取本地媒体轨道
|
||||
for (const track of tracks) {
|
||||
this.renderstreaming.addTransceiver(track, { direction: 'sendonly' }); // 添加发送轨道
|
||||
if (this.state.localStream) {
|
||||
const tracks = this.state.localStream.getTracks(); // 获取本地媒体轨道
|
||||
for (const track of tracks) {
|
||||
this.renderstreaming.addTransceiver(track, { direction: 'sendonly' }); // 添加发送轨道
|
||||
}
|
||||
this.setCodecPreferences(); // 设置编解码器偏好
|
||||
this.showStatsMessage(); // 显示统计信息
|
||||
} else {
|
||||
console.error('Local stream is not available');
|
||||
showNotification('本地视频流不可用', 'error');
|
||||
}
|
||||
setCodecPreferences(); // 设置编解码器偏好
|
||||
showStatsMessage(); // 显示统计信息
|
||||
};
|
||||
|
||||
// 连接断开回调
|
||||
this.renderstreaming.onDisconnect = () => {
|
||||
hangUp(); // 挂断连接
|
||||
this.hangUp(); // 挂断连接
|
||||
};
|
||||
|
||||
// 轨道事件回调
|
||||
@@ -206,6 +222,8 @@ class CallStateManager {
|
||||
this.state.remoteStream = new MediaStream();
|
||||
}
|
||||
this.state.remoteStream.addTrack(data.track);
|
||||
// 通知UI远程流已更新
|
||||
this.notify({ type: 'REMOTE_STREAM_OBTAINED', stream: this.state.remoteStream });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -221,21 +239,21 @@ class CallStateManager {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async hangUp() {
|
||||
clearStatsMessage(); // 清除统计信息
|
||||
messageDiv.style.display = 'block';
|
||||
messageDiv.innerText = `Disconnect peer on ${connectionId}.`;
|
||||
this.clearStatsMessage(); // 清除统计信息
|
||||
this.messageDiv.style.display = 'block';
|
||||
this.messageDiv.innerText = `Disconnect peer on ${this.connectionId}.`;
|
||||
|
||||
// 删除连接并停止WebRTC
|
||||
await renderstreaming.deleteConnection();
|
||||
await renderstreaming.stop();
|
||||
renderstreaming = null;
|
||||
remoteVideo.srcObject = null; // 清除远程视频源
|
||||
await this.renderstreaming.deleteConnection();
|
||||
await this.renderstreaming.stop();
|
||||
this.renderstreaming = null;
|
||||
this.remoteVideo.srcObject = null; // 清除远程视频源
|
||||
|
||||
connectionId = null;
|
||||
this.connectionId = null;
|
||||
|
||||
// 启用编解码器选择
|
||||
if (supportsSetCodecPreferences) {
|
||||
codecPreferences.disabled = false;
|
||||
if (this.supportsSetCodecPreferences) {
|
||||
this.codecPreferences.disabled = false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
@@ -245,8 +263,8 @@ class CallStateManager {
|
||||
/** @type {RTCRtpCodecCapability[] | null} */
|
||||
let selectedCodecs = null;
|
||||
|
||||
if (supportsSetCodecPreferences) {
|
||||
const preferredCodec = codecPreferences.options[codecPreferences.selectedIndex];
|
||||
if (this.supportsSetCodecPreferences) {
|
||||
const preferredCodec = this.codecPreferences.options[this.codecPreferences.selectedIndex];
|
||||
if (preferredCodec.value !== '') {
|
||||
const [mimeType, sdpFmtpLine] = preferredCodec.value.split(' ');
|
||||
const { codecs } = RTCRtpSender.getCapabilities('video');
|
||||
@@ -261,7 +279,7 @@ class CallStateManager {
|
||||
}
|
||||
|
||||
// 获取视频收发器并设置编解码器偏好
|
||||
const transceivers = renderstreaming.getTransceivers().filter(t => t.receiver.track.kind == "video");
|
||||
const transceivers = this.renderstreaming.getTransceivers().filter(t => t.receiver.track.kind == "video");
|
||||
if (transceivers && transceivers.length > 0) {
|
||||
transceivers.forEach(t => t.setCodecPreferences(selectedCodecs));
|
||||
}
|
||||
@@ -310,26 +328,26 @@ class CallStateManager {
|
||||
}
|
||||
|
||||
// 加入通话
|
||||
joinCall(connectionId) {
|
||||
async joinCall(connectionId) {
|
||||
this.state.session.status = 'connecting';
|
||||
this.notify({ type: 'CALL_STATUS_CHANGE', status: 'connecting' });
|
||||
showNotification(`正在加入通话 (${connectionId})`);
|
||||
|
||||
// 初始化
|
||||
this.init();
|
||||
await this.init();
|
||||
|
||||
// 保存连接ID
|
||||
this.connectionId = connectionId;
|
||||
}
|
||||
|
||||
// 创建通话
|
||||
createCall() {
|
||||
async createCall() {
|
||||
this.state.session.status = 'connecting';
|
||||
this.notify({ type: 'CALL_STATUS_CHANGE', status: 'connecting' });
|
||||
showNotification('正在创建通话...');
|
||||
|
||||
// 初始化
|
||||
this.init();
|
||||
await this.init();
|
||||
}
|
||||
|
||||
// 模拟远端活动 (开发测试用)
|
||||
@@ -364,6 +382,18 @@ class CallStateManager {
|
||||
// socket.emit('media-state-changed', payload);
|
||||
}
|
||||
|
||||
// 显示统计信息
|
||||
showStatsMessage() {
|
||||
console.log('Showing stats message');
|
||||
// 这里可以添加显示统计信息的逻辑
|
||||
}
|
||||
|
||||
// 清除统计信息
|
||||
clearStatsMessage() {
|
||||
console.log('Clearing stats message');
|
||||
// 这里可以添加清除统计信息的逻辑
|
||||
}
|
||||
|
||||
// Getters
|
||||
getState() { return this.state; }
|
||||
getLocalUser() { return this.state.session.localUser; }
|
||||
|
||||
Reference in New Issue
Block a user