Beispiel #1
0
 private void StopRecordOnSeriesSchedule(RecordingDetail recording)
 {
   Log.Debug("Scheduler: endtime={0}, Program.EndTime={1}, postRecTime={2}", recording.EndTime,
             recording.Program.EndTime, recording.Schedule.PostRecordInterval);
   if (DateTime.Now <= recording.Program.EndTime.AddMinutes(recording.Schedule.PostRecordInterval))
   {
     CancelSchedule(recording, recording.Schedule.IdSchedule);
   }
   else
   {
     _episodeManagement.OnScheduleEnded(recording.FileName, recording.Schedule, recording.Program);
   }
 }
Beispiel #2
0
    private void IterateCardsUntilRecording(RecordingDetail recDetail, IUser user,
                                            ICollection<CardDetail> cardsForReservation,
                                            CardReservationRec cardRes)
    {
      IDictionary<CardDetail, ICardTuneReservationTicket> tickets = null;
      try
      {
        ICollection<CardDetail> cardsIterated = new HashSet<CardDetail>();

        int cardIterations = 0;
        bool moreCardsAvailable = true;
        bool recSucceded = false;
        while (moreCardsAvailable && !recSucceded)
        {
          tickets = CardReservationHelper.RequestCardReservations(user, cardsForReservation, _tvController, cardRes, cardsIterated, recDetail.Channel.IdChannel);
          if (tickets.Count == 0)
          {
            //no free cards available
            Log.Write("scheduler: no free card reservation(s) could be made.");
            break;
          }
          TvResult tvResult;
          ICollection<ICardTuneReservationTicket> ticketsList = tickets.Values;
          var cardAllocationTicket = new AdvancedCardAllocationTicket(_layer, _tvController, ticketsList);
          ICollection<CardDetail> cards = cardAllocationTicket.UpdateFreeCardsForChannelBasedOnTicket(
                                                                              cardsForReservation,
                                                                              user, out tvResult);          
          CardReservationHelper.CancelCardReservationsExceedingMaxConcurrentTickets(tickets, cards, _tvController.CardCollection);
          CardReservationHelper.CancelCardReservationsNotFoundInFreeCards(cardsForReservation, tickets, cards, _tvController.CardCollection);

          int maxCards = GetMaxCards(cards);
          CardReservationHelper.CancelCardReservationsBasedOnMaxCardsLimit(tickets, cards, maxCards, _tvController.CardCollection);
          UpdateCardsIterated(cardsIterated, cards); //keep track of what cards have been iterated here.

          if (cards != null && cards.Count > 0)
          {
            cardIterations += cards.Count;
            recSucceded = IterateTicketsUntilRecording(recDetail, user, cards, cardRes, maxCards, tickets, cardsIterated);
            moreCardsAvailable = _maxRecordFreeCardsToTry == 0 || _maxRecordFreeCardsToTry > cardIterations;
          }
          else
          {
            Log.Write("scheduler: no free cards found for recording.");
            break;
          }
        } // end of while
      }
      finally
      {
        CardReservationHelper.CancelAllCardReservations(tickets, _tvController.CardCollection);
      }
    }
Beispiel #3
0
    private bool IterateTicketsUntilRecording(RecordingDetail recDetail, IUser user, ICollection<CardDetail> cards, CardReservationRec cardRes, int maxCards, IDictionary<CardDetail, ICardTuneReservationTicket> tickets, ICollection<CardDetail> cardsIterated)
    {
      bool recSucceded = false;
      while (!recSucceded && tickets.Count > 0)
      {
        List<CardDetail> freeCards =
          cards.Where(t => t.NumberOfOtherUsers == 0 || (t.NumberOfOtherUsers > 0 && t.SameTransponder)).ToList();
        List<CardDetail> availCards = cards.Where(t => t.NumberOfOtherUsers > 0 && !t.SameTransponder).ToList();

        Log.Write("scheduler: try max {0} of {1} free cards for recording", maxCards, cards.Count);
        if (freeCards.Count > 0)
        {          
          recSucceded = FindFreeCardAndStartRecord(recDetail, user, freeCards, maxCards, tickets, cardRes);
        }
        else if (availCards.Count > 0)
        {
          recSucceded = FindAvailCardAndStartRecord(recDetail, user, availCards, maxCards, tickets, cardRes);
        }

        if (!recSucceded)
        {
          CardDetail cardInfo = GetCardDetailForRecording(cards);
          cards.Remove(cardInfo);
        }
      }
      return recSucceded;
    }
Beispiel #4
0
 private RecordingDetail IsTimeToRecordOnce(Schedule schedule, DateTime currentTime, out bool isTimeToRecord)
 {
   isTimeToRecord = false;
   RecordingDetail newRecording = null;
   if (currentTime >= schedule.StartTime.AddMinutes(-schedule.PreRecordInterval) &&
       currentTime <= schedule.EndTime.AddMinutes(schedule.PostRecordInterval))
   {
     VirtualCard vCard = null;
     bool isRecordingSchedule = IsRecordingSchedule(schedule.IdSchedule, out vCard);
     if (!isRecordingSchedule)
     {
       newRecording = new RecordingDetail(schedule, schedule.ReferencedChannel(), schedule.EndTime, schedule.Series);
       isTimeToRecord = true;
     }
   }
   return newRecording;
 }
Beispiel #5
0
    /// <summary>
    /// Starts recording the recording specified
    /// </summary>
    /// <param name="recDetail"></param>
    /// <returns>true if recording is started, otherwise false</returns>
    private void StartRecord(RecordingDetail recDetail)
    {
      IUser user = recDetail.User;

      Log.Write("Scheduler: Time to record {0} {1}-{2} {3}", recDetail.Channel.DisplayName,
                DateTime.Now.ToShortTimeString(), recDetail.EndTime.ToShortTimeString(),
                recDetail.Schedule.ProgramName);
      //get list of all cards we can use to do the recording           
      StartRecordOnFreeCard(recDetail, ref user);
    }
Beispiel #6
0
 private void ResetRecordingStateOnProgram(RecordingDetail recording)
 {
   if (recording.Program.IdProgram > 0)
   {
     recording.Program.IsRecordingManual = false;
     recording.Program.IsRecordingSeries = false;
     recording.Program.IsRecordingOnce = false;
     recording.Program.IsRecordingOncePending = false;
     recording.Program.IsRecordingSeriesPending = false;
     recording.Program.Persist();
   }
 }   
Beispiel #7
0
 private void CancelSchedule(RecordingDetail newRecording, int scheduleId)
 {
   CanceledSchedule canceled = new CanceledSchedule(scheduleId,
                                                    newRecording.Program.IdChannel,
                                                    newRecording.Program.StartTime);
   canceled.Persist();
   _episodeManagement.OnScheduleEnded(newRecording.FileName, newRecording.Schedule,
                                      newRecording.Program);
 }
Beispiel #8
0
    private bool StartRecordingOnDisc(RecordingDetail recDetail, ref IUser user, CardDetail cardInfo, ICardTuneReservationTicket ticket, CardReservationRec cardResImpl)
    {
      bool startRecordingOnDisc = false;
      _tvController.EpgGrabberEnabled = false;
      Log.Write("Scheduler : record, first tune to channel");
      
      cardResImpl.CardInfo = cardInfo;
      cardResImpl.RecDetail = recDetail;      
      
      TvResult tuneResult = _tvController.Tune(ref user, cardInfo.TuningDetail, recDetail.Channel.IdChannel, ticket, cardResImpl);      
      startRecordingOnDisc = (tuneResult == TvResult.Succeeded);

      return startRecordingOnDisc;
    }    
Beispiel #9
0
 private static void CreateRecording(RecordingDetail recDetail)
 {
   int idServer = recDetail.CardInfo.Card.IdServer;
   Log.Debug(String.Format("Scheduler: adding new row in db for title=\"{0}\" of type=\"{1}\"",
                           recDetail.Program.Title, recDetail.Schedule.ScheduleType));
   recDetail.Recording = new Recording(recDetail.Schedule.IdChannel, recDetail.Schedule.IdSchedule, true,
                                       recDetail.RecordingStartDateTime, DateTime.Now, recDetail.Program.Title,
                                       recDetail.Program.Description, recDetail.Program.Genre, recDetail.FileName,
                                       recDetail.Schedule.KeepMethod,
                                       recDetail.Schedule.KeepDate, 0, idServer, recDetail.Program.EpisodeName,
                                       recDetail.Program.SeriesNum, recDetail.Program.EpisodeNum,
                                       recDetail.Program.EpisodePart);
   recDetail.Recording.Persist();
 }
Beispiel #10
0
    /// <summary>
    /// stops failed recording
    /// </summary>
    /// <param name="recording">Recording</param>    
    private void StopFailedRecord(RecordingDetail recording)
    {
      try
      {
        IUser user = recording.User;

        if (recording.CardInfo != null && _tvController.SupportsSubChannels(recording.CardInfo.Id) == false)
        {
          _tvController.StopTimeShifting(ref user);
        }

        Log.Write("Scheduler: stop failed record {0} {1}-{2} {3}", recording.Channel.DisplayName,
                  recording.RecordingStartDateTime,
                  recording.EndTime, recording.Schedule.ProgramName);

        if (_tvController.IsRecording(ref user))
        {
          if (_tvController.StopRecording(ref user))
          {
            ResetRecordingStateOnProgram(recording);
            if (recording.Recording != null)
            {
              recording.Recording.Delete();
              recording.Recording = null;
            }

            if (_recordingsInProgressList.Contains(recording))
            {
              _recordingsInProgressList.Remove(recording);
            }
          }
        }
      }
      catch (Exception ex)
      {
        Log.Write(ex);
      }
    }
Beispiel #11
0
 private void StartRecordingNotification(RecordingDetail recDetail)
 {
   IUser user = recDetail.User;
   _tvController.Fire(this,
                      new TvServerEventArgs(TvServerEventType.StartRecording, new VirtualCard(user), (User)user,
                                            recDetail.Schedule, null));
 }
Beispiel #12
0
    private bool SetupAndStartRecord(RecordingDetail recDetail, ref IUser user, CardDetail cardInfo, ICardTuneReservationTicket ticket, CardReservationRec cardResImpl)
    {
      bool result = false;
      if (cardInfo != null)
      {
        user.CardId = cardInfo.Id;
        StartRecordingNotification(recDetail);
        SetupRecordingFolder(cardInfo);
        if (StartRecordingOnDisc(recDetail, ref user, cardInfo, ticket, cardResImpl))
        {
          CreateRecording(recDetail);
          try
          {
            recDetail.User.CardId = user.CardId;
            SetRecordingProgramState(recDetail);
            _recordingsInProgressList.Add(recDetail);
            RecordingStartedNotification(recDetail);
            SetupQualityControl(recDetail);
            WriteMatroskaFile(recDetail);
          }
          catch (Exception ex)
          {
            //consume exception, since it isn't catastrophic
            Log.Write(ex);
          }

          Log.Write("Scheduler: recList: count: {0} add scheduleid: {1} card: {2}",
                    _recordingsInProgressList.Count,
                    recDetail.Schedule.IdSchedule, recDetail.CardInfo.Card.Name);
          result = true;
        }
      }
      else
      {
        Log.Write("scheduler: no card found to record on.");
      }
      return result;
    }
Beispiel #13
0
 private bool FindFreeCardAndStartRecord(RecordingDetail recDetail, IUser user, ICollection<CardDetail> cards, int maxCards, IDictionary<CardDetail, ICardTuneReservationTicket> tickets, CardReservationRec cardResImpl)
 {
   bool result = false;
   //keep tuning each card until we are succesful
   for (int i = 0; i < maxCards; i++)
   {
     CardDetail cardInfo = null;
     try
     {
       cardInfo = GetCardDetailForRecording(cards);
       ITvCardHandler tvCardHandler;
       if (_tvController.CardCollection.TryGetValue(cardInfo.Id, out tvCardHandler))
       {
         ICardTuneReservationTicket ticket = GetTicketByCardDetail(cardInfo, tickets);
         if (ticket == null)
         {
           ticket = CardReservationHelper.RequestCardReservation(user, cardInfo, _tvController, cardResImpl, recDetail.Channel.IdChannel);
           if (ticket != null)
           {
             tickets[cardInfo] = ticket;
           }
         }
         if (ticket != null)
         {
           result = SetupAndStartRecord(recDetail, ref user, cardInfo, ticket, cardResImpl);
           if (result)
           {
             break;
           }
         }
         else
         {
           Log.Write("scheduler: could not find free cardreservation on card:{0}", cardInfo.Id);
         }
       }
     }
     catch (Exception ex)
     {
       Log.Error(ex.ToString());
     }
     Log.Write("scheduler: recording failed, lets try next available card.");
     CardReservationHelper.CancelCardReservationAndRemoveTicket(cardInfo, tickets, _tvController.CardCollection);
     StopFailedRecord(recDetail);
     if (cardInfo != null && cards.Contains(cardInfo))
     {
       cards.Remove(cardInfo);
     }
   }
   return result;
 }
Beispiel #14
0
 private void StartRecordOnFreeCard(RecordingDetail recDetail, ref IUser user)
 {
   var cardAllocationStatic = new AdvancedCardAllocationStatic(_layer, _tvController);
   List<CardDetail> freeCardsForReservation = cardAllocationStatic.GetFreeCardsForChannel(_tvController.CardCollection, recDetail.Channel, ref user);
   StartRecordOnCard(recDetail, ref user, freeCardsForReservation);
 }
Beispiel #15
0
 private void StopRecordOnOnceSchedule(RecordingDetail recording)
 {
   IUser user = recording.User;
   if (recording.IsSerie)
   {
     _episodeManagement.OnScheduleEnded(recording.FileName, recording.Schedule, recording.Program);
   }
   _tvController.Fire(this,
                      new TvServerEventArgs(TvServerEventType.ScheduleDeleted, new VirtualCard(user), (User)user,
                                            recording.Schedule, null));
   // now we can safely delete it
   recording.Schedule.Delete();
 }
Beispiel #16
0
 private static void SetRecordingProgramState(RecordingDetail recDetail)
 {
   if (recDetail.Program.IdProgram > 0)
   {
     recDetail.Program.IsRecordingOnce = true;
     recDetail.Program.IsRecordingSeries = recDetail.Schedule.Series;
     recDetail.Program.IsRecordingManual = recDetail.Schedule.IsManual;
     recDetail.Program.IsRecordingOncePending = false;
     recDetail.Program.IsRecordingSeriesPending = false;
     recDetail.Program.Persist();
   }
 }
Beispiel #17
0
 private void ResetRecordingState(RecordingDetail recording)
 {
   try
   {
     recording.Recording.Refresh();
     recording.Recording.EndTime = DateTime.Now;
     recording.Recording.IsRecording = false;
     recording.Recording.Persist();
   }
   catch (Exception ex)
   {
     Log.Error("StopRecord - updating record id={0} failed {1}", recording.Recording.IdRecording, ex.StackTrace);
   }
 }
Beispiel #18
0
 private void SetupQualityControl(RecordingDetail recDetail)
 {
   IUser user = recDetail.User;
   int cardId = user.CardId;
   if (_tvController.SupportsQualityControl(cardId))
   {
     if (recDetail.Schedule.BitRateMode != VIDEOENCODER_BITRATE_MODE.NotSet && _tvController.SupportsBitRate(cardId))
     {
       _tvController.SetQualityType(cardId, recDetail.Schedule.QualityType);
     }
     if (recDetail.Schedule.QualityType != QualityType.NotSet && _tvController.SupportsBitRateModes(cardId) &&
         _tvController.SupportsPeakBitRateMode(cardId))
     {
       _tvController.SetBitRateMode(cardId, recDetail.Schedule.BitRateMode);
     }
   }
 }
Beispiel #19
0
    private bool IsEpisodeUnrecorded(int scheduleType, RecordingDetail newRecording)
    {
      string ToRecordTitle = "";
      string ToRecordEpisode = "";
      bool NewRecordingNeeded = true;

      //cleanup: remove EPG additions of Clickfinder plugin      
      try
      {
        // Allow user to turn this on or off in case of unreliable EPG
        if (_preventDuplicateEpisodes && newRecording != null)
        {
          switch (_preventDuplicateEpisodesKey)
          {
            case 1: // Episode Number
              ToRecordEpisode = newRecording.Program.SeriesNum + "." + newRecording.Program.EpisodeNum + "." +
                                newRecording.Program.EpisodePart;
              break;
            default: // Episode Name
              ToRecordEpisode = CleanEpisodeTitle(newRecording.Program.EpisodeName);
              break;
          }

          ToRecordTitle = CleanEpisodeTitle(newRecording.Program.Title);

          Log.Debug("Scheduler: Check recordings for schedule {0}...", ToRecordTitle);
          // EPG needs to have episode information to distinguish between repeatings and new broadcasts
          if (ToRecordEpisode.Equals(String.Empty) || ToRecordEpisode.Equals(".."))
          {
            // Check the type so we aren't logging too verbose on single runs
            if (scheduleType != (int)ScheduleRecordingType.Once)
            {
              Log.Info("Scheduler: No epsisode title found for schedule {0} - omitting repeating check.",
                       newRecording.Program.Title);
            }
          }
          else
          {
            IList<Recording> pastRecordings = Recording.ListAll();
            string pastRecordEpisode = "";
            for (int i = 0; i < pastRecordings.Count; i++)
            {
              // Checking the record "title" itself to avoid unnecessary checks.
              // Furthermore some EPG sources could misuse the episode field for other, non-unique information

              Log.Debug("Scheduler: checking pastReecording: {0} {1} {2} {3}", pastRecordings[i].Title, pastRecordings[i].EpisodeNum, pastRecordings[i].EpisodePart, pastRecordings[i].EpisodeName);

              if (CleanEpisodeTitle(pastRecordings[i].Title).Equals(ToRecordTitle,
                                                                    StringComparison.CurrentCultureIgnoreCase))
              {
                
                Log.Debug("Scheduler: Found recording of schedule {0} - checking episodes...", ToRecordTitle);
                // The schedule which is about to be recorded is already found on our disk
                switch (_preventDuplicateEpisodesKey)
                {
                  case 1: // Episode Number
                    pastRecordEpisode = pastRecordings[i].SeriesNum + "." + pastRecordings[i].EpisodeNum + "." +
                                        pastRecordings[i].EpisodePart;
                    break;
                  default: // 0 EpisodeName
                    pastRecordEpisode = CleanEpisodeTitle(pastRecordings[i].EpisodeName);
                    break;
                }

                if (pastRecordEpisode.Equals(ToRecordEpisode, StringComparison.CurrentCultureIgnoreCase))
                {
                  var startExisting = pastRecordings[i].StartTime;
                  var endExisting = pastRecordings[i].EndTime;
                  var startNew = newRecording.Program.StartTime.AddMinutes(-newRecording.Schedule.PreRecordInterval);
                  var endNew = newRecording.Program.EndTime.AddMinutes(newRecording.Schedule.PostRecordInterval);

                  var isOverlap = startNew < endExisting && endNew > startExisting;

                  // Check if new program overlaps with existing recording and is on the same channel
                  // if so assume previous failure and recording needs to be resumed
                  if (isOverlap && pastRecordings[i].IdChannel == newRecording.Channel.IdChannel)
                  {
                    Log.Info(
                      "Scheduler: Schedule {0} ({1}) had already been started - expect previous failure and try to resume...",
                      ToRecordTitle, ToRecordEpisode);
                  }
                  else
                  {
                    // Check whether the file itself does really exist
                    // There could be faulty drivers 
                    try
                    {
                      // Make sure there's no 1KB file left over (e.g when card fails to tune to channel)
                      FileInfo fi = new FileInfo(pastRecordings[i].FileName);
                      // This will throw an exception if the file is not present
                      if (fi.Length > 4096)
                      {
                        NewRecordingNeeded = false;

                        // Handle schedules so TV Service won't try to re-schedule them every 15 seconds
                        if ((ScheduleRecordingType)newRecording.Schedule.ScheduleType == ScheduleRecordingType.Once)
                        {
                          // One-off schedules can be spawned for some schedule types to record the actual episode
                          // if this is the case then add a cancelled schedule for this episode against the parent
                          int parentScheduleID = newRecording.Schedule.IdParentSchedule;
                          if (parentScheduleID > 0)
                          {                            
                            CancelSchedule(newRecording, parentScheduleID);
                          }

                          
                          IUser user = newRecording.User;
                          _tvController.Fire(this,
                                             new TvServerEventArgs(TvServerEventType.ScheduleDeleted,
                                                                   new VirtualCard(user), (User)user,
                                                                   newRecording.Schedule,
                                                                   null));
                          // now we can safely delete it
                          newRecording.Schedule.Delete();
                        }
                        else
                        {
                          CancelSchedule(newRecording, newRecording.Schedule.IdSchedule);
                        }

                        Log.Info("Scheduler: Schedule {0}-{1} ({2}) has already been recorded ({3}) - aborting...",
                                 newRecording.Program.StartTime.ToString(), ToRecordTitle, ToRecordEpisode,
                                 pastRecordings[i].StartTime.ToString());
                      }
                    }
                    catch (Exception ex)
                    {
                      Log.Error(
                        "Scheduler: Schedule {0} ({1}) has already been recorded but the file is invalid ({2})! Going to record again...",
                        ToRecordTitle, ToRecordEpisode, ex.Message);
                    }
                  }
                }
              }
            }
          }
        }
      }
      catch (Exception ex1)
      {
        Log.Error("Scheduler: Error checking schedule {0} for repeatings {1}", ToRecordTitle, ex1.ToString());
      }
      return NewRecordingNeeded;
    }
Beispiel #20
0
    private void WriteMatroskaFile(RecordingDetail recDetail)
    {
      if (_createTagInfoXML)
      {
        string fileName = recDetail.FileName;
        MatroskaTagInfo info = new MatroskaTagInfo();
        info.title = recDetail.Program.Title;
        info.description = recDetail.Program.Description;
        info.genre = recDetail.Program.Genre;

        info.channelName = recDetail.Schedule.ReferencedChannel().DisplayName;
        info.episodeName = recDetail.Program.EpisodeName;
        info.seriesNum = recDetail.Program.SeriesNum;
        info.episodeNum = recDetail.Program.EpisodeNum;
        info.episodePart = recDetail.Program.EpisodePart;
        info.startTime = recDetail.RecordingStartDateTime;
        info.endTime = recDetail.EndTime;

        MatroskaTagHandler.WriteTag(System.IO.Path.ChangeExtension(fileName, ".xml"), info);
      }
    }
Beispiel #21
0
    /// <summary>
    /// Method which checks if its time to record the schedule specified
    /// </summary>
    /// <param name="schedule">Schedule</param>
    /// <param name="currentTime">current Date/Time</param>
    /// <param name="newRecording">Recording detail which is used to further process the recording</param>
    /// <returns>true if schedule should be recorded now, else false</returns>
    private bool IsTimeToRecord(Schedule schedule, DateTime currentTime, out RecordingDetail newRecording)
    {
      bool isTimeToRecord = false;
      newRecording = null;
      ScheduleRecordingType type = (ScheduleRecordingType)schedule.ScheduleType;

      switch (type)
      {
        case ScheduleRecordingType.Once:
          newRecording = IsTimeToRecordOnce(schedule, currentTime, out isTimeToRecord);
          break;

        case ScheduleRecordingType.Daily:
          newRecording = IsTimeToRecordDaily(schedule, currentTime, out isTimeToRecord);
          break;

        case ScheduleRecordingType.Weekends:
          newRecording = IsTimeToRecordWeekends(schedule, currentTime, out isTimeToRecord);
          break;

        case ScheduleRecordingType.WorkingDays:
          newRecording = IsTimeToRecordWorkingDays(schedule, currentTime, out isTimeToRecord);
          break;

        case ScheduleRecordingType.Weekly:
          newRecording = IsTimeToRecordWeekly(schedule, currentTime, out isTimeToRecord);
          break;

        case ScheduleRecordingType.EveryTimeOnThisChannel:
          isTimeToRecord = IsTimeToRecordEveryTimeOnThisChannel(schedule, currentTime);
          break;

        case ScheduleRecordingType.EveryTimeOnEveryChannel:
          isTimeToRecord = IsTimeToRecordEveryTimeOnEveryChannel(schedule);
          break;
        case ScheduleRecordingType.WeeklyEveryTimeOnThisChannel:
          isTimeToRecord = IsTimeToRecordWeeklyEveryTimeOnThisChannel(schedule, currentTime);
          break;
      }
      return isTimeToRecord;
    }
Beispiel #22
0
    private void StopRecord(RecordingDetail recording)
    {
      try
      {
        IUser user = recording.User;

        if (_tvController.SupportsSubChannels(recording.CardInfo.Id) == false)
        {
          _tvController.StopTimeShifting(ref user);
        }

        Log.Write("Scheduler: stop record {0} {1}-{2} {3}", recording.Channel.DisplayName,
                  recording.RecordingStartDateTime,
                  recording.EndTime, recording.Schedule.ProgramName);

        if (_tvController.StopRecording(ref user))
        {
          ResetRecordingState(recording);
          ResetRecordingStateOnProgram(recording);
          _recordingsInProgressList.Remove(recording); //only remove recording from the list, if we are succesfull

          if ((ScheduleRecordingType)recording.Schedule.ScheduleType == ScheduleRecordingType.Once)
          {
            StopRecordOnOnceSchedule(recording);
          }
          else
          {
            StopRecordOnSeriesSchedule(recording);
          }

          RecordingEndedNotification(recording);
        }
        else
        {
          RetryStopRecord(recording);
        }
      }
      catch (Exception ex)
      {
        Log.Write(ex);
      }
    }
Beispiel #23
0
 private RecordingDetail CreateNewRecordingDetail(Schedule schedule, DateTime currentTime)
 {
   RecordingDetail newRecording = null;
   DateTime start = new DateTime(currentTime.Year, currentTime.Month, currentTime.Day, schedule.StartTime.Hour,
                                 schedule.StartTime.Minute, schedule.StartTime.Second);
   DateTime end = new DateTime(currentTime.Year, currentTime.Month, currentTime.Day, schedule.EndTime.Hour,
                               schedule.EndTime.Minute, schedule.EndTime.Second);
   if (start > end)
     end = end.AddDays(1);
   if (currentTime >= start.AddMinutes(-schedule.PreRecordInterval) &&
       currentTime <= end.AddMinutes(schedule.PostRecordInterval))
   {
     if (!schedule.IsSerieIsCanceled(start))
     {
       VirtualCard vCard = null;
       bool isRecordingSchedule = IsRecordingSchedule(schedule.IdSchedule, out vCard);
       if (!isRecordingSchedule)
       {
         newRecording = new RecordingDetail(schedule, schedule.ReferencedChannel(), end, true);
       }
     }
   }
   return newRecording;
 }
Beispiel #24
0
 private void RetryStopRecord(RecordingDetail recording)
 {
   Log.Write("Scheduler: stop record did not succeed (trying again in 1 min.) {0} {1}-{2} {3}",
             recording.Channel.DisplayName, recording.RecordingStartDateTime, recording.EndTime,
             recording.Schedule.ProgramName);
   recording.Recording.EndTime = recording.Recording.EndTime.AddMinutes(1);
   //lets try and stop the recording in 1 min. again.
   recording.Recording.Persist();
 }
Beispiel #25
0
    private void StartRecordOnCard(
      RecordingDetail recDetail, 
		  ref IUser user,      
      ICollection<CardDetail> cardsForReservation)
    {
      var cardRes = new CardReservationRec(_tvController);                

      if (cardsForReservation.Count == 0)
      {
        //no free cards available
        Log.Write("scheduler: no free cards found for recording during initial card allocation.");
      }
      else
      {
        IterateCardsUntilRecording(recDetail, user, cardsForReservation, cardRes);
      }
    }
Beispiel #26
0
 private void RecordingEndedNotification(RecordingDetail recording)
 {
   IUser user = recording.User;
   _tvController.Fire(this,
                      new TvServerEventArgs(TvServerEventType.RecordingEnded, new VirtualCard(user), (User)user,
                                            recording.Schedule, recording.Recording));
 }
Beispiel #27
0
        private void TsCopier(object itemlist, Recording rec, Schedule newSchedule)
        {
            string[] bufferListObject;
              bufferListObject = new string[3];
              List<string[]> _itemlist = (List<string[]>)itemlist;
              bool foundHeader = false;
              bufferListObject = _itemlist[0];
              string targetTs = Path.GetDirectoryName(bufferListObject[2]) + "\\" + Path.GetFileNameWithoutExtension(bufferListObject[2]) + "_buffer.ts";

              try
              {
            Log.Info("TsCopier: targetTs {0}", targetTs);

            using (FileStream writer = new FileStream(targetTs, FileMode.CreateNew, FileAccess.Write))
            {
              for (int i = 0; i < _itemlist.Count; i++)
              {
            bufferListObject = _itemlist[i];

            try
            {
              if (File.Exists(bufferListObject[0]))
              {
                using (FileStream reader = new FileStream(bufferListObject[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                  Log.Info("TsCopier: TSfilename {0}", bufferListObject[0]);
                  Log.Debug("TsCopier: TSfilename filesize {0}", bufferListObject[1]);

                  if (!foundHeader)
                  {
                    byte[] prebuf = new byte[1024 * 1024];
                    int bytesPreRead;
                    bytesPreRead = reader.Read(prebuf, 0, 1024 * 1024);
                    long position = 0;

                    // find TS packet header
                    while (bytesPreRead > 0 && !foundHeader)
                    {
                      for (int x = 0; x < 1024 * 1024 - 376; x++)
                      {
                        if (prebuf[x] == 0x47 && prebuf[x + 188] == 0x47 && prebuf[x + 376] == 0x47)
                        {
                          Log.Debug("TsCopier: TS packet header found at {0} pos in {1}.", x, bufferListObject[0]);
                          position = x;
                          foundHeader = true;
                          break;
                        }
                      }
                      bytesPreRead = reader.Read(prebuf, 0, 1024 * 1024);
                    }

                    reader.Position = position;

                    if (!foundHeader)
                    {
                      Log.Debug("TsCopier: TS packet header not found in {0}.", bufferListObject[0]);
                      break;
                    }
                  }

                  byte[] buf = new byte[1024 * 1024];
                  int bytesRead = reader.Read(buf, 0, 1024 * 1024);
                  while (bytesRead > 0)
                  {
                    if (reader.Position > Convert.ToInt64(bufferListObject[1]))
                      bytesRead -= (int)(reader.Position - Convert.ToInt64(bufferListObject[1]));

                    if (bytesRead <= 0)
                      break;

                    writer.Write(buf, 0, bytesRead);
                    bytesRead = reader.Read(buf, 0, 1024 * 1024);
                    Thread.Sleep(100);
                  }
                  reader.Close();
                }
              }
            }
            catch (Exception ex)
            {
              Log.Error("TsCopier exception: {0}", ex);
            }
              }
              writer.Flush();
              writer.Close();
              Log.Info("TsCopier: Done {0}", targetTs);
            }
              }
              catch (Exception ex)
              {
            Log.Error("TsCopier Exception: {0}", ex);
              }

              try
              {
            Log.Debug("TsCopier: Creating Recording entry for {0}", targetTs);

            RecordingDetail recDetail = new RecordingDetail(newSchedule, newSchedule.ReferencedChannel(), DateTime.Now, false);

            recDetail.Recording = new Recording(recDetail.Schedule.IdChannel, recDetail.Schedule.IdSchedule, false,
                                          rec.StartTime, DateTime.Now, rec.Title + " (from buffer)",
                                          recDetail.Program.Description, recDetail.Program.Genre, targetTs,
                                          recDetail.Schedule.KeepMethod,
                                          recDetail.Schedule.KeepDate, 0, rec.IdServer, recDetail.Program.EpisodeName,
                                          recDetail.Program.SeriesNum, recDetail.Program.EpisodeNum,
                                          recDetail.Program.EpisodePart);

            recDetail.Recording.Persist();

            IUser user = recDetail.User;

            TsBufferExtractor.Controller.Fire(this, new TvServerEventArgs(TvServerEventType.RecordingEnded, new VirtualCard(user), (User)user,
                                                 recDetail.Schedule, recDetail.Recording));

            MatroskaTagInfo info = new MatroskaTagInfo();
            info.title = rec.Title + " (from buffer)";
            info.description = recDetail.Program.Description;
            info.genre = recDetail.Program.Genre;

            info.channelName = recDetail.Schedule.ReferencedChannel().DisplayName;
            info.episodeName = recDetail.Program.EpisodeName;
            info.seriesNum = recDetail.Program.SeriesNum;
            info.episodeNum = recDetail.Program.EpisodeNum;
            info.episodePart = recDetail.Program.EpisodePart;
            info.startTime = rec.StartTime;
            info.endTime = DateTime.Now;

            MatroskaTagHandler.WriteTag(System.IO.Path.ChangeExtension(targetTs, ".xml"), info);
            Log.Info("TsCopier: Finished the job.");
              }
              catch (Exception ex)
              {
            Log.Error("TsCopier Exception: {0}", ex);
              }
        }
Beispiel #28
0
    private bool FindAvailCardAndStartRecord(RecordingDetail recDetail, IUser user, ICollection<CardDetail> cards, int maxCards, ICollection<ICardTuneReservationTicket> tickets, CardReservationRec cardResImpl)
    {
      bool result = false;
      //keep tuning each card until we are succesful                   

      for (int k = 0; k < maxCards; k++)
      {
        ITvCardHandler tvCardHandler;
        CardDetail cardInfo = GetCardInfoForRecording(cards);
        if (_tvController.CardCollection.TryGetValue(cardInfo.Id, out tvCardHandler))
        {
          ICardTuneReservationTicket ticket = GetTicketByCardId(tickets, cardInfo.Id);

          if (ticket != null)
          {
            try
            {
              cardInfo = HijackCardForRecording(cards, ticket);
              result = SetupAndStartRecord(recDetail, ref user, cardInfo, ticket, cardResImpl);
              if (result)
              {
                break;
              }

            }
            catch (Exception ex)
            {
              CardReservationHelper.CancelCardReservationAndRemoveTicket(tvCardHandler, tickets);
              Log.Write(ex);
              StopFailedRecord(recDetail);
            }
          }
          else
          {
            Log.Write("scheduler: could not find available cardreservation on card:{0}", cardInfo.Id);
          }
        }
        Log.Write("scheduler: recording failed, lets try next available card.");
        CardReservationHelper.CancelCardReservationAndRemoveTicket(tvCardHandler, tickets);
        if (cardInfo != null && cards.Contains(cardInfo))
        {
          cards.Remove(cardInfo);
        }
      }
      return result;
    }