示例#1
0
        private IEnumerable <ChannelInfo> FindChannels(ChannelList channelList, string name, string uid)
        {
            // if there's only a single channel with the given name, use it regardless of UID (allows for a changed freq/tranpsonder)
            IList <ChannelInfo> list = channelList.GetChannelByName(name).ToList();

            if (list.Count == 1)
            {
                return(list);
            }

            string[] uidParts;
            if (uid.StartsWith("C") && (uidParts = uid.Split('-')).Length <= 4)
            {
                // older CSV files didn't use the Transponder as part of the UID, which is necessary
                // to distinguish between DVB-T channels with identical (onid,tsid,sid), which may be received
                // from multiple regional transmitters on different transponders
                int onid = int.Parse(uidParts[1]);
                int tsid = int.Parse(uidParts[2]);
                int sid  = int.Parse(uidParts[3]);
                return(channelList.Channels.Where(c =>
                                                  c.OriginalNetworkId == onid &&
                                                  c.TransportStreamId == tsid &&
                                                  c.ServiceId == sid
                                                  ).ToList());
            }

            var byUidList = channelList.GetChannelByUid(uid);

            return(byUidList);
        }
示例#2
0
        /// <summary>
        /// Applies the ordering of a reference list to the TV list
        /// </summary>
        /// <param name="refDataRoot">object representing the whole reference list file</param>
        /// <param name="refList">the particular ChannelList to take the order from</param>
        /// <param name="tvList">the particular ChannelList to apply the order to</param>
        /// <param name="addProxyChannels">if true, a placeholder channel will be created in the tvList if there is no matching TV channel for a reference channel</param>
        /// <param name="positionOffset">can be used to shift the Pr# of the reference list so avoid conflicts with already assigned Pr# in the TV list</param>
        /// <param name="chanFilter">a function which is called for each channel in the reference list (with 2nd parameter=true) and TV list (2nd parameter=false) to determine if the channel is part of the reordering
        /// This is used to filter for analog/digital, radio/TV, antenna/cable/sat/ip
        /// </param>
        /// <param name="overwrite">controls whether Pr# will be reassigned to the reference channel when they are already in-use in the TV list</param>
        /// <param name="consecutive">when true, consecutive numbers will be used instead of the Pr# in the reference list when applying the order</param>
        public void ApplyReferenceList(DataRoot refDataRoot, ChannelList refList, ChannelList tvList, bool addProxyChannels = true, int positionOffset = 0, Func <ChannelInfo, bool, bool> chanFilter = null, bool overwrite = true, bool consecutive = false)
        {
            // create Hashtable for exact channel lookup
            // the UID of a TV channel list contains a source-indicator (Analog, Cable, Sat), which may be undefined in the reference list)
            var onidTsidSid = new Dictionary <long, List <ChannelInfo> >();

            foreach (var channel in tvList.Channels)
            {
                var key  = DvbKey(channel.OriginalNetworkId, channel.TransportStreamId, channel.ServiceId);
                var list = onidTsidSid.TryGet(key);
                if (list == null)
                {
                    list = new List <ChannelInfo>();
                    onidTsidSid.Add(key, list);
                }
                list.Add(channel);
            }

            var incNr = 1 + positionOffset;

            foreach (var refChannel in refList.Channels.OrderBy(ch => ch.OldProgramNr))
            {
                if (!(chanFilter?.Invoke(refChannel, true) ?? true))
                {
                    continue;
                }

                var tvChannels = tvList.GetChannelByUid(refChannel.Uid);

                // try to find matching channels based on ONID+TSID+SID
                if (tvChannels.Count == 0)
                {
                    var key = DvbKey(refChannel.OriginalNetworkId, refChannel.TransportStreamId, refChannel.ServiceId);
                    List <ChannelInfo> candidates;
                    if (key != 0 && onidTsidSid.TryGetValue(key, out candidates))
                    {
                        tvChannels = candidates;

                        // narrow the list down further when a transponder is also provided (i.e. the same TV channel can be received on multiple DVB-T frequencies)
                        if (tvChannels.Count > 1 && !string.IsNullOrEmpty(refChannel.ChannelOrTransponder))
                        {
                            candidates = tvChannels.Where(ch => ch.ChannelOrTransponder == refChannel.ChannelOrTransponder).ToList();
                            if (candidates.Count > 0)
                            {
                                tvChannels = candidates;
                            }
                        }
                    }
                }

                // try to find matching channels by name
                if (tvChannels.Count == 0 && !string.IsNullOrWhiteSpace(refChannel.Name))
                {
                    tvChannels = tvList.GetChannelByName(refChannel.Name).ToList();
                }

                // get the first unassigned channel from the candidates (e.g. when matching by non-unique names), or fall back to the first matching channel (e.g. by unique ID)
                ChannelInfo tvChannel = tvChannels.FirstOrDefault(c => c.GetPosition(0) == -1);
                if (tvChannel == null && tvChannels.Count > 0)
                {
                    tvChannel = tvChannels[0];
                }

                if (tvChannel != null)
                {
                    if (!(chanFilter?.Invoke(tvChannel, false) ?? true))
                    {
                        continue;
                    }

                    var newNr = consecutive ? incNr++ : refChannel.OldProgramNr + positionOffset;

                    // handle conflicts when the number is already in-use
                    var curChans = tvList.GetChannelByNewProgNr(newNr);
                    if (!overwrite && curChans.Any())
                    {
                        continue;
                    }
                    foreach (var chan in curChans)
                    {
                        chan.NewProgramNr = -1;
                    }

                    tvChannel.SetPosition(0, newNr);
                    tvChannel.Skip      = refChannel.Skip;
                    tvChannel.Lock      = refChannel.Lock;
                    tvChannel.Hidden    = refChannel.Hidden;
                    tvChannel.IsDeleted = refChannel.IsDeleted;
                    if ((tvChannel.SignalSource & SignalSource.Analog) != 0 && !string.IsNullOrEmpty(refChannel.Name))
                    {
                        tvChannel.Name           = refChannel.Name;
                        tvChannel.IsNameModified = true;
                    }

                    ApplyFavorites(refDataRoot, refChannel, tvChannel);
                }
                else if (addProxyChannels)
                {
                    tvChannel = new ChannelInfo(refChannel.SignalSource, refChannel.Uid, refChannel.OldProgramNr, refChannel.Name);
                    tvList.AddChannel(tvChannel);
                }
            }
        }
示例#3
0
    private IEnumerable<ChannelInfo> FindChannels(ChannelList channelList, string name, string uid)
    {
      // if there's only a single channel with the given name, use it regardless of UID (allows for a changed freq/tranpsonder)
      IList<ChannelInfo> list = channelList.GetChannelByName(name).ToList();
      if (list.Count == 1)
        return list;

      string[] uidParts;
      if (uid.StartsWith("C") && (uidParts = uid.Split('-')).Length <= 4)
      {
        // older CSV files didn't use the Transponder as part of the UID, which is necessary
        // to distinguish between DVB-T channels with identical (onid,tsid,sid), which may be received 
        // from multiple regional transmitters on different transponders
        int onid = int.Parse(uidParts[1]);
        int tsid = int.Parse(uidParts[2]);
        int sid = int.Parse(uidParts[3]);
        return channelList.Channels.Where(c => 
          c.OriginalNetworkId == onid && 
          c.TransportStreamId == tsid &&
          c.ServiceId == sid
          ).ToList();
      }

      var byUidList = channelList.GetChannelByUid(uid);
      return byUidList;
    }
示例#4
0
        private ChannelInfo FindChannel(ChannelList tvList, int subListIndex, ChannelInfo refChannel, Dictionary <long, List <ChannelInfo> > onidTsidSid)
        {
            List <ChannelInfo> candidates;

            // try to find matching channels based on UID or ONID+TSID+SID+Transponder
            var channels = refChannel.Uid == "0-0-0" ? new List <ChannelInfo>() : tvList.GetChannelByUid(refChannel.Uid).ToList();

            if (channels.Count == 0)
            {
                var key = DvbKey(refChannel.OriginalNetworkId, refChannel.TransportStreamId, refChannel.ServiceId);
                if (key != 0 && onidTsidSid.TryGetValue(key, out candidates))
                {
                    channels = candidates;
                }

                // narrow the list down further when a transponder is also provided (i.e. the same channel can be received on multiple DVB-T frequencies)
                if (channels.Count > 1 && !string.IsNullOrEmpty(refChannel.ChannelOrTransponder))
                {
                    candidates = channels.Where(ch => ch.ChannelOrTransponder == refChannel.ChannelOrTransponder).ToList();
                    if (candidates.Count > 0)
                    {
                        channels = candidates;
                    }
                }
            }
            var channel = channels.FirstOrDefault(c => c.GetPosition(subListIndex) == -1);

            if (channel != null)
            {
                return(channel);
            }


            // try to find matching channels by name
            channels = tvList.GetChannelByName(refChannel.Name).Where(c => c.GetPosition(subListIndex) == -1).ToList();

            // if the reference list has information about a service type (tv/radio/data), then only consider channels matching it (or lacking service type information)
            var serviceType = refChannel.SignalSource & SignalSource.MaskTvRadioData;

            if (serviceType != 0)
            {
                channels = channels.Where(ch =>
                {
                    var m = ch.SignalSource & SignalSource.MaskTvRadioData;
                    return(m == 0 || m == serviceType);
                }).ToList();
            }

            if (channels.Count == 0)
            {
                return(null);
            }

            if (channels.Count > 1)
            {
                // exact upper/lowercase matching (often there are channels like "DISCOVERY" and "Discovery")
                candidates = channels.Where(c => c.Name == refChannel.Name).ToList();
                if (candidates.Count > 0)
                {
                    channels = candidates;
                }
            }
            if (channels.Count > 1)
            {
                // prefer unencrypted channels
                candidates = channels.Where(c => c.Encrypted.HasValue && c.Encrypted.Value == false).ToList();
                if (candidates.Count > 0)
                {
                    channels = candidates;
                }
            }
            return(channels[0]);
        }
示例#5
0
        private void ParseChannel(string line)
        {
            var parts = line.Split(Separators);

            if (parts.Length < 2)
            {
                return;
            }
            int         progNr;
            Transponder transponder = null;

            if (!int.TryParse(parts[0], out progNr))
            {
                return;
            }
            if (parts.Length >= 3)
            {
                int transponderIndex;
                if (int.TryParse(parts[2], out transponderIndex))
                {
                    transponder = this.dataRoot.Transponder.TryGet(transponderIndex);
                    if (transponder == null)
                    {
                        warnings.AppendFormat("Line #{0,4}: invalid transponder index {1}\r\n", this.lineNumber, transponderIndex);
                    }
                }
            }

            string name = parts[1].Replace("\"", "");

            if (name.Trim().Length == 0)
            {
                return;
            }

            int found    = 0;
            var channels = channelList.GetChannelByName(name);

            if (transponder != null)
            {
                channels = channels.Where(chan => chan.Transponder == transponder);
            }

            foreach (var channel in channels)
            {
                if (channel.NewProgramNr != -1)
                {
                    continue;
                }
                ++found;
                if (found > 1)
                {
                    break;
                }
                channel.NewProgramNr = progNr;
            }

            if (found == 0)
            {
                this.warnings.AppendFormat("Line {0,4}: Pr# {1,4}, channel '{2}' could not be found\r\n", this.lineNumber, progNr, name);
            }
            if (found > 1)
            {
                this.warnings.AppendFormat("Line {0,4}: Pr# {1,4}, channel '{2}' found multiple times\r\n", this.lineNumber, progNr, name);
            }
        }