예제 #1
0
        public async Task <IEnumerable <RecordingInfo> > GetRecordingsAsync(CancellationToken cancellationToken)
        {
            var recordings = _recordingProvider.GetAll().ToList();
            var updated    = false;

            foreach (var recording in recordings)
            {
                if (recording.Status == RecordingStatus.InProgress)
                {
                    if (string.IsNullOrWhiteSpace(recording.TimerId) || !_activeRecordings.ContainsKey(recording.TimerId))
                    {
                        recording.Status          = RecordingStatus.Cancelled;
                        recording.DateLastUpdated = DateTime.UtcNow;
                        _recordingProvider.Update(recording);
                        updated = true;
                    }
                }
            }

            if (updated)
            {
                recordings = _recordingProvider.GetAll().ToList();
            }

            return(recordings);
        }
예제 #2
0
        public async Task UpdateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken)
        {
            _seriesTimerProvider.Update(info);
            List <ProgramInfo> epgData;

            if (info.RecordAnyChannel)
            {
                var channels = await GetChannelsAsync(true, CancellationToken.None).ConfigureAwait(false);

                var channelIds = channels.Select(i => i.Id).ToList();
                epgData = GetEpgDataForChannels(channelIds);
            }
            else
            {
                epgData = GetEpgDataForChannel(info.ChannelId);
            }

            await UpdateTimersForSeriesTimer(epgData, info).ConfigureAwait(false);
        }
예제 #3
0
        public async Task UpdateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken)
        {
            var instance = _seriesTimerProvider.GetAll().FirstOrDefault(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase));

            if (instance != null)
            {
                instance.ChannelId             = info.ChannelId;
                instance.Days                  = info.Days;
                instance.EndDate               = info.EndDate;
                instance.IsPostPaddingRequired = info.IsPostPaddingRequired;
                instance.IsPrePaddingRequired  = info.IsPrePaddingRequired;
                instance.PostPaddingSeconds    = info.PostPaddingSeconds;
                instance.PrePaddingSeconds     = info.PrePaddingSeconds;
                instance.Priority              = info.Priority;
                instance.RecordAnyChannel      = info.RecordAnyChannel;
                instance.RecordAnyTime         = info.RecordAnyTime;
                instance.RecordNewOnly         = info.RecordNewOnly;
                instance.StartDate             = info.StartDate;

                _seriesTimerProvider.Update(instance);

                List <ProgramInfo> epgData;
                if (instance.RecordAnyChannel)
                {
                    var channels = await GetChannelsAsync(true, CancellationToken.None).ConfigureAwait(false);

                    var channelIds = channels.Select(i => i.Id).ToList();
                    epgData = GetEpgDataForChannels(channelIds);
                }
                else
                {
                    epgData = GetEpgDataForChannel(instance.ChannelId);
                }

                await UpdateTimersForSeriesTimer(epgData, instance, true).ConfigureAwait(false);
            }
        }
예제 #4
0
파일: EmbyTV.cs 프로젝트: mcanthony/Emby
        private async Task RecordStream(TimerInfo timer, CancellationToken cancellationToken)
        {
            if (timer == null)
            {
                throw new ArgumentNullException("timer");
            }

            var mediaStreamInfo = await GetChannelStream(timer.ChannelId, null, CancellationToken.None);

            var duration = (timer.EndDate - DateTime.UtcNow).Add(TimeSpan.FromSeconds(timer.PostPaddingSeconds));

            HttpRequestOptions httpRequestOptions = new HttpRequestOptions()
            {
                Url = mediaStreamInfo.Path
            };

            var info       = GetProgramInfoFromCache(timer.ChannelId, timer.ProgramId);
            var recordPath = RecordingPath;

            if (info.IsMovie)
            {
                recordPath = Path.Combine(recordPath, "Movies", _fileSystem.GetValidFilename(info.Name));
            }
            else if (info.IsSeries)
            {
                recordPath = Path.Combine(recordPath, "Series", _fileSystem.GetValidFilename(info.Name));
            }
            else if (info.IsKids)
            {
                recordPath = Path.Combine(recordPath, "Kids", _fileSystem.GetValidFilename(info.Name));
            }
            else if (info.IsSports)
            {
                recordPath = Path.Combine(recordPath, "Sports", _fileSystem.GetValidFilename(info.Name));
            }
            else
            {
                recordPath = Path.Combine(recordPath, "Other", _fileSystem.GetValidFilename(info.Name));
            }

            var recordingFileName = _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info)) + ".ts";

            recordPath = Path.Combine(recordPath, recordingFileName);
            Directory.CreateDirectory(Path.GetDirectoryName(recordPath));

            var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.ProgramId, info.Id, StringComparison.OrdinalIgnoreCase));

            if (recording == null)
            {
                recording = new RecordingInfo
                {
                    ChannelId       = info.ChannelId,
                    Id              = Guid.NewGuid().ToString("N"),
                    StartDate       = info.StartDate,
                    EndDate         = info.EndDate,
                    Genres          = info.Genres,
                    IsKids          = info.IsKids,
                    IsLive          = info.IsLive,
                    IsMovie         = info.IsMovie,
                    IsHD            = info.IsHD,
                    IsNews          = info.IsNews,
                    IsPremiere      = info.IsPremiere,
                    IsSeries        = info.IsSeries,
                    IsSports        = info.IsSports,
                    IsRepeat        = !info.IsPremiere,
                    Name            = info.Name,
                    EpisodeTitle    = info.EpisodeTitle,
                    ProgramId       = info.Id,
                    HasImage        = info.HasImage,
                    ImagePath       = info.ImagePath,
                    ImageUrl        = info.ImageUrl,
                    OriginalAirDate = info.OriginalAirDate,
                    Status          = RecordingStatus.Scheduled,
                    Overview        = info.Overview,
                    SeriesTimerId   = timer.SeriesTimerId,
                    TimerId         = timer.Id,
                    ShowId          = info.ShowId
                };
                _recordingProvider.Add(recording);
            }

            recording.Path            = recordPath;
            recording.Status          = RecordingStatus.InProgress;
            recording.DateLastUpdated = DateTime.UtcNow;
            _recordingProvider.Update(recording);

            _logger.Info("Beginning recording.");

            try
            {
                httpRequestOptions.BufferContent = false;
                var durationToken = new CancellationTokenSource(duration);
                var linkedToken   = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;
                httpRequestOptions.CancellationToken = linkedToken;
                _logger.Info("Writing file to path: " + recordPath);
                using (var response = await _httpClient.SendAsync(httpRequestOptions, "GET"))
                {
                    using (var output = File.Open(recordPath, FileMode.Create, FileAccess.Write, FileShare.Read))
                    {
                        await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, linkedToken);
                    }
                }

                recording.Status = RecordingStatus.Completed;
                _logger.Info("Recording completed");
            }
            catch (OperationCanceledException)
            {
                _logger.Info("Recording stopped");
                recording.Status = RecordingStatus.Completed;
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error recording", ex);
                recording.Status = RecordingStatus.Error;
            }
            finally
            {
                CancellationTokenSource removed;
                _activeRecordings.TryRemove(timer.Id, out removed);
            }

            recording.DateLastUpdated = DateTime.UtcNow;
            _recordingProvider.Update(recording);

            if (recording.Status == RecordingStatus.Completed)
            {
                OnSuccessfulRecording(recording);
                _timerProvider.Delete(timer);
            }
            else if (DateTime.UtcNow < timer.EndDate)
            {
                const int retryIntervalSeconds = 60;
                _logger.Info("Retrying recording in {0} seconds.", retryIntervalSeconds);

                _timerProvider.StartTimer(timer, TimeSpan.FromSeconds(retryIntervalSeconds));
            }
            else
            {
                _timerProvider.Delete(timer);
                _recordingProvider.Delete(recording);
            }
        }