private void OnMetaData(DataMessage msg) { this.metadata = msg; var info = new AtomCollection(); info.SetChanInfoType("FLV"); info.SetChanInfoStreamType("video/x-flv"); info.SetChanInfoStreamExt(".flv"); if (metadata.Arguments[0].Type==AMF.AMFValueType.ECMAArray || metadata.Arguments[0].Type==AMF.AMFValueType.Object){ var bitrate = 0.0; var val = metadata.Arguments[0]["maxBitrate"]; if (!AMF.AMFValue.IsNull(val)) { double maxBitrate; string maxBitrateStr = System.Text.RegularExpressions.Regex.Replace((string)val, @"([\d]+)k", "$1"); if (double.TryParse(maxBitrateStr, out maxBitrate)) { bitrate += maxBitrate; } } else if (!AMF.AMFValue.IsNull(val = metadata.Arguments[0]["videodatarate"])) { bitrate += (double)val; } if (!AMF.AMFValue.IsNull(val = metadata.Arguments[0]["audiodatarate"])) { bitrate += (double)val; } info.SetChanInfoBitrate((int)bitrate); } OnChannelInfoChanged(info); OnHeaderChanged(msg); OnContentChanged(msg); }
private void BroadcastStart_Click(object sender, EventArgs args) { Uri source; if (Uri.TryCreate(bcStreamUrl.Text, UriKind.Absolute, out source)) { StreamSource = source; } else { StreamSource = null; } var reader = bcContentType.SelectedItem as ContentReaderItem; if (reader!=null) ContentReaderFactory = reader.ContentReaderFactory; var yp = bcYP.SelectedItem as YellowPageItem; if (yp!=null) YellowPage = yp.YellowPage; var info = new AtomCollection(); int bitrate; if (Int32.TryParse(bcBitrate.Text, out bitrate)) { info.SetChanInfoBitrate(bitrate); } info.SetChanInfoName(bcChannelName.Text); info.SetChanInfoGenre(bcGenre.Text); info.SetChanInfoDesc(bcDescription.Text); info.SetChanInfoComment(bcComment.Text); info.SetChanInfoURL(bcContactUrl.Text); ChannelInfo = new ChannelInfo(info); var track = new AtomCollection(); track.SetChanTrackTitle(bcTrackTitle.Text); track.SetChanTrackGenre(bcTrackGenre.Text); track.SetChanTrackAlbum(bcAlbum.Text); track.SetChanTrackCreator(bcCreator.Text); track.SetChanTrackURL(bcTrackURL.Text); ChannelTrack = new ChannelTrack(track); if (StreamSource!=null && ContentReaderFactory!=null && !String.IsNullOrEmpty(ChannelInfo.Name)) { DialogResult = DialogResult.OK; } }
public ParsedContent Read(Stream stream) { if (stream.Length-stream.Position<=0) throw new EndOfStreamException(); var res = new ParsedContent(); var pos = Channel.ContentPosition; if (Channel.ContentHeader==null) { streamIndex = Channel.GenerateStreamID(); streamOrigin = DateTime.Now; res.ContentHeader = new Content(streamIndex, TimeSpan.Zero, pos, new byte[] { }); var channel_info = new AtomCollection(Channel.ChannelInfo.Extra); channel_info.SetChanInfoType("RAW"); channel_info.SetChanInfoStreamType("application/octet-stream"); channel_info.SetChanInfoStreamExt(""); res.ChannelInfo = new ChannelInfo(channel_info); } res.Contents = new List<Content>(); while (stream.Length-stream.Position>0) { var bytes = new byte[Math.Min(8192, stream.Length-stream.Position)]; var sz = stream.Read(bytes, 0, bytes.Length); if (sz>0) { Array.Resize(ref bytes, sz); res.Contents.Add(new Content(streamIndex, DateTime.Now-streamOrigin, pos, bytes)); pos += sz; } } return res; }
public void OnFLVHeader() { var info = new AtomCollection(); info.SetChanInfoType("FLV"); info.SetChanInfoStreamType("video/x-flv"); info.SetChanInfoStreamExt(".flv"); OnChannelInfoChanged(info); }
private Atom CreateBroadcastPacket(BroadcastGroup group, Atom packet) { var bcst = new AtomCollection(); bcst.SetBcstFrom(PeerCast.SessionID); bcst.SetBcstGroup(group); bcst.SetBcstHops(0); bcst.SetBcstTTL(11); PCPVersion.SetBcstVersion(bcst); bcst.SetBcstChannelID(Channel.ChannelID); bcst.Add(packet); return(new Atom(Atom.PCP_BCST, bcst)); }
public void InitServerAtoms() { Atoms = new AtomCollection(); var atoms = new List <string>(); atoms.AddRange(Content.EnumerateAssets("fx")); atoms.AddRange(Content.EnumerateAssets("entities")); atoms.AddRange(Content.EnumerateAssets("models")); atoms.AddRange(Content.EnumerateAssets("decals")); Atoms.AddRange(atoms); }
private Atom CreateContentBodyPacket(Channel channel, long pos, IEnumerable <byte> data) { var chan = new AtomCollection(); chan.SetChanID(channel.ChannelID); var chan_pkt = new AtomCollection(); chan_pkt.SetChanPktType(Atom.PCP_CHAN_PKT_DATA); chan_pkt.SetChanPktPos((uint)(pos & 0xFFFFFFFFU)); chan_pkt.SetChanPktData(data.ToArray()); chan.SetChanPkt(chan_pkt); return(new Atom(Atom.PCP_CHAN, chan)); }
public ParsedContent Read(Stream stream) { var chunks = 0; var res = new ParsedContent(); var pos = Channel.ContentPosition; try { while (chunks<8) { var chunk = ASFChunk.Read(stream); chunks++; switch (chunk.KnownType) { case ASFChunk.ChunkType.Header: { var header = ASFHeader.Read(chunk); var info = new AtomCollection(Channel.ChannelInfo.Extra); info.SetChanInfoBitrate(header.Bitrate); if (header.Streams.Any(type => type==ASFHeader.StreamType.Video)) { info.SetChanInfoType("WMV"); info.SetChanInfoStreamType("video/x-ms-wmv"); info.SetChanInfoStreamExt(".wmv"); } else if (header.Streams.Any(type => type==ASFHeader.StreamType.Audio)) { info.SetChanInfoType("WMA"); info.SetChanInfoStreamType("audio/x-ms-wma"); info.SetChanInfoStreamExt(".wma"); } else { info.SetChanInfoType("ASF"); info.SetChanInfoStreamType("video/x-ms-asf"); info.SetChanInfoStreamExt(".asf"); } res.ChannelInfo = new ChannelInfo(info); streamIndex = Channel.GenerateStreamID(); streamOrigin = DateTime.Now; res.ContentHeader = new Content(streamIndex, TimeSpan.Zero, pos, chunk.ToByteArray()); pos += chunk.TotalLength; } break; case ASFChunk.ChunkType.Data: if (res.Contents==null) res.Contents = new System.Collections.Generic.List<Content>(); res.Contents.Add(new Content(streamIndex, DateTime.Now-streamOrigin, pos, chunk.ToByteArray())); pos += chunk.TotalLength; break; case ASFChunk.ChunkType.Unknown: break; } } } catch (EndOfStreamException) { if (chunks==0) throw; } return res; }
private void BroadcastStart_Click(object sender, EventArgs args) { Uri source; if (Uri.TryCreate(bcStreamUrl.Text, UriKind.Absolute, out source)) { StreamSource = source; } else { StreamSource = null; } var reader = bcContentType.SelectedItem as ContentReaderItem; if (reader != null) { ContentReaderFactory = reader.ContentReaderFactory; } var yp = bcYP.SelectedItem as YellowPageItem; if (yp != null) { YellowPage = yp.YellowPage; } var info = new AtomCollection(); int bitrate; if (Int32.TryParse(bcBitrate.Text, out bitrate)) { info.SetChanInfoBitrate(bitrate); } info.SetChanInfoName(bcChannelName.Text); info.SetChanInfoGenre(bcGenre.Text); info.SetChanInfoDesc(bcDescription.Text); info.SetChanInfoComment(bcComment.Text); info.SetChanInfoURL(bcContactUrl.Text); ChannelInfo = new ChannelInfo(info); var track = new AtomCollection(); track.SetChanTrackTitle(bcTrackTitle.Text); track.SetChanTrackGenre(bcTrackGenre.Text); track.SetChanTrackAlbum(bcAlbum.Text); track.SetChanTrackCreator(bcCreator.Text); track.SetChanTrackURL(bcTrackURL.Text); ChannelTrack = new ChannelTrack(track); if (StreamSource != null && ContentReaderFactory != null && !String.IsNullOrEmpty(ChannelInfo.Name)) { DialogResult = DialogResult.OK; } }
/// <summary> /// 指定したパケットを含むブロードキャストパケットを作成します /// </summary> /// <param name="group">配送先グループ</param> /// <param name="packet">配送するパケット</param> /// <returns>作成したPCP_BCSTパケット</returns> public virtual Atom CreateBroadcastPacket(BroadcastGroup group, Atom packet) { var bcst = new AtomCollection(); bcst.SetBcstFrom(PeerCast.SessionID); bcst.SetBcstGroup(group); bcst.SetBcstHops(0); bcst.SetBcstTTL(11); bcst.SetBcstVersion(PCP_VERSION); bcst.SetBcstVersionVP(PCP_VERSION_VP); bcst.SetBcstChannelID(Channel.ChannelID); bcst.Add(packet); return(new Atom(Atom.PCP_BCST, bcst)); }
private Atom CreateChannelBcst(Channel channel, bool playing) { var bcst = new AtomCollection(); bcst.SetBcstTTL(1); bcst.SetBcstHops(0); bcst.SetBcstFrom(PeerCast.SessionID); PCPVersion.SetBcstVersion(bcst); bcst.SetBcstChannelID(channel.ChannelID); bcst.SetBcstGroup(BroadcastGroup.Root); PostChannelInfo(bcst, channel); PostHostInfo(bcst, channel, playing); return(new Atom(Atom.PCP_BCST, bcst)); }
private void UpdateRecvRate(IContentSink sink, double bitrate) { if (recvRate == 0.0 || (recvRate * 1.2 < bitrate && bitrate < recvRate * 10.0)) { recvRate = bitrate; var info = new AtomCollection(Channel.ChannelInfo.Extra); info.SetChanInfoType("TS"); info.SetChanInfoStreamType("video/mp2t"); info.SetChanInfoStreamExt(".ts"); info.SetChanInfoBitrate((int)bitrate / 1000); sink.OnChannelInfo(new ChannelInfo(info)); } }
protected virtual void OnPCPHelo(Atom atom) { var session_id = atom.Children.GetHeloSessionID(); var oleh = new AtomCollection(); oleh.SetHeloSessionID(PeerCast.SessionID); Send(new Atom(Atom.PCP_OLEH, oleh)); if (session_id==null) { Logger.Info("Helo has no SessionID"); Stop(StopReason.NotIdentifiedError); } else { Logger.Debug("Helo from {0}", PeerCast.SessionID.ToString("N")); Stop(StopReason.None); } }
private void PostChannelBcst(Channel channel, bool playing) { var bcst = new AtomCollection(); bcst.SetBcstTTL(1); bcst.SetBcstHops(0); bcst.SetBcstFrom(PeerCast.SessionID); bcst.SetBcstVersion(PCP_VERSION); bcst.SetBcstVersionVP(PCP_VERSION_VP); bcst.SetBcstChannelID(channel.ChannelID); bcst.SetBcstGroup(BroadcastGroup.Root); PostChannelInfo(bcst, channel); PostHostInfo(bcst, channel, playing); lock (posts) posts.Add(new Atom(Atom.PCP_BCST, bcst)); }
private ChannelInfo CreateChannelInfo(BroadcastViewModel viewModel) { var info = new AtomCollection(); if (viewModel.bitrate.HasValue) { info.SetChanInfoBitrate(viewModel.bitrate.Value); } info.SetChanInfoName(viewModel.channelName); info.SetChanInfoGenre(viewModel.genre); info.SetChanInfoDesc(viewModel.description); info.SetChanInfoComment(viewModel.comment); info.SetChanInfoURL(viewModel.contactUrl); return(new ChannelInfo(info)); }
private void PostChannelInfo(AtomCollection parent, Channel channel) { var atom = new AtomCollection(); atom.SetChanID(channel.ChannelID); atom.SetChanBCID(PeerCast.BroadcastID); if (channel.ChannelInfo != null) { atom.SetChanInfo(channel.ChannelInfo.Extra); } if (channel.ChannelTrack != null) { atom.SetChanTrack(channel.ChannelTrack.Extra); } parent.SetChan(atom); }
protected IEnumerable <Atom> CreateContentHeaderPacket(Channel channel, Content content) { var chan = new AtomCollection(); chan.SetChanID(channel.ChannelID); var chan_pkt = new AtomCollection(); chan_pkt.SetChanPktType(Atom.PCP_CHAN_PKT_HEAD); chan_pkt.SetChanPktPos((uint)(content.Position & 0xFFFFFFFFU)); chan_pkt.SetChanPktData(content.Data); chan.SetChanPkt(chan_pkt); chan.SetChanInfo(channel.ChannelInfo.Extra); chan.SetChanTrack(channel.ChannelTrack.Extra); Logger.Debug("Sending Header: {0}", content.Position); return(Enumerable.Repeat(new Atom(Atom.PCP_CHAN, chan), 1)); }
/// <summary> /// 現在のチャンネルとPeerCastの状態からHostパケットを作ります /// </summary> /// <returns>作ったPCP_HOSTパケット</returns> public virtual Atom CreateHostPacket() { var host = new AtomCollection(); host.SetHostChannelID(Channel.ChannelID); host.SetHostSessionID(PeerCast.SessionID); var globalendpoint = PeerCast.GetGlobalEndPoint( RemoteEndPoint.AddressFamily, OutputStreamType.Relay); if (globalendpoint != null) { host.AddHostIP(globalendpoint.Address); host.AddHostPort(globalendpoint.Port); } var localendpoint = PeerCast.GetLocalEndPoint( RemoteEndPoint.AddressFamily, OutputStreamType.Relay); if (localendpoint != null) { host.AddHostIP(localendpoint.Address); host.AddHostPort(localendpoint.Port); } host.SetHostNumListeners(Channel.LocalDirects); host.SetHostNumRelays(Channel.LocalRelays); host.SetHostUptime(Channel.Uptime); if (Channel.Contents.Count > 0) { host.SetHostOldPos((uint)(Channel.Contents.Oldest.Position & 0xFFFFFFFFU)); host.SetHostNewPos((uint)(Channel.Contents.Newest.Position & 0xFFFFFFFFU)); } host.SetHostVersion(PCP_VERSION); host.SetHostVersionVP(PCP_VERSION_VP); host.SetHostFlags1( (PeerCast.AccessController.IsChannelRelayable(Channel) ? PCPHostFlags1.Relay : 0) | (PeerCast.AccessController.IsChannelPlayable(Channel) ? PCPHostFlags1.Direct : 0) | ((!PeerCast.IsFirewalled.HasValue || PeerCast.IsFirewalled.Value) ? PCPHostFlags1.Firewalled : 0) | (RecvRate > 0 ? PCPHostFlags1.Receiving : 0)); host.SetHostUphostIP(RemoteEndPoint.Address); host.SetHostUphostPort(RemoteEndPoint.Port); return(new Atom(Atom.PCP_HOST, host)); }
protected virtual void OnPCPHelo(Atom atom) { var session_id = atom.Children.GetHeloSessionID(); var oleh = new AtomCollection(); oleh.SetHeloSessionID(PeerCast.SessionID); Send(new Atom(Atom.PCP_OLEH, oleh)); if (session_id == null) { Logger.Info("Helo has no SessionID"); Stop(StopReason.NotIdentifiedError); } else { Logger.Debug("Helo from {0}", PeerCast.SessionID.ToString("N")); Stop(StopReason.None); } }
/// <summary> /// 現在のチャンネルとPeerCastの状態からHostパケットを作ります /// </summary> /// <returns>作ったPCP_HOSTパケット</returns> private Atom CreatePCPHOST() { var host = new AtomCollection(); host.SetHostChannelID(Channel.ChannelID); host.SetHostSessionID(PeerCast.SessionID); var globalendpoint = PeerCast.GetGlobalEndPoint( connection.RemoteEndPoint.AddressFamily, OutputStreamType.Relay); if (globalendpoint != null) { host.AddHostIP(globalendpoint.Address); host.AddHostPort(globalendpoint.Port); } var localendpoint = PeerCast.GetLocalEndPoint( connection.RemoteEndPoint.AddressFamily, OutputStreamType.Relay); if (localendpoint != null) { host.AddHostIP(localendpoint.Address); host.AddHostPort(localendpoint.Port); } host.SetHostNumListeners(Channel.LocalDirects); host.SetHostNumRelays(Channel.LocalRelays); host.SetHostUptime(Channel.Uptime); if (Channel.Contents.Count > 0) { host.SetHostOldPos((uint)(Channel.Contents.Oldest.Position & 0xFFFFFFFFU)); host.SetHostNewPos((uint)(Channel.Contents.Newest.Position & 0xFFFFFFFFU)); } PCPVersion.SetHostVersion(host); host.SetHostFlags1( (PeerCast.AccessController.IsChannelRelayable(Channel) ? PCPHostFlags1.Relay : 0) | (PeerCast.AccessController.IsChannelPlayable(Channel) ? PCPHostFlags1.Direct : 0) | ((PeerCast.GetPortStatus(connection.RemoteEndPoint.AddressFamily) != PortStatus.Open) ? PCPHostFlags1.Firewalled : 0) | (RecvRate > 0 ? PCPHostFlags1.Receiving : 0)); host.SetHostUphostIP(connection.RemoteEndPoint.Address); host.SetHostUphostPort(connection.RemoteEndPoint.Port); return(new Atom(Atom.PCP_HOST, host)); }
private bool SendPCPHelo() { var helo = new AtomCollection(); helo.SetHeloAgent(PeerCast.AgentName); helo.SetHeloSessionID(PeerCast.SessionID); if (PeerCast.IsFirewalled.HasValue) { if (PeerCast.IsFirewalled.Value) { //Do nothing } else { var listener = PeerCast.FindListener( RemoteEndPoint.Address, OutputStreamType.Relay | OutputStreamType.Metadata); helo.SetHeloPort(listener.LocalEndPoint.Port); } } else { var listener = PeerCast.FindListener( RemoteEndPoint.Address, OutputStreamType.Relay | OutputStreamType.Metadata); if (listener != null) { helo.SetHeloPing(listener.LocalEndPoint.Port); } } PCPVersion.SetHeloVersion(helo); try { connection.Send(stream => { AtomWriter.Write(stream, new Atom(Atom.PCP_HELO, helo)); }); } catch (IOException e) { Logger.Info(e); Stop(StopReason.ConnectionError); return(false); } return(true); }
private void PostHostInfo(AtomCollection parent, Channel channel, bool playing) { var hostinfo = new AtomCollection(); hostinfo.SetHostChannelID(channel.ChannelID); hostinfo.SetHostSessionID(PeerCast.SessionID); var globalendpoint = PeerCast.GetGlobalEndPoint(AddressFamily.InterNetwork, OutputStreamType.Relay); if (globalendpoint != null) { hostinfo.AddHostIP(globalendpoint.Address); hostinfo.AddHostPort(globalendpoint.Port); } var localendpoint = PeerCast.GetLocalEndPoint(AddressFamily.InterNetwork, OutputStreamType.Relay); if (localendpoint != null) { hostinfo.AddHostIP(localendpoint.Address); hostinfo.AddHostPort(localendpoint.Port); } hostinfo.SetHostNumListeners(channel.TotalDirects); hostinfo.SetHostNumRelays(channel.TotalRelays); hostinfo.SetHostUptime(channel.Uptime); if (channel.Contents.Count > 0) { hostinfo.SetHostOldPos((uint)(channel.Contents.Oldest.Position & 0xFFFFFFFFU)); hostinfo.SetHostNewPos((uint)(channel.Contents.Newest.Position & 0xFFFFFFFFU)); } PCPVersion.SetHostVersion(hostinfo); var relayable = PeerCast.AccessController.IsChannelRelayable(channel); var playable = PeerCast.AccessController.IsChannelPlayable(channel) && PeerCast.FindListener(remoteEndPoint.Address, OutputStreamType.Play) != null; var firewalled = !PeerCast.IsFirewalled.HasValue || PeerCast.IsFirewalled.Value || PeerCast.FindListener(remoteEndPoint.Address, OutputStreamType.Relay) == null; var receiving = playing && channel.Status == SourceStreamStatus.Receiving; hostinfo.SetHostFlags1( (relayable ? PCPHostFlags1.Relay : 0) | (playable ? PCPHostFlags1.Direct : 0) | (firewalled ? PCPHostFlags1.Firewalled : 0) | PCPHostFlags1.Tracker | (receiving ? PCPHostFlags1.Receiving : PCPHostFlags1.None)); parent.SetHost(hostinfo); }
protected async Task OnPCPHelo(Atom atom, CancellationToken cancel_token) { var session_id = atom.Children.GetHeloSessionID(); RemoteSessionID = session_id; var oleh = new AtomCollection(); oleh.SetHeloSessionID(PeerCast.SessionID); await Connection.WriteAsync(new Atom(Atom.PCP_OLEH, oleh)).ConfigureAwait(false); if (session_id == null) { Logger.Info("Helo has no SessionID"); OnStopped(StopReason.NotIdentifiedError); } else { Logger.Debug("Helo from {0}", PeerCast.SessionID.ToString("N")); OnStopped(StopReason.None); } }
protected override void Effect(AtomCollection targets, object parameters) { var aParameters = (object[])parameters; var dmg = (Damage)aParameters[0]; var tpc = (int)aParameters[1]; if (tpc == -1) { targets.ForEach(t => { var damageable = (IDamageable)t; damageable.SufferDamage(dmg); if (damageable.Dead) { ((Atom)Launcher).NotifyListeners(String.Format("Kills {0}", ((Atom)t).Name)); damageable.Die((IFighter)Launcher); } }); } else { targets.ForEach(t => { var damageable = (IDamageable)t; if (tpc >= damageable.CASpecial) { damageable.SufferDamage(dmg); } if (damageable.Dead) { ((Atom)Launcher).NotifyListeners(String.Format("Kills {0}", ((Atom)t).Name)); damageable.Die((IFighter)Launcher); } }); } }
public ChannelInfoViewModel() { update = new Command(() => { var info = new AtomCollection(channel.ChannelInfo.Extra); info.SetChanInfoGenre(genre); info.SetChanInfoDesc(description); info.SetChanInfoURL(contactUrl); info.SetChanInfoComment(comment); channel.ChannelInfo = new ChannelInfo(info); var track = new AtomCollection(channel.ChannelTrack.Extra); track.SetChanTrackAlbum(trackAlbum); track.SetChanTrackCreator(trackArtist); track.SetChanTrackTitle(trackTitle); track.SetChanTrackGenre(trackGenre); track.SetChanTrackURL(trackUrl); channel.ChannelTrack = new ChannelTrack(track); IsModified = false; }, () => channel!=null && IsTracker && IsModified); }
private void PostHostInfo(AtomCollection parent, Channel channel, bool playing) { var host = channel.SelfNode; var hostinfo = new AtomCollection(); hostinfo.SetHostChannelID(channel.ChannelID); hostinfo.SetHostSessionID(PeerCast.SessionID); var globalendpoint = host.GlobalEndPoint; if (globalendpoint != null) { hostinfo.AddHostIP(globalendpoint.Address); hostinfo.AddHostPort(globalendpoint.Port); } var localendpoint = host.LocalEndPoint; if (localendpoint != null) { hostinfo.AddHostIP(localendpoint.Address); hostinfo.AddHostPort(localendpoint.Port); } hostinfo.SetHostNumListeners(channel.TotalDirects); hostinfo.SetHostNumRelays(channel.TotalRelays); hostinfo.SetHostUptime(channel.Uptime); if (channel.Contents.Count > 0) { hostinfo.SetHostOldPos((uint)(channel.Contents.Oldest.Position & 0xFFFFFFFFU)); hostinfo.SetHostNewPos((uint)(channel.Contents.Newest.Position & 0xFFFFFFFFU)); } hostinfo.SetHostVersion(PCP_VERSION); hostinfo.SetHostVersionVP(PCP_VERSION_VP); hostinfo.SetHostFlags1( (PeerCast.AccessController.IsChannelRelayable(channel) ? PCPHostFlags1.Relay : 0) | (PeerCast.AccessController.IsChannelPlayable(channel) ? PCPHostFlags1.Direct : 0) | ((!PeerCast.IsFirewalled.HasValue || PeerCast.IsFirewalled.Value) ? PCPHostFlags1.Firewalled : 0) | PCPHostFlags1.Tracker | (playing ? PCPHostFlags1.Receiving : PCPHostFlags1.None)); parent.SetHost(hostinfo); }
public ChannelInfoViewModel() { update = new Command(() => { var info = new AtomCollection(channel.ChannelInfo.Extra); info.SetChanInfoGenre(genre); info.SetChanInfoDesc(description); info.SetChanInfoURL(contactUrl); info.SetChanInfoComment(comment); channel.ChannelInfo = new ChannelInfo(info); var track = new AtomCollection(channel.ChannelTrack.Extra); track.SetChanTrackAlbum(trackAlbum); track.SetChanTrackCreator(trackArtist); track.SetChanTrackTitle(trackTitle); track.SetChanTrackGenre(trackGenre); track.SetChanTrackURL(trackUrl); channel.ChannelTrack = new ChannelTrack(track); IsModified = false; }, () => channel != null && IsTracker && IsModified); }
private void OnPCPBcst(Atom atom) { var channel_id = atom.Children.GetBcstChannelID(); if (channel_id != null) { Channel channel; lock (announcingChannels) { channel = announcingChannels.Find(c => c.Channel.ChannelID == channel_id).Channel; } var group = atom.Children.GetBcstGroup(); var from = atom.Children.GetBcstFrom(); var ttl = atom.Children.GetBcstTTL(); var hops = atom.Children.GetBcstHops(); if (channel != null && group != null && from != null && ttl != null && ttl.Value > 0) { var bcst = new AtomCollection(atom.Children); bcst.SetBcstTTL((byte)(ttl.Value - 1)); bcst.SetBcstHops((byte)((hops ?? 0) + 1)); channel.Broadcast(null, new Atom(Atom.PCP_BCST, bcst), group.Value); } } }
private ChannelInfo ResetContentType(ChannelInfo channel_info, Content content_header) { if (channel_info == null) { throw new ArgumentNullException("channel_info"); } var content_type = channel_info.ContentType; if (content_type == null || content_type == "UNKNOWN") { string mime_type = null; if (content_header != null && PeerCast.ContentReaderFactories.Any( factory => factory.TryParseContentType(content_header.Data, out content_type, out mime_type))) { var new_info = new AtomCollection(channel_info.Extra); new_info.SetChanInfoType(content_type); new_info.SetChanInfoStreamType(mime_type); channel_info = new ChannelInfo(new_info); } } return(channel_info); }
protected IEnumerable<Atom> CreateContentHeaderPacket(Channel channel, Content content) { var chan = new AtomCollection(); chan.SetChanID(channel.ChannelID); var chan_pkt = new AtomCollection(); chan_pkt.SetChanPktType(Atom.PCP_CHAN_PKT_HEAD); chan_pkt.SetChanPktPos((uint)(content.Position & 0xFFFFFFFFU)); chan_pkt.SetChanPktData(content.Data); chan.SetChanPkt(chan_pkt); chan.SetChanInfo(channel.ChannelInfo.Extra); chan.SetChanTrack(channel.ChannelTrack.Extra); Logger.Debug("Sending Header: {0}", content.Position); return Enumerable.Repeat(new Atom(Atom.PCP_CHAN, chan), 1); }
private Atom CreateChanPacket() { var chan = new AtomCollection(); chan.SetChanID(Channel.ChannelID); chan.SetChanInfo(Channel.ChannelInfo.Extra); chan.SetChanTrack(Channel.ChannelTrack.Extra); return new Atom(Atom.PCP_CHAN, chan); }
public ParsedContent Read(Stream stream) { var res = new ParsedContent(); var bodies = new List <Element>(); var info = new AtomCollection(Channel.ChannelInfo.Extra); var processed = false; var eos = false; while (!eos) { var start_pos = stream.Position; try { var elt = Element.ReadHeader(stream); if (ebml.MaxIDLength < elt.ID.Length || ebml.MaxSizeLength < elt.Size.Length) { throw new BadDataException(); } switch (state) { case ReaderState.EBML: if (elt.ID.BinaryEquals(Elements.EBML)) { elt.ReadBody(stream); ebml = new EBML(elt); state = ReaderState.Segment; } else { throw new BadDataException(); } break; case ReaderState.Segment: if (elt.ID.BinaryEquals(Elements.Segment)) { segment = new Segment(elt); state = ReaderState.EndOfHeader; } else if (elt.ID.BinaryEquals(Elements.EBML)) { stream.Position = elt.Position; state = ReaderState.EBML; continue; } else if (elt.ID.BinaryEquals(Elements.Void) || elt.ID.BinaryEquals(Elements.CRC32)) { elt.ReadBody(stream); } else { throw new BadDataException(); } break; case ReaderState.EndOfHeader: if (elt.ID.BinaryEquals(Elements.Segment)) { stream.Position = elt.Position; state = ReaderState.Segment; continue; } else if (elt.ID.BinaryEquals(Elements.EBML)) { stream.Position = elt.Position; state = ReaderState.EBML; continue; } else if (elt.ID.BinaryEquals(Elements.Cluster)) { stream.Position = elt.Position; state = ReaderState.Cluster; clusters.Clear(); MemoryStream header; using (header = new MemoryStream()) { ebml.Element.Write(header); segment.Element.Write(header); foreach (var c in segment.HeaderElements) { c.Write(header); } } res.ContentHeader = new Content(0, header.ToArray()); if (ebml.DocType == "webm") { info.SetChanInfoType("WEBM"); info.SetChanInfoStreamType("video/webm"); info.SetChanInfoStreamExt(".webm"); } else { info.SetChanInfoType("MKV"); info.SetChanInfoStreamType("video/x-matroska"); info.SetChanInfoStreamExt(".mkv"); } res.ChannelInfo = new ChannelInfo(info); } else { elt.ReadBody(stream); segment.AddHeader(elt); } break; case ReaderState.Cluster: if (elt.ID.BinaryEquals(Elements.Segment)) { stream.Position = elt.Position; state = ReaderState.Segment; continue; } else if (elt.ID.BinaryEquals(Elements.EBML)) { stream.Position = elt.Position; state = ReaderState.EBML; continue; } else if (elt.ID.BinaryEquals(Elements.Cluster)) { if (clusters.Count > 0) { var timespan = clusters.Sum(c => c.Timespan); if (timespan >= 30.0) { var sz = clusters.Sum(c => c.Timespan > 0 ? c.BlockSize : 0); var kbps = (int)((sz * 8 / timespan + 900) / 1000.0); info.SetChanInfoBitrate(kbps); res.ChannelInfo = new ChannelInfo(info); while (clusters.Count > 1) { clusters.RemoveFirst(); } } } var cluster = new Cluster(elt); clusters.AddLast(cluster); bodies.Add(elt); state = ReaderState.Timecode; } else if (elt.ID.BinaryEquals(Elements.Void) || elt.ID.BinaryEquals(Elements.CRC32)) { elt.ReadBody(stream); bodies.Add(elt); } else { throw new BadDataException(); } break; case ReaderState.Timecode: if (elt.ID.BinaryEquals(Elements.Segment)) { stream.Position = elt.Position; state = ReaderState.Segment; continue; } else if (elt.ID.BinaryEquals(Elements.EBML)) { stream.Position = elt.Position; state = ReaderState.EBML; continue; } else if (elt.ID.BinaryEquals(Elements.Cluster)) { stream.Position = elt.Position; state = ReaderState.Cluster; continue; } else if (elt.ID.BinaryEquals(Elements.Timecode)) { elt.ReadBody(stream); if (clusters.Last != null) { clusters.Last.Value.Timecode = Element.ReadUInt(new MemoryStream(elt.Data), elt.Data.Length) * (segment.TimecodeScale / 1000000000.0); if (clusters.Count > 1) { clusters.Last.Previous.Value.Timespan = clusters.Last.Value.Timecode - clusters.Last.Previous.Value.Timecode; } } bodies.Add(elt); state = ReaderState.Block; } else if (elt.ID.BinaryEquals(Elements.SimpleBlock) || elt.ID.BinaryEquals(Elements.BlockGroup)) { stream.Position = elt.Position; state = ReaderState.Block; continue; } else { elt.ReadBody(stream); bodies.Add(elt); } break; case ReaderState.Block: if (elt.ID.BinaryEquals(Elements.Segment)) { stream.Position = elt.Position; state = ReaderState.Segment; continue; } else if (elt.ID.BinaryEquals(Elements.EBML)) { stream.Position = elt.Position; state = ReaderState.EBML; continue; } else if (elt.ID.BinaryEquals(Elements.Cluster)) { stream.Position = elt.Position; state = ReaderState.Cluster; continue; } else if ((elt.ID.BinaryEquals(Elements.SimpleBlock) || elt.ID.BinaryEquals(Elements.BlockGroup)) && (clusters.Last.Value.BlockID == null || elt.ID.BinaryEquals(clusters.Last.Value.BlockID))) { elt.ReadBody(stream); clusters.Last.Value.BlockSize += elt.Size.Value; clusters.Last.Value.BlockID = elt.ID.Binary; bodies.Add(elt); } else if (clusters.Last.Value.BlockID == null) { elt.ReadBody(stream); bodies.Add(elt); } else { stream.Position = elt.Position; state = ReaderState.Cluster; continue; } break; } processed = true; } catch (EndOfStreamException) { if (!processed) { throw; } stream.Position = start_pos; eos = true; } catch (BadDataException) { stream.Position = start_pos + 1; } } if (res.ContentHeader != null) { position = res.ContentHeader.Position + res.ContentHeader.Data.Length; } if (bodies.Count > 0) { res.Contents = new List <Content>(); foreach (var body in bodies) { MemoryStream s; using (s = new MemoryStream()) { body.Write(s); } var data = s.ToArray(); res.Contents.Add(new Content(position, data)); position += data.Length; } } return(res); }
private void OnChannelTrackChanged(AtomCollection info) { ContentSink.OnChannelTrack(new ChannelTrack(info)); }
private async Task<bool> PingHost(IPEndPoint target, Guid remote_session_id, CancellationToken cancel_token) { Logger.Debug("Ping requested. Try to ping: {0}({1})", target, remote_session_id); bool result = false; try { var client = new System.Net.Sockets.TcpClient(); client.ReceiveTimeout = 2000; client.SendTimeout = 2000; await client.ConnectAsync(target.Address, target.Port); var stream = client.GetStream(); await stream.WriteAsync(new Atom(Atom.PCP_CONNECT, 1), cancel_token); var helo = new AtomCollection(); helo.SetHeloSessionID(PeerCast.SessionID); await stream.WriteAsync(new Atom(Atom.PCP_HELO, helo), cancel_token); var res = await stream.ReadAtomAsync(cancel_token); if (res.Name==Atom.PCP_OLEH) { var session_id = res.Children.GetHeloSessionID(); if (session_id.HasValue && session_id.Value==remote_session_id) { Logger.Debug("Ping succeeded"); result = true; } else { Logger.Debug("Ping failed. Remote SessionID mismatched"); } } await stream.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT), cancel_token); stream.Close(); client.Close(); } catch (InvalidDataException e) { Logger.Debug("Ping failed"); Logger.Debug(e); } catch (System.Net.Sockets.SocketException e) { Logger.Debug("Ping failed"); Logger.Debug(e); } catch (EndOfStreamException e) { Logger.Debug("Ping failed"); Logger.Debug(e); } catch (System.IO.IOException io_error) { Logger.Debug("Ping failed"); Logger.Debug(io_error); if (!(io_error.InnerException is System.Net.Sockets.SocketException)) { throw; } } return result; }
private Atom CreateContentBodyPacket(Channel channel, long pos, IEnumerable<byte> data) { var chan = new AtomCollection(); chan.SetChanID(channel.ChannelID); var chan_pkt = new AtomCollection(); chan_pkt.SetChanPktType(Atom.PCP_CHAN_PKT_DATA); chan_pkt.SetChanPktPos((uint)(pos & 0xFFFFFFFFU)); chan_pkt.SetChanPktData(data.ToArray()); chan.SetChanPkt(chan_pkt); return new Atom(Atom.PCP_CHAN, chan); }
protected virtual void OnPCPHelo(Atom atom) { if (Downhost!=null) return; Logger.Debug("Helo received"); var session_id = atom.Children.GetHeloSessionID(); int remote_port = 0; if (session_id!=null) { var host = new HostBuilder(); host.SessionID = session_id.Value; var port = atom.Children.GetHeloPort(); var ping = atom.Children.GetHeloPing(); if (port!=null) { remote_port = port.Value; } else if (ping!=null) { if (IsPingTarget(((IPEndPoint)RemoteEndPoint).Address) && PingHost(new IPEndPoint(((IPEndPoint)RemoteEndPoint).Address, ping.Value), session_id.Value)) { remote_port = ping.Value; } else { remote_port = 0; } } else { remote_port = 0; } if (remote_port!=0) { var ip = new IPEndPoint(((IPEndPoint)RemoteEndPoint).Address, remote_port); if (host.GlobalEndPoint==null || !host.GlobalEndPoint.Equals(ip)) { host.GlobalEndPoint = ip; } } host.IsFirewalled = remote_port==0; host.Extra.Update(atom.Children); Downhost = host.ToHost(); UserAgent = atom.Children.GetHeloAgent() ?? UserAgent; } var oleh = new AtomCollection(); if (RemoteEndPoint!=null && RemoteEndPoint.AddressFamily==System.Net.Sockets.AddressFamily.InterNetwork) { oleh.SetHeloRemoteIP(((IPEndPoint)RemoteEndPoint).Address); } oleh.SetHeloAgent(PeerCast.AgentName); oleh.SetHeloSessionID(PeerCast.SessionID); oleh.SetHeloRemotePort(remote_port); PCPVersion.SetHeloVersion(oleh); Send(new Atom(Atom.PCP_OLEH, oleh)); if (Downhost==null) { Logger.Info("Helo has no SessionID"); //セッションIDが無かった Stop(StopReason.NotIdentifiedError); } else if ((Downhost.Extra.GetHeloVersion() ?? 0)<1200) { Logger.Info("Helo version {0} is too old", Downhost.Extra.GetHeloVersion() ?? 0); //クライアントバージョンが無かった、もしくは古すぎ Stop(StopReason.BadAgentError); } else if (IsRelayFull) { Logger.Debug("Handshake succeeded {0}({1}) but relay is full", Downhost.GlobalEndPoint, Downhost.SessionID.ToString("N")); Stop(StopReason.UnavailableError); } else { Logger.Debug("Handshake succeeded {0}({1})", Downhost.GlobalEndPoint, Downhost.SessionID.ToString("N")); Send(new Atom(Atom.PCP_OK, (int)1)); } }
protected override Task OnStopped(CancellationToken cancel_token) { switch (StoppedReason) { case StopReason.None: break; case StopReason.Any: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT)); break; case StopReason.SendTimeoutError: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_SKIP)); break; case StopReason.BadAgentError: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_BADAGENT)); break; case StopReason.ConnectionError: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_READ)); break; case StopReason.NotIdentifiedError: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_NOTIDENTIFIED)); break; case StopReason.UnavailableError: { //次に接続するホストを送ってQUIT foreach (var node in SelectSourceHosts((IPEndPoint)RemoteEndPoint)) { if (Downhost != null && Downhost.SessionID == node.SessionID) { continue; } var host_atom = new AtomCollection(node.Extra); Atom ip = host_atom.FindByName(Atom.PCP_HOST_IP); while (ip != null) { host_atom.Remove(ip); ip = host_atom.FindByName(Atom.PCP_HOST_IP); } Atom port = host_atom.FindByName(Atom.PCP_HOST_PORT); while (port != null) { host_atom.Remove(port); port = host_atom.FindByName(Atom.PCP_HOST_PORT); } host_atom.SetHostSessionID(node.SessionID); var globalendpoint = node.GlobalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(globalendpoint.Address); host_atom.AddHostPort(globalendpoint.Port); var localendpoint = node.LocalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(localendpoint.Address); host_atom.AddHostPort(localendpoint.Port); host_atom.SetHostNumRelays(node.RelayCount); host_atom.SetHostNumListeners(node.DirectCount); host_atom.SetHostChannelID(Channel.ChannelID); host_atom.SetHostFlags1( (node.IsFirewalled ? PCPHostFlags1.Firewalled : PCPHostFlags1.None) | (node.IsTracker ? PCPHostFlags1.Tracker : PCPHostFlags1.None) | (node.IsRelayFull ? PCPHostFlags1.None : PCPHostFlags1.Relay) | (node.IsDirectFull ? PCPHostFlags1.None : PCPHostFlags1.Direct) | (node.IsReceiving ? PCPHostFlags1.Receiving : PCPHostFlags1.None) | (node.IsControlFull ? PCPHostFlags1.None : PCPHostFlags1.ControlIn)); Connection.WriteAsync(new Atom(Atom.PCP_HOST, host_atom)); Logger.Debug("Sending Node: {0}({1})", globalendpoint, node.SessionID.ToString("N")); } } Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_UNAVAILABLE)); break; case StopReason.OffAir: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_OFFAIR)); break; case StopReason.UserShutdown: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_SHUTDOWN)); break; } if (Channel != null) { Channel.ContentChanged -= Channel_ContentChanged; Channel.ChannelInfoChanged -= Channel_ChannelPropertyChanged; Channel.ChannelTrackChanged -= Channel_ChannelPropertyChanged; } return(base.OnStopped(cancel_token)); }
private ChannelInfo UpdateChannelInfo(ChannelInfo a, ChannelInfo b) { var base_atoms = new AtomCollection(a.Extra); var new_atoms = new AtomCollection(b.Extra); if (!useContentBitrate) { new_atoms.RemoveByName(Atom.PCP_CHAN_INFO_BITRATE); } base_atoms.Update(new_atoms); return new ChannelInfo(base_atoms); }
public ParsedContent Read(Stream stream) { var chunks = 0; var res = new ParsedContent(); var pos = Channel.ContentPosition; try { while (chunks < 8) { var chunk = ASFChunk.Read(stream); chunks++; switch (chunk.KnownType) { case ASFChunk.ChunkType.Header: { var header = ASFHeader.Read(chunk); var info = new AtomCollection(Channel.ChannelInfo.Extra); info.SetChanInfoBitrate(header.Bitrate); if (header.Streams.Any(type => type == ASFHeader.StreamType.Video)) { info.SetChanInfoType("WMV"); info.SetChanInfoStreamType("video/x-ms-wmv"); info.SetChanInfoStreamExt(".wmv"); } else if (header.Streams.Any(type => type == ASFHeader.StreamType.Audio)) { info.SetChanInfoType("WMA"); info.SetChanInfoStreamType("audio/x-ms-wma"); info.SetChanInfoStreamExt(".wma"); } else { info.SetChanInfoType("ASF"); info.SetChanInfoStreamType("video/x-ms-asf"); info.SetChanInfoStreamExt(".asf"); } res.ChannelInfo = new ChannelInfo(info); res.ContentHeader = new Content(pos, chunk.ToByteArray()); pos += chunk.TotalLength; } break; case ASFChunk.ChunkType.Data: if (res.Contents == null) { res.Contents = new System.Collections.Generic.List <Content>(); } res.Contents.Add(new Content(pos, chunk.ToByteArray())); pos += chunk.TotalLength; break; case ASFChunk.ChunkType.Unknown: break; } } } catch (EndOfStreamException) { if (chunks == 0) { throw; } } return(res); }
protected void OnPCPChanInfo(Atom atom) { var channel_info = new ChannelInfo(atom.Children); var content_type = channel_info.ContentType; if (content_type==null || content_type=="UNKNOWN") { var header = Channel.ContentHeader; string mime_type = null; if (header!=null && PeerCast.ContentReaderFactories.Any( factory => factory.TryParseContentType(header.Data, out content_type, out mime_type))) { var new_info = new AtomCollection(atom.Children); new_info.SetChanInfoType(content_type); new_info.SetChanInfoStreamType(mime_type); channel_info = new ChannelInfo(new_info); } } Channel.ChannelInfo = channel_info; BroadcastHostInfo(); }
private void OnChannelInfoChanged(AtomCollection info) { contents.ChannelInfo = new ChannelInfo(info); }
private void OnChannelTrackChanged(AtomCollection info) { contents.ChannelTrack = new ChannelTrack(info); }
protected override void DoStop(StopReason reason) { switch (reason) { case StopReason.None: break; case StopReason.Any: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT)); break; case StopReason.SendTimeoutError: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_SKIP)); break; case StopReason.BadAgentError: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_BADAGENT)); break; case StopReason.ConnectionError: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_READ)); break; case StopReason.NotIdentifiedError: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_NOTIDENTIFIED)); break; case StopReason.UnavailableError: { //次に接続するホストを送ってQUIT foreach (var node in SelectSourceHosts((IPEndPoint)RemoteEndPoint)) { if (Downhost!=null && Downhost.SessionID==node.SessionID) continue; var host_atom = new AtomCollection(node.Extra); Atom ip = host_atom.FindByName(Atom.PCP_HOST_IP); while (ip!=null) { host_atom.Remove(ip); ip = host_atom.FindByName(Atom.PCP_HOST_IP); } Atom port = host_atom.FindByName(Atom.PCP_HOST_PORT); while (port!=null) { host_atom.Remove(port); port = host_atom.FindByName(Atom.PCP_HOST_PORT); } host_atom.SetHostSessionID(node.SessionID); var globalendpoint = node.GlobalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(globalendpoint.Address); host_atom.AddHostPort(globalendpoint.Port); var localendpoint = node.LocalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(localendpoint.Address); host_atom.AddHostPort(localendpoint.Port); host_atom.SetHostNumRelays(node.RelayCount); host_atom.SetHostNumListeners(node.DirectCount); host_atom.SetHostChannelID(Channel.ChannelID); host_atom.SetHostFlags1( (node.IsFirewalled ? PCPHostFlags1.Firewalled : PCPHostFlags1.None) | (node.IsTracker ? PCPHostFlags1.Tracker : PCPHostFlags1.None) | (node.IsRelayFull ? PCPHostFlags1.None : PCPHostFlags1.Relay) | (node.IsDirectFull ? PCPHostFlags1.None : PCPHostFlags1.Direct) | (node.IsReceiving ? PCPHostFlags1.Receiving : PCPHostFlags1.None) | (node.IsControlFull ? PCPHostFlags1.None : PCPHostFlags1.ControlIn)); Send(new Atom(Atom.PCP_HOST, host_atom)); Logger.Debug("Sending Node: {0}({1})", globalendpoint, node.SessionID.ToString("N")); } } Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_UNAVAILABLE)); break; case StopReason.OffAir: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_OFFAIR)); break; case StopReason.UserShutdown: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_SHUTDOWN)); break; } base.DoStop(reason); }
protected void OnPCPBcst(Atom atom) { var dest = atom.Children.GetBcstDest(); if (dest==null || dest==PeerCast.SessionID) { foreach (var c in atom.Children) ProcessAtom(c); } var ttl = atom.Children.GetBcstTTL(); var hops = atom.Children.GetBcstHops(); var from = atom.Children.GetBcstFrom(); var group = atom.Children.GetBcstGroup(); if (ttl != null && hops != null && group != null && from != null && dest != PeerCast.SessionID && ttl>1) { var bcst = new AtomCollection(atom.Children); bcst.SetBcstTTL((byte)(ttl - 1)); bcst.SetBcstHops((byte)(hops + 1)); Channel.Broadcast(uphost, new Atom(atom.Name, bcst), group.Value); } }
protected virtual void OnPCPBcst(Atom atom) { var dest = atom.Children.GetBcstDest(); var ttl = atom.Children.GetBcstTTL(); var hops = atom.Children.GetBcstHops(); var from = atom.Children.GetBcstFrom(); var group = atom.Children.GetBcstGroup(); if (ttl != null && hops != null && group != null && from != null && dest != PeerCast.SessionID && ttl>0) { Logger.Debug("Relaying BCST TTL: {0}, Hops: {1}", ttl, hops); var bcst = new AtomCollection(atom.Children); bcst.SetBcstTTL((byte)(ttl - 1)); bcst.SetBcstHops((byte)(hops + 1)); Channel.Broadcast(Downhost, new Atom(atom.Name, bcst), group.Value); } if (dest==null || dest==PeerCast.SessionID) { Logger.Debug("Processing BCST({0})", dest==null ? "(null)" : dest.Value.ToString("N")); foreach (var c in atom.Children) ProcessAtom(c); } }
/// <summary> /// 現在のチャンネルとPeerCastの状態からHostパケットを作ります /// </summary> /// <returns>作ったPCP_HOSTパケット</returns> private Atom CreateHostPacket() { var host = new AtomCollection(); host.SetHostChannelID(Channel.ChannelID); host.SetHostSessionID(PeerCast.SessionID); var globalendpoint = PeerCast.GetGlobalEndPoint( RemoteEndPoint.AddressFamily, OutputStreamType.Relay); if (globalendpoint!=null) { host.AddHostIP(globalendpoint.Address); host.AddHostPort(globalendpoint.Port); } var localendpoint = PeerCast.GetLocalEndPoint( RemoteEndPoint.AddressFamily, OutputStreamType.Relay); if (localendpoint!=null) { host.AddHostIP(localendpoint.Address); host.AddHostPort(localendpoint.Port); } host.SetHostNumListeners(Channel.LocalDirects); host.SetHostNumRelays(Channel.LocalRelays); host.SetHostUptime(Channel.Uptime); if (Channel.Contents.Count > 0) { host.SetHostOldPos((uint)(Channel.Contents.Oldest.Position & 0xFFFFFFFFU)); host.SetHostNewPos((uint)(Channel.Contents.Newest.Position & 0xFFFFFFFFU)); } PCPVersion.SetHostVersion(host); host.SetHostFlags1( (PeerCast.AccessController.IsChannelRelayable(Channel) ? PCPHostFlags1.Relay : 0) | (PeerCast.AccessController.IsChannelPlayable(Channel) ? PCPHostFlags1.Direct : 0) | ((!PeerCast.IsFirewalled.HasValue || PeerCast.IsFirewalled.Value) ? PCPHostFlags1.Firewalled : 0) | (RecvRate>0 ? PCPHostFlags1.Receiving : 0)); host.SetHostUphostIP(RemoteEndPoint.Address); host.SetHostUphostPort(RemoteEndPoint.Port); return new Atom(Atom.PCP_HOST, host); }
protected virtual bool PingHost(IPEndPoint target, Guid remote_session_id) { Logger.Debug("Ping requested. Try to ping: {0}({1})", target, remote_session_id); bool result = false; try { var client = new System.Net.Sockets.TcpClient(); client.Connect(target); client.ReceiveTimeout = 3000; client.SendTimeout = 3000; var stream = client.GetStream(); var conn = new Atom(Atom.PCP_CONNECT, 1); AtomWriter.Write(stream, conn); var helo = new AtomCollection(); helo.SetHeloSessionID(PeerCast.SessionID); AtomWriter.Write(stream, new Atom(Atom.PCP_HELO, helo)); var res = AtomReader.Read(stream); if (res.Name==Atom.PCP_OLEH) { var session_id = res.Children.GetHeloSessionID(); if (session_id.HasValue && session_id.Value==remote_session_id) { Logger.Debug("Ping succeeded"); result = true; } else { Logger.Debug("Ping failed. Remote SessionID mismatched"); } } AtomWriter.Write(stream, new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT)); stream.Close(); client.Close(); } catch (InvalidDataException e) { Logger.Debug("Ping failed"); Logger.Debug(e); } catch (System.Net.Sockets.SocketException e) { Logger.Debug("Ping failed"); Logger.Debug(e); } catch (EndOfStreamException e) { Logger.Debug("Ping failed"); Logger.Debug(e); } catch (System.IO.IOException io_error) { Logger.Debug("Ping failed"); Logger.Debug(io_error); if (!(io_error.InnerException is System.Net.Sockets.SocketException)) { throw; } } return result; }
public async Task ReadAsync(IContentSink sink, Stream stream, CancellationToken cancel_token) { int streamIndex = -1; DateTime streamOrigin = DateTime.Now; long contentPosition = 0; bool eof = false; do { ASFChunk chunk = null; try { chunk = await ASFChunk.ReadAsync(stream, cancel_token).ConfigureAwait(false); } catch (EndOfStreamException) { eof = true; continue; } switch (chunk.KnownType) { case ASFChunk.ChunkType.Header: { var header = ASFHeader.Read(chunk); var info = new AtomCollection(Channel.ChannelInfo.Extra); info.SetChanInfoBitrate(header.Bitrate); if (header.Streams.Any(type => type == ASFHeader.StreamType.Video)) { info.SetChanInfoType("WMV"); info.SetChanInfoStreamType("video/x-ms-wmv"); info.SetChanInfoStreamExt(".wmv"); } else if (header.Streams.Any(type => type == ASFHeader.StreamType.Audio)) { info.SetChanInfoType("WMA"); info.SetChanInfoStreamType("audio/x-ms-wma"); info.SetChanInfoStreamExt(".wma"); } else { info.SetChanInfoType("ASF"); info.SetChanInfoStreamType("video/x-ms-asf"); info.SetChanInfoStreamExt(".asf"); } sink.OnChannelInfo(new ChannelInfo(info)); streamIndex = Channel.GenerateStreamID(); streamOrigin = DateTime.Now; contentPosition = 0; var data = chunk.ToByteArray(); sink.OnContentHeader(new Content(streamIndex, TimeSpan.Zero, contentPosition, data, PCPChanPacketContinuation.None)); contentPosition += data.Length; break; } case ASFChunk.ChunkType.Data: { var data = chunk.ToByteArray(); sink.OnContent( new Content(streamIndex, DateTime.Now - streamOrigin, contentPosition, chunk.ToByteArray(), PCPChanPacketContinuation.None) ); contentPosition += data.Length; } break; case ASFChunk.ChunkType.Unknown: break; } } while (!eof); }
private ChannelTrack CreateChannelTrack(BroadcastViewModel viewModel) { var collection = new AtomCollection(); collection.SetChanTrackTitle(viewModel.TrackTitle); collection.SetChanTrackGenre(viewModel.TrackGenre); collection.SetChanTrackAlbum(viewModel.TrackAlbum); collection.SetChanTrackCreator(viewModel.TrackArtist); collection.SetChanTrackURL(viewModel.TrackUrl); return new ChannelTrack(collection); }
private ChannelInfo CreateChannelInfo(BroadcastViewModel viewModel) { var info = new AtomCollection(); if (viewModel.bitrate.HasValue) info.SetChanInfoBitrate(viewModel.bitrate.Value); info.SetChanInfoName(viewModel.channelName); info.SetChanInfoGenre(viewModel.genre); info.SetChanInfoDesc(viewModel.description); info.SetChanInfoComment(viewModel.comment); info.SetChanInfoURL(viewModel.contactUrl); return new ChannelInfo(info); }
private ChannelTrack UpdateChannelTrack(ChannelTrack a, ChannelTrack b) { var base_atoms = new AtomCollection(a.Extra); base_atoms.Update(b.Extra); return new ChannelTrack(base_atoms); }
private void OnChannelInfoChanged(AtomCollection info) { ContentSink.OnChannelInfo(new ChannelInfo(info)); }
private async Task OnPCPHelo(Atom atom, CancellationToken cancel_token) { if (Downhost != null) { return; } Logger.Debug("Helo received"); var session_id = atom.Children.GetHeloSessionID(); int remote_port = 0; if (session_id != null) { var host = new HostBuilder(); host.SessionID = session_id.Value; var port = atom.Children.GetHeloPort(); var ping = atom.Children.GetHeloPing(); if (port != null) { remote_port = port.Value; } else if (ping != null) { if (IsPingTarget(((IPEndPoint)RemoteEndPoint).Address) && await PingHost(new IPEndPoint(((IPEndPoint)RemoteEndPoint).Address, ping.Value), session_id.Value, cancel_token).ConfigureAwait(false)) { remote_port = ping.Value; } else { remote_port = 0; } } else { remote_port = 0; } if (remote_port != 0) { var ip = new IPEndPoint(((IPEndPoint)RemoteEndPoint).Address, remote_port); if (host.GlobalEndPoint == null || !host.GlobalEndPoint.Equals(ip)) { host.GlobalEndPoint = ip; } } host.IsFirewalled = remote_port == 0; host.Extra.Update(atom.Children); Downhost = host.ToHost(); var user_agent = atom.Children.GetHeloAgent(); if (user_agent != null) { UserAgent = user_agent; } } var oleh = new AtomCollection(); if (RemoteEndPoint != null && RemoteEndPoint.AddressFamily == Channel.NetworkAddressFamily) { oleh.SetHeloRemoteIP(((IPEndPoint)RemoteEndPoint).Address); } oleh.SetHeloAgent(PeerCast.AgentName); oleh.SetHeloSessionID(PeerCast.SessionID); oleh.SetHeloRemotePort(remote_port); PCPVersion.SetHeloVersion(oleh); await Connection.WriteAsync(new Atom(Atom.PCP_OLEH, oleh), cancel_token).ConfigureAwait(false); if (Downhost == null) { Logger.Info("Helo has no SessionID"); //セッションIDが無かった Stop(StopReason.NotIdentifiedError); } else if ((Downhost.Extra.GetHeloVersion() ?? 0) < 1200) { Logger.Info("Helo version {0} is too old", Downhost.Extra.GetHeloVersion() ?? 0); //クライアントバージョンが無かった、もしくは古すぎ Stop(StopReason.BadAgentError); } else if (IsRelayFull) { Logger.Debug("Handshake succeeded {0}({1}) but relay is full", Downhost.GlobalEndPoint, Downhost.SessionID.ToString("N")); Stop(StopReason.UnavailableError); } else { Logger.Debug("Handshake succeeded {0}({1})", Downhost.GlobalEndPoint, Downhost.SessionID.ToString("N")); await Connection.WriteAsync(new Atom(Atom.PCP_OK, (int)1), cancel_token).ConfigureAwait(false); } }
private void SetChannelInfo(string channelId, JObject info, JObject track) { var channel = GetChannel(channelId); if (channel!=null && channel.IsBroadcasting) { if (info!=null) { var new_info = new AtomCollection(channel.ChannelInfo.Extra); if (info["name"]!=null) new_info.SetChanInfoName((string)info["name"]); if (info["url"]!=null) new_info.SetChanInfoURL((string)info["url"]); if (info["genre"]!=null) new_info.SetChanInfoGenre((string)info["genre"]); if (info["desc"]!=null) new_info.SetChanInfoDesc((string)info["desc"]); if (info["comment"]!=null) new_info.SetChanInfoComment((string)info["comment"]); channel.ChannelInfo = new ChannelInfo(new_info); } if (track!=null) { var new_track = new AtomCollection(channel.ChannelTrack.Extra); if (track["name"]!=null) new_track.SetChanTrackTitle((string)track["name"]); if (track["genre"]!=null) new_track.SetChanTrackGenre((string)track["genre"]); if (track["album"]!=null) new_track.SetChanTrackAlbum((string)track["album"]); if (track["creator"]!=null) new_track.SetChanTrackCreator((string)track["creator"]); if (track["url"]!=null) new_track.SetChanTrackURL((string)track["url"]); channel.ChannelTrack = new ChannelTrack(new_track); } } }
/// <summary> /// 指定したパケットを含むブロードキャストパケットを作成します /// </summary> /// <param name="group">配送先グループ</param> /// <param name="packet">配送するパケット</param> /// <returns>作成したPCP_BCSTパケット</returns> private Atom CreateBroadcastPacket(BroadcastGroup group, Atom packet) { var bcst = new AtomCollection(); bcst.SetBcstFrom(PeerCast.SessionID); bcst.SetBcstGroup(group); bcst.SetBcstHops(0); bcst.SetBcstTTL(11); PCPVersion.SetBcstVersion(bcst); bcst.SetBcstChannelID(Channel.ChannelID); bcst.Add(packet); return new Atom(Atom.PCP_BCST, bcst); }
private string BroadcastChannel( int? yellowPageId, string sourceUri, string contentReader, JObject info, JObject track, string sourceStream=null) { IYellowPageClient yp = null; if (yellowPageId.HasValue) { yp = PeerCast.YellowPages.FirstOrDefault(y => GetObjectId(y)==yellowPageId.Value); if (yp==null) throw new RPCError(RPCErrorCode.InvalidParams, "Yellow page not found"); } if (sourceUri==null) throw new RPCError(RPCErrorCode.InvalidParams, "source uri required"); Uri source; try { source = new Uri(sourceUri); } catch (UriFormatException) { throw new RPCError(RPCErrorCode.InvalidParams, "Invalid Uri"); } var content_reader = PeerCast.ContentReaderFactories.FirstOrDefault(reader => reader.Name==contentReader); if (content_reader==null) throw new RPCError(RPCErrorCode.InvalidParams, "Content reader not found"); var source_stream = PeerCast.SourceStreamFactories .Where(sstream => (sstream.Type & SourceStreamType.Broadcast)!=0) .FirstOrDefault(sstream => sstream.Name==sourceStream); if (source_stream==null) { source_stream = PeerCast.SourceStreamFactories .Where(sstream => (sstream.Type & SourceStreamType.Broadcast)!=0) .FirstOrDefault(sstream => sstream.Scheme==source.Scheme); } if (source_stream==null) throw new RPCError(RPCErrorCode.InvalidParams, "Source stream not found"); var new_info = new AtomCollection(); if (info!=null) { info.TryGetThen("name", v => new_info.SetChanInfoName(v)); info.TryGetThen("url", v => new_info.SetChanInfoURL(v)); info.TryGetThen("genre", v => new_info.SetChanInfoGenre(v)); info.TryGetThen("desc", v => new_info.SetChanInfoDesc(v)); info.TryGetThen("comment", v => new_info.SetChanInfoComment(v)); } var channel_info = new ChannelInfo(new_info); if (channel_info.Name==null || channel_info.Name=="") { throw new RPCError(RPCErrorCode.InvalidParams, "Channel name must not be empty"); } var channel_id = PeerCastStation.Core.BroadcastChannel.CreateChannelID( PeerCast.BroadcastID, channel_info.Name, channel_info.Genre ?? "", source.ToString()); var channel = PeerCast.BroadcastChannel(yp, channel_id, channel_info, source, source_stream, content_reader); if (track!=null) { var new_track = new AtomCollection(channel.ChannelTrack.Extra); track.TryGetThen("name", v => new_track.SetChanTrackTitle(v)); track.TryGetThen("genre", v => new_track.SetChanTrackGenre(v)); track.TryGetThen("album", v => new_track.SetChanTrackAlbum(v)); track.TryGetThen("creator", v => new_track.SetChanTrackCreator(v)); track.TryGetThen("url", v => new_track.SetChanTrackURL(v)); channel.ChannelTrack = new ChannelTrack(new_track); } return channel.ChannelID.ToString("N").ToUpper(); }
private bool SendPCPHelo() { var helo = new AtomCollection(); helo.SetHeloAgent(PeerCast.AgentName); helo.SetHeloSessionID(PeerCast.SessionID); if (PeerCast.IsFirewalled.HasValue) { if (PeerCast.IsFirewalled.Value) { //Do nothing } else { var listener = PeerCast.FindListener( RemoteEndPoint.Address, OutputStreamType.Relay | OutputStreamType.Metadata); helo.SetHeloPort(listener.LocalEndPoint.Port); } } else { var listener = PeerCast.FindListener( RemoteEndPoint.Address, OutputStreamType.Relay | OutputStreamType.Metadata); if (listener!=null) { helo.SetHeloPing(listener.LocalEndPoint.Port); } } PCPVersion.SetHeloVersion(helo); try { connection.Send(stream => { AtomWriter.Write(stream, new Atom(Atom.PCP_HELO, helo)); }); } catch (IOException e) { Logger.Info(e); Stop(StopReason.ConnectionError); return false; } return true; }
/// <summary> /// HostBuilderを初期化します /// </summary> public HostBuilder() { SessionID = Guid.Empty; BroadcastID = Guid.Empty; LocalEndPoint = null; GlobalEndPoint = null; RelayCount = 0; DirectCount = 0; IsFirewalled = false; IsTracker = false; IsRelayFull = false; IsDirectFull = false; IsReceiving = false; IsControlFull = false; Extensions = new List<string>(); Extra = new AtomCollection(); }
public ParsedContent Read(Stream stream) { var res = new ParsedContent(); var info = new AtomCollection(Channel.ChannelInfo.Extra); var processed = false; var eos = false; while (!eos) { var start_pos = stream.Position; try { switch (state) { case ReaderState.Header: { var bin = ReadBytes(stream, 13); var header = new FileHeader(bin); if (header.IsValid) { Logger.Info("FLV Header found"); fileHeader = header; bin = header.Binary; res.ContentHeader = new Content(position, bin); res.Contents = null; info.SetChanInfoType("FLV"); info.SetChanInfoStreamType("video/x-flv"); info.SetChanInfoStreamExt(".flv"); res.ChannelInfo = new ChannelInfo(info); position = bin.Length; tags.Clear(); state = ReaderState.Body; } else { throw new BadDataException(); } } break; case ReaderState.Body: { var bin = ReadBytes(stream, 11); var read_valid = false; var body = new FLVTag(bin); if (body.IsValidHeader) { body.ReadBody(stream); body.ReadFooter(stream); if (body.IsValidFooter) { read_valid = true; bin = body.Binary; if (res.Contents == null) { res.Contents = new List <Content>(); } res.Contents.Add(new Content(position, bin)); tags.AddLast(new TagDesc { Timestamp = body.Timestamp / 1000.0, DataSize = body.DataSize }); var timespan = tags.Last.Value.Timestamp - tags.First.Value.Timestamp; if (timespan >= 30.0) { var sz = tags.Take(tags.Count - 1).Sum(t => t.DataSize); info.SetChanInfoBitrate((int)(sz * 8 / timespan + 900) / 1000); res.ChannelInfo = new ChannelInfo(info); while (tags.Count > 1) { tags.RemoveFirst(); } } position += bin.Length; } } if (!read_valid) { stream.Position = start_pos; var header = new FileHeader(ReadBytes(stream, 13)); if (header.IsValid) { Logger.Info("New FLV Header found"); read_valid = true; fileHeader = header; bin = header.Binary; res.ContentHeader = new Content(0, bin); res.Contents = null; info.SetChanInfoType("FLV"); info.SetChanInfoStreamType("video/x-flv"); info.SetChanInfoStreamExt(".flv"); res.ChannelInfo = new ChannelInfo(info); tags.Clear(); position = bin.Length; } } if (!read_valid) { throw new BadDataException(); } } break; } processed = true; } catch (EndOfStreamException) { if (!processed) { throw; } stream.Position = start_pos; eos = true; } catch (BadDataException) { stream.Position = start_pos + 1; } } return(res); }
/// <summary> /// 指定されたHostBuilderの値でHostBuilderを初期化します /// </summary> /// <param name="host">初期化元のHostBuilder</param> public HostBuilder(HostBuilder host) { if (host!=null) { SessionID = host.SessionID; BroadcastID = host.BroadcastID; LocalEndPoint = host.LocalEndPoint; GlobalEndPoint = host.GlobalEndPoint; RelayCount = host.RelayCount; DirectCount = host.DirectCount; IsFirewalled = host.IsFirewalled; IsTracker = host.IsTracker; IsRelayFull = host.IsRelayFull; IsDirectFull = host.IsDirectFull; IsReceiving = host.IsReceiving; IsControlFull = host.IsControlFull; Extensions = new List<string>(host.Extensions); Extra = new AtomCollection(host.Extra); } else { SessionID = Guid.Empty; BroadcastID = Guid.Empty; LocalEndPoint = null; GlobalEndPoint = null; RelayCount = 0; DirectCount = 0; IsFirewalled = false; IsTracker = false; IsRelayFull = false; IsDirectFull = false; IsReceiving = false; IsControlFull = false; Extensions = new List<string>(); Extra = new AtomCollection(); } }