void DisconnectSession(ushort client_id) { ClientSession clientSession; if (ClientSessions.TryGetValue(client_id, out clientSession)) { if (clientSession != null) { IStreamConnect client = clientSession.Connect; if (client.IsPublishing) { UnRegisterPublish(client_id); } if (client.IsPlaying) { var client_channels = _routedClients.FindAll((t) => (t.Item1 == client_id || t.Item2 == client_id)); _routedClients.RemoveAll((t) => (t.Item1 == client_id)); foreach (var i in client_channels) { _routedClients.Remove(i); } } client.OnDisconnected(new ExceptionalEventArgs("disconnected")); } } ClientSessions.Remove(client_id); }
internal void SendDataHandler(object sender, ChannelDataReceivedEventArgs e) { var server = (RtmpConnect)sender; var server_clients = _routedClients.FindAll((t) => t.Item2 == server.ClientID); foreach (var i in server_clients) { IStreamConnect client; ClientSession client_state = null; if (e.type != i.Item3) { continue; } ClientSessions.TryGetValue(i.Item1, out client_state); switch (i.Item3) { case ChannelType.Audio: if (client_state == null) { continue; } client = client_state.Connect; client.SendAmf0Data(e.e); break; case ChannelType.Video: if (client_state == null) { continue; } client = client_state.Connect; client.SendAmf0Data(e.e); break; case ChannelType.Message: throw new NotImplementedException(); } } }
internal bool UnRegisterPublish(ushort clientId) { var key = _clientRouteTable.First(x => x.Value == clientId).Key; ClientSession state; if (_clientRouteTable.ContainsKey(key)) { if (ClientSessions.TryGetValue(clientId, out state)) { IStreamConnect connect = state.Connect; connect.ChannelDataReceived -= SendDataHandler; var clients = _routedClients.FindAll(t => t.Item2 == clientId); foreach (var i in clients) { DisconnectSession(i.Item1); } _routedClients.RemoveAll(t => t.Item2 == clientId); } _clientRouteTable.Remove(key); return(true); } return(false); }
internal void ConnectToClient(string liveChannel, string path, ushort clientID, ChannelType channel_type) { ClientSession clientSession; ushort cachedClientID; var uri = new Uri("http://127.0.0.1/" + path); var key = new Tuple <string, string>(liveChannel, uri.AbsolutePath); if (!_clientRouteTable.TryGetValue(key, out cachedClientID)) { throw new KeyNotFoundException("请求地址不存在~"); } if (!ClientSessions.TryGetValue(cachedClientID, out clientSession)) { IStreamConnect connect = clientSession.Connect; _clientRouteTable.Remove(key); throw new KeyNotFoundException("请求客户端不存在~"); } _routedClients.Add(new Tuple <ushort, ushort, ChannelType>(clientID, cachedClientID, channel_type)); }
/// <summary> /// 将发布者的媒体的meta发给播放者 /// </summary> /// <param name="liveChannel"></param> /// <param name="path"></param> /// <param name="self"></param> /// <param name="flvHeader"></param> internal void SendMetadataToPlayer(string liveChannel, string path, IStreamConnect self, bool flvHeader = false) { ushort publisherID; IStreamConnect publisher; ClientSession publisherState; var uri = new Uri("http://127.0.0.1/" + path); var key = new Tuple <string, string>(liveChannel, uri.AbsolutePath); if (!_clientRouteTable.TryGetValue(key, out publisherID)) { throw new KeyNotFoundException("请求地址不存在~"); } if (!ClientSessions.TryGetValue(publisherID, out publisherState)) { _clientRouteTable.Remove(key); throw new KeyNotFoundException("请求客户端不存在~"); } publisher = publisherState.Connect; if (publisher.IsPublishing) { var flv_metadata = (Dictionary <string, object>)publisher.FlvMetaData.MethodCall.Parameters[0]; var has_audio = flv_metadata.ContainsKey("audiocodecid"); var has_video = flv_metadata.ContainsKey("videocodecid"); if (flvHeader) { var header_buffer = Enumerable.Repeat <byte>(0x00, 13).ToArray <byte>(); header_buffer[0] = 0x46; header_buffer[1] = 0x4C; header_buffer[2] = 0x56; header_buffer[3] = 0x01; byte has_audio_flag = 0x01 << 2; byte has_video_flag = 0x01; byte type_flag = 0x00; if (has_audio) { type_flag |= has_audio_flag; } if (has_video) { type_flag |= has_video_flag; } header_buffer[4] = type_flag; var data_offset = BitConverter.GetBytes((uint)9); header_buffer[5] = data_offset[3]; header_buffer[6] = data_offset[2]; header_buffer[7] = data_offset[1]; header_buffer[8] = data_offset[0]; self.SendRawData(header_buffer); } self.SendAmf0Data(publisher.FlvMetaData); if (has_audio) { self.SendAmf0Data(publisher.AACConfigureRecord); } if (has_video) { self.SendAmf0Data(publisher.AvCConfigureRecord); } } }