/// <summary> /// 要求对方发送的媒体 /// </summary> /// <param name="query">配置</param> /// <param name="remote">远程媒体信息</param> internal void emitQuery(Dictionary <string, object> query, RemoteMedia remote) { var meidaQuery = new MediaQuery(); Query?.Invoke(meidaQuery, remote); if (meidaQuery.Audio) { query["audio"] = true; } if (meidaQuery.Video) { query["video"] = true; } }
/** * 开始通话 * @param {Object}} msg 通话配置 * @param {Boolean} master 是否主叫 */ public void _callMedia(Dictionary <string, object> msg, bool master) { var from = msg.Get <string>("from"); var version = msg.Get <string>("version"); var info = msg.Get <Dictionary <string, object> >("info"); RemoteMedia now; this.remotes.TryGetValue(from, out now); if (null == now || now.version != version) { if (now != null) { now.close(); } now = new RemoteMedia(master, this, from, version, info); this.remotes[from] = now; now.connect(); this.Call?.Invoke(now); } }
/** * 创建一个P2P连接 * @param {RemoteMedia}} remote 远程媒体 */ public MediaConnection(RemoteMedia remote) { this.remote = remote; var config = new RTCConfiguration(); foreach (var c in this.call.iceServers) { config.AddServer(c.urls, c.username, c.credential); } this.connection = RtcNavigator.createPeerConnection(config); //当需要发送candidate的时候 this.connection.IceCandidate += evt => { this.socket.send(new { kind = "webrtc", action = "candidate", to = this.remote.id, candidate = new { candidate = evt.Sdp, sdpMid = evt.SdpMid, sdpMLineIndex = evt.SdpMLineIndex } }); }; //如果支持新的api,当收到track this.connection.TrackAdded += evt => { this._tracks[evt.Track.Kind] = evt.Track; this._emitAddTrack(); }; //当媒体流被移除时 this.connection.TrackRemoved += evt => { this._tracks.Remove(evt.Track.Kind); this._emitAddTrack(); }; //当连接状态发生改变时 this.connection.IceConnectionChange += state => { this.iceConnectionState = state; //new, checking, connected, completed, failed, disconnected, closed; switch (state) { case IceConnectionState.Connected: case IceConnectionState.Completed: case IceConnectionState.Failed: case IceConnectionState.Disconnected: case IceConnectionState.Closed: if (this._candidates == null || this._candidates.Count > 0) { this._candidates = new List <IceCandidate>(); } break; } var name = GetIceConnectionName(state); this.StateChanged?.Invoke(name); this._clearchecker(); }; this.connection.DataChannel += channel => { this._registerDataChannel(channel); }; //检查超时 this._timer = Timeout.setTimeout(this._timeoutchecker, 10000); //初始化状态 this.resetState(true); }