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.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 livetvasset = new MediaSourceInfo();

                    livetvasset.Id = "" + currSubscriptionId;

                    // Use HTTP basic auth in HTTP header 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;
                    livetvasset.RequiredHttpHeaders = _htsConnectionHandler.GetHeaders();

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

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

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

                    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("");
        }
        public async Task <MediaSourceInfo> GetChannelStream(string channelId, string mediaSourceId, CancellationToken cancellationToken)
        {
            var ticket = await _channelTicketHandler.GetTicket(channelId, cancellationToken);

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

                MediaSourceInfo livetvasset = new MediaSourceInfo();

                livetvasset.Id = channelId;

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

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

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

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

                return(livetvasset);
            }
            else
            {
                return(new MediaSourceInfo
                {
                    Id = channelId,
                    Path = _htsConnectionHandler.GetHttpBaseUrl() + ticket.Url,
                    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
                        }
                    }
                });
            }
        }