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); } }
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); } }
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; }
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; }
/// <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); }
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(); } }
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); }
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; }
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(); }
/// <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); } }
private void StartRecordingNotification(RecordingDetail recDetail) { IUser user = recDetail.User; _tvController.Fire(this, new TvServerEventArgs(TvServerEventType.StartRecording, new VirtualCard(user), (User)user, recDetail.Schedule, null)); }
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; }
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; }
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); }
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(); }
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(); } }
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); } }
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); } } }
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; }
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); } }
/// <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; }
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); } }
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; }
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(); }
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); } }
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)); }
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); } }
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; }