Exemple #1
0
        /// <summary>
        /// Update a single Timer
        /// </summary>
        /// <param name="info">The program info</param>
        /// <param name="cancellationToken">The CancellationToken</param>
        /// <returns></returns>
        public async Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken)
        {
            _logger.Info(string.Format("[MythTV] Start UpdateTimer Async for ChannelId: {0} & Name: {1}", info.ChannelId, info.Name));
            EnsureSetup();

            using (var stream = await _httpClient.Get(GetOptions(cancellationToken, "/Dvr/GetRecordSchedule?RecordId={0}", info.Id)).ConfigureAwait(false))
            {
                RecRule orgRule = DvrResponse.GetRecRule(stream, _jsonSerializer, _logger);
                if (orgRule != null)
                {
                    orgRule.Title    = info.Name;
                    orgRule.ChanId   = info.ChannelId;
                    orgRule.CallSign = await GetCallsign(info.ChannelId, cancellationToken);

                    orgRule.EndTime     = info.EndDate;
                    orgRule.StartTime   = info.StartDate;
                    orgRule.StartOffset = info.PrePaddingSeconds / 60;
                    orgRule.EndOffset   = info.PostPaddingSeconds / 60;

                    var options = PostOptions(cancellationToken, ConvertJsonRecRuleToPost(_jsonSerializer.SerializeToString(orgRule)), "/Dvr/UpdateRecordSchedule");

                    using (var response = await _httpClient.Post(options).ConfigureAwait(false)) { }
                }
            }
        }
Exemple #2
0
        /// <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)
        {
            var timerJson = _jsonSerializer.SerializeToString(info);

            _logger.Info($"[MythTV] Start CreateTimer Async for TimerInfo\n{timerJson}");

            await EnsureSetup();

            var options = GetRuleStreamOptions(info.ProgramId, info.StartDate, cancellationToken);

            using (var stream = await _httpClient.Get(options))
            {
                try
                {
                    var json = new DvrResponse().GetNewTimerJson(info, stream, _jsonSerializer, _logger);
                    var post = PostOptions(cancellationToken,
                                           ConvertJsonRecRuleToPost(json),
                                           "/Dvr/AddRecordSchedule");
                    await _httpClient.Post(post).ConfigureAwait(false);
                }
                catch (ExistingTimerException existing)
                {
                    _logger.Info($"[MythTV] found existing rule {existing.id}");
                    await CancelTimerAsync(existing.id, cancellationToken);
                }
            }
        }
Exemple #3
0
 public async Task <SeriesTimerInfo> GetNewTimerDefaultsAsync(CancellationToken cancellationToken, ProgramInfo program = null)
 {
     _logger.Info("[MythTV] Start GetNewTimerDefault Async");
     EnsureSetup();
     using (var stream = await _httpClient.Get(GetOptions(cancellationToken, "/Dvr/GetRecordSchedule?Template=Default")).ConfigureAwait(false))
     {
         return(DvrResponse.GetDefaultTimerInfo(stream, _jsonSerializer, _logger));
     }
 }
Exemple #4
0
        /// <summary>
        /// Get the recurrent recordings
        /// </summary>
        /// <param name="cancellationToken">The CancellationToken</param>
        /// <returns></returns>
        public async Task <IEnumerable <SeriesTimerInfo> > GetSeriesTimersAsync(CancellationToken cancellationToken)
        {
            _logger.Info("[MythTV] Start GetSeriesTimer Async, retrieve the recurring recordings");
            EnsureSetup();

            using (var stream = await _httpClient.Get(GetOptions(cancellationToken, "/Dvr/GetRecordScheduleList")).ConfigureAwait(false))
            {
                return(DvrResponse.GetSeriesTimers(stream, _jsonSerializer, _logger));
            }
        }
Exemple #5
0
        /// <summary>
        /// Create a recurrent recording
        /// </summary>
        /// <param name="info">The recurrend program info</param>
        /// <param name="cancellationToken">The CancelationToken</param>
        /// <returns></returns>
        public async Task CreateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken)
        {
            _logger.Info(string.Format("[MythTV] Start CreateSeriesTimer Async for ChannelId: {0} & Name: {1}", info.ChannelId, info.Name));
            EnsureSetup();

            using (var stream = await _httpClient.Get(GetOptions(cancellationToken, "/Dvr/GetRecordSchedule?Template=Default")).ConfigureAwait(false))
            {
                RecRule orgRule = DvrResponse.GetRecRule(stream, _jsonSerializer, _logger);
                if (orgRule != null)
                {
                    orgRule.Title    = info.Name;
                    orgRule.ChanId   = info.ChannelId;
                    orgRule.CallSign = await GetCallsign(info.ChannelId, cancellationToken);

                    orgRule.EndTime     = info.EndDate;
                    orgRule.StartTime   = info.StartDate;
                    orgRule.StartOffset = info.PrePaddingSeconds / 60;
                    orgRule.EndOffset   = info.PostPaddingSeconds / 60;
                    orgRule.Type        = "Record All";
                    //orgRule.FindDay
                    if (info.RecordAnyChannel)
                    {
                        orgRule.Filter |= RecFilter.ThisChannel;
                    }
                    else
                    {
                        orgRule.Filter &= RecFilter.ThisChannel;
                    }
                    if (info.RecordAnyTime)
                    {
                        orgRule.Filter &= RecFilter.ThisDayTime;
                    }
                    else
                    {
                        orgRule.Filter |= RecFilter.ThisDayTime;
                    }
                    if (info.RecordNewOnly)
                    {
                        orgRule.Filter |= RecFilter.NewEpisode;
                    }
                    else
                    {
                        orgRule.Filter &= RecFilter.NewEpisode;
                    }

                    var options = PostOptions(cancellationToken, ConvertJsonRecRuleToPost(_jsonSerializer.SerializeToString(orgRule)), "/Dvr/AddRecordSchedule");

                    using (var response = await _httpClient.Post(options).ConfigureAwait(false)) { }
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Update the series Timer
        /// </summary>
        /// <param name="info">The series program info</param>
        /// <param name="cancellationToken">The CancellationToken</param>
        /// <returns></returns>
        public async Task UpdateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken)
        {
            var seriesTimerJson = _jsonSerializer.SerializeToString(info);

            _logger.Info($"[MythTV] Start UpdateSeriesTimer Async for SeriesTimerInfo\n{seriesTimerJson}");

            await EnsureSetup();

            var options = GetRuleStreamOptions(info.Id, cancellationToken);

            using (var stream = await _httpClient.Get(options))
            {
                var json = new DvrResponse().GetNewSeriesTimerJson(info, stream, _jsonSerializer, _logger);
                var post = PostOptions(cancellationToken, ConvertJsonRecRuleToPost(json), "/Dvr/UpdateRecordSchedule");
                await _httpClient.Post(post).ConfigureAwait(false);
            }
        }
Exemple #7
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)
        {
            _logger.Info("[MythTV] Start GetRecordings Async, retrieve all 'Pending', 'Inprogress' and 'Completed' recordings ");
            await EnsureSetup();

            IEnumerable <RecordingInfo> outp;

            using (var stream = await _httpClient.Get(GetOptions(cancellationToken, "/Dvr/GetRecordedList")).ConfigureAwait(false))
            {
                outp = new DvrResponse(Plugin.Instance.Configuration.StorageGroupMaps).GetRecordings(stream, _jsonSerializer, _logger, _fileSystem).ToList();
            }

            if (_imageGrabber != null)
            {
                await _imageGrabber.AddImages(outp, cancellationToken);
            }

            return(outp);
        }
Exemple #8
0
        public async Task <LiveTvServiceStatusInfo> GetStatusInfoAsync(CancellationToken cancellationToken)
        {
            EnsureSetup();

            bool   upgradeAvailable = false;
            string serverVersion    = string.Empty;

            var conInfoTask = _httpClient.Get(GetOptions(cancellationToken, "/Myth/GetConnectionInfo")).ConfigureAwait(false);

            var tunersTask   = _httpClient.Get(GetOptions(cancellationToken, "/Dvr/GetEncoderList")).ConfigureAwait(false);
            var encodersTask = _httpClient.Get(GetOptions(cancellationToken, "/Capture/GetCaptureCardList")).ConfigureAwait(false);

            EncoderList     tuners   = null;
            CaptureCardList encoders = null;

            using (var stream = await tunersTask)
            {
                tuners = DvrResponse.ParseEncoderList(stream, _jsonSerializer, _logger);
            }

            using (var stream = await encodersTask)
            {
                encoders = CaptureResponse.ParseCaptureCardList(stream, _jsonSerializer, _logger);
            }

            using (var stream = await conInfoTask)
            {
                var conInfo = UtilityResponse.GetConnectionInfo(stream, _jsonSerializer, _logger);
                serverVersion = conInfo.Version.Ver;
            }

            //Tuner information
            List <LiveTvTunerInfo> tvTunerInfos = new List <LiveTvTunerInfo>();

            foreach (var tuner in tuners.Encoders)
            {
                LiveTvTunerInfo info = new LiveTvTunerInfo()
                {
                    Id     = tuner.Id.ToString(),
                    Status = (LiveTvTunerStatus)tuner.State
                };

                switch (tuner.State)
                {
                case 0:
                    info.Status = LiveTvTunerStatus.Available;
                    break;

                case 7:
                    info.Status = LiveTvTunerStatus.RecordingTv;
                    break;
                }

                if (!string.IsNullOrWhiteSpace(tuner.Recording.Title))
                {
                    info.RecordingId = tuner.Recording.ProgramId;
                    info.ProgramName = string.Format("{0} : {1}", tuner.Recording.Title, tuner.Recording.SubTitle);
                }

                foreach (var enc in encoders.CaptureCards)
                {
                    if (enc.CardId == tuner.Id)
                    {
                        info.Name       = string.Format("{0} {1}", enc.CardType, enc.VideoDevice);
                        info.SourceType = enc.CardType;
                        break;
                    }
                }

                tvTunerInfos.Add(info);
            }

            return(new LiveTvServiceStatusInfo
            {
                HasUpdateAvailable = upgradeAvailable,
                Version = serverVersion,
                Tuners = tvTunerInfos
            });
        }
Exemple #9
0
        public async Task <MediaSourceInfo> GetChannelStream(string channelOid, string mediaSourceId, CancellationToken cancellationToken)
        {
            _logger.Info("[MythTV] Start ChannelStream");

            throw new NotImplementedException();

            using (var stream = await _httpClient.Get(GetOptions(cancellationToken, "/Dvr/GetRecordSchedule?Template=Default")).ConfigureAwait(false))
            {
                RecRule orgRule = DvrResponse.GetRecRule(stream, _jsonSerializer, _logger);
                if (orgRule != null)
                {
                    DateTime startTime = DateTime.Now.ToUniversalTime();
                    orgRule.Title    = string.Format("Emby LiveTV: {0} ({1}) - {1}", await GetCallsign(channelOid, cancellationToken), channelOid, startTime);
                    orgRule.ChanId   = channelOid;
                    orgRule.CallSign = await GetCallsign(channelOid, cancellationToken);

                    orgRule.EndTime     = startTime.AddHours(5);
                    orgRule.StartTime   = startTime;
                    orgRule.StartOffset = 0;
                    orgRule.EndOffset   = 0;
                    orgRule.Type        = "Single Record";

                    var postContent = ConvertJsonRecRuleToPost(_jsonSerializer.SerializeToString(orgRule));

                    var options = PostOptions(cancellationToken, postContent, "/Dvr/AddRecordSchedule");

                    using (var response = await _httpClient.Post(options).ConfigureAwait(false))
                    {
                        RecordId recId = DvrResponse.ParseRecordId(response.Content, _jsonSerializer);
                        for (int i = 0; i < Plugin.Instance.Configuration.LiveTvWaits; i++)
                        {
                            await Task.Delay(200).ConfigureAwait(false);

                            try
                            {
                                using (var rpstream = await _httpClient.Get(GetOptions(cancellationToken, "/Dvr/GetRecorded?ChanId={0}&StartTime={1}", channelOid, FormateMythDate(startTime))).ConfigureAwait(false))
                                {
                                    var recProg = DvrResponse.ParseRecorded(rpstream, _jsonSerializer, _logger);//Host.DvrService.GetRecorded(int.Parse(channelOid), startTime);
                                    if (recProg != null && File.Exists(Path.Combine(Plugin.Instance.Configuration.UncPath, recProg.FileName)))
                                    {
                                        return(new MediaSourceInfo
                                        {
                                            Id = [email protected](CultureInfo.InvariantCulture),
                                            Path = Path.Combine(Plugin.Instance.Configuration.UncPath, recProg.FileName),
                                            Protocol = MediaProtocol.File,
                                            MediaStreams = new List <MediaStream>
                                            {
                                                new MediaStream
                                                {
                                                    Type = MediaStreamType.Video,
                                                    // Set the index to -1 because we don't know the exact index of the video stream within the container
                                                    Index = -1
                                                },
                                                new MediaStream
                                                {
                                                    Type = MediaStreamType.Audio,
                                                    // Set the index to -1 because we don't know the exact index of the audio stream within the container
                                                    Index = -1
                                                }
                                            }
                                        });

                                        break;
                                    }
                                }
                            }
                            catch
                            {
                                _logger.Info("GetChannelStream wait {0} for {1}", i, channelOid);
                            }
                        }
                    }
                }

                throw new ResourceNotFoundException(string.Format("Could not stream channel {0}", channelOid));
            }
        }
Exemple #10
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);
        }
Exemple #11
0
        /// <summary>
        /// Ensure that we are connected to the NextPvr server
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task EnsureSetup()
        {
            var config = Plugin.Instance.Configuration;

            if (string.IsNullOrEmpty(config.Host))
            {
                _logger.Error("[MythTV] Host must be configured.");
                throw new InvalidOperationException("MythTV host must be configured.");
            }


            List <StorageGroupDir> storageGroups;

            using (var stream = await _httpClient.Get(GetOptions(CancellationToken.None, "/Myth/GetStorageGroupDirs")).ConfigureAwait(false))
            {
                storageGroups = new MythResponse().GetStorageGroupDirs(stream, _jsonSerializer, _logger, true);
            }

            List <StorageGroupMap> storageGroupMaps = config.StorageGroupMaps;

            if (!storageGroupMaps.Any())
            {
                storageGroupMaps = storageGroups.Select(x => new StorageGroupMap {
                    GroupName   = x.GroupName,
                    DirName     = x.DirName,
                    DirNameEmby = x.DirName
                }).ToList();
            }
            else
            {
                // drop groups no longer on server
                storageGroupMaps.RemoveAll(g => !storageGroups.Select(x => x.GroupName).Contains(g.GroupName));

                // add in new groups from server
                List <StorageGroupDir> newGroups = storageGroups;
                newGroups.RemoveAll(g => storageGroupMaps.Select(x => x.GroupName).Contains(g.GroupName));
                storageGroupMaps.AddRange(newGroups.Select(x => new StorageGroupMap {
                    GroupName   = x.GroupName,
                    DirName     = x.DirName,
                    DirNameEmby = x.DirName
                }));
            }

            // make sure there are no trailing path separators
            foreach (var group in storageGroupMaps)
            {
                group.DirName     = group.DirName.TrimEnd('/');
                group.DirNameEmby = group.DirNameEmby.TrimEnd('/');
            }

            Plugin.Instance.Configuration.StorageGroupMaps = storageGroupMaps;

            List <string> recGroupNames;

            using (var stream = await _httpClient.Get(GetOptions(CancellationToken.None, "/Dvr/GetRecGroupList")).ConfigureAwait(false))
            {
                recGroupNames = new DvrResponse().GetRecGroupList(stream, _jsonSerializer, _logger);
            }

            List <RecGroup> recGroups = config.RecGroups;

            if (!recGroups.Any())
            {
                recGroups = recGroupNames.Select(x => new RecGroup(x)).ToList();
            }
            else
            {
                // drop groups no longer on server
                recGroups.RemoveAll(g => !recGroupNames.Contains(g.Name));

                // add in new groups from server
                recGroups.AddRange(recGroupNames.Except(recGroups.Select(x => x.Name)).Select(g => new RecGroup(g)).ToList());
            }
            Plugin.Instance.Configuration.RecGroups = recGroups;

            Plugin.Instance.SaveConfiguration();


            if (config.UseSchedulesDirectImages)
            {
                _imageGrabber = new SchedulesDirectImages(_httpClient, _jsonSerializer, _logger);
            }
        }