コード例 #1
0
        protected override async Task <List <ProgramInfo> > GetProgramsInternal(TunerHostInfo tuner, string tunerChannelId, DateTimeOffset startDateUtc, DateTimeOffset endDateUtc, CancellationToken cancellationToken)
        {
            var connectionHandler = GetConnectionHandler(tuner);

            GetEventsResponseHandler currGetEventsResponseHandler = new GetEventsResponseHandler(startDateUtc, endDateUtc, Logger);

            HTSMessage queryEvents = new HTSMessage();

            queryEvents.Method = "getEvents";
            queryEvents.putField("channelId", Convert.ToInt32(tunerChannelId));
            queryEvents.putField("maxTime", (endDateUtc).ToUnixTimeSeconds());
            cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(new CancellationTokenSource(TIMEOUT).Token, cancellationToken).Token;

            Logger.Info("[TVHclient] GetProgramsAsync, ask TVH for events of channel '" + tunerChannelId + "'.");

            var list = await connectionHandler.SendMessage(queryEvents, currGetEventsResponseHandler.GetResponse, cancellationToken).ConfigureAwait(false);

            foreach (var item in list)
            {
                item.ChannelId = tunerChannelId;
                item.Id        = GetProgramEntryId(item.ShowId, item.StartDate, item.ChannelId);
            }

            return(list);
        }
コード例 #2
0
        public async Task <IEnumerable <ProgramInfo> > GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
        {
            int timeOut = await WaitForInitialLoadTask(cancellationToken);

            if (timeOut == -1 || cancellationToken.IsCancellationRequested)
            {
                _logger.LogInformation("[TVHclient] GetProgramsAsync, call canceled or timed out - returning empty list.");
                return(new List <ProgramInfo>());
            }

            GetEventsResponseHandler currGetEventsResponseHandler = new GetEventsResponseHandler(startDateUtc, endDateUtc, _logger, cancellationToken);

            HTSMessage queryEvents = new HTSMessage();

            queryEvents.Method = "getEvents";
            queryEvents.putField("channelId", Convert.ToInt32(channelId));
            queryEvents.putField("maxTime", ((DateTimeOffset)endDateUtc).ToUnixTimeSeconds());
            _htsConnectionHandler.SendMessage(queryEvents, currGetEventsResponseHandler);

            _logger.LogInformation("[TVHclient] GetProgramsAsync, ask TVH for events of channel '{chanid}'.", channelId);

            TaskWithTimeoutRunner <IEnumerable <ProgramInfo> > twtr   = new TaskWithTimeoutRunner <IEnumerable <ProgramInfo> >(TIMEOUT);
            TaskWithTimeoutResult <IEnumerable <ProgramInfo> > twtRes = await
                                                                        twtr.RunWithTimeout(currGetEventsResponseHandler.GetEvents(cancellationToken, channelId));

            if (twtRes.HasTimeout)
            {
                _logger.LogInformation("[TVHclient] GetProgramsAsync, timeout during call for events of channel '{chanid}'.", channelId);
                return(new List <ProgramInfo>());
            }

            return(twtRes.Result);
        }
コード例 #3
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)
        {
            ensureConnection();

            int timeOut = await WaitForInitialLoadTask(cancellationToken);

            if (timeOut == -1 || cancellationToken.IsCancellationRequested)
            {
                _logger.Info("[TVHclient] CreateTimerAsync, call canceled or timed out.");
                return;
            }

            HTSMessage createTimerMessage = new HTSMessage();

            createTimerMessage.Method = "addDvrEntry";
            createTimerMessage.putField("channelId", info.ChannelId);
            createTimerMessage.putField("start", DateTimeHelper.getUnixUTCTimeFromUtcDateTime(info.StartDate));
            createTimerMessage.putField("stop", DateTimeHelper.getUnixUTCTimeFromUtcDateTime(info.EndDate));
            createTimerMessage.putField("startExtra", (long)(info.PrePaddingSeconds / 60));
            createTimerMessage.putField("stopExtra", (long)(info.PostPaddingSeconds / 60));
            createTimerMessage.putField("priority", _priority); // info.Priority delivers always 0 - no GUI
            createTimerMessage.putField("configName", _profile);
            createTimerMessage.putField("description", info.Overview);
            createTimerMessage.putField("title", info.Name);
            createTimerMessage.putField("creator", Plugin.Instance.Configuration.Username);

            //HTSMessage createTimerResponse = await Task.Factory.StartNew<HTSMessage>(() =>
            //{
            //    LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
            //    _htsConnection.sendMessage(createTimerMessage, lbrh);
            //    return lbrh.getResponse();
            //});

            TaskWithTimeoutRunner <HTSMessage> twtr   = new TaskWithTimeoutRunner <HTSMessage>(TIMEOUT);
            TaskWithTimeoutResult <HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew <HTSMessage>(() =>
            {
                LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
                _htsConnection.sendMessage(createTimerMessage, lbrh);
                return(lbrh.getResponse());
            }));

            if (twtRes.HasTimeout)
            {
                _logger.Error("[TVHclient] Can't create timer because of timeout");
            }
            else
            {
                HTSMessage createTimerResponse = twtRes.Result;
                Boolean    success             = createTimerResponse.getInt("success", 0) == 1;
                if (!success)
                {
                    _logger.Error("[TVHclient] Can't create timer: '" + createTimerResponse.getString("error") + "'");
                }
            }
        }
コード例 #4
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)
        {
            ensureConnection();

            int timeOut = await WaitForInitialLoadTask(cancellationToken);

            if (timeOut == -1 || cancellationToken.IsCancellationRequested)
            {
                _logger.Info("[TVHclient] UpdateTimerAsync, call canceled or timed out.");
                return;
            }

            HTSMessage updateTimerMessage = new HTSMessage();

            updateTimerMessage.Method = "updateDvrEntry";
            updateTimerMessage.putField("id", info.Id);
            updateTimerMessage.putField("startExtra", (long)(info.PrePaddingSeconds / 60));
            updateTimerMessage.putField("stopExtra", (long)(info.PostPaddingSeconds / 60));

            //HTSMessage updateTimerResponse = await Task.Factory.StartNew<HTSMessage>(() =>
            //{
            //    LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
            //    _htsConnection.sendMessage(updateTimerMessage, lbrh);
            //    return lbrh.getResponse();
            //});

            TaskWithTimeoutRunner <HTSMessage> twtr   = new TaskWithTimeoutRunner <HTSMessage>(TIMEOUT);
            TaskWithTimeoutResult <HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew <HTSMessage>(() =>
            {
                LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
                _htsConnection.sendMessage(updateTimerMessage, lbrh);
                return(lbrh.getResponse());
            }));

            if (twtRes.HasTimeout)
            {
                _logger.Error("[TVHclient] Can't update timer because of timeout");
            }
            else
            {
                HTSMessage updateTimerResponse = twtRes.Result;
                Boolean    success             = updateTimerResponse.getInt("success", 0) == 1;
                if (!success)
                {
                    _logger.Error("[TVHclient] Can't update timer: '" + updateTimerResponse.getString("error") + "'");
                }
            }
        }
コード例 #5
0
        public async Task <IEnumerable <ProgramInfo> > GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
        {
            ensureConnection();

            int timeOut = await WaitForInitialLoadTask(cancellationToken);

            if (timeOut == -1 || cancellationToken.IsCancellationRequested)
            {
                _logger.Info("[TVHclient] GetProgramsAsync, call canceled or timed out - returning empty list.");
                return(new List <ProgramInfo>());
            }

            GetEventsResponseHandler currGetEventsResponseHandler = new GetEventsResponseHandler(startDateUtc, endDateUtc, _logger, cancellationToken);

            HTSMessage queryEvents = new HTSMessage();

            queryEvents.Method = "getEvents";
            queryEvents.putField("channelId", Convert.ToInt32(channelId));
            _htsConnection.sendMessage(queryEvents, currGetEventsResponseHandler);

            //IEnumerable<ProgramInfo> pi = await currGetEventsResponseHandler.GetEvents(cancellationToken);
            //return pi;

            TaskWithTimeoutRunner <IEnumerable <ProgramInfo> > twtr   = new TaskWithTimeoutRunner <IEnumerable <ProgramInfo> >(TIMEOUT);
            TaskWithTimeoutResult <IEnumerable <ProgramInfo> > twtRes = await
                                                                        twtr.RunWithTimeout(currGetEventsResponseHandler.GetEvents(cancellationToken));

            if (twtRes.HasTimeout)
            {
                return(new List <ProgramInfo>());
            }

            return(twtRes.Result);
        }
コード例 #6
0
        public void add(HTSMessage message)
        {
            _tunerDataHelper.addTunerInfo(message);

            lock (_data)
            {
                if (_data.ContainsKey(message.getInt("channelId")))
                {
                    int        channelID     = message.getInt("channelId");
                    HTSMessage storedMessage = _data[channelID];
                    if (storedMessage != null)
                    {
                        foreach (KeyValuePair <string, object> entry in message)
                        {
                            if (storedMessage.containsField(entry.Key))
                            {
                                storedMessage.removeField(entry.Key);
                            }
                            storedMessage.putField(entry.Key, entry.Value);
                        }
                    }
                    else
                    {
                        _logger.Error("[TVHclient] ChannelDataHelper: update for channelID '" + channelID + "' but no initial data found!");
                    }
                }
                else
                {
                    if (message.containsField("channelNumber") && message.getInt("channelNumber") > 0) // use only channels with number > 0
                    {
                        _data.Add(message.getInt("channelId"), message);
                    }
                }
            }
        }
コード例 #7
0
        public async Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken)
        {
            int timeOut = await WaitForInitialLoadTask(cancellationToken);

            if (timeOut == -1 || cancellationToken.IsCancellationRequested)
            {
                _logger.LogDebug("[TVHclient] LiveTvService.UpdateTimerAsync: call cancelled or timed out");
                return;
            }

            HTSMessage updateTimerMessage = new HTSMessage();

            updateTimerMessage.Method = "updateDvrEntry";
            updateTimerMessage.putField("id", info.Id);
            updateTimerMessage.putField("startExtra", (long)(info.PrePaddingSeconds / 60));
            updateTimerMessage.putField("stopExtra", (long)(info.PostPaddingSeconds / 60));

            TaskWithTimeoutRunner <HTSMessage> twtr   = new TaskWithTimeoutRunner <HTSMessage>(TIMEOUT);
            TaskWithTimeoutResult <HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew <HTSMessage>(() =>
            {
                LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
                _htsConnectionHandler.SendMessage(updateTimerMessage, lbrh);
                LastRecordingChange = DateTime.UtcNow;
                return(lbrh.getResponse());
            }));

            if (twtRes.HasTimeout)
            {
                _logger.LogError("[TVHclient] LiveTvService.UpdateTimerAsync: can't update timer because the timeout was reached");
            }
            else
            {
                HTSMessage updateTimerResponse = twtRes.Result;
                Boolean    success             = updateTimerResponse.getInt("success", 0) == 1;
                if (!success)
                {
                    if (updateTimerResponse.containsField("error"))
                    {
                        _logger.LogError("[TVHclient] LiveTvService.UpdateTimerAsync: can't update timer: '{why}'", updateTimerResponse.getString("error"));
                    }
                    else if (updateTimerResponse.containsField("noaccess"))
                    {
                        _logger.LogError("[TVHclient] LiveTvService.UpdateTimerAsync: can't update timer: '{why}'", updateTimerResponse.getString("noaccess"));
                    }
                }
            }
        }
コード例 #8
0
        protected override async Task <List <MediaSourceInfo> > GetChannelStreamMediaSources(TunerHostInfo tuner, BaseItem dbChannnel, ChannelInfo providerChannel, CancellationToken cancellationToken)
        {
            var connectionHandler = GetConnectionHandler(tuner);

            var channelId = GetTunerChannelIdFromEmbyChannelId(tuner, providerChannel.Id);

            HTSMessage getTicketMessage = new HTSMessage();

            getTicketMessage.Method = "getTicket";
            getTicketMessage.putField("channelId", channelId);

            cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(new CancellationTokenSource(TIMEOUT).Token, cancellationToken).Token;
            var getTicketResponse = await connectionHandler.SendMessage(getTicketMessage, cancellationToken).ConfigureAwait(false);

            var mediaSource = new MediaSourceInfo
            {
                Id           = "tvh_" + channelId,
                Path         = connectionHandler.GetHttpBaseUrl() + getTicketResponse.getString("path") + "?ticket=" + getTicketResponse.getString("ticket"),
                Protocol     = MediaProtocol.Http,
                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,
                        // Set to true if unknown to enable deinterlacing
                        IsInterlaced = true
                    },
                    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
                    }
                },

                RequiresOpening = true,
                RequiresClosing = true,

                SupportsDirectPlay   = false,
                SupportsDirectStream = true,
                SupportsTranscoding  = true,
                IsInfiniteStream     = true
            };

            return(new List <MediaSourceInfo> {
                mediaSource
            });
        }
コード例 #9
0
        /// <summary>
        /// Cancel the Series Timer
        /// </summary>
        /// <param name="timerId">The Timer Id</param>
        /// <param name="cancellationToken">The CancellationToken</param>
        /// <returns></returns>
        public async Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken)
        {
            ensureConnection();

            int timeOut = await WaitForInitialLoadTask(cancellationToken);

            if (timeOut == -1 || cancellationToken.IsCancellationRequested)
            {
                _logger.Info("[TVHclient] CancelSeriesTimerAsync, call canceled or timed out.");
                return;
            }

            HTSMessage deleteAutorecMessage = new HTSMessage();

            deleteAutorecMessage.Method = "deleteAutorecEntry";
            deleteAutorecMessage.putField("id", timerId);

            //HTSMessage deleteAutorecResponse = await Task.Factory.StartNew<HTSMessage>(() =>
            //{
            //    LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
            //    _htsConnection.sendMessage(deleteAutorecMessage, lbrh);
            //    return lbrh.getResponse();
            //});

            TaskWithTimeoutRunner <HTSMessage> twtr   = new TaskWithTimeoutRunner <HTSMessage>(TIMEOUT);
            TaskWithTimeoutResult <HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew <HTSMessage>(() =>
            {
                LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
                _htsConnection.sendMessage(deleteAutorecMessage, lbrh);
                return(lbrh.getResponse());
            }));

            if (twtRes.HasTimeout)
            {
                _logger.Error("[TVHclient] Can't delete recording because of timeout");
            }
            else
            {
                HTSMessage deleteAutorecResponse = twtRes.Result;
                Boolean    success = deleteAutorecResponse.getInt("success", 0) == 1;
                if (!success)
                {
                    _logger.Error("[TVHclient] Can't cancel timer: '" + deleteAutorecResponse.getString("error") + "'");
                }
            }
        }
コード例 #10
0
        public void Add(HTSMessage message)
        {
            if (_tunerDataHelper != null)
            {
                // TVHeadend don't send the information we need
                // _tunerDataHelper.addTunerInfo(message);
            }

            lock (_data)
            {
                try
                {
                    int channelID = message.getInt("channelId");
                    if (_data.ContainsKey(channelID))
                    {
                        HTSMessage storedMessage = _data[channelID];
                        if (storedMessage != null)
                        {
                            foreach (KeyValuePair <string, object> entry in message)
                            {
                                if (storedMessage.containsField(entry.Key))
                                {
                                    storedMessage.removeField(entry.Key);
                                }
                                storedMessage.putField(entry.Key, entry.Value);
                            }
                        }
                        else
                        {
                            _logger.LogError("[TVHclient] ChannelDataHelper: update for channelID '{id}' but no initial data found!", channelID);
                        }
                    }
                    else
                    {
                        if (message.containsField("channelNumber") && message.getInt("channelNumber") > 0) // use only channels with number > 0
                        {
                            _data.Add(channelID, message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "[TVHclient] ChannelDataHelper.Add caught exception. HTSMessage: {m} ", message);
                }
            }
        }
コード例 #11
0
        public async Task CancelTimerAsync(string timerId, CancellationToken cancellationToken)
        {
            int timeOut = await WaitForInitialLoadTask(cancellationToken);

            if (timeOut == -1 || cancellationToken.IsCancellationRequested)
            {
                _logger.Info("[TVHclient] CancelTimerAsync, call canceled or timed out.");
                return;
            }

            HTSMessage cancelTimerMessage = new HTSMessage();

            cancelTimerMessage.Method = "cancelDvrEntry";
            cancelTimerMessage.putField("id", timerId);

            TaskWithTimeoutRunner <HTSMessage> twtr   = new TaskWithTimeoutRunner <HTSMessage>(TIMEOUT);
            TaskWithTimeoutResult <HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew <HTSMessage>(() =>
            {
                LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
                _htsConnectionHandler.SendMessage(cancelTimerMessage, lbrh);
                LastRecordingChange = DateTimeOffset.UtcNow;
                return(lbrh.getResponse());
            }));

            if (twtRes.HasTimeout)
            {
                _logger.Error("[TVHclient] Can't cancel timer because of timeout");
            }
            else
            {
                HTSMessage cancelTimerResponse = twtRes.Result;
                Boolean    success             = cancelTimerResponse.getInt("success", 0) == 1;
                if (!success)
                {
                    if (cancelTimerResponse.containsField("error"))
                    {
                        _logger.Error("[TVHclient] Can't cancel timer: '" + cancelTimerResponse.getString("error") + "'");
                    }
                    else if (cancelTimerResponse.containsField("noaccess"))
                    {
                        _logger.Error("[TVHclient] Can't cancel timer: '" + cancelTimerResponse.getString("noaccess") + "'");
                    }
                }
            }
        }
コード例 #12
0
        public async Task DeleteRecordingAsync(string recordingId, CancellationToken cancellationToken)
        {
            int timeOut = await WaitForInitialLoadTask(cancellationToken);

            if (timeOut == -1 || cancellationToken.IsCancellationRequested)
            {
                _logger.LogInformation("[TVHclient] DeleteRecordingAsync, call canceled or timed out.");
                return;
            }

            HTSMessage deleteRecordingMessage = new HTSMessage();

            deleteRecordingMessage.Method = "deleteDvrEntry";
            deleteRecordingMessage.putField("id", recordingId);

            TaskWithTimeoutRunner <HTSMessage> twtr   = new TaskWithTimeoutRunner <HTSMessage>(TIMEOUT);
            TaskWithTimeoutResult <HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew <HTSMessage>(() =>
            {
                LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
                _htsConnectionHandler.SendMessage(deleteRecordingMessage, lbrh);
                LastRecordingChange = DateTime.UtcNow;
                return(lbrh.getResponse());
            }));

            if (twtRes.HasTimeout)
            {
                _logger.LogError("[TVHclient] Can't delete recording because of timeout");
            }
            else
            {
                HTSMessage deleteRecordingResponse = twtRes.Result;
                Boolean    success = deleteRecordingResponse.getInt("success", 0) == 1;
                if (!success)
                {
                    if (deleteRecordingResponse.containsField("error"))
                    {
                        _logger.LogError("[TVHclient] Can't delete recording: '{why}'", deleteRecordingResponse.getString("error"));
                    }
                    else if (deleteRecordingResponse.containsField("noaccess"))
                    {
                        _logger.LogError("[TVHclient] Can't delete recording: '{why}'", deleteRecordingResponse.getString("noaccess"));
                    }
                }
            }
        }
コード例 #13
0
        public void dvrEntryUpdate(HTSMessage message)
        {
            string id = message.getString("id");

            lock (_data)
            {
                HTSMessage oldMessage = _data[id];
                if (oldMessage == null)
                {
                    _logger.Info("[TVHclient] DvrDataHelper.dvrEntryUpdate id not in database - skip!" + message.ToString());
                    return;
                }
                foreach (KeyValuePair <string, object> entry in message)
                {
                    if (oldMessage.containsField(entry.Key))
                    {
                        oldMessage.removeField(entry.Key);
                    }
                    oldMessage.putField(entry.Key, entry.Value);
                }
            }
        }
コード例 #14
0
        public void autorecEntryUpdate(HTSMessage message)
        {
            string id = message.getString("id");

            lock (_data)
            {
                HTSMessage oldMessage = _data[id];
                if (oldMessage == null)
                {
                    _logger.LogDebug("[TVHclient] AutorecDataHelper.autorecEntryAdd: id not in database - skipping");
                    return;
                }
                foreach (KeyValuePair <string, object> entry in message)
                {
                    if (oldMessage.containsField(entry.Key))
                    {
                        oldMessage.removeField(entry.Key);
                    }
                    oldMessage.putField(entry.Key, entry.Value);
                }
            }
        }
コード例 #15
0
        public async Task <MediaSourceInfo> GetRecordingStream(string recordingId, string mediaSourceId, CancellationToken cancellationToken)
        {
            HTSMessage getTicketMessage = new HTSMessage();

            getTicketMessage.Method = "getTicket";
            getTicketMessage.putField("dvrId", recordingId);

            TaskWithTimeoutRunner <HTSMessage> twtr   = new TaskWithTimeoutRunner <HTSMessage>(TIMEOUT);
            TaskWithTimeoutResult <HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew <HTSMessage>(() =>
            {
                LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
                _htsConnectionHandler.SendMessage(getTicketMessage, lbrh);
                return(lbrh.getResponse());
            }));

            if (twtRes.HasTimeout)
            {
                _logger.LogError("[TVHclient] Timeout obtaining playback authentication ticket from TVH");
            }
            else
            {
                HTSMessage getTicketResponse = twtRes.Result;

                if (_subscriptionId == int.MaxValue)
                {
                    _subscriptionId = 0;
                }
                int currSubscriptionId = _subscriptionId++;

                if (_htsConnectionHandler.GetEnableSubsMaudios())
                {
                    _logger.LogInformation("[TVHclient] Support for live TV subtitles and multiple audio tracks is enabled.");

                    MediaSourceInfo recordingasset = new MediaSourceInfo();

                    recordingasset.Id = "" + currSubscriptionId;

                    // Use HTTP basic auth instead of TVH ticketing system for authentication to allow the users to switch subs or audio tracks at any time
                    recordingasset.Path     = _htsConnectionHandler.GetHttpBaseUrl() + getTicketResponse.getString("path");
                    recordingasset.Protocol = MediaProtocol.Http;

                    // Set asset source and type for stream probing and logging
                    string recordingasset_probeUrl = "" + recordingasset.Path;

                    // If enabled, force video deinterlacing for recordings
                    if (_htsConnectionHandler.GetForceDeinterlace())
                    {
                        _logger.LogInformation("[TVHclient] Force video deinterlacing for all channels and recordings is enabled.");

                        foreach (MediaStream i in recordingasset.MediaStreams)
                        {
                            if (i.Type == MediaStreamType.Video && i.IsInterlaced == false)
                            {
                                i.IsInterlaced = true;
                            }
                        }
                    }

                    return(recordingasset);
                }
                else
                {
                    return(new MediaSourceInfo
                    {
                        Id = "" + currSubscriptionId,
                        Path = _htsConnectionHandler.GetHttpBaseUrl() + getTicketResponse.getString("path") + "?ticket=" + getTicketResponse.getString("ticket"),
                        Protocol = MediaProtocol.Http,
                        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,
                                // Set to true if unknown to enable deinterlacing
                                IsInterlaced = true
                            },
                            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
                            }
                        }
                    });
                }
            }

            throw new TimeoutException();
        }
コード例 #16
0
        public async Task <MediaSourceInfo> GetRecordingStream(string recordingId, string mediaSourceId, CancellationToken cancellationToken)
        {
            ensureConnection();

            HTSMessage getTicketMessage = new HTSMessage();

            getTicketMessage.Method = "getTicket";
            getTicketMessage.putField("dvrId", recordingId);

            //HTSMessage getTicketResponse = await Task.Factory.StartNew<HTSMessage>(() =>
            //{
            //    LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
            //    _htsConnection.sendMessage(getTicketMessage, lbrh);
            //    return lbrh.getResponse();
            //});

            TaskWithTimeoutRunner <HTSMessage> twtr   = new TaskWithTimeoutRunner <HTSMessage>(TIMEOUT);
            TaskWithTimeoutResult <HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew <HTSMessage>(() =>
            {
                LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
                _htsConnection.sendMessage(getTicketMessage, lbrh);
                return(lbrh.getResponse());
            }));

            if (twtRes.HasTimeout)
            {
                _logger.Error("[TVHclient] Can't delete recording because of timeout");
            }
            else
            {
                HTSMessage getTicketResponse = twtRes.Result;

                if (_subscriptionId == int.MaxValue)
                {
                    _subscriptionId = 0;
                }
                int currSubscriptionId = _subscriptionId++;

                return(new MediaSourceInfo
                {
                    Id = "" + currSubscriptionId,
                    Path = _httpBaseUrl + getTicketResponse.getString("path") + "?ticket=" + getTicketResponse.getString("ticket"),
                    Protocol = MediaProtocol.Http,
                    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,
                            // Set to true if unknown to enable deinterlacing
                            IsInterlaced = true
                        },
                        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
                        }
                    }
                });
            }

            throw new TimeoutException();
        }
コード例 #17
0
        public async Task <MediaSourceInfo> GetChannelStream(string channelId, string mediaSourceId, CancellationToken cancellationToken)
        {
            HTSMessage getTicketMessage = new HTSMessage();

            getTicketMessage.Method = "getTicket";
            getTicketMessage.putField("channelId", channelId);

            TaskWithTimeoutRunner <HTSMessage> twtr   = new TaskWithTimeoutRunner <HTSMessage>(TIMEOUT);
            TaskWithTimeoutResult <HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew <HTSMessage>(() =>
            {
                LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
                _htsConnectionHandler.SendMessage(getTicketMessage, lbrh);
                return(lbrh.getResponse());
            }));

            if (twtRes.HasTimeout)
            {
                _logger.Error("[TVHclient] Timeout obtaining playback authentication ticket from TVH");
            }
            else
            {
                HTSMessage getTicketResponse = twtRes.Result;

                if (_subscriptionId == int.MaxValue)
                {
                    _subscriptionId = 0;
                }
                int currSubscriptionId = _subscriptionId++;

                if (_htsConnectionHandler.GetEnableSubsMaudios())
                {
                    _logger.Info("[TVHclient] Support for live TV subtitles and multiple audio tracks is enabled.");

                    MediaSourceInfo livetvasset = new MediaSourceInfo();

                    livetvasset.Id = "" + currSubscriptionId;

                    // Use HTTP basic auth instead of TVH ticketing system for authentication to allow the users to switch subs or audio tracks at any time
                    livetvasset.Path     = _htsConnectionHandler.GetHttpBaseUrl() + getTicketResponse.getString("path");
                    livetvasset.Protocol = MediaProtocol.Http;

                    // Probe the asset stream to determine available sub-streams
                    string livetvasset_probeUrl = "" + livetvasset.Path;
                    string livetvasset_source   = "LiveTV";

                    // Probe the asset stream to determine available sub-streams
                    await ProbeStream(livetvasset, livetvasset_probeUrl, livetvasset_source, cancellationToken);

                    return(livetvasset);
                }
                else
                {
                    return(new MediaSourceInfo
                    {
                        Id = "" + currSubscriptionId,
                        Path = _htsConnectionHandler.GetHttpBaseUrl() + getTicketResponse.getString("path") + "?ticket=" + getTicketResponse.getString("ticket"),
                        Protocol = MediaProtocol.Http,
                        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,
                                // Set to true if unknown to enable deinterlacing
                                IsInterlaced = true
                            },
                            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
                            }
                        }
                    });
                }
            }

            throw new TimeoutException("");
        }