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);
        }
Example #2
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;
 }
        public override bool ValidateAndUpdateRecording(CardChannelAllocation channelAllocation, UpcomingProgram recordingProgram, DateTime stopTimeUtc)
        {
            bool threadNotFound;
            bool result = _recordingThreads.ValidateAndUpdateRecording(recordingProgram, stopTimeUtc, out threadNotFound);

            if (threadNotFound)
            {
                Log(TraceEventType.Warning, "{0} - ValidateAndUpdateRecording called on unknown recording {1}", this.Name, recordingProgram.CreateProgramTitle());
            }
            return(result);
        }
Example #4
0
 public RecordingThreadBase(Guid recorderId, string schedulerBaseUrl, CardChannelAllocation channelAllocation,
                            DateTime startTimeUtc, DateTime stopTimeUtc, UpcomingProgram recordingProgram, bool okToRenameRecordedFiles)
     : base("Record")
 {
     _recorderId              = recorderId;
     _schedulerBaseUrl        = schedulerBaseUrl;
     _channelAllocation       = channelAllocation;
     _startTimeUtc            = startTimeUtc;
     _stopTimeUtc             = stopTimeUtc;
     _recordingProgram        = recordingProgram;
     _okToRenameRecordedFiles = okToRenameRecordedFiles;
 }
Example #5
0
        /// <summary>
        /// Validate a recording is still running, and update its actual stop time.
        /// </summary>
        /// <param name="channelAllocation">The card allocation for the channel.</param>
        /// <param name="recordingProgram">The program being recorded.</param>
        /// <param name="stopTimeUtc">The up-to-date stop time (UTC).</param>
        /// <returns>True if the recording was still running (and its stop time was succesfully updated), false if there was a problem or the recording is not running.</returns>
        public async Task <bool> ValidateAndUpdateRecording(CardChannelAllocation channelAllocation, UpcomingProgram recordingProgram, DateTime stopTimeUtc)
        {
            var request = NewRequest(HttpMethod.Put, "Recording/ValidateAndUpdate");

            request.AddBody(new
            {
                channelAllocation = channelAllocation,
                recordingProgram  = recordingProgram,
                stopTimeUtc       = stopTimeUtc
            });
            return(await ExecuteResult <bool>(request).ConfigureAwait(false));
        }
Example #6
0
        public void StartRecordingFailed(CardChannelAllocation channelAllocation, UpcomingProgram recordingProgram, string reason)
        {
            var request = NewRequest("/RecorderCallback/Recording/StartFailed", Method.PUT);

            request.AddBody(new
            {
                Allocation       = channelAllocation,
                RecordingProgram = recordingProgram,
                Reason           = reason
            });
            Execute(request);
        }
Example #7
0
        /// <summary>
        /// Validate a recording is still running, and update its actual stop time.
        /// </summary>
        /// <param name="channelAllocation">The card allocation for the channel.</param>
        /// <param name="recordingProgram">The program being recorded.</param>
        /// <param name="stopTimeUtc">The up-to-date stop time (UTC).</param>
        /// <returns>True if the recording was still running (and its stop time was succesfully updated), false if there was a problem or the recording is not running.</returns>
        public bool ValidateAndUpdateRecording(CardChannelAllocation channelAllocation, UpcomingProgram recordingProgram, DateTime stopTimeUtc)
        {
            var request = NewRequest("/Recording/ValidateAndUpdate", Method.PUT);

            request.AddBody(new
            {
                channelAllocation = channelAllocation,
                recordingProgram  = recordingProgram,
                stopTimeUtc       = stopTimeUtc
            });
            return(ExecuteResult <bool>(request));
        }
        public async Task StartRecordingFailed(CardChannelAllocation channelAllocation, UpcomingProgram recordingProgram, string reason)
        {
            var request = NewRequest(HttpMethod.Put, "RecorderCallback/Recording/StartFailed");

            request.AddBody(new
            {
                Allocation       = channelAllocation,
                RecordingProgram = recordingProgram,
                Reason           = reason
            });
            await ExecuteAsync(request).ConfigureAwait(false);
        }
Example #9
0
 public RecordingThreadBase(Guid recorderTunerId, string serverHostName, int serverTcpPort, CardChannelAllocation channelAllocation,
                            DateTime startTimeUtc, DateTime stopTimeUtc, UpcomingProgram recordingProgram, bool okToRenameRecordedFiles)
     : base("Record")
 {
     _recorderTunerId         = recorderTunerId;
     _serverHostName          = serverHostName;
     _serverTcpPort           = serverTcpPort;
     _channelAllocation       = channelAllocation;
     _startTimeUtc            = startTimeUtc;
     _stopTimeUtc             = stopTimeUtc;
     _recordingProgram        = recordingProgram;
     _okToRenameRecordedFiles = okToRenameRecordedFiles;
 }
Example #10
0
        /// <summary>
        /// Tell the recorder to actually start a recording on the given card.  The implementation
        /// must call /Recording/New on the Recorder callback service when the recording actually
        /// starts.  If the recording can't start for some reason, StartRecordingFailed() must be called.
        /// In case the recording ends (prematurely or on time) /Recording/End must be called.  IMPORTANT:
        /// If the suggested relative path and filename was used the recorder should
        /// return 'false' to /Recording/End's 'okToMoveFile'!
        /// </summary>
        /// <param name="schedulerBaseUrl">The callback URL for the Recorder to communicate with the Scheduler.</param>
        /// <param name="channelAllocation">The card allocation for the channel.</param>
        /// <param name="startTimeUtc">The actual time to start the recording (UTC).</param>
        /// <param name="stopTimeUtc">The actual time to stop the recording (UTC).</param>
        /// <param name="recordingProgram">The program to record.</param>
        /// <param name="suggestedBaseFileName">The suggested relative path and filename (without extension) of the recording file.</param>
        /// <returns>A boolean indicating the recording was initiated succesfully.</returns>
        public async Task <bool> StartRecording(string schedulerBaseUrl, CardChannelAllocation channelAllocation, DateTime startTimeUtc, DateTime stopTimeUtc, UpcomingProgram recordingProgram, string suggestedBaseFileName)
        {
            var request = NewRequest(HttpMethod.Post, "Recording/Start");

            request.AddBody(new
            {
                schedulerBaseUrl      = schedulerBaseUrl,
                channelAllocation     = channelAllocation,
                startTimeUtc          = startTimeUtc,
                stopTimeUtc           = stopTimeUtc,
                recordingProgram      = recordingProgram,
                suggestedBaseFileName = suggestedBaseFileName
            });
            return(await ExecuteResult <bool>(request).ConfigureAwait(false));
        }
Example #11
0
        /// <summary>
        /// Tune to a channel, and get a live stream to that channel.
        /// </summary>
        /// <param name="channel">The channel to tune to.</param>
        /// <param name="upcomingRecordingAllocation">The allocation if the next upcoming recording, or null if there isn't one.</param>
        /// <param name="liveStream">Reference to a live stream that is either existing or null for a new one.</param>
        /// <returns>A LiveStreamResult value to indicate success or failure.</returns>
        public LiveStreamResult TuneLiveStream(Channel channel, CardChannelAllocation upcomingRecordingAllocation, ref LiveStream liveStream)
        {
            var request = NewRequest("/Live/Tune", Method.POST);

            request.AddBody(new
            {
                channel = channel,
                upcomingRecordingAllocation = upcomingRecordingAllocation,
                stream = liveStream
            });
            var data = Execute <TuneLiveStreamResult>(request);

            liveStream = data.stream;
            return(data.result);
        }
Example #12
0
        /// <summary>
        /// Tell the recorder to actually start a recording on the given card.  The implementation
        /// must call /Recording/New on the Recorder callback service when the recording actually
        /// starts.  If the recording can't start for some reason, StartRecordingFailed() must be called.
        /// In case the recording ends (prematurely or on time) /Recording/End must be called.  IMPORTANT:
        /// If the suggested relative path and filename was used the recorder should
        /// return 'false' to /Recording/End's 'okToMoveFile'!
        /// </summary>
        /// <param name="schedulerBaseUrl">The callback URL for the Recorder to communicate with the Scheduler.</param>
        /// <param name="channelAllocation">The card allocation for the channel.</param>
        /// <param name="startTimeUtc">The actual time to start the recording (UTC).</param>
        /// <param name="stopTimeUtc">The actual time to stop the recording (UTC).</param>
        /// <param name="recordingProgram">The program to record.</param>
        /// <param name="suggestedBaseFileName">The suggested relative path and filename (without extension) of the recording file.</param>
        /// <returns>A boolean indicating the recording was initiated succesfully.</returns>
        public bool StartRecording(string schedulerBaseUrl, CardChannelAllocation channelAllocation, DateTime startTimeUtc, DateTime stopTimeUtc, UpcomingProgram recordingProgram, string suggestedBaseFileName)
        {
            var request = NewRequest("/Recording/Start", Method.POST);

            request.AddBody(new
            {
                schedulerBaseUrl      = schedulerBaseUrl,
                channelAllocation     = channelAllocation,
                startTimeUtc          = startTimeUtc,
                stopTimeUtc           = stopTimeUtc,
                recordingProgram      = recordingProgram,
                suggestedBaseFileName = suggestedBaseFileName
            });
            return(ExecuteResult <bool>(request));
        }
Example #13
0
        /// <summary>
        /// Tune to a channel, and get a live stream to that channel.
        /// </summary>
        /// <param name="channel">The channel to tune to.</param>
        /// <param name="upcomingRecordingAllocation">The allocation if the next upcoming recording, or null if there isn't one.</param>
        /// <param name="liveStream">A live stream that is either existing or null for a new one.</param>
        /// <returns>A LiveStreamResult value to indicate success or failure, and a new or updated live stream.</returns>
        public async Task <TuneLiveStreamResult> TuneLiveStream(Channel channel, CardChannelAllocation upcomingRecordingAllocation, LiveStream liveStream)
        {
            var request = NewRequest(HttpMethod.Post, "Live/Tune");

            request.AddBody(new
            {
                channel = channel,
                upcomingRecordingAllocation = upcomingRecordingAllocation,
                stream = liveStream
            });
            var data = await ExecuteAsync <InternalTuneLiveStreamResult>(request).ConfigureAwait(false);

            return(new TuneLiveStreamResult
            {
                Result = data.result,
                Stream = data.stream
            });
        }
Example #14
0
 private static string BuildRecordingInfoToolTip(DateTime actualStartTime, DateTime actualStopTime,
                                                 CardChannelAllocation allocation, string onText)
 {
     if (allocation != null)
     {
         PluginService pluginService = RecorderTunersCache.GetRecorderTunerById(allocation.RecorderTunerId);
         if (pluginService != null)
         {
             return(String.Format(CultureInfo.CurrentCulture, "{0} - {1} {2} {3} ({4})",
                                  actualStartTime.ToShortTimeString(), actualStopTime.ToShortTimeString(),
                                  onText, pluginService.Name, allocation.CardId));
         }
         else
         {
             return(String.Format(CultureInfo.CurrentCulture, "{0} - {1} on ?",
                                  actualStartTime.ToShortTimeString(), actualStopTime.ToShortTimeString()));
         }
     }
     return(null);
 }
Example #15
0
        private static string GetIconImageFileName(ScheduleType scheduleType, bool isPartOfSeries, UpcomingCancellationReason cancellationReason,
                                                   bool isRecording, CardChannelAllocation cardChannelAllocation, List <Guid> conflictingPrograms)
        {
            string suffix = String.Empty;

            if (isPartOfSeries)
            {
                suffix += "Series";
            }
            if (cancellationReason != UpcomingCancellationReason.None)
            {
                suffix += "Cancelled";
                if (cancellationReason == UpcomingCancellationReason.PreviouslyRecorded ||
                    cancellationReason == UpcomingCancellationReason.AlreadyQueued)
                {
                    suffix += "History";
                }
            }
            else
            {
                if (isRecording)
                {
                    if (cardChannelAllocation == null)
                    {
                        suffix += "InConflict";
                        //toolTip = ProcessUtility.CreateConflictingProgramsToolTip(_model.UpcomingRecordings,
                        //    upcoming.UpcomingRecording.ConflictingPrograms, Utility.GetLocalizedText(TextId.ConflictsHeader),
                        //    Utility.GetLocalizedText(TextId.NoCardFoundForRecording));
                    }
                    else if (conflictingPrograms.Count > 0)
                    {
                        suffix += "WithWarning";
                        //toolTip = ProcessUtility.CreateConflictingProgramsToolTip(_model.UpcomingRecordings,
                        //    upcoming.UpcomingRecording.ConflictingPrograms, Utility.GetLocalizedText(TextId.ConflictsHeader),
                        //    Utility.GetLocalizedText((TextId.NoCardFoundForRecording));
                    }
                }
            }
            return(GUIGraphicsContext.Skin + @"\Media\ARGUS_" + scheduleType.ToString() + suffix + ".png");
        }
Example #16
0
 public abstract bool StartRecording(string schedulerBaseUrl, CardChannelAllocation channelAllocation, DateTime startTimeUtc, DateTime stopTimeUtc, UpcomingProgram recordingProgram, string suggestedBaseFileName);
Example #17
0
 public abstract bool ValidateAndUpdateRecording(CardChannelAllocation channelAllocation, UpcomingProgram recordingProgram, DateTime stopTimeUtc);
        public override LiveStreamResult TuneLiveStream(Channel channel, CardChannelAllocation upcomingRecordingAllocation, ref LiveStream liveStream)
        {
            try
            {
                TvDatabase.Channel     mpChannel;
                List <TvDatabase.Card> availableCards = GetCardsForChannel(channel, out mpChannel);

                // Sort the cards by priority.
                availableCards.Sort(delegate(TvDatabase.Card c1, TvDatabase.Card c2) { return(c1.Priority.CompareTo(c2.Priority)); });

                if (liveStream != null &&
                    _liveStreamUsers.ContainsKey(liveStream.RtspUrl))
                {
                    IUser tve3User = _liveStreamUsers[liveStream.RtspUrl];
                    foreach (TvDatabase.Card card in availableCards)
                    {
                        if (card.IdCard == tve3User.CardId)
                        {
                            if (Utility.CardFreeOrUsingSameTransponder(card, mpChannel, tve3User))
                            {
                                Log("TuneLiveTvStream(): tuning on card {0} {1}", card.IdCard, card.Name);
                                lock (_liveStreamsLock)
                                {
                                    _liveStreams[liveStream.RtspUrl].StreamLastAliveTimeUtc = DateTime.UtcNow;
                                }
                                LiveStreamResult result = StartTimeShifting(channel, card, mpChannel, ref tve3User, ref liveStream);
                                if (result != LiveStreamResult.NoFreeCardFound)
                                {
                                    return(result);
                                }
                            }
                        }
                    }

                    return(LiveStreamResult.NoRetunePossible);
                }
                else
                {
                    if (liveStream != null)
                    {
                        StopLiveStream(liveStream);
                        liveStream = null;
                    }

                    List <int> inUseHybridGroups = new List <int>();

                    foreach (TvDatabase.Card card in availableCards)
                    {
                        if (!Utility.IsInSameHybridGroup(card, inUseHybridGroups) &&
                            Utility.CardFreeOrUsingSameTransponder(card, mpChannel))
                        {
                            string userName = String.Format(CultureInfo.InvariantCulture, "{0}{1}", _argusLiveUserName, Guid.NewGuid());

                            IUser tve3User = new User(userName, true, card.IdCard);
                            tve3User.IdChannel  = mpChannel.IdChannel;
                            tve3User.SubChannel = -1;

                            Log("TuneLiveTvStream(): tuning on card {0} {1}", card.IdCard, card.Name);

                            LiveStreamResult result = StartTimeShifting(channel, card, mpChannel, ref tve3User, ref liveStream);
                            if (result != LiveStreamResult.NoFreeCardFound)
                            {
                                return(result);
                            }
                        }
                        // For hybrid cards, keep track of the groups that are in use.
                        inUseHybridGroups.AddRange(Utility.GetHybridGroupIds(card));
                    }

                    return(LiveStreamResult.NoFreeCardFound);
                }
            }
            catch (Exception ex)
            {
                Log(TraceEventType.Error, ex.Message);
                return(LiveStreamResult.UnknownError);
            }
        }
        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);
        }
 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;
 }
Example #21
0
 public virtual LiveStreamResult TuneLiveStream(Channel channel, CardChannelAllocation upcomingRecordingAllocation, ref LiveStream liveStream)
 {
     liveStream = null;
     return(LiveStreamResult.NotSupported);
 }
Example #22
0
 public abstract bool StartRecording(string serverHostName, int tcpPort, CardChannelAllocation channelAllocation, DateTime startTimeUtc, DateTime stopTimeUtc, UpcomingProgram recordingProgram, string suggestedBaseFileName);