Example #1
0
 private List<Guid> GetRecordingGroupIds(RecordingInfo recording)
 {
     return GetRecordingGroupNames(recording).Select(i => i.ToLower()
         .GetMD5())
         .ToList();
 }
        private RecordingInfo GetRecordingInfo(EpgEventJSONObject i)
        {
            var info = new RecordingInfo();

            var recurr = i.recurr;
            if (recurr != null)
            {
                if (recurr.OID != 0)
                {
                    info.SeriesTimerId = recurr.OID.ToString(_usCulture);
                }
            }

            var schd = i.schd;

            if (schd != null)
            {
                info.ChannelId = schd.ChannelOid.ToString(_usCulture);
                info.Id = schd.OID.ToString(_usCulture);
                if (File.Exists(schd.RecordingFileName))
                {
                    info.Path = schd.RecordingFileName;
                }
                else
                {
                    info.Url = _baseUrl + "/live?recording=" + schd.OID;
                }
               
                info.Status = ParseStatus(schd.Status);
                info.StartDate = DateTime.Parse(schd.StartTime).ToUniversalTime();
                info.EndDate = DateTime.Parse(schd.EndTime).ToUniversalTime();

                info.IsHD = string.Equals(schd.Quality, "hdtv", StringComparison.OrdinalIgnoreCase);
                info.ImageUrl = string.IsNullOrEmpty(schd.FanArt) ? null : (_baseUrl + "/" + schd.FanArt);
                info.HasImage = !string.IsNullOrEmpty(schd.FanArt);
            }

            var epg = i.epgEvent;

            if (epg != null)
            {
                info.Audio = ListingsResponse.ParseAudio(epg.Audio);
                info.ProgramId = epg.OID.ToString(_usCulture);
                info.OfficialRating = epg.Rating;
                info.EpisodeTitle = epg.Subtitle;
                info.Name = epg.Title;
                info.Overview = epg.Desc;
                info.Genres = epg.Genres.Where(g => !string.IsNullOrWhiteSpace(g)).ToList();
                info.IsRepeat = !epg.FirstRun;
                info.IsSeries = true;    //!string.IsNullOrEmpty(epg.Subtitle); http://emby.media/community/index.php?/topic/21264-series-record-ability-missing-in-emby-epg/#entry239633
                info.CommunityRating = ListingsResponse.ParseCommunityRating(epg.StarRating);
                info.IsHD = string.Equals(epg.Quality, "hdtv", StringComparison.OrdinalIgnoreCase);
                info.IsNews = epg.Genres.Contains("news", StringComparer.OrdinalIgnoreCase);
                info.IsMovie = epg.Genres.Contains("movie", StringComparer.OrdinalIgnoreCase);
                info.IsKids = epg.Genres.Contains("kids", StringComparer.OrdinalIgnoreCase);

                info.IsSports = epg.Genres.Contains("sports", StringComparer.OrdinalIgnoreCase) ||
                    epg.Genres.Contains("Sports non-event", StringComparer.OrdinalIgnoreCase) ||
                    epg.Genres.Contains("Sports event", StringComparer.OrdinalIgnoreCase) ||
                    epg.Genres.Contains("Sports talk", StringComparer.OrdinalIgnoreCase) ||
                    epg.Genres.Contains("Sports news", StringComparer.OrdinalIgnoreCase);
            }

            return info;
        }
Example #3
0
        public Task<IEnumerable<RecordingInfo>> buildDvrInfos(CancellationToken cancellationToken)
        {
            return Task.Factory.StartNew<IEnumerable<RecordingInfo>>(() =>
            {
                lock (_data)
                {
                    List<RecordingInfo> result = new List<RecordingInfo>();
                    foreach (KeyValuePair<string, HTSMessage> entry in _data)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            _logger.Info("[TVHclient] DvrDataHelper.buildDvrInfos, call canceled - returning part list.");
                            return result;
                        }

                        HTSMessage m = entry.Value;
                        RecordingInfo ri = new RecordingInfo();

                        try
                        {
                            if (m.containsField("id"))
                            {
                                ri.Id = "" + m.getInt("id");
                            }
                        }
                        catch (InvalidCastException)
                        {
                        }

                        try
                        {
                            if (m.containsField("channel"))
                            {
                                ri.ChannelId = "" + m.getInt("channel");
                            }
                        }
                        catch (InvalidCastException)
                        {
                        }

                        try
                        {
                            if (m.containsField("start"))
                            {
                                long unixUtc = m.getLong("start");
                                ri.StartDate = _initialDateTimeUTC.AddSeconds(unixUtc).ToUniversalTime();
                            }
                        }
                        catch (InvalidCastException)
                        {
                        }

                        try
                        {
                            if (m.containsField("stop"))
                            {
                                long unixUtc = m.getLong("stop");
                                ri.EndDate = _initialDateTimeUTC.AddSeconds(unixUtc).ToUniversalTime();
                            }
                        }
                        catch (InvalidCastException)
                        {
                        }

                        try
                        {
                            if (m.containsField("title"))
                            {
                                ri.Name = m.getString("title");
                            }
                        }
                        catch (InvalidCastException)
                        {
                        }

                        try
                        {
                            if (m.containsField("description"))
                            {
                                ri.Overview = m.getString("description");
                            }
                        }
                        catch (InvalidCastException)
                        {
                        }

                        try
                        {
                            if (m.containsField("summary"))
                            {
                                ri.EpisodeTitle = m.getString("summary");
                            }
                        }
                        catch (InvalidCastException)
                        {
                        }

                        ri.HasImage = false;
                        // public string ImagePath { get; set; }
                        // public string ImageUrl { get; set; }

                        try
                        {
                            if (m.containsField("state"))
                            {
                                string state = m.getString("state");
                                switch (state)
                                {
                                    case "completed":
                                        ri.Status = RecordingStatus.Completed;
                                        break;
                                    case "scheduled":
                                        ri.Status = RecordingStatus.Scheduled;
                                        continue;
                                    //break;
                                    case "missed":
                                        ri.Status = RecordingStatus.Error;
                                        break;
                                    case "recording":
                                        ri.Status = RecordingStatus.InProgress;
                                        break;

                                    default:
                                        _logger.Fatal("[TVHclient] DvrDataHelper.buildDvrInfos: state '" + state + "' not handled!");
                                        continue;
                                    //break;
                                }
                            }
                        }
                        catch (InvalidCastException)
                        {
                        }

                        // Path must not be set to force emby use of the LiveTvService methods!!!!
                        //if (m.containsField("path"))
                        //{
                        //    ri.Path = m.getString("path");
                        //}

                        try
                        {
                            if (m.containsField("autorecId"))
                            {
                                ri.SeriesTimerId = m.getString("autorecId");
                            }
                        }
                        catch (InvalidCastException)
                        {
                        }

                        try
                        {
                            if (m.containsField("eventId"))
                            {
                                ri.ProgramId = "" + m.getInt("eventId");
                            }
                        }
                        catch (InvalidCastException)
                        {
                        }

                        /*
                                public ProgramAudio? Audio { get; set; }
                                public ChannelType ChannelType { get; set; }
                                public float? CommunityRating { get; set; }
                                public List<string> Genres { get; set; }
                                public bool? IsHD { get; set; }
                                public bool IsKids { get; set; }
                                public bool IsLive { get; set; }
                                public bool IsMovie { get; set; }
                                public bool IsNews { get; set; }
                                public bool IsPremiere { get; set; }
                                public bool IsRepeat { get; set; }
                                public bool IsSeries { get; set; }
                                public bool IsSports { get; set; }
                                public string OfficialRating { get; set; }
                                public DateTime? OriginalAirDate { get; set; }
                                public string Url { get; set; }
                         */

                        result.Add(ri);
                    }
                    return result;
                }
            });
        }
Example #4
0
        private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, Guid parentFolderId, CancellationToken cancellationToken)
        {
            var isNew = false;

            var id = _tvDtoService.GetInternalRecordingId(serviceName, info.Id);

            var item = _itemRepo.RetrieveItem(id);

            if (item == null)
            {
                if (info.ChannelType == ChannelType.TV)
                {
                    item = new LiveTvVideoRecording
                    {
                        Name = info.Name,
                        Id = id,
                        DateCreated = DateTime.UtcNow,
                        DateModified = DateTime.UtcNow,
                        VideoType = VideoType.VideoFile
                    };
                }
                else
                {
                    item = new LiveTvAudioRecording
                    {
                        Name = info.Name,
                        Id = id,
                        DateCreated = DateTime.UtcNow,
                        DateModified = DateTime.UtcNow
                    };
                }

                isNew = true;
            }

            item.ChannelId = _tvDtoService.GetInternalChannelId(serviceName, info.ChannelId).ToString("N");
            item.CommunityRating = info.CommunityRating;
            item.OfficialRating = info.OfficialRating;
            item.Overview = info.Overview;
            item.EndDate = info.EndDate;
            item.Genres = info.Genres;
            item.PremiereDate = info.OriginalAirDate;

            var recording = (ILiveTvRecording)item;

            recording.ExternalId = info.Id;

            var dataChanged = false;

            recording.Audio = info.Audio;
            recording.EndDate = info.EndDate;
            recording.EpisodeTitle = info.EpisodeTitle;
            recording.IsHD = info.IsHD;
            recording.IsKids = info.IsKids;
            recording.IsLive = info.IsLive;
            recording.IsMovie = info.IsMovie;
            recording.IsNews = info.IsNews;
            recording.IsPremiere = info.IsPremiere;
            recording.IsRepeat = info.IsRepeat;
            recording.IsSports = info.IsSports;
            recording.SeriesTimerId = info.SeriesTimerId;
            recording.StartDate = info.StartDate;

            if (!dataChanged)
            {
                dataChanged = recording.IsSeries != info.IsSeries;
            }
            recording.IsSeries = info.IsSeries;

            if (!item.HasImage(ImageType.Primary))
            {
                if (!string.IsNullOrWhiteSpace(info.ImagePath))
                {
                    item.SetImagePath(ImageType.Primary, info.ImagePath);
                }
                else if (!string.IsNullOrWhiteSpace(info.ImageUrl))
                {
                    item.SetImagePath(ImageType.Primary, info.ImageUrl);
                }
            }

            var statusChanged = info.Status != recording.Status;

            recording.Status = info.Status;

            recording.ServiceName = serviceName;

            if (!string.IsNullOrEmpty(info.Path))
            {
                if (!dataChanged)
                {
                    dataChanged = !string.Equals(item.Path, info.Path);
                }
                var fileInfo = _fileSystem.GetFileInfo(info.Path);

                recording.DateCreated = _fileSystem.GetCreationTimeUtc(fileInfo);
                recording.DateModified = _fileSystem.GetLastWriteTimeUtc(fileInfo);
                item.Path = info.Path;
            }
            else if (!string.IsNullOrEmpty(info.Url))
            {
                if (!dataChanged)
                {
                    dataChanged = !string.Equals(item.Path, info.Url);
                }
                item.Path = info.Url;
            }

            var metadataRefreshMode = MetadataRefreshMode.Default;

            if (isNew)
            {
                await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
            }
            else if (dataChanged || info.DateLastUpdated > recording.DateLastSaved || statusChanged)
            {
                metadataRefreshMode = MetadataRefreshMode.FullRefresh;
                await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
            }

            _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(_fileSystem)
            {
                MetadataRefreshMode = metadataRefreshMode
            });

            return item.Id;
        }
Example #5
0
        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;
            }

            recording.DateLastUpdated = DateTime.UtcNow;
            _recordingProvider.Update(recording);
            _timerProvider.Delete(timer);
            _logger.Info("Recording was a success");

            if (recording.Status == RecordingStatus.Completed)
            {
                OnSuccessfulRecording(recording);
            }
        }
        public RecordingInfo GetRecording(CancellationToken cancellationToken, String id)
        {
            var response = GetFromService<Recording>(cancellationToken, "GetRecordingById?id={0}", id);
            var configuration = Plugin.Instance.Configuration;
            if (configuration.EnableDirectAccess && !configuration.RequiresPathSubstitution)
            {
                var recording = new RecordingInfo()
                {
                    ChannelId = response.ChannelId.ToString(CultureInfo.InvariantCulture),
                    EndDate = response.EndTime,
                    EpisodeTitle = response.EpisodeName,
                    Genres = new List<String>(),
                    Id = response.Id.ToString(CultureInfo.InvariantCulture),
                    IsSeries = (!String.IsNullOrEmpty(response.EpisodeNum)) ? true : false,
                    Name = response.Title,
                    Overview = response.Description,
                    ProgramId = response.ScheduleId.ToString(CultureInfo.InvariantCulture),
                    StartDate = response.StartTime,
                    Path = response.FileName,
                };

                if (response.IsRecording)
                {
                    var schedule = GetFromService<Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", response.ScheduleId);
                    {
                        if (schedule.Series)
                        {
                            recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                        }
                    }
                }

                if (!String.IsNullOrEmpty(response.Genre))
                {
                    recording.Genres.Add(response.Genre);
                }

                return recording;
            }

            else if (configuration.EnableDirectAccess && configuration.RequiresPathSubstitution)
            {
                var localpath = String.Format("{0}", configuration.LocalFilePath);
                var remotepath = String.Format("{0}", configuration.RemoteFilePath);

            var recording = new RecordingInfo()
            {
                ChannelId = response.ChannelId.ToString(CultureInfo.InvariantCulture),
                EndDate = response.EndTime,
                EpisodeTitle = response.EpisodeName,
                Genres = new List<String>(),
                Id = response.Id.ToString(CultureInfo.InvariantCulture),
                    IsSeries = (!String.IsNullOrEmpty(response.EpisodeNum)) ? true : false,
                Name = response.Title,
                Overview = response.Description,
                ProgramId = response.ScheduleId.ToString(CultureInfo.InvariantCulture),
                StartDate = response.StartTime,
                    Path = response.FileName.Replace(localpath, remotepath),
            };

                if (response.IsRecording)
                {
                    var schedule = GetFromService<Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", response.ScheduleId);
                    {
                        if (schedule.Series)
                        {
                            recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                        }
                    }
                }

            if (!String.IsNullOrEmpty(response.Genre))
            {
                recording.Genres.Add(response.Genre);
            }

            return recording;
            }

            else
            {
                var recording = new RecordingInfo()
                {
                    ChannelId = response.ChannelId.ToString(CultureInfo.InvariantCulture),
                    EndDate = response.EndTime,
                    EpisodeTitle = response.EpisodeName,
                    Genres = new List<String>(),
                    Id = response.Id.ToString(CultureInfo.InvariantCulture),
                    IsSeries = (!String.IsNullOrEmpty(response.EpisodeNum)) ? true : false,
                    Name = response.Title,
                    Overview = response.Description,
                    ProgramId = response.ScheduleId.ToString(CultureInfo.InvariantCulture),
                    StartDate = response.StartTime,
                };

                if (response.IsRecording)
                {
                    var schedule = GetFromService<Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", response.ScheduleId);
                    {
                        if (schedule.Series)
                        {
                            recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                        }
                    }
                }

                if (!String.IsNullOrEmpty(response.Genre))
                {
                    recording.Genres.Add(response.Genre);
                }

                return recording;
            }
        }
Example #7
0
        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;
            }

            recording.DateLastUpdated = DateTime.UtcNow;
            _recordingProvider.Update(recording);
            _timerProvider.Delete(timer);
            _logger.Info("Recording was a success");

            if (recording.Status == RecordingStatus.Completed)
            {
                OnSuccessfulRecording(recording);
            }
        }
        public IEnumerable<RecordingInfo> GetRecordings(CancellationToken cancellationToken)
        {
            var response = GetFromService<List<Recording>>(cancellationToken, "GetRecordings");

            var recordings = response.Select(r =>
            {
                var recording = new RecordingInfo()
                {
                    ChannelId = r.ChannelId.ToString(CultureInfo.InvariantCulture),
                    EndDate = r.EndTime,
                    EpisodeTitle = r.EpisodeName,
                    Genres = new List<String>(),
                    Id = r.Id.ToString(CultureInfo.InvariantCulture),
                    Name = r.Title,
                    Overview = r.Description,
                    ProgramId = r.ScheduleId.ToString(CultureInfo.InvariantCulture),
                    StartDate = r.StartTime,
                    ImageUrl = _wssProxy.GetRecordingImageUrl(r.Id.ToString()),
                };

                if (!String.IsNullOrEmpty(r.Genre))
                {
                    recording.Genres.Add(r.Genre);
                }

                return recording;

            }).ToList();

            return recordings;
        }
Example #9
0
        private RecordingInfo ProgramToRecordingInfo(Program item, IFileSystem fileSystem)
        {
            RecordingInfo recInfo = new RecordingInfo()
            {
                Id              = item.Recording.RecordedId,
                SeriesTimerId   = item.Recording.RecordId,
                ChannelId       = item.Channel.ChanId,
                ChannelType     = ChannelType.TV,
                Name            = item.Title,
                Overview        = item.Description,
                StartDate       = item.StartTime,
                EndDate         = item.EndTime,
                ProgramId       = $"{item.Channel.ChanId}_{item.StartTime.Ticks}",
                Status          = RecStatusToRecordingStatus(item.Recording.Status),
                IsRepeat        = item.Repeat,
                IsHD            = (item.VideoProps & VideoFlags.VID_HDTV) == VideoFlags.VID_HDTV,
                Audio           = ProgramAudio.Stereo,
                OriginalAirDate = item.Airdate,
                IsMovie         = item.CatType == "movie",
                IsSports        = item.CatType == "sports" ||
                                  GeneralHelpers.ContainsWord(item.Category, "sport",
                                                              StringComparison.OrdinalIgnoreCase) ||
                                  GeneralHelpers.ContainsWord(item.Category, "motor sports",
                                                              StringComparison.OrdinalIgnoreCase) ||
                                  GeneralHelpers.ContainsWord(item.Category, "football",
                                                              StringComparison.OrdinalIgnoreCase) ||
                                  GeneralHelpers.ContainsWord(item.Category, "cricket",
                                                              StringComparison.OrdinalIgnoreCase),
                IsSeries = item.CatType == "series" || item.CatType == "tvshow",
                IsNews   = GeneralHelpers.ContainsWord(item.Category, "news",
                                                       StringComparison.OrdinalIgnoreCase),
                IsKids = GeneralHelpers.ContainsWord(item.Category, "animation",
                                                     StringComparison.OrdinalIgnoreCase),
                ShowId = item.ProgramId,
            };

            if (!string.IsNullOrEmpty(item.SubTitle))
            {
                recInfo.EpisodeTitle = item.SubTitle;
            }
            else if (item.Season != null && item.Episode != null && item.Season > 0 && item.Episode > 0)
            {
                recInfo.EpisodeTitle = string.Format("{0:D}x{1:D2}", item.Season, item.Episode);
            }
            else
            {
                recInfo.EpisodeTitle = item.Airdate.ToString("yyyy-MM-dd");
            }

            string recPath = Path.Combine(StorageGroups[item.Recording.StorageGroup].DirNameEmby, item.FileName);

            if (fileSystem.FileExists(recPath))
            {
                recInfo.Path = recPath;
            }
            else
            {
                recInfo.Url = string.Format("{0}/Content/GetFile?StorageGroup={1}&FileName={2}",
                                            Plugin.Instance.Configuration.WebServiceUrl,
                                            item.Recording.StorageGroup,
                                            item.FileName);
            }

            recInfo.Genres.AddRange(item.Category.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries));

            recInfo.HasImage = false;
            if (item.Artwork.ArtworkInfos.Count > 0)
            {
                var art = item.Artwork.ArtworkInfos.Where(i => i.Type.Equals("coverart"));
                if (art.Any())
                {
                    var url = item.Artwork.ArtworkInfos.Where(i => i.Type.Equals("coverart")).First().URL;
                    recInfo.ImageUrl = string.Format("{0}{1}",
                                                     Plugin.Instance.Configuration.WebServiceUrl,
                                                     url);
                    recInfo.HasImage = true;
                }
            }

            return(recInfo);
        }
        private RecordingInfo GetRecordingInfo(EpgEventJSONObject i)
        {
            var info = new RecordingInfo();

            var recurr = i.recurr;

            if (recurr != null)
            {
                if (recurr.OID != 0)
                {
                    info.SeriesTimerId = recurr.OID.ToString(_usCulture);
                }
            }

            var schd = i.schd;

            if (schd != null)
            {
                info.ChannelId = schd.ChannelOid.ToString(_usCulture);
                info.Id        = schd.OID.ToString(_usCulture);
                if (File.Exists(schd.RecordingFileName))
                {
                    info.Path = schd.RecordingFileName;
                }
                else
                {
                    info.Url = _baseUrl + "/live?recording=" + schd.OID;
                }

                info.Status    = ParseStatus(schd.Status);
                info.StartDate = DateTime.Parse(schd.StartTime).ToUniversalTime();
                info.EndDate   = DateTime.Parse(schd.EndTime).ToUniversalTime();

                info.IsHD     = string.Equals(schd.Quality, "hdtv", StringComparison.OrdinalIgnoreCase);
                info.ImageUrl = string.IsNullOrEmpty(schd.FanArt) ? null : (_baseUrl + "/" + schd.FanArt);
                info.HasImage = !string.IsNullOrEmpty(schd.FanArt);
            }

            var epg = i.epgEvent;

            if (epg != null)
            {
                info.Audio           = ListingsResponse.ParseAudio(epg.Audio);
                info.ProgramId       = epg.OID.ToString(_usCulture);
                info.OfficialRating  = epg.Rating;
                info.EpisodeTitle    = epg.Subtitle;
                info.Name            = epg.Title;
                info.Overview        = epg.Desc;
                info.Genres          = epg.Genres.Where(g => !string.IsNullOrWhiteSpace(g)).ToList();
                info.IsRepeat        = !epg.FirstRun;
                info.IsSeries        = true; //!string.IsNullOrEmpty(epg.Subtitle); http://emby.media/community/index.php?/topic/21264-series-record-ability-missing-in-emby-epg/#entry239633
                info.CommunityRating = ListingsResponse.ParseCommunityRating(epg.StarRating);
                info.IsHD            = string.Equals(epg.Quality, "hdtv", StringComparison.OrdinalIgnoreCase);
                info.IsNews          = epg.Genres.Contains("news", StringComparer.OrdinalIgnoreCase);
                info.IsMovie         = epg.Genres.Contains("movie", StringComparer.OrdinalIgnoreCase);
                info.IsKids          = epg.Genres.Contains("kids", StringComparer.OrdinalIgnoreCase);

                info.IsSports = epg.Genres.Contains("sports", StringComparer.OrdinalIgnoreCase) ||
                                epg.Genres.Contains("Sports non-event", StringComparer.OrdinalIgnoreCase) ||
                                epg.Genres.Contains("Sports event", StringComparer.OrdinalIgnoreCase) ||
                                epg.Genres.Contains("Sports talk", StringComparer.OrdinalIgnoreCase) ||
                                epg.Genres.Contains("Sports news", StringComparer.OrdinalIgnoreCase);
            }

            return(info);
        }
 public void Init()
 {
     instance = new RecordingInfo();
 }
Example #12
0
        internal Event(
            Engine engine,
            UInt64 idRundownEvent,
            UInt64 idEventBinding,
            VideoLayer videoLayer,
            TEventType eventType,
            TStartType startType,
            TPlayState playState,
            DateTime scheduledTime,
            TimeSpan duration,
            TimeSpan scheduledDelay,
            TimeSpan scheduledTC,
            Guid mediaGuid,
            string eventName,
            DateTime startTime,
            TimeSpan startTC,
            TimeSpan?requestedStartTime,
            TimeSpan transitionTime,
            TimeSpan transitionPauseTime,
            TTransitionType transitionType,
            TEasing transitionEasing,
            double?audioVolume,
            UInt64 idProgramme,
            string idAux,
            bool isEnabled,
            bool isHold,
            bool isLoop,
            AutoStartFlags autoStartFlags,
            bool isCGEnabled,
            byte crawl,
            byte logo,
            byte parental,
            short routerPort,
            RecordingInfo recordingInfo)
        {
            _engine              = engine;
            _rundownSync         = engine.RundownSync;
            Id                   = idRundownEvent;
            IdEventBinding       = idEventBinding;
            _layer               = videoLayer;
            _eventType           = eventType;
            _startType           = startType;
            _playState           = playState == TPlayState.Paused ? TPlayState.Scheduled: playState == TPlayState.Fading ? TPlayState.Played : playState;
            _scheduledTime       = scheduledTime;
            _duration            = duration;
            _scheduledDelay      = scheduledDelay;
            _scheduledTc         = scheduledTC;
            _eventName           = eventName;
            _startTime           = startTime;
            _startTc             = startTC;
            _requestedStartTime  = requestedStartTime;
            _transitionTime      = transitionTime;
            _transitionPauseTime = transitionPauseTime;
            _transitionType      = transitionType;
            _transitionEasing    = transitionEasing;
            _audioVolume         = audioVolume;
            _idProgramme         = idProgramme;
            _idAux               = idAux;
            _isEnabled           = isEnabled;
            _isHold              = isHold;
            _isLoop              = isLoop;
            _isCGEnabled         = isCGEnabled;
            _crawl               = crawl;
            _logo                = logo;
            _parental            = parental;
            _autoStartFlags      = autoStartFlags;
            _mediaGuid           = mediaGuid;
            _subEvents           = new Lazy <SynchronizedCollection <Event> >(() =>
            {
                var result = new SynchronizedCollection <Event>();
                if (Id == 0)
                {
                    return(result);
                }
                var seList = DatabaseProvider.Database.ReadSubEvents(_engine, this);
                foreach (Event e in seList)
                {
                    e.Parent = this;
                    result.Add(e);
                }
                return(result);
            });

            _next = new Lazy <Event>(() =>
            {
                var next = (Event)DatabaseProvider.Database.ReadNext(_engine, this);
                if (next != null)
                {
                    next.Prior = this;
                }
                return(next);
            });

            _prior = new Lazy <Event>(() =>
            {
                Event prior = null;
                if (startType == TStartType.After && IdEventBinding > 0)
                {
                    prior = (Event)DatabaseProvider.Database.ReadEvent(_engine, IdEventBinding);
                }
                if (prior != null)
                {
                    prior.Next = this;
                }
                return(prior);
            });

            _parent = new Lazy <Event>(() =>
            {
                if ((startType == TStartType.WithParent || startType == TStartType.WithParentFromEnd) && IdEventBinding > 0)
                {
                    return((Event)DatabaseProvider.Database.ReadEvent(_engine, IdEventBinding));
                }
                return(null);
            });

            _rights = new Lazy <List <IAclRight> >(() =>
            {
                var rights = DatabaseProvider.Database.ReadEventAclList <EventAclRight>(this, _engine.AuthenticationService as IAuthenticationServicePersitency);
                rights.ForEach(r => ((EventAclRight)r).Saved += AclEvent_Saved);
                return(rights);
            });
            _routerPort    = routerPort;
            _recordingInfo = recordingInfo;

            FieldLengths = DatabaseProvider.Database.EventFieldLengths;
        }
        /// <summary>
        /// Create a new recording
        /// </summary>
        /// <param name="info">The TimerInfo</param>
        /// <param name="cancellationToken">The cancellationToken</param>
        /// <returns></returns>
        public async Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken)
        {
            _logger.Info(string.Format("[VuPlus] Start CreateTimerAsync for ChannelId: {0} & Name: {1}", info.ChannelId, info.Name));
            await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);

            // extract eventid from info.ProgramId
            string[] words = info.ProgramId.Split('~');
            var eventid = words[1];

            var protocol = "http";
            if (Plugin.Instance.Configuration.UseSecureHTTPS)
                protocol = "https";

            var baseUrl = protocol + "://" + Plugin.Instance.Configuration.HostName + ":" + Plugin.Instance.Configuration.WebInterfacePort;

            var url = string.Format("{0}/web/timeraddbyeventid?sRef={1}&eventid={2}", baseUrl, info.ChannelId, eventid);

            if (!string.IsNullOrEmpty(Plugin.Instance.Configuration.RecordingPath))
            {
                url = url + string.Format("&dirname={0}", WebUtility.UrlEncode(Plugin.Instance.Configuration.RecordingPath));
            }

            UtilsHelper.DebugInformation(_logger, string.Format("[VuPlus] CreateTimerAsync url: {0}", url));

            var options = new HttpRequestOptions
            {
                CancellationToken = cancellationToken,
                Url = url
            };

            if (!string.IsNullOrEmpty(Plugin.Instance.Configuration.WebInterfaceUsername))
            {
                string authInfo = Plugin.Instance.Configuration.WebInterfaceUsername + ":" + Plugin.Instance.Configuration.WebInterfacePassword;
                authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
                options.RequestHeaders["Authorization"] = "Basic " + authInfo;
            }

            using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    string xmlResponse = reader.ReadToEnd();
                    UtilsHelper.DebugInformation(_logger, string.Format("[VuPlus] CancelTimerAsync response: {0}", xmlResponse));

                    try
                    {
                        var xml = new XmlDocument();
                        xml.LoadXml(xmlResponse);

                        XmlNodeList e2simplexmlresult = xml.GetElementsByTagName("e2simplexmlresult");
                        foreach (XmlNode xmlNode in e2simplexmlresult)
                        {
                            var recordingInfo = new RecordingInfo();

                            var e2state = "?";
                            var e2statetext = "?";

                            foreach (XmlNode node in xmlNode.ChildNodes)
                            {
                                if (node.Name == "e2state")
                                {
                                    e2state = node.InnerText;
                                }
                                else if (node.Name == "e2statetext")
                                {
                                    e2statetext = node.InnerText;
                                }
                            }

                            if (e2state != "True")
                            {
                                _logger.Error("[VuPlus] Failed to create timer.");
                                _logger.Error(string.Format("[VuPlus] CreateTimerAsync e2statetext: {0}", e2statetext));
                                throw new ApplicationException("Failed to create timer.");
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        _logger.Error("[VuPlus] Failed to parse create timer information.");
                        _logger.Error(string.Format("[VuPlus] CreateTimerAsync error: {0}", e.Message));
                        throw new ApplicationException("Failed to parse create timer information.");
                    }
                }
            }
        }
        /// <summary>
        /// Delete the Recording async from the disk
        /// </summary>
        /// <param name="recordingId">The recordingId</param>
        /// <param name="cancellationToken">The cancellationToken</param>
        /// <returns></returns>
        public async Task DeleteRecordingAsync(string recordingId, CancellationToken cancellationToken)
        {
            _logger.Info(string.Format("[VuPlus] Start Delete Recording Async for recordingId: {0}", recordingId));
            await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);

            var protocol = "http";
            if (Plugin.Instance.Configuration.UseSecureHTTPS)
                protocol = "https";

            var baseUrl = protocol + "://" + Plugin.Instance.Configuration.HostName + ":" + Plugin.Instance.Configuration.WebInterfacePort;

            var url = string.Format("{0}/web/moviedelete?sRef={1}", baseUrl, recordingId);
            UtilsHelper.DebugInformation(_logger, string.Format("[VuPlus] DeleteRecordingAsync url: {0}", url));

            var options = new HttpRequestOptions
            {
                CancellationToken = cancellationToken,
                Url = url
            };

            if (!string.IsNullOrEmpty(Plugin.Instance.Configuration.WebInterfaceUsername))
            {
                string authInfo = Plugin.Instance.Configuration.WebInterfaceUsername + ":" + Plugin.Instance.Configuration.WebInterfacePassword;
                authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
                options.RequestHeaders["Authorization"] = "Basic " + authInfo;
            }

            using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    string xmlResponse = reader.ReadToEnd();
                    UtilsHelper.DebugInformation(_logger, string.Format("[VuPlus] DeleteRecordingAsync response: {0}", xmlResponse));

                    try
                    {
                        var xml = new XmlDocument();
                        xml.LoadXml(xmlResponse);

                        XmlNodeList e2simplexmlresult = xml.GetElementsByTagName("e2simplexmlresult");
                        foreach (XmlNode xmlNode in e2simplexmlresult)
                        {
                            var recordingInfo = new RecordingInfo();

                            var e2state = "?";
                            var e2statetext = "?";

                            foreach (XmlNode node in xmlNode.ChildNodes)
                            {
                                if (node.Name == "e2state")
                                {
                                    e2state = node.InnerText;
                                }
                                else if (node.Name == "e2statetext")
                                {
                                    e2statetext = node.InnerText;
                                }
                            }

                            if (e2state != "True")
                            {
                                _logger.Error("[VuPlus] Failed to delete recording information.");
                                _logger.Error(string.Format("[VuPlus] DeleteRecordingAsync e2statetext: {0}", e2statetext));
                                throw new ApplicationException("Failed to delete recording.");
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        _logger.Error("[VuPlus] Failed to parse delete recording information.");
                        _logger.Error(string.Format("[VuPlus] DeleteRecordingAsync error: {0}", e.Message));
                        throw new ApplicationException("Failed to parse delete recording information.");
                    }
                }
            }
        }
        public IEnumerable <RecordingInfo> GetRecordings(CancellationToken cancellationToken)
        {
            var response      = GetFromService <List <Recording> >(cancellationToken, "GetRecordings");
            var configuration = Plugin.Instance.Configuration;

            if (configuration.EnableDirectAccess && !configuration.RequiresPathSubstitution)
            {
                var recordings = response.Select(r =>
                {
                    var recording = new RecordingInfo()
                    {
                        ChannelId    = r.ChannelId.ToString(CultureInfo.InvariantCulture),
                        EndDate      = r.EndTime,
                        EpisodeTitle = r.EpisodeName,
                        Genres       = new List <String>(),
                        Id           = r.Id.ToString(CultureInfo.InvariantCulture),
                        IsSeries     = (!String.IsNullOrEmpty(r.EpisodeNum)) ? true : false,
                        Name         = r.Title,
                        Overview     = r.Description,
                        ProgramId    = r.ScheduleId.ToString(CultureInfo.InvariantCulture),
                        StartDate    = r.StartTime,
                        ImageUrl     = _wssProxy.GetRecordingImageUrl(r.Id.ToString()),
                        Path         = r.FileName,
                    };

                    if (r.IsRecording)
                    {
                        var schedule = GetFromService <Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", r.ScheduleId);
                        {
                            if (schedule.Series)
                            {
                                recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                            }
                        }
                    }

                    if (!String.IsNullOrEmpty(r.Genre))
                    {
                        recording.Genres.Add(r.Genre);
                    }

                    return(recording);
                }).ToList();

                return(recordings);
            }

            else if (configuration.EnableDirectAccess && configuration.RequiresPathSubstitution)
            {
                var localpath  = String.Format("{0}", configuration.LocalFilePath);
                var remotepath = String.Format("{0}", configuration.RemoteFilePath);

                var recordings = response.Select(r =>
                {
                    var recording = new RecordingInfo()
                    {
                        ChannelId    = r.ChannelId.ToString(CultureInfo.InvariantCulture),
                        EndDate      = r.EndTime,
                        EpisodeTitle = r.EpisodeName,
                        Genres       = new List <String>(),
                        Id           = r.Id.ToString(CultureInfo.InvariantCulture),
                        IsSeries     = (!String.IsNullOrEmpty(r.EpisodeNum)) ? true : false,
                        Name         = r.Title,
                        Overview     = r.Description,
                        ProgramId    = r.ScheduleId.ToString(CultureInfo.InvariantCulture),
                        StartDate    = r.StartTime,
                        ImageUrl     = _wssProxy.GetRecordingImageUrl(r.Id.ToString()),
                        Path         = r.FileName.Replace(localpath, remotepath),
                    };

                    if (r.IsRecording)
                    {
                        var schedule = GetFromService <Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", r.ScheduleId);
                        {
                            if (schedule.Series)
                            {
                                recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                            }
                        }
                    }

                    if (!String.IsNullOrEmpty(r.Genre))
                    {
                        recording.Genres.Add(r.Genre);
                    }

                    return(recording);
                }).ToList();

                return(recordings);
            }

            else
            {
                var recordings = response.Select(r =>
                {
                    var recording = new RecordingInfo()
                    {
                        ChannelId    = r.ChannelId.ToString(CultureInfo.InvariantCulture),
                        EndDate      = r.EndTime,
                        EpisodeTitle = r.EpisodeName,
                        Genres       = new List <String>(),
                        Id           = r.Id.ToString(CultureInfo.InvariantCulture),
                        IsSeries     = (!String.IsNullOrEmpty(r.EpisodeNum)) ? true : false,
                        Name         = r.Title,
                        Overview     = r.Description,
                        ProgramId    = r.ScheduleId.ToString(CultureInfo.InvariantCulture),
                        StartDate    = r.StartTime,
                        ImageUrl     = _wssProxy.GetRecordingImageUrl(r.Id.ToString(), scheduleDefaults.PreRecordInterval),
                    };

                    if (r.IsRecording)
                    {
                        var schedule = GetFromService <Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", r.ScheduleId);
                        {
                            if (schedule.Series)
                            {
                                recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                            }
                        }
                    }

                    if (!String.IsNullOrEmpty(r.Genre))
                    {
                        recording.Genres.Add(r.Genre);
                    }

                    return(recording);
                }).ToList();

                return(recordings);
            }
        }
        public RecordingInfo GetRecording(CancellationToken cancellationToken, String id)
        {
            var response = GetFromService<Recording>(cancellationToken, "GetRecordingById?id={0}", id);

            var recording = new RecordingInfo()
            {
                ChannelId = response.ChannelId.ToString(CultureInfo.InvariantCulture),
                EndDate = response.EndTime,
                EpisodeTitle = response.EpisodeName,
                Genres = new List<String>(),
                Id = response.Id.ToString(CultureInfo.InvariantCulture),
                Name = response.Title,
                Overview = response.Description,
                ProgramId = response.ScheduleId.ToString(CultureInfo.InvariantCulture),
                StartDate = response.StartTime,
                Path = response.FileName,
            };

            if (!String.IsNullOrEmpty(response.Genre))
            {
                recording.Genres.Add(response.Genre);
            }

            return recording;
        }
        public RecordingInfo GetRecording(CancellationToken cancellationToken, String id)
        {
            var response      = GetFromService <Recording>(cancellationToken, "GetRecordingById?id={0}", id);
            var configuration = Plugin.Instance.Configuration;

            if (configuration.EnableDirectAccess && !configuration.RequiresPathSubstitution)
            {
                var recording = new RecordingInfo()
                {
                    ChannelId    = response.ChannelId.ToString(CultureInfo.InvariantCulture),
                    EndDate      = response.EndTime,
                    EpisodeTitle = response.EpisodeName,
                    Genres       = new List <String>(),
                    Id           = response.Id.ToString(CultureInfo.InvariantCulture),
                    IsSeries     = (!String.IsNullOrEmpty(response.EpisodeNum)) ? true : false,
                    Name         = response.Title,
                    Overview     = response.Description,
                    ProgramId    = response.ScheduleId.ToString(CultureInfo.InvariantCulture),
                    StartDate    = response.StartTime,
                    Path         = response.FileName,
                };

                if (response.IsRecording)
                {
                    var schedule = GetFromService <Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", response.ScheduleId);
                    {
                        if (schedule.Series)
                        {
                            recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                        }
                    }
                }

                if (!String.IsNullOrEmpty(response.Genre))
                {
                    recording.Genres.Add(response.Genre);
                }

                return(recording);
            }

            else if (configuration.EnableDirectAccess && configuration.RequiresPathSubstitution)
            {
                var localpath  = String.Format("{0}", configuration.LocalFilePath);
                var remotepath = String.Format("{0}", configuration.RemoteFilePath);

                var recording = new RecordingInfo()
                {
                    ChannelId    = response.ChannelId.ToString(CultureInfo.InvariantCulture),
                    EndDate      = response.EndTime,
                    EpisodeTitle = response.EpisodeName,
                    Genres       = new List <String>(),
                    Id           = response.Id.ToString(CultureInfo.InvariantCulture),
                    IsSeries     = (!String.IsNullOrEmpty(response.EpisodeNum)) ? true : false,
                    Name         = response.Title,
                    Overview     = response.Description,
                    ProgramId    = response.ScheduleId.ToString(CultureInfo.InvariantCulture),
                    StartDate    = response.StartTime,
                    Path         = response.FileName.Replace(localpath, remotepath),
                };

                if (response.IsRecording)
                {
                    var schedule = GetFromService <Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", response.ScheduleId);
                    {
                        if (schedule.Series)
                        {
                            recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                        }
                    }
                }

                if (!String.IsNullOrEmpty(response.Genre))
                {
                    recording.Genres.Add(response.Genre);
                }

                return(recording);
            }

            else
            {
                var recording = new RecordingInfo()
                {
                    ChannelId    = response.ChannelId.ToString(CultureInfo.InvariantCulture),
                    EndDate      = response.EndTime,
                    EpisodeTitle = response.EpisodeName,
                    Genres       = new List <String>(),
                    Id           = response.Id.ToString(CultureInfo.InvariantCulture),
                    IsSeries     = (!String.IsNullOrEmpty(response.EpisodeNum)) ? true : false,
                    Name         = response.Title,
                    Overview     = response.Description,
                    ProgramId    = response.ScheduleId.ToString(CultureInfo.InvariantCulture),
                    StartDate    = response.StartTime,
                };

                if (response.IsRecording)
                {
                    var schedule = GetFromService <Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", response.ScheduleId);
                    {
                        if (schedule.Series)
                        {
                            recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                        }
                    }
                }

                if (!String.IsNullOrEmpty(response.Genre))
                {
                    recording.Genres.Add(response.Genre);
                }

                return(recording);
            }
        }
Example #18
0
        private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, CancellationToken cancellationToken)
        {
            if (timer == null)
            {
                throw new ArgumentNullException("timer");
            }

            if (string.IsNullOrWhiteSpace(timer.ProgramId))
            {
                throw new InvalidOperationException("timer.ProgramId is null. Cannot record.");
            }

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

            if (info == null)
            {
                throw new InvalidOperationException(string.Format("Program with Id {0} not found", timer.ProgramId));
            }

            var recordPath = RecordingPath;

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

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

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

            var recordingId = info.Id.GetMD5().ToString("N");
            var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.Id, recordingId, StringComparison.OrdinalIgnoreCase));

            if (recording == null)
            {
                recording = new RecordingInfo
                {
                    ChannelId = info.ChannelId,
                    Id = recordingId,
                    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,
                    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);
            }

            try
            {
                var result = await GetChannelStreamInternal(timer.ChannelId, null, CancellationToken.None);
                var mediaStreamInfo = result.Item1;
                var isResourceOpen = true;

                // Unfortunately due to the semaphore we have to have a nested try/finally
                try
                {
                    // HDHR doesn't seem to release the tuner right away after first probing with ffmpeg
                    await Task.Delay(3000, cancellationToken).ConfigureAwait(false);

                    var duration = recordingEndDate - DateTime.UtcNow;

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

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

                    _logger.Info("Beginning recording.");

                    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 = _fileSystem.GetFileStream(recordPath, FileMode.Create, FileAccess.Write, FileShare.Read))
                        {
                            result.Item2.Release();
                            isResourceOpen = false;

                            await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, linkedToken);
                        }
                    }

                    recording.Status = RecordingStatus.Completed;
                    _logger.Info("Recording completed");
                }
                finally
                {
                    if (isResourceOpen)
                    {
                        result.Item2.Release();
                    }
                }
            }
            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);
            }
        }
Example #19
0
 // Такие четыре метода должны быть у всех слоев выше слоя Markup
 // Слои вызывают эти методы рекурсивно по цепочке
 abstract protected bool DisplayCameraOpen(RecordingInfo rec);
Example #20
0
        private async void OnSuccessfulRecording(RecordingInfo recording)
        {
            if (GetConfiguration().EnableAutoOrganize)
            {
                if (recording.IsSeries)
                {
                    try
                    {
                        var organize = new EpisodeFileOrganizer(_organizationService, _config, _fileSystem, _logger, _libraryManager, _libraryMonitor, _providerManager);

                        var result = await organize.OrganizeEpisodeFile(recording.Path, CancellationToken.None).ConfigureAwait(false);

                        if (result.Status == FileSortingStatus.Success)
                        {
                            _recordingProvider.Delete(recording);
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.ErrorException("Error processing new recording", ex);
                    }
                }
            }
        }
        public RecordingInfoDto GetRecordingInfoDto(RecordingInfo info, ILiveTvService service, User user = null)
        {
            var dto = new RecordingInfoDto
            {
                Id = GetInternalRecordingId(service.Name, info.Id).ToString("N"),
                ChannelName = info.ChannelName,
                Overview = info.Overview,
                EndDate = info.EndDate,
                Name = info.Name,
                StartDate = info.StartDate,
                ExternalId = info.Id,
                ChannelId = GetInternalChannelId(service.Name, info.ChannelId, info.ChannelName).ToString("N"),
                Status = info.Status,
                Path = info.Path,
                Genres = info.Genres,
                IsRepeat = info.IsRepeat,
                EpisodeTitle = info.EpisodeTitle,
                ChannelType = info.ChannelType,
                MediaType = info.ChannelType == ChannelType.Radio ? MediaType.Audio : MediaType.Video,
                CommunityRating = info.CommunityRating,
                OfficialRating = info.OfficialRating,
                Audio = info.Audio,
                IsHD = info.IsHD,
                ServiceName = service.Name,
                Url = info.Url
            };

            if (user != null)
            {
                //dto.UserData = _dtoService.GetUserItemDataDto(_userDataManager.GetUserData(user.Id, info.GetUserDataKey()));
            }

            var duration = info.EndDate - info.StartDate;
            dto.DurationMs = Convert.ToInt32(duration.TotalMilliseconds);

            if (!string.IsNullOrEmpty(info.ProgramId))
            {
                dto.ProgramId = GetInternalProgramId(service.Name, info.ProgramId).ToString("N");
            }

            return dto;
        }
        public IEnumerable<RecordingInfo> GetRecordings(CancellationToken cancellationToken)
        {
            var response = GetFromService<List<Recording>>(cancellationToken, "GetRecordings");
            var configuration = Plugin.Instance.Configuration;
            if (configuration.EnableDirectAccess && !configuration.RequiresPathSubstitution)
            {
                var recordings = response.Select(r =>
                {
                    var recording = new RecordingInfo()
                    {
                        ChannelId = r.ChannelId.ToString(CultureInfo.InvariantCulture),
                        EndDate = r.EndTime,
                        EpisodeTitle = r.EpisodeName,
                        Genres = new List<String>(),
                        Id = r.Id.ToString(CultureInfo.InvariantCulture),
                        IsSeries = (!String.IsNullOrEmpty(r.EpisodeNum)) ? true : false,
                        Name = r.Title,
                        Overview = r.Description,
                        ProgramId = r.ScheduleId.ToString(CultureInfo.InvariantCulture),
                        StartDate = r.StartTime,
                        ImageUrl = _wssProxy.GetRecordingImageUrl(r.Id.ToString()),
                        Path = r.FileName,
                    };

                    if (r.IsRecording)
                    {
                        var schedule = GetFromService<Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", r.ScheduleId);
                        {
                            if (schedule.Series)
                            {
                                recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                            }
                        }
                    }

                    if (!String.IsNullOrEmpty(r.Genre))
                    {
                        recording.Genres.Add(r.Genre);
                    }

                    return recording;

                }).ToList();

                return recordings;
            }

            else if (configuration.EnableDirectAccess && configuration.RequiresPathSubstitution)
            {
                var localpath = String.Format("{0}", configuration.LocalFilePath);
                var remotepath = String.Format("{0}", configuration.RemoteFilePath);

                var recordings = response.Select(r =>
                {
                    var recording = new RecordingInfo()
                    {
                        ChannelId = r.ChannelId.ToString(CultureInfo.InvariantCulture),
                        EndDate = r.EndTime,
                        EpisodeTitle = r.EpisodeName,
                        Genres = new List<String>(),
                        Id = r.Id.ToString(CultureInfo.InvariantCulture),
                        IsSeries = (!String.IsNullOrEmpty(r.EpisodeNum)) ? true : false,
                        Name = r.Title,
                        Overview = r.Description,
                        ProgramId = r.ScheduleId.ToString(CultureInfo.InvariantCulture),
                        StartDate = r.StartTime,
                        ImageUrl = _wssProxy.GetRecordingImageUrl(r.Id.ToString()),
                        Path = r.FileName.Replace(localpath, remotepath),
                    };

                    if (r.IsRecording)
                    {
                        var schedule = GetFromService<Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", r.ScheduleId);
                        {
                            if (schedule.Series)
                            {
                                recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                            }
                        }
                    }

                    if (!String.IsNullOrEmpty(r.Genre))
                    {
                        recording.Genres.Add(r.Genre);
                    }

                    return recording;

                }).ToList();

                return recordings;
            }

            else
            {
            var recordings = response.Select(r =>
            {
                var recording = new RecordingInfo()
                {
                    ChannelId = r.ChannelId.ToString(CultureInfo.InvariantCulture),
                    EndDate = r.EndTime,
                    EpisodeTitle = r.EpisodeName,
                    Genres = new List<String>(),
                    Id = r.Id.ToString(CultureInfo.InvariantCulture),
                        IsSeries = (!String.IsNullOrEmpty(r.EpisodeNum)) ? true : false,
                    Name = r.Title,
                    Overview = r.Description,
                    ProgramId = r.ScheduleId.ToString(CultureInfo.InvariantCulture),
                    StartDate = r.StartTime,
                    ImageUrl = _wssProxy.GetRecordingImageUrl(r.Id.ToString(), scheduleDefaults.PreRecordInterval),
                };

                    if (r.IsRecording)
                    {
                        var schedule = GetFromService<Schedule>(cancellationToken, "GetScheduleById?scheduleId={0}", r.ScheduleId);
                        {
                            if (schedule.Series)
                            {
                                recording.SeriesTimerId = schedule.ParentScheduleId.ToString(CultureInfo.InvariantCulture);
                            }
                        }
                    }

                if (!String.IsNullOrEmpty(r.Genre))
                {
                    recording.Genres.Add(r.Genre);
                }

                return recording;

            }).ToList();

            return recordings;
            }
        }
Example #23
0
        private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, CancellationToken cancellationToken)
        {
            if (timer == null)
            {
                throw new ArgumentNullException("timer");
            }

            ProgramInfo info = null;

            if (string.IsNullOrWhiteSpace(timer.ProgramId))
            {
                _logger.Info("Timer {0} has null programId", timer.Id);
            }
            else
            {
                info = GetProgramInfoFromCache(timer.ChannelId, timer.ProgramId);
            }

            if (info == null)
            {
                _logger.Info("Unable to find program with Id {0}. Will search using start date", timer.ProgramId);
                info = GetProgramInfoFromCache(timer.ChannelId, timer.StartDate);
            }

            if (info == null)
            {
                throw new InvalidOperationException(string.Format("Program with Id {0} not found", timer.ProgramId));
            }

            var recordPath = RecordingPath;

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

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

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

            var recordingId = info.Id.GetMD5().ToString("N");
            var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.Id, recordingId, StringComparison.OrdinalIgnoreCase));

            if (recording == null)
            {
                recording = new RecordingInfo
                {
                    ChannelId = info.ChannelId,
                    Id = recordingId,
                    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,
                    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.AddOrUpdate(recording);
            }

            try
            {
                var result = await GetChannelStreamInternal(timer.ChannelId, null, CancellationToken.None).ConfigureAwait(false);
                var mediaStreamInfo = result.Item1;
                var isResourceOpen = true;

                // Unfortunately due to the semaphore we have to have a nested try/finally
                try
                {
                    // HDHR doesn't seem to release the tuner right away after first probing with ffmpeg
                    await Task.Delay(3000, cancellationToken).ConfigureAwait(false);

                    var duration = recordingEndDate - DateTime.UtcNow;

                    var recorder = await GetRecorder().ConfigureAwait(false);

                    if (recorder is EncodedRecorder)
                    {
                        recordPath = Path.ChangeExtension(recordPath, ".mp4");
                    }

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

                    _logger.Info("Beginning recording. Will record for {0} minutes.", duration.TotalMinutes.ToString(CultureInfo.InvariantCulture));

                    var durationToken = new CancellationTokenSource(duration);
                    var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;

                    _logger.Info("Writing file to path: " + recordPath);
                    _logger.Info("Opening recording stream from tuner provider");

                    Action onStarted = () =>
                    {
                        result.Item2.Release();
                        isResourceOpen = false;
                    };

                    await recorder.Record(mediaStreamInfo, recordPath, onStarted, linkedToken).ConfigureAwait(false);

                    recording.Status = RecordingStatus.Completed;
                    _logger.Info("Recording completed");
                }
                finally
                {
                    if (isResourceOpen)
                    {
                        result.Item2.Release();
                    }
                }
            }
            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.AddOrUpdate(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);
            }
        }
Example #24
0
        private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
        {
            var isNew = false;

            var id = _tvDtoService.GetInternalRecordingId(serviceName, info.Id);

            var item = _itemRepo.RetrieveItem(id);

            if (item == null)
            {
                if (info.ChannelType == ChannelType.TV)
                {
                    item = new LiveTvVideoRecording
                    {
                        Name = info.Name,
                        Id = id,
                        DateCreated = DateTime.UtcNow,
                        DateModified = DateTime.UtcNow,
                        VideoType = VideoType.VideoFile
                    };
                }
                else
                {
                    item = new LiveTvAudioRecording
                    {
                        Name = info.Name,
                        Id = id,
                        DateCreated = DateTime.UtcNow,
                        DateModified = DateTime.UtcNow
                    };
                }

                isNew = true;
            }

            item.ChannelId = _tvDtoService.GetInternalChannelId(serviceName, info.ChannelId).ToString("N");
            item.CommunityRating = info.CommunityRating;
            item.OfficialRating = info.OfficialRating;
            item.Overview = info.Overview;
            item.EndDate = info.EndDate;
            item.Genres = info.Genres;

            var recording = (ILiveTvRecording)item;

            recording.ExternalId = info.Id;

            recording.ProgramId = _tvDtoService.GetInternalProgramId(serviceName, info.ProgramId).ToString("N");
            recording.Audio = info.Audio;
            recording.ChannelType = info.ChannelType;
            recording.EndDate = info.EndDate;
            recording.EpisodeTitle = info.EpisodeTitle;
            recording.ProviderImagePath = info.ImagePath;
            recording.ProviderImageUrl = info.ImageUrl;
            recording.IsHD = info.IsHD;
            recording.IsKids = info.IsKids;
            recording.IsLive = info.IsLive;
            recording.IsMovie = info.IsMovie;
            recording.IsNews = info.IsNews;
            recording.IsPremiere = info.IsPremiere;
            recording.IsRepeat = info.IsRepeat;
            recording.IsSeries = info.IsSeries;
            recording.IsSports = info.IsSports;
            recording.OriginalAirDate = info.OriginalAirDate;
            recording.SeriesTimerId = info.SeriesTimerId;
            recording.StartDate = info.StartDate;
            recording.Status = info.Status;

            recording.ServiceName = serviceName;

            var originalPath = item.Path;

            if (!string.IsNullOrEmpty(info.Path))
            {
                item.Path = info.Path;
            }
            else if (!string.IsNullOrEmpty(info.Url))
            {
                item.Path = info.Url;
            }

            var pathChanged = !string.Equals(originalPath, item.Path);

            if (isNew)
            {
                await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
            }
            else if (pathChanged)
            {
                await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
            }

            _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions());

            return item.Id;
        }
Example #25
0
        private async Task<LiveTvRecording> GetRecording(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
        {
            var isNew = false;

            var id = _tvDtoService.GetInternalRecordingId(serviceName, info.Id);

            var item = _itemRepo.RetrieveItem(id) as LiveTvRecording;

            if (item == null)
            {
                item = new LiveTvRecording
                {
                    Name = info.Name,
                    Id = id,
                    DateCreated = DateTime.UtcNow,
                    DateModified = DateTime.UtcNow
                };

                isNew = true;
            }

            item.RecordingInfo = info;
            item.ServiceName = serviceName;

            await item.RefreshMetadata(cancellationToken, forceSave: isNew, resetResolveArgs: false);

            return item;
        }
Example #26
0
        private IEnumerable<string> GetRecordingGroupNames(RecordingInfo recording)
        {
            var list = new List<string>();

            if (recording.IsSeries)
            {
                list.Add(recording.Name);
            }

            if (recording.IsKids)
            {
                list.Add("Kids");
            }

            if (recording.IsMovie)
            {
                list.Add("Movies");
            }

            if (recording.IsNews)
            {
                list.Add("News");
            }

            if (recording.IsSports)
            {
                list.Add("Sports");
            }

            if (!recording.IsSports && !recording.IsNews && !recording.IsMovie && !recording.IsKids && !recording.IsSeries)
            {
                list.Add("Others");
            }

            return list;
        }
Example #27
0
        private RecordingInfo GetRecordingInfo(ActiveRecordingInfo info)
        {
            var timer = info.Timer;
            var program = info.Program;

            var result = new RecordingInfo
            {
                ChannelId = timer.ChannelId,
                CommunityRating = timer.CommunityRating,
                DateLastUpdated = DateTime.UtcNow,
                EndDate = timer.EndDate,
                EpisodeTitle = timer.EpisodeTitle,
                Genres = timer.Genres,
                Id = "recording" + timer.Id,
                IsKids = timer.IsKids,
                IsMovie = timer.IsMovie,
                IsNews = timer.IsNews,
                IsRepeat = timer.IsRepeat,
                IsSeries = timer.IsProgramSeries,
                IsSports = timer.IsSports,
                Name = timer.Name,
                OfficialRating = timer.OfficialRating,
                OriginalAirDate = timer.OriginalAirDate,
                Overview = timer.Overview,
                ProgramId = timer.ProgramId,
                SeriesTimerId = timer.SeriesTimerId,
                StartDate = timer.StartDate,
                Status = RecordingStatus.InProgress,
                TimerId = timer.Id
            };

            if (program != null)
            {
                result.Audio = program.Audio;
                result.ImagePath = program.ImagePath;
                result.ImageUrl = program.ImageUrl;
                result.IsHD = program.IsHD;
                result.IsLive = program.IsLive;
                result.IsPremiere = program.IsPremiere;
                result.ShowId = program.ShowId;
            }

            return result;
        }
Example #28
0
        private async Task<ILiveTvRecording> GetRecording(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
        {
            var isNew = false;

            var id = _tvDtoService.GetInternalRecordingId(serviceName, info.Id);

            var item = _itemRepo.RetrieveItem(id) as ILiveTvRecording;

            if (item == null)
            {
                if (info.ChannelType == ChannelType.TV)
                {
                    item = new LiveTvVideoRecording
                    {
                        Name = info.Name,
                        Id = id,
                        DateCreated = DateTime.UtcNow,
                        DateModified = DateTime.UtcNow,
                        VideoType = VideoType.VideoFile
                    };
                }
                else
                {
                    item = new LiveTvAudioRecording
                    {
                        Name = info.Name,
                        Id = id,
                        DateCreated = DateTime.UtcNow,
                        DateModified = DateTime.UtcNow
                    };
                }

                isNew = true;
            }

            item.RecordingInfo = info;
            item.ServiceName = serviceName;

            var originalPath = item.Path;

            if (!string.IsNullOrEmpty(info.Path))
            {
                item.Path = info.Path;
            }
            else if (!string.IsNullOrEmpty(info.Url))
            {
                item.Path = info.Url;
            }

            var pathChanged = !string.Equals(originalPath, item.Path);

            await item.RefreshMetadata(new MetadataRefreshOptions
            {
                ForceSave = isNew || pathChanged

            }, cancellationToken);

            _libraryManager.RegisterItem((BaseItem)item);

            return item;
        }
Example #29
0
        /// <summary>
        /// Gets the Recordings async
        /// </summary>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task{IEnumerable{RecordingInfo}}</returns>
        public async Task<IEnumerable<RecordingInfo>> GetRecordingsAsync(CancellationToken cancellationToken)
        {
            List<RecordingInfo> ret = new List<RecordingInfo>();

            _logger.Info("[MythTV] Start GetRecordings Async, retrieve all 'Pending', 'Inprogress' and 'Completed' recordings ");
            EnsureSetup();

            using (var stream = await _httpClient.Get(GetOptions(cancellationToken, "/Dvr/GetRecordedList")).ConfigureAwait(false))
            {
                var recordings = DvrResponse.ParseProgramList(stream, _jsonSerializer, _logger);

                foreach (var item in recordings.Programs)
                {
                    if (!Plugin.Instance.RecGroupExclude.Contains(item.Recording.RecGroup))
                    {
                        RecordingInfo val = new RecordingInfo()
                        {
                            Name = item.Title,
                            EpisodeTitle = item.SubTitle,
                            Overview = item.Description,
                            Audio = ProgramAudio.Stereo, //Hardcode for now (ProgramAudio)item.AudioProps,
                            ChannelId = item.Channel.ChanId.ToString(),
                            ProgramId = item.ProgramId,
                            SeriesTimerId = item.Recording.RecordId.ToString(),
                            EndDate = (DateTime)item.EndTime,
                            StartDate = (DateTime)item.StartTime,
                            Url = string.Format("{0}{1}", Plugin.Instance.Configuration.WebServiceUrl, string.Format("/Content/GetFile?StorageGroup={0}&FileName={1}", item.Recording.StorageGroup, item.FileName)),
                            Id = string.Format("StartTime={0}&ChanId={1}", ((DateTime)item.StartTime).Ticks, item.Channel.ChanId),
                            IsSeries = GeneralHelpers.ContainsWord(item.CatType, "series", StringComparison.OrdinalIgnoreCase),
                            IsMovie = GeneralHelpers.ContainsWord(item.CatType, "movie", StringComparison.OrdinalIgnoreCase),
                            IsRepeat = item.Repeat,
                            IsNews = GeneralHelpers.ContainsWord(item.Category, "news",
                            StringComparison.OrdinalIgnoreCase),
                            IsKids = GeneralHelpers.ContainsWord(item.Category, "animation",
                            StringComparison.OrdinalIgnoreCase),
                            IsSports =
                                GeneralHelpers.ContainsWord(item.Category, "sport",
                                    StringComparison.OrdinalIgnoreCase) ||
                                GeneralHelpers.ContainsWord(item.Category, "motor sports",
                                    StringComparison.OrdinalIgnoreCase) ||
                                GeneralHelpers.ContainsWord(item.Category, "football",
                                    StringComparison.OrdinalIgnoreCase) ||
                                GeneralHelpers.ContainsWord(item.Category, "cricket",
                                    StringComparison.OrdinalIgnoreCase)
                        };

                        if (Plugin.Instance.RecordingUncs.Count > 0)
                        {
                            foreach (string unc in Plugin.Instance.RecordingUncs)
                            {
                                string recPath = Path.Combine(unc, item.FileName);
                                if (File.Exists(recPath))
                                {
                                    val.Path = recPath;
                                    break;
                                }
                            }
                        }
                        val.Genres.AddRange(item.Category.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries));
                        if (item.Artwork.ArtworkInfos.Count() > 0)
                        {
                            val.HasImage = true;
                            val.ImageUrl = string.Format("{0}{1}", Plugin.Instance.Configuration.WebServiceUrl, item.Artwork.ArtworkInfos[0].URL);
                        }
                        else
                            val.HasImage = false;

                        ret.Add(val);
                    }
                }
            }

            return ret;
        }
Example #30
0
        private async Task RecordStream(TimerInfo timer, CancellationToken cancellationToken)
        {
            var mediaStreamInfo = await GetChannelStream(timer.ChannelId, "none", CancellationToken.None);
            var duration = (timer.EndDate - RecordingHelper.GetStartTime(timer)).TotalSeconds + timer.PrePaddingSeconds;

            HttpRequestOptions httpRequestOptions = new HttpRequestOptionsMod()
            {
                Url = mediaStreamInfo.Path + "?duration=" + duration
            };

            var info = GetProgramInfoFromCache(timer.ChannelId, timer.ProgramId);
            var recordPath = RecordingPath;
            if (info.IsMovie)
            {
                recordPath = Path.Combine(recordPath, "Movies", StringHelper.RemoveSpecialCharacters(info.Name));
            }
            else
            {
                recordPath = Path.Combine(recordPath, "TV", StringHelper.RemoveSpecialCharacters(info.Name));
            }

            recordPath = Path.Combine(recordPath, RecordingHelper.GetRecordingName(timer, info));
            Directory.CreateDirectory(Path.GetDirectoryName(recordPath));

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

            if (recording == null)
            {
                recording = new RecordingInfo()
                {
                    ChannelId = info.ChannelId,
                    Id = info.Id,
                    StartDate = info.StartDate,
                    EndDate = info.EndDate,
                    Genres = info.Genres ?? null,
                    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 ?? false,
                    ImagePath = info.ImagePath ?? null,
                    ImageUrl = info.ImageUrl,
                    OriginalAirDate = info.OriginalAirDate,
                    Status = RecordingStatus.Scheduled,
                    Overview = info.Overview,
                    SeriesTimerId = info.Id.Substring(0, 10)
                };
                _recordingProvider.Add(recording);
            }

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

            try
            {
                httpRequestOptions.BufferContent = false;
                httpRequestOptions.CancellationToken = cancellationToken;
                _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, 4096, cancellationToken);
                    }
                }

                recording.Status = RecordingStatus.Completed;
            }
            catch (OperationCanceledException)
            {
                recording.Status = RecordingStatus.Cancelled;
            }
            catch
            {
                recording.Status = RecordingStatus.Error;
            }

            _recordingProvider.Update(recording);
            _timerProvider.Delete(timer);
            _logger.Info("Recording was a success");
        }
        /// <summary>
        /// Gets the Recordings async
        /// </summary>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task{IEnumerable{RecordingInfo}}</returns>
        public async Task<IEnumerable<RecordingInfo>> GetRecordingsAsync(CancellationToken cancellationToken)
        {
            _logger.Info("[VuPlus] Start GetRecordingsAsync, retrieve all 'Inprogress' and 'Completed' recordings ");
            await EnsureConnectionAsync(cancellationToken).ConfigureAwait(false);

            var protocol = "http";
            if (Plugin.Instance.Configuration.UseSecureHTTPS)
                protocol = "https";

            var baseUrl = protocol + "://" + Plugin.Instance.Configuration.HostName + ":" + Plugin.Instance.Configuration.WebInterfacePort;

            var url = string.Format("{0}/web/movielist", baseUrl);
            UtilsHelper.DebugInformation(_logger, string.Format("[VuPlus] GetRecordingsAsync url: {0}", url));

            var options = new HttpRequestOptions
            {
                CancellationToken = cancellationToken,
                Url = url
            };

            if (!string.IsNullOrEmpty(Plugin.Instance.Configuration.WebInterfaceUsername))
            {
                string authInfo = Plugin.Instance.Configuration.WebInterfaceUsername + ":" + Plugin.Instance.Configuration.WebInterfacePassword;
                authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
                options.RequestHeaders["Authorization"] = "Basic " + authInfo;
            }

            using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    string xmlResponse = reader.ReadToEnd();
                    UtilsHelper.DebugInformation(_logger, string.Format("[VuPlus] GetRecordingsAsync response: {0}", xmlResponse));

                    try
                    {
                        var xml = new XmlDocument();
                        xml.LoadXml(xmlResponse);

                        List<RecordingInfo> recordingInfos = new List<RecordingInfo>();

                        int count = 1;

                        XmlNodeList e2movie = xml.GetElementsByTagName("e2movie");

                        foreach (XmlNode xmlNode in e2movie)
                        {
                            var recordingInfo = new RecordingInfo();

                            var e2servicereference = "?";
                            var e2title = "?";
                            var e2description = "?";
                            var e2servicename = "?";
                            var e2time = "?";
                            var e2length = "?";
                            var e2filename = "?";

                            foreach (XmlNode node in xmlNode.ChildNodes)
                            {
                                if (node.Name == "e2servicereference")
                                {
                                    e2servicereference = node.InnerText;
                                }
                                else if (node.Name == "e2title")
                                {
                                    e2title = node.InnerText;
                                }
                                else if (node.Name == "e2description")
                                {
                                    e2description = node.InnerText;
                                }
                                else if (node.Name == "e2servicename")
                                {
                                    e2servicename = node.InnerText;
                                }
                                else if (node.Name == "e2time")
                                {
                                    e2time = node.InnerText;
                                }
                                else if (node.Name == "e2length")
                                {
                                    e2length = node.InnerText;
                                }
                                else if (node.Name == "e2filename")
                                {
                                    e2filename = node.InnerText;
                                }
                            }

                            recordingInfo.Audio = null;

                            recordingInfo.ChannelId = null;
                            //check for radio channel
                            if (e2servicereference.ToUpper().Contains("RADIO"))
                                recordingInfo.ChannelType = ChannelType.Radio;
                            else
                                recordingInfo.ChannelType = ChannelType.TV;
                            recordingInfo.HasImage = false;
                            recordingInfo.ImagePath = null;
                            recordingInfo.ImageUrl = null;

                            foreach (ChannelInfo channelInfo in tvChannelInfos)
                            {
                                if (channelInfo.Name == e2servicename)
                                {
                                    UtilsHelper.DebugInformation(_logger, string.Format("[VuPlus] GetRecordingsAsync match on channel name : {0} for recording {1}", e2servicename, e2title));
                                    recordingInfo.ChannelId = channelInfo.Id;
                                    recordingInfo.ChannelType = channelInfo.ChannelType;
                                    recordingInfo.HasImage = true;
                                    recordingInfo.ImagePath = channelInfo.ImagePath;
                                    recordingInfo.ImageUrl = channelInfo.ImageUrl;
                                    break;
                                }
                            }

                            if (recordingInfo.ChannelId == null)
                            {
                                UtilsHelper.DebugInformation(_logger, string.Format("[VuPlus] GetRecordingsAsync no match on channel name : {0} for recording {1}", e2servicename, e2title));
                            }

                            recordingInfo.CommunityRating = 0;

                            long sdated = Int64.Parse(e2time);
                            DateTime sdate = ApiHelper.DateTimeFromUnixTimestampSeconds(sdated);
                            recordingInfo.StartDate = sdate.ToUniversalTime();

                            //length in format mm:ss
                            string[] words = e2length.Split(':');
                            long mins = Int64.Parse(words[0]);
                            long seconds = Int64.Parse(words[1]);
                            long edated = Int64.Parse(e2time) + (mins * 60) + (seconds);
                            DateTime edate = ApiHelper.DateTimeFromUnixTimestampSeconds(edated);
                            recordingInfo.EndDate = edate.ToUniversalTime();

                            //recordingInfo.EpisodeTitle = e2title;
                            recordingInfo.EpisodeTitle = null;

                            recordingInfo.Overview = e2description;

                            List<String> genre = new List<String>();
                            genre.Add("Unknown");
                            recordingInfo.Genres = genre;

                            recordingInfo.Id = e2servicereference;
                            recordingInfo.IsHD = false;
                            recordingInfo.IsKids = false;
                            recordingInfo.IsLive = false;
                            recordingInfo.IsMovie = false;
                            recordingInfo.IsNews = false;
                            recordingInfo.IsPremiere = false;
                            recordingInfo.IsRepeat = false;
                            recordingInfo.IsSeries = false;
                            recordingInfo.IsSports = false;
                            recordingInfo.Name = e2title;
                            recordingInfo.OfficialRating = null;
                            recordingInfo.OriginalAirDate = null;
                            recordingInfo.Overview = e2description;
                            recordingInfo.Path = null;
                            recordingInfo.ProgramId = null;
                            recordingInfo.SeriesTimerId = null;
                            recordingInfo.Url = baseUrl + "/file?file=" + WebUtility.UrlEncode(e2filename);

                            recordingInfos.Add(recordingInfo);
                            count = count + 1;
                        }
                        return recordingInfos;
                    }
                    catch (Exception e)
                    {
                        _logger.Error("[VuPlus] Failed to parse timer information.");
                        _logger.Error(string.Format("[VuPlus] GetRecordingsAsync error: {0}", e.Message));
                        throw new ApplicationException("Failed to parse timer information.");
                    }
                }
            }
        }