public override bool StartRecording(string serverHostName, int tcpPort, CardChannelAllocation channelAllocation,
                                            DateTime startTimeUtc, DateTime stopTimeUtc, UpcomingProgram recordingProgram, string suggestedBaseFileName)
        {
            bool result = false;

            TvDatabase.Card recordOnCard = GetCardByCardId(channelAllocation.CardId);
            if (recordOnCard != null)
            {
                TvDatabase.Channel channel = GetLinkedMediaPortalChannel(channelAllocation.ChannelType,
                                                                         channelAllocation.ChannelId, channelAllocation.ChannelName);
                if (channel != null)
                {
                    result = this.RecordingThreads.StartNewThread(new RecordingThread(this.RecorderTunerId,
                                                                                      serverHostName, tcpPort, channelAllocation, startTimeUtc, stopTimeUtc,
                                                                                      recordingProgram, suggestedBaseFileName, recordOnCard, channel));
                    if (!result)
                    {
                        Log(TraceEventType.Error, "{0} - Already recording {1}", this.Name, recordingProgram.CreateProgramTitle());
                    }
                }
                else
                {
                    Log(TraceEventType.Error, "{0} - Channel {1} not found", this.Name, channelAllocation.ChannelName);
                }
            }
            else
            {
                Log(TraceEventType.Error, "{0} - Card {1} not found", this.Name, channelAllocation.CardId);
            }

            return(result);
        }
예제 #2
0
        public static bool CardFreeOrUsingSameTransponder(TvDatabase.Card card, TvDatabase.Channel channel, IUser userToIgnore)
        {
            IUser[] cardUsers = TvServerPlugin.TvController_GetUsersForCard(card.IdCard);
            if (cardUsers != null)
            {
                TvDatabase.TuningDetail tuning = Utility.FindTuningDetailOnCard(channel, card.IdCard);

                HashSet <int> activeChannels = new HashSet <int>();

                foreach (IUser cardUser in cardUsers)
                {
                    if (userToIgnore == null ||
                        cardUser.Name != userToIgnore.Name)
                    {
                        if (!cardUser.Name.Equals("epg", StringComparison.InvariantCultureIgnoreCase))
                        {
                            activeChannels.Add(cardUser.IdChannel);
                            if (!Utility.IsSameTransponder(card.IdCard, tuning, cardUser.IdChannel))
                            {
                                return(false);
                            }
                        }
                    }
                }

                return(activeChannels.Contains(channel.IdChannel) ||
                       card.DecryptLimit == 0 ||
                       activeChannels.Count < card.DecryptLimit);
            }
            return(true);
        }
        public override string AllocateCard(Channel channel, CardChannelAllocation[] alreadyAllocated, bool useReversePriority)
        {
            try
            {
                //
                // Find the channel in MediaPortal (match by DisplayName) and get all the
                // cards this channel is mapped to.
                //
                TvDatabase.Channel     mpChannel;
                List <TvDatabase.Card> availableCards = GetCardsForChannel(channel, out mpChannel);

                // Sort the cards by reverse(!) priority.
                int order = useReversePriority ? -1 : 1;
                availableCards.Sort(delegate(TvDatabase.Card c1, TvDatabase.Card c2) { return(order * c1.Priority.CompareTo(c2.Priority)); });

                //
                // Now remove all cards that were previously allocated.
                //
                foreach (CardChannelAllocation allocation in alreadyAllocated)
                {
                    TvDatabase.Card        allocatedCard           = GetCardByCardId(allocation.CardId);
                    List <int>             allocatedHybridGroupIds = Utility.GetHybridGroupIds(allocatedCard);
                    List <TvDatabase.Card> cardsToRemove           = new List <TvDatabase.Card>();
                    foreach (TvDatabase.Card card in availableCards)
                    {
                        bool isHybrid = (card.IdCard != allocatedCard.IdCard) &&
                                        Utility.IsInSameHybridGroup(card, allocatedHybridGroupIds);
                        if (isHybrid ||
                            !IsCardFreeOrSharedByAllocation(card, mpChannel, allocation, alreadyAllocated))
                        {
                            cardsToRemove.Add(card);
                        }
                    }
                    foreach (TvDatabase.Card cardToRemove in cardsToRemove)
                    {
                        availableCards.Remove(cardToRemove);
                    }
                }

                //
                // If there's still at least one card available, return the card
                // with the highest priority.
                //
                foreach (TvDatabase.Card card in availableCards)
                {
                    TvDatabase.TuningDetail tuning = Utility.FindTuningDetailOnCard(mpChannel, card.IdCard);
                    if (tuning != null)
                    {
                        return(GetCardId(card));
                    }
                }
            }
            catch (Exception ex)
            {
                Log(TraceEventType.Error, ex.Message);
            }
            return(null);
        }
예제 #4
0
 public RecordingThread(Guid recorderTunerId, string serverHostName, int tcpPort, CardChannelAllocation channelAllocation,
     DateTime startTimeUtc, DateTime stopTimeUtc, UpcomingProgram recordingProgram, string suggestedBaseFileName,
     TvDatabase.Card recordOnCard, TvDatabase.Channel channel)
     : base(recorderTunerId, serverHostName, tcpPort, channelAllocation, startTimeUtc, stopTimeUtc, recordingProgram, true)
 {
     _suggestedBaseFileName = suggestedBaseFileName;
     _recordOnCard = recordOnCard;
     _channel = channel;
 }
 public RecordingThread(Guid recorderTunerId, string serverHostName, int tcpPort, CardChannelAllocation channelAllocation,
                        DateTime startTimeUtc, DateTime stopTimeUtc, UpcomingProgram recordingProgram, string suggestedBaseFileName,
                        TvDatabase.Card recordOnCard, TvDatabase.Channel channel)
     : base(recorderTunerId, serverHostName, tcpPort, channelAllocation, startTimeUtc, stopTimeUtc, recordingProgram, true)
 {
     _suggestedBaseFileName = suggestedBaseFileName;
     _recordOnCard          = recordOnCard;
     _channel = channel;
 }
예제 #6
0
 public RecordingThread(Guid recorderId, string schedulerBaseUrl, CardChannelAllocation channelAllocation,
     DateTime startTimeUtc, DateTime stopTimeUtc, UpcomingProgram recordingProgram, string suggestedBaseFileName,
     TvDatabase.Card recordOnCard, TvDatabase.Channel channel)
     : base(recorderId, schedulerBaseUrl, channelAllocation, startTimeUtc, stopTimeUtc, recordingProgram, true)
 {
     _suggestedBaseFileName = suggestedBaseFileName;
     _recordOnCard = recordOnCard;
     _channel = channel;
 }
예제 #7
0
 public RecordingThread(Guid recorderId, string schedulerBaseUrl, CardChannelAllocation channelAllocation,
                        DateTime startTimeUtc, DateTime stopTimeUtc, UpcomingProgram recordingProgram, string suggestedBaseFileName,
                        TvDatabase.Card recordOnCard, TvDatabase.Channel channel)
     : base(recorderId, schedulerBaseUrl, channelAllocation, startTimeUtc, stopTimeUtc, recordingProgram, true)
 {
     _suggestedBaseFileName = suggestedBaseFileName;
     _recordOnCard          = recordOnCard;
     _channel = channel;
 }
예제 #8
0
 public static bool IsInSameHybridGroup(TvDatabase.Card card, List <int> otherCardGroupIds)
 {
     if (otherCardGroupIds.Count > 0)
     {
         List <int> cardGroupIds = GetHybridGroupIds(card);
         foreach (int cardGroupId in cardGroupIds)
         {
             if (otherCardGroupIds.Contains(cardGroupId))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
예제 #9
0
        public static List <int> GetHybridGroupIds(TvDatabase.Card card)
        {
            List <int> groupIds = new List <int>();

            if (card != null)
            {
                SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof(TvDatabase.CardGroupMap));
                sb.AddConstraint(Operator.Equals, "idCard", card.IdCard);
                SqlResult result = Broker.Execute(sb.GetStatement());
                List <TvDatabase.CardGroupMap> groupMaps = (List <TvDatabase.CardGroupMap>)
                                                           ObjectFactory.GetCollection(typeof(TvDatabase.CardGroupMap), result, new List <TvDatabase.CardGroupMap>());
                foreach (TvDatabase.CardGroupMap groupMap in groupMaps)
                {
                    groupIds.Add(groupMap.IdCardGroup);
                }
            }
            return(groupIds);
        }
        private bool IsCardFreeOrSharedByAllocation(TvDatabase.Card card, TvDatabase.Channel mpChannel, CardChannelAllocation allocation,
                                                    CardChannelAllocation[] alreadyAllocated)
        {
            TvDatabase.TuningDetail tuning = Utility.FindTuningDetailOnCard(mpChannel, card.IdCard);
            if (GetCardId(card) == allocation.CardId &&
                tuning != null)
            {
                //
                // The card is allocated by this allocation, but may be able to reuse the card. So let's
                // check if the if the card (and CAM) allow this.
                //
                // Note: "!ChannelAlreadyAllocatedOn(alreadyAllocated, allocation.CardId, channelId)" was
                // not added since TV Server can record the same channel several times on the same transponder.
                if (card.DecryptLimit == 0 ||
                    CountNumTimesAllocated(alreadyAllocated, allocation.CardId) < card.DecryptLimit)
                {
                    // Get the previously allocated channel and its tuning details and let's check if the
                    // channel we want is on the same transponder as that channel.
                    TvDatabase.Channel allocatedChannel = GetLinkedMediaPortalChannel(allocation.ChannelType,
                                                                                      allocation.ChannelId, allocation.ChannelName);
                    TvDatabase.Card allocatedCard = GetCardByCardId(allocation.CardId);
                    if (allocatedChannel != null &&
                        allocatedCard != null &&
                        Utility.IsSameTransponder(allocatedCard.IdCard, tuning, allocatedChannel))
                    {
                        // Same transponder, so we can actually re-use this card and consider it free.
                        return(true);
                    }
                }
                // The card is allocated by this allocation, and it's not for a channel on the same
                // transponder, so it's not free.
                return(false);
            }

            // The card is not allocated by this allocation, so it's free.
            return(true);
        }
예제 #11
0
 public static bool CardFreeOrUsingSameTransponder(TvDatabase.Card card, TvDatabase.Channel channel)
 {
     return(CardFreeOrUsingSameTransponder(card, channel, null));
 }
 private static string GetCardId(TvDatabase.Card card)
 {
     return(card.IdCard.ToString(CultureInfo.InvariantCulture));
 }
        private LiveStreamResult StartTimeShifting(Channel channel, TvDatabase.Card card, TvDatabase.Channel mpChannel,
                                                   ref IUser tve3User, ref LiveStream liveStream)
        {
            IChannel tuningChannel = Utility.FindTuningChannelOnCard(mpChannel, card.IdCard);

            if (tuningChannel != null)
            {
                if (TvServerPlugin.TvController_Tune(ref tve3User, tuningChannel, mpChannel.IdChannel) == TvResult.Succeeded)
                {
                    string timeshiftFileName = Path.Combine(card.TimeShiftFolder,
                                                            String.Format(CultureInfo.InvariantCulture, @"live{0}-{1}", tve3User.CardId, tve3User.SubChannel));

                    switch (TvServerPlugin.TvController_StartTimeShifting(ref tve3User, ref timeshiftFileName))
                    {
                    case TvResult.Succeeded:
                        if (liveStream == null)
                        {
                            string rtspUrl      = TvServerPlugin.TvController_GetStreamingUrl(tve3User);
                            string tsBufferFile = GetTsBufferFile(tve3User);
                            liveStream = new LiveStream(channel, rtspUrl);
                            liveStream.TimeshiftFile = tsBufferFile;
#if USE_ARGUS_RTSP
                            string rtspUrlSuffix = String.Format(_rtspUrlSuffixFormat, tve3User.CardId, tve3User.SubChannel);
                            liveStream.RtspUrl = StartRtspStream(tsBufferFile, rtspUrlSuffix);
#endif
                        }
                        liveStream.Channel = channel;
                        liveStream.CardId  = tve3User.CardId.ToString(CultureInfo.InvariantCulture);
                        liveStream.StreamLastAliveTimeUtc = DateTime.UtcNow;
                        lock (_liveStreamsLock)
                        {
                            _liveStreams[liveStream.RtspUrl]     = liveStream;
                            _liveStreamUsers[liveStream.RtspUrl] = tve3User;
                        }
                        return(LiveStreamResult.Succeeded);

                    case TvResult.AllCardsBusy:
                        return(LiveStreamResult.NoFreeCardFound);

                    case TvResult.ChannelIsScrambled:
                        return(LiveStreamResult.IsScrambled);

                    case TvResult.ChannelNotMappedToAnyCard:
                    case TvResult.NoSignalDetected:
                    case TvResult.NoTuningDetails:
                    case TvResult.NoVideoAudioDetected:
                    case TvResult.UnknownChannel:
                        return(LiveStreamResult.ChannelTuneFailed);

                    default:
                        return(LiveStreamResult.UnknownError);
                    }
                }
                else
                {
                    Log(TraceEventType.Error, "StartTimeShifting(): failed to tune to {0}", tuningChannel.Name);
                    return(LiveStreamResult.ChannelTuneFailed);
                }
            }
            else
            {
                Log(TraceEventType.Error, "StartTimeShifting(): no tuning channel found for {0}", mpChannel.DisplayName);
                return(LiveStreamResult.ChannelTuneFailed);
            }
        }