diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-11-03 19:35:19 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-11-03 19:35:19 -0400 |
| commit | d5ea8ca3ad378fc7e0a18ad314e1dfce07003ab6 (patch) | |
| tree | 4742a665e3455389a9795ff8b6c292263b3876e8 /MediaBrowser.Server.Implementations/LiveTv/TunerHosts | |
| parent | d0babf322dad6624ee15622d11db52e58db5197f (diff) | |
move classes to portable
Diffstat (limited to 'MediaBrowser.Server.Implementations/LiveTv/TunerHosts')
9 files changed, 1 insertions, 1651 deletions
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs deleted file mode 100644 index 0fe74798f5..0000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ /dev/null @@ -1,249 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.LiveTv; -using MediaBrowser.Model.Logging; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Model.Dlna; -using MediaBrowser.Model.Serialization; - -namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts -{ - public abstract class BaseTunerHost - { - protected readonly IServerConfigurationManager Config; - protected readonly ILogger Logger; - protected IJsonSerializer JsonSerializer; - protected readonly IMediaEncoder MediaEncoder; - - private readonly ConcurrentDictionary<string, ChannelCache> _channelCache = - new ConcurrentDictionary<string, ChannelCache>(StringComparer.OrdinalIgnoreCase); - - protected BaseTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder) - { - Config = config; - Logger = logger; - JsonSerializer = jsonSerializer; - MediaEncoder = mediaEncoder; - } - - protected abstract Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken); - public abstract string Type { get; } - - public async Task<IEnumerable<ChannelInfo>> GetChannels(TunerHostInfo tuner, bool enableCache, CancellationToken cancellationToken) - { - ChannelCache cache = null; - var key = tuner.Id; - - if (enableCache && !string.IsNullOrWhiteSpace(key) && _channelCache.TryGetValue(key, out cache)) - { - if (DateTime.UtcNow - cache.Date < TimeSpan.FromMinutes(60)) - { - return cache.Channels.ToList(); - } - } - - var result = await GetChannelsInternal(tuner, cancellationToken).ConfigureAwait(false); - var list = result.ToList(); - Logger.Debug("Channels from {0}: {1}", tuner.Url, JsonSerializer.SerializeToString(list)); - - if (!string.IsNullOrWhiteSpace(key) && list.Count > 0) - { - cache = cache ?? new ChannelCache(); - cache.Date = DateTime.UtcNow; - cache.Channels = list; - _channelCache.AddOrUpdate(key, cache, (k, v) => cache); - } - - return list; - } - - protected virtual List<TunerHostInfo> GetTunerHosts() - { - return GetConfiguration().TunerHosts - .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) - .ToList(); - } - - public async Task<IEnumerable<ChannelInfo>> GetChannels(bool enableCache, CancellationToken cancellationToken) - { - var list = new List<ChannelInfo>(); - - var hosts = GetTunerHosts(); - - foreach (var host in hosts) - { - try - { - var channels = await GetChannels(host, enableCache, cancellationToken).ConfigureAwait(false); - var newChannels = channels.Where(i => !list.Any(l => string.Equals(i.Id, l.Id, StringComparison.OrdinalIgnoreCase))).ToList(); - - list.AddRange(newChannels); - } - catch (Exception ex) - { - Logger.ErrorException("Error getting channel list", ex); - } - } - - return list; - } - - protected abstract Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken); - - public async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken) - { - if (IsValidChannelId(channelId)) - { - var hosts = GetTunerHosts(); - - var hostsWithChannel = new List<TunerHostInfo>(); - - foreach (var host in hosts) - { - try - { - var channels = await GetChannels(host, true, cancellationToken).ConfigureAwait(false); - - if (channels.Any(i => string.Equals(i.Id, channelId, StringComparison.OrdinalIgnoreCase))) - { - hostsWithChannel.Add(host); - } - } - catch (Exception ex) - { - Logger.Error("Error getting channels", ex); - } - } - - foreach (var host in hostsWithChannel) - { - try - { - // Check to make sure the tuner is available - // If there's only one tuner, don't bother with the check and just let the tuner be the one to throw an error - if (hostsWithChannel.Count > 1 && - !await IsAvailable(host, channelId, cancellationToken).ConfigureAwait(false)) - { - Logger.Error("Tuner is not currently available"); - continue; - } - - var mediaSources = await GetChannelStreamMediaSources(host, channelId, cancellationToken).ConfigureAwait(false); - - // Prefix the id with the host Id so that we can easily find it - foreach (var mediaSource in mediaSources) - { - mediaSource.Id = host.Id + mediaSource.Id; - } - - return mediaSources; - } - catch (Exception ex) - { - Logger.Error("Error opening tuner", ex); - } - } - } - - return new List<MediaSourceInfo>(); - } - - protected abstract Task<LiveStream> GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken); - - public async Task<LiveStream> GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken) - { - if (!IsValidChannelId(channelId)) - { - throw new FileNotFoundException(); - } - - var hosts = GetTunerHosts(); - - var hostsWithChannel = new List<TunerHostInfo>(); - - foreach (var host in hosts) - { - if (string.IsNullOrWhiteSpace(streamId)) - { - try - { - var channels = await GetChannels(host, true, cancellationToken).ConfigureAwait(false); - - if (channels.Any(i => string.Equals(i.Id, channelId, StringComparison.OrdinalIgnoreCase))) - { - hostsWithChannel.Add(host); - } - } - catch (Exception ex) - { - Logger.Error("Error getting channels", ex); - } - } - else if (streamId.StartsWith(host.Id, StringComparison.OrdinalIgnoreCase)) - { - hostsWithChannel = new List<TunerHostInfo> { host }; - streamId = streamId.Substring(host.Id.Length); - break; - } - } - - foreach (var host in hostsWithChannel) - { - try - { - var liveStream = await GetChannelStream(host, channelId, streamId, cancellationToken).ConfigureAwait(false); - await liveStream.Open(cancellationToken).ConfigureAwait(false); - return liveStream; - } - catch (Exception ex) - { - Logger.Error("Error opening tuner", ex); - } - } - - throw new LiveTvConflictException(); - } - - protected virtual bool EnableMediaProbing - { - get { return false; } - } - - protected async Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) - { - try - { - return await IsAvailableInternal(tuner, channelId, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - Logger.ErrorException("Error checking tuner availability", ex); - return false; - } - } - - protected abstract Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken); - - protected abstract bool IsValidChannelId(string channelId); - - protected LiveTvOptions GetConfiguration() - { - return Config.GetConfiguration<LiveTvOptions>("livetv"); - } - - private class ChannelCache - { - public DateTime Date; - public List<ChannelInfo> Channels; - } - } -} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs deleted file mode 100644 index f039da9274..0000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs +++ /dev/null @@ -1,159 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Dlna; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.LiveTv; -using MediaBrowser.Model.Logging; -using System; -using System.Linq; -using System.Threading; -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Dlna; -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Serialization; - -namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun -{ - public class HdHomerunDiscovery : IServerEntryPoint - { - private readonly IDeviceDiscovery _deviceDiscovery; - private readonly IServerConfigurationManager _config; - private readonly ILogger _logger; - private readonly ILiveTvManager _liveTvManager; - private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); - private readonly IHttpClient _httpClient; - private readonly IJsonSerializer _json; - - public HdHomerunDiscovery(IDeviceDiscovery deviceDiscovery, IServerConfigurationManager config, ILogger logger, ILiveTvManager liveTvManager, IHttpClient httpClient, IJsonSerializer json) - { - _deviceDiscovery = deviceDiscovery; - _config = config; - _logger = logger; - _liveTvManager = liveTvManager; - _httpClient = httpClient; - _json = json; - } - - public void Run() - { - _deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered; - } - - void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs<UpnpDeviceInfo> e) - { - string server = null; - var info = e.Argument; - - if (info.Headers.TryGetValue("SERVER", out server) && server.IndexOf("HDHomeRun", StringComparison.OrdinalIgnoreCase) != -1) - { - string location; - if (info.Headers.TryGetValue("Location", out location)) - { - //_logger.Debug("HdHomerun found at {0}", location); - - // Just get the beginning of the url - Uri uri; - if (Uri.TryCreate(location, UriKind.Absolute, out uri)) - { - var apiUrl = location.Replace(uri.LocalPath, String.Empty, StringComparison.OrdinalIgnoreCase) - .TrimEnd('/'); - - //_logger.Debug("HdHomerun api url: {0}", apiUrl); - AddDevice(apiUrl); - } - } - } - } - - private async void AddDevice(string url) - { - await _semaphore.WaitAsync().ConfigureAwait(false); - - try - { - var options = GetConfiguration(); - - if (options.TunerHosts.Any(i => - string.Equals(i.Type, HdHomerunHost.DeviceType, StringComparison.OrdinalIgnoreCase) && - UriEquals(i.Url, url))) - { - return; - } - - // Strip off the port - url = new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped).TrimEnd('/'); - - // Test it by pulling down the lineup - using (var stream = await _httpClient.Get(new HttpRequestOptions - { - Url = string.Format("{0}/discover.json", url), - CancellationToken = CancellationToken.None, - BufferContent = false - })) - { - var response = _json.DeserializeFromStream<HdHomerunHost.DiscoverResponse>(stream); - - var existing = GetConfiguration().TunerHosts - .FirstOrDefault(i => string.Equals(i.Type, HdHomerunHost.DeviceType, StringComparison.OrdinalIgnoreCase) && string.Equals(i.DeviceId, response.DeviceID, StringComparison.OrdinalIgnoreCase)); - - if (existing == null) - { - await _liveTvManager.SaveTunerHost(new TunerHostInfo - { - Type = HdHomerunHost.DeviceType, - Url = url, - DataVersion = 1, - DeviceId = response.DeviceID - - }).ConfigureAwait(false); - } - else - { - if (!string.Equals(existing.Url, url, StringComparison.OrdinalIgnoreCase)) - { - existing.Url = url; - await _liveTvManager.SaveTunerHost(existing).ConfigureAwait(false); - } - } - } - } - catch (Exception ex) - { - _logger.ErrorException("Error saving device", ex); - } - finally - { - _semaphore.Release(); - } - } - - private bool UriEquals(string savedUri, string location) - { - return string.Equals(NormalizeUrl(location), NormalizeUrl(savedUri), StringComparison.OrdinalIgnoreCase); - } - - private string NormalizeUrl(string url) - { - if (!url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) - { - url = "http://" + url; - } - - url = url.TrimEnd('/'); - - // Strip off the port - return new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped); - } - - private LiveTvOptions GetConfiguration() - { - return _config.GetConfiguration<LiveTvOptions>("livetv"); - } - - public void Dispose() - { - } - } -} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs deleted file mode 100644 index a32f4cca23..0000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ /dev/null @@ -1,570 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.LiveTv; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.MediaInfo; -using MediaBrowser.Model.Serialization; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Model.IO; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.IO; -using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Net; - -namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun -{ - public class HdHomerunHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost - { - private readonly IHttpClient _httpClient; - private readonly IFileSystem _fileSystem; - private readonly IServerApplicationHost _appHost; - - public HdHomerunHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IHttpClient httpClient, IFileSystem fileSystem, IServerApplicationHost appHost) - : base(config, logger, jsonSerializer, mediaEncoder) - { - _httpClient = httpClient; - _fileSystem = fileSystem; - _appHost = appHost; - } - - public string Name - { - get { return "HD Homerun"; } - } - - public override string Type - { - get { return DeviceType; } - } - - public static string DeviceType - { - get { return "hdhomerun"; } - } - - private const string ChannelIdPrefix = "hdhr_"; - - private string GetChannelId(TunerHostInfo info, Channels i) - { - var id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture); - - if (info.DataVersion >= 1) - { - id += '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"); - } - - return id; - } - - private async Task<IEnumerable<Channels>> GetLineup(TunerHostInfo info, CancellationToken cancellationToken) - { - var options = new HttpRequestOptions - { - Url = string.Format("{0}/lineup.json", GetApiUrl(info, false)), - CancellationToken = cancellationToken, - BufferContent = false - }; - using (var stream = await _httpClient.Get(options)) - { - var lineup = JsonSerializer.DeserializeFromStream<List<Channels>>(stream) ?? new List<Channels>(); - - if (info.ImportFavoritesOnly) - { - lineup = lineup.Where(i => i.Favorite).ToList(); - } - - return lineup.Where(i => !i.DRM).ToList(); - } - } - - protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) - { - var lineup = await GetLineup(info, cancellationToken).ConfigureAwait(false); - - return lineup.Select(i => new ChannelInfo - { - Name = i.GuideName, - Number = i.GuideNumber.ToString(CultureInfo.InvariantCulture), - Id = GetChannelId(info, i), - IsFavorite = i.Favorite, - TunerHostId = info.Id, - IsHD = i.HD == 1, - AudioCodec = i.AudioCodec, - VideoCodec = i.VideoCodec - }); - } - - private readonly Dictionary<string, DiscoverResponse> _modelCache = new Dictionary<string, DiscoverResponse>(); - private async Task<string> GetModelInfo(TunerHostInfo info, CancellationToken cancellationToken) - { - lock (_modelCache) - { - DiscoverResponse response; - if (_modelCache.TryGetValue(info.Url, out response)) - { - return response.ModelNumber; - } - } - - try - { - using (var stream = await _httpClient.Get(new HttpRequestOptions() - { - Url = string.Format("{0}/discover.json", GetApiUrl(info, false)), - CancellationToken = cancellationToken, - CacheLength = TimeSpan.FromDays(1), - CacheMode = CacheMode.Unconditional, - TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds), - BufferContent = false - })) - { - var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream); - - lock (_modelCache) - { - _modelCache[info.Id] = response; - } - - return response.ModelNumber; - } - } - catch (HttpException ex) - { - if (ex.StatusCode.HasValue && ex.StatusCode.Value == System.Net.HttpStatusCode.NotFound) - { - var defaultValue = "HDHR"; - // HDHR4 doesn't have this api - lock (_modelCache) - { - _modelCache[info.Id] = new DiscoverResponse - { - ModelNumber = defaultValue - }; - } - return defaultValue; - } - - throw; - } - } - - public async Task<List<LiveTvTunerInfo>> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken) - { - var model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false); - - using (var stream = await _httpClient.Get(new HttpRequestOptions() - { - Url = string.Format("{0}/tuners.html", GetApiUrl(info, false)), - CancellationToken = cancellationToken, - TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds), - BufferContent = false - })) - { - var tuners = new List<LiveTvTunerInfo>(); - using (var sr = new StreamReader(stream, System.Text.Encoding.UTF8)) - { - while (!sr.EndOfStream) - { - string line = StripXML(sr.ReadLine()); - if (line.Contains("Channel")) - { - LiveTvTunerStatus status; - var index = line.IndexOf("Channel", StringComparison.OrdinalIgnoreCase); - var name = line.Substring(0, index - 1); - var currentChannel = line.Substring(index + 7); - if (currentChannel != "none") { status = LiveTvTunerStatus.LiveTv; } else { status = LiveTvTunerStatus.Available; } - tuners.Add(new LiveTvTunerInfo - { - Name = name, - SourceType = string.IsNullOrWhiteSpace(model) ? Name : model, - ProgramName = currentChannel, - Status = status - }); - } - } - } - return tuners; - } - } - - public async Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken) - { - var list = new List<LiveTvTunerInfo>(); - - foreach (var host in GetConfiguration().TunerHosts - .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase))) - { - try - { - list.AddRange(await GetTunerInfos(host, cancellationToken).ConfigureAwait(false)); - } - catch (Exception ex) - { - Logger.ErrorException("Error getting tuner info", ex); - } - } - - return list; - } - - private string GetApiUrl(TunerHostInfo info, bool isPlayback) - { - var url = info.Url; - - if (string.IsNullOrWhiteSpace(url)) - { - throw new ArgumentException("Invalid tuner info"); - } - - if (!url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) - { - url = "http://" + url; - } - - var uri = new Uri(url); - - if (isPlayback) - { - var builder = new UriBuilder(uri); - builder.Port = 5004; - uri = builder.Uri; - } - - return uri.AbsoluteUri.TrimEnd('/'); - } - - private static string StripXML(string source) - { - char[] buffer = new char[source.Length]; - int bufferIndex = 0; - bool inside = false; - - for (int i = 0; i < source.Length; i++) - { - char let = source[i]; - if (let == '<') - { - inside = true; - continue; - } - if (let == '>') - { - inside = false; - continue; - } - if (!inside) - { - buffer[bufferIndex] = let; - bufferIndex++; - } - } - return new string(buffer, 0, bufferIndex); - } - - private class Channels - { - public string GuideNumber { get; set; } - public string GuideName { get; set; } - public string VideoCodec { get; set; } - public string AudioCodec { get; set; } - public string URL { get; set; } - public bool Favorite { get; set; } - public bool DRM { get; set; } - public int HD { get; set; } - } - - private async Task<MediaSourceInfo> GetMediaSource(TunerHostInfo info, string channelId, string profile) - { - int? width = null; - int? height = null; - bool isInterlaced = true; - string videoCodec = null; - string audioCodec = "ac3"; - - int? videoBitrate = null; - int? audioBitrate = null; - - if (string.Equals(profile, "mobile", StringComparison.OrdinalIgnoreCase)) - { - width = 1280; - height = 720; - isInterlaced = false; - videoCodec = "h264"; - videoBitrate = 2000000; - } - else if (string.Equals(profile, "heavy", StringComparison.OrdinalIgnoreCase)) - { - width = 1920; - height = 1080; - isInterlaced = false; - videoCodec = "h264"; - videoBitrate = 15000000; - } - else if (string.Equals(profile, "internet540", StringComparison.OrdinalIgnoreCase)) - { - width = 960; - height = 546; - isInterlaced = false; - videoCodec = "h264"; - videoBitrate = 2500000; - } - else if (string.Equals(profile, "internet480", StringComparison.OrdinalIgnoreCase)) - { - width = 848; - height = 480; - isInterlaced = false; - videoCodec = "h264"; - videoBitrate = 2000000; - } - else if (string.Equals(profile, "internet360", StringComparison.OrdinalIgnoreCase)) - { - width = 640; - height = 360; - isInterlaced = false; - videoCodec = "h264"; - videoBitrate = 1500000; - } - else if (string.Equals(profile, "internet240", StringComparison.OrdinalIgnoreCase)) - { - width = 432; - height = 240; - isInterlaced = false; - videoCodec = "h264"; - videoBitrate = 1000000; - } - - var channels = await GetChannels(info, true, CancellationToken.None).ConfigureAwait(false); - var channel = channels.FirstOrDefault(i => string.Equals(i.Number, channelId, StringComparison.OrdinalIgnoreCase)); - if (channel != null) - { - if (string.IsNullOrWhiteSpace(videoCodec)) - { - videoCodec = channel.VideoCodec; - } - audioCodec = channel.AudioCodec; - - if (!videoBitrate.HasValue) - { - videoBitrate = (channel.IsHD ?? true) ? 15000000 : 2000000; - } - audioBitrate = (channel.IsHD ?? true) ? 448000 : 192000; - } - - // normalize - if (string.Equals(videoCodec, "mpeg2", StringComparison.OrdinalIgnoreCase)) - { - videoCodec = "mpeg2video"; - } - - string nal = null; - if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase)) - { - nal = "0"; - } - - var url = GetApiUrl(info, true) + "/auto/v" + channelId; - - if (!string.IsNullOrWhiteSpace(profile) && !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase)) - { - url += "?transcode=" + profile; - } - - var id = profile; - if (string.IsNullOrWhiteSpace(id)) - { - id = "native"; - } - id += "_" + url.GetMD5().ToString("N"); - - var mediaSource = new MediaSourceInfo - { - Path = 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, - IsInterlaced = isInterlaced, - Codec = videoCodec, - Width = width, - Height = height, - BitRate = videoBitrate, - NalLengthSize = nal - - }, - 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, - Codec = audioCodec, - BitRate = audioBitrate - } - }, - RequiresOpening = true, - RequiresClosing = false, - BufferMs = 0, - Container = "ts", - Id = id, - SupportsDirectPlay = false, - SupportsDirectStream = true, - SupportsTranscoding = true, - IsInfiniteStream = true - }; - - return mediaSource; - } - - protected EncodingOptions GetEncodingOptions() - { - return Config.GetConfiguration<EncodingOptions>("encoding"); - } - - private string GetHdHrIdFromChannelId(string channelId) - { - return channelId.Split('_')[1]; - } - - protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) - { - var list = new List<MediaSourceInfo>(); - - if (!channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase)) - { - return list; - } - var hdhrId = GetHdHrIdFromChannelId(channelId); - - list.Add(await GetMediaSource(info, hdhrId, "native").ConfigureAwait(false)); - - try - { - if (info.AllowHWTranscoding) - { - string model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false); - model = model ?? string.Empty; - - if ((model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1)) - { - list.Add(await GetMediaSource(info, hdhrId, "heavy").ConfigureAwait(false)); - - list.Add(await GetMediaSource(info, hdhrId, "internet540").ConfigureAwait(false)); - list.Add(await GetMediaSource(info, hdhrId, "internet480").ConfigureAwait(false)); - list.Add(await GetMediaSource(info, hdhrId, "internet360").ConfigureAwait(false)); - list.Add(await GetMediaSource(info, hdhrId, "internet240").ConfigureAwait(false)); - list.Add(await GetMediaSource(info, hdhrId, "mobile").ConfigureAwait(false)); - } - } - } - catch - { - - } - - return list; - } - - protected override bool IsValidChannelId(string channelId) - { - if (string.IsNullOrWhiteSpace(channelId)) - { - throw new ArgumentNullException("channelId"); - } - - return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase); - } - - protected override async Task<LiveStream> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) - { - var profile = streamId.Split('_')[0]; - - Logger.Info("GetChannelStream: channel id: {0}. stream id: {1} profile: {2}", channelId, streamId, profile); - - if (!channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase)) - { - throw new ArgumentException("Channel not found"); - } - var hdhrId = GetHdHrIdFromChannelId(channelId); - - var mediaSource = await GetMediaSource(info, hdhrId, profile).ConfigureAwait(false); - - var liveStream = new HdHomerunLiveStream(mediaSource, streamId, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost); - liveStream.EnableStreamSharing = true; - return liveStream; - } - - public async Task Validate(TunerHostInfo info) - { - if (!info.IsEnabled) - { - return; - } - - lock (_modelCache) - { - _modelCache.Clear(); - } - - try - { - // Test it by pulling down the lineup - using (var stream = await _httpClient.Get(new HttpRequestOptions - { - Url = string.Format("{0}/discover.json", GetApiUrl(info, false)), - CancellationToken = CancellationToken.None, - BufferContent = false - })) - { - var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream); - - info.DeviceId = response.DeviceID; - } - } - catch (HttpException ex) - { - if (ex.StatusCode.HasValue && ex.StatusCode.Value == System.Net.HttpStatusCode.NotFound) - { - // HDHR4 doesn't have this api - return; - } - - throw; - } - } - - protected override async Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) - { - var info = await GetTunerInfos(tuner, cancellationToken).ConfigureAwait(false); - - return info.Any(i => i.Status == LiveTvTunerStatus.Available); - } - - public class DiscoverResponse - { - public string FriendlyName { get; set; } - public string ModelNumber { get; set; } - public string FirmwareName { get; set; } - public string FirmwareVersion { get; set; } - public string DeviceID { get; set; } - public string DeviceAuth { get; set; } - public string BaseURL { get; set; } - public string LineupURL { get; set; } - } - } -} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs deleted file mode 100644 index 7bb4dc92e0..0000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Model.IO; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.MediaInfo; -using MediaBrowser.Server.Implementations.LiveTv.EmbyTV; -using System.Collections.Generic; -using System.Linq; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.IO; - -namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun -{ - public class HdHomerunLiveStream : LiveStream, IDirectStreamProvider - { - private readonly ILogger _logger; - private readonly IHttpClient _httpClient; - private readonly IFileSystem _fileSystem; - private readonly IServerApplicationPaths _appPaths; - private readonly IServerApplicationHost _appHost; - - private readonly CancellationTokenSource _liveStreamCancellationTokenSource = new CancellationTokenSource(); - private readonly TaskCompletionSource<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>(); - private readonly MulticastStream _multicastStream; - - - public HdHomerunLiveStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost) - : base(mediaSource) - { - _fileSystem = fileSystem; - _httpClient = httpClient; - _logger = logger; - _appPaths = appPaths; - _appHost = appHost; - OriginalStreamId = originalStreamId; - _multicastStream = new MulticastStream(_logger); - } - - protected override async Task OpenInternal(CancellationToken openCancellationToken) - { - _liveStreamCancellationTokenSource.Token.ThrowIfCancellationRequested(); - - var mediaSource = OriginalMediaSource; - - var url = mediaSource.Path; - - _logger.Info("Opening HDHR Live stream from {0}", url); - - var taskCompletionSource = new TaskCompletionSource<bool>(); - - StartStreaming(url, taskCompletionSource, _liveStreamCancellationTokenSource.Token); - - //OpenedMediaSource.Protocol = MediaProtocol.File; - //OpenedMediaSource.Path = tempFile; - //OpenedMediaSource.ReadAtNativeFramerate = true; - - OpenedMediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; - OpenedMediaSource.Protocol = MediaProtocol.Http; - OpenedMediaSource.SupportsDirectPlay = false; - OpenedMediaSource.SupportsDirectStream = true; - OpenedMediaSource.SupportsTranscoding = true; - - await taskCompletionSource.Task.ConfigureAwait(false); - - //await Task.Delay(5000).ConfigureAwait(false); - } - - public override Task Close() - { - _logger.Info("Closing HDHR live stream"); - _liveStreamCancellationTokenSource.Cancel(); - - return _liveStreamTaskCompletionSource.Task; - } - - private async Task StartStreaming(string url, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken) - { - await Task.Run(async () => - { - var isFirstAttempt = true; - - while (!cancellationToken.IsCancellationRequested) - { - try - { - using (var response = await _httpClient.SendAsync(new HttpRequestOptions - { - Url = url, - CancellationToken = cancellationToken, - BufferContent = false - - }, "GET").ConfigureAwait(false)) - { - _logger.Info("Opened HDHR stream from {0}", url); - - if (!cancellationToken.IsCancellationRequested) - { - _logger.Info("Beginning multicastStream.CopyUntilCancelled"); - - Action onStarted = null; - if (isFirstAttempt) - { - onStarted = () => openTaskCompletionSource.TrySetResult(true); - } - - await _multicastStream.CopyUntilCancelled(response.Content, onStarted, cancellationToken).ConfigureAwait(false); - } - } - } - catch (OperationCanceledException) - { - break; - } - catch (Exception ex) - { - if (isFirstAttempt) - { - _logger.ErrorException("Error opening live stream:", ex); - openTaskCompletionSource.TrySetException(ex); - break; - } - - _logger.ErrorException("Error copying live stream, will reopen", ex); - } - - isFirstAttempt = false; - } - - _liveStreamTaskCompletionSource.TrySetResult(true); - - }).ConfigureAwait(false); - } - - public Task CopyToAsync(Stream stream, CancellationToken cancellationToken) - { - return _multicastStream.CopyToAsync(stream); - } - } -} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs deleted file mode 100644 index b85b3810a3..0000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ /dev/null @@ -1,167 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.LiveTv; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.MediaInfo; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.IO; -using MediaBrowser.Model.IO; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.IO; -using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Model.Serialization; -using MediaBrowser.Server.Implementations.LiveTv.EmbyTV; - -namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts -{ - public class M3UTunerHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost - { - private readonly IFileSystem _fileSystem; - private readonly IHttpClient _httpClient; - private readonly IServerApplicationHost _appHost; - - public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost) - : base(config, logger, jsonSerializer, mediaEncoder) - { - _fileSystem = fileSystem; - _httpClient = httpClient; - _appHost = appHost; - } - - public override string Type - { - get { return "m3u"; } - } - - public string Name - { - get { return "M3U Tuner"; } - } - - private const string ChannelIdPrefix = "m3u_"; - - protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) - { - return await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(info.Url, ChannelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false); - } - - public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken) - { - var list = GetTunerHosts() - .Select(i => new LiveTvTunerInfo() - { - Name = Name, - SourceType = Type, - Status = LiveTvTunerStatus.Available, - Id = i.Url.GetMD5().ToString("N"), - Url = i.Url - }) - .ToList(); - - return Task.FromResult(list); - } - - protected override async Task<LiveStream> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) - { - var sources = await GetChannelStreamMediaSources(info, channelId, cancellationToken).ConfigureAwait(false); - - var liveStream = new LiveStream(sources.First()); - return liveStream; - } - - public async Task Validate(TunerHostInfo info) - { - using (var stream = await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).GetListingsStream(info.Url, CancellationToken.None).ConfigureAwait(false)) - { - - } - } - - protected override bool IsValidChannelId(string channelId) - { - return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase); - } - - protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) - { - var urlHash = info.Url.GetMD5().ToString("N"); - var prefix = ChannelIdPrefix + urlHash; - if (!channelId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) - { - return null; - } - - var channels = await GetChannels(info, true, cancellationToken).ConfigureAwait(false); - var m3uchannels = channels.Cast<M3UChannel>(); - var channel = m3uchannels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase)); - if (channel != null) - { - var path = channel.Path; - MediaProtocol protocol = MediaProtocol.File; - if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase)) - { - protocol = MediaProtocol.Http; - } - else if (path.StartsWith("rtmp", StringComparison.OrdinalIgnoreCase)) - { - protocol = MediaProtocol.Rtmp; - } - else if (path.StartsWith("rtsp", StringComparison.OrdinalIgnoreCase)) - { - protocol = MediaProtocol.Rtsp; - } - else if (path.StartsWith("udp", StringComparison.OrdinalIgnoreCase)) - { - protocol = MediaProtocol.Udp; - } - - var mediaSource = new MediaSourceInfo - { - Path = channel.Path, - Protocol = protocol, - 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, - 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 = false, - RequiresClosing = false, - - ReadAtNativeFramerate = false, - - Id = channel.Path.GetMD5().ToString("N"), - IsInfiniteStream = true - }; - - return new List<MediaSourceInfo> { mediaSource }; - } - return new List<MediaSourceInfo>(); - } - - protected override Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) - { - return Task.FromResult(true); - } - } -} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs deleted file mode 100644 index 3bfe902dfb..0000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Model.IO; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; -using MediaBrowser.Controller.IO; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts -{ - public class M3uParser - { - private readonly ILogger _logger; - private readonly IFileSystem _fileSystem; - private readonly IHttpClient _httpClient; - private readonly IServerApplicationHost _appHost; - - public M3uParser(ILogger logger, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost) - { - _logger = logger; - _fileSystem = fileSystem; - _httpClient = httpClient; - _appHost = appHost; - } - - public async Task<List<M3UChannel>> Parse(string url, string channelIdPrefix, string tunerHostId, CancellationToken cancellationToken) - { - var urlHash = url.GetMD5().ToString("N"); - - // Read the file and display it line by line. - using (var reader = new StreamReader(await GetListingsStream(url, cancellationToken).ConfigureAwait(false))) - { - return GetChannels(reader, urlHash, channelIdPrefix, tunerHostId); - } - } - - public Task<Stream> GetListingsStream(string url, CancellationToken cancellationToken) - { - if (url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) - { - return _httpClient.Get(new HttpRequestOptions - { - Url = url, - CancellationToken = cancellationToken, - // Some data providers will require a user agent - UserAgent = _appHost.FriendlyName + "/" + _appHost.ApplicationVersion - }); - } - return Task.FromResult(_fileSystem.OpenRead(url)); - } - - private List<M3UChannel> GetChannels(StreamReader reader, string urlHash, string channelIdPrefix, string tunerHostId) - { - var channels = new List<M3UChannel>(); - string line; - string extInf = ""; - while ((line = reader.ReadLine()) != null) - { - line = line.Trim(); - if (string.IsNullOrWhiteSpace(line)) - { - continue; - } - - if (line.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase)) - { - continue; - } - - if (line.StartsWith("#EXTINF:", StringComparison.OrdinalIgnoreCase)) - { - extInf = line.Substring(8).Trim(); - _logger.Info("Found m3u channel: {0}", extInf); - } - else if (!string.IsNullOrWhiteSpace(extInf) && !line.StartsWith("#", StringComparison.OrdinalIgnoreCase)) - { - var channel = GetChannelnfo(extInf, tunerHostId, line); - channel.Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N"); - channel.Path = line; - channels.Add(channel); - extInf = ""; - } - } - return channels; - } - private M3UChannel GetChannelnfo(string extInf, string tunerHostId, string mediaUrl) - { - var titleIndex = extInf.LastIndexOf(','); - var channel = new M3UChannel(); - channel.TunerHostId = tunerHostId; - - channel.Number = extInf.Trim().Split(' ')[0] ?? "0"; - channel.Name = extInf.Substring(titleIndex + 1); - - //Check for channel number with the format from SatIp - int number; - var numberIndex = channel.Name.IndexOf('.'); - if (numberIndex > 0) - { - if (int.TryParse(channel.Name.Substring(0, numberIndex), out number)) - { - channel.Number = number.ToString(); - channel.Name = channel.Name.Substring(numberIndex + 1); - } - } - - if (string.Equals(channel.Number, "-1", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(mediaUrl)) - { - channel.Number = Path.GetFileNameWithoutExtension(mediaUrl.Split('/').Last()); - } - - if (string.Equals(channel.Number, "-1", StringComparison.OrdinalIgnoreCase)) - { - channel.Number = "0"; - } - - channel.ImageUrl = FindProperty("tvg-logo", extInf); - - var name = FindProperty("tvg-name", extInf); - if (string.IsNullOrWhiteSpace(name)) - { - name = FindProperty("tvg-id", extInf); - } - - channel.Name = name; - - var numberString = FindProperty("tvg-id", extInf); - if (string.IsNullOrWhiteSpace(numberString)) - { - numberString = FindProperty("channel-id", extInf); - } - - if (!string.IsNullOrWhiteSpace(numberString)) - { - channel.Number = numberString; - } - - return channel; - - } - private string FindProperty(string property, string properties) - { - var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase); - var matches = reg.Matches(properties); - foreach (Match match in matches) - { - if (match.Groups[1].Value == property) - { - return match.Groups[2].Value; - } - } - return null; - } - } - - - public class M3UChannel : ChannelInfo - { - public string Path { get; set; } - } -}
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs deleted file mode 100644 index 8ff3fd6c17..0000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts -{ - public class MulticastStream - { - private readonly List<QueueStream> _outputStreams = new List<QueueStream>(); - private const int BufferSize = 81920; - private CancellationToken _cancellationToken; - private readonly ILogger _logger; - - public MulticastStream(ILogger logger) - { - _logger = logger; - } - - public async Task CopyUntilCancelled(Stream source, Action onStarted, CancellationToken cancellationToken) - { - _cancellationToken = cancellationToken; - - while (!cancellationToken.IsCancellationRequested) - { - byte[] buffer = new byte[BufferSize]; - - var bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); - - if (bytesRead > 0) - { - byte[] copy = new byte[bytesRead]; - Buffer.BlockCopy(buffer, 0, copy, 0, bytesRead); - - List<QueueStream> streams = null; - - lock (_outputStreams) - { - streams = _outputStreams.ToList(); - } - - foreach (var stream in streams) - { - stream.Queue(copy); - } - - if (onStarted != null) - { - var onStartedCopy = onStarted; - onStarted = null; - Task.Run(onStartedCopy); - } - } - - else - { - await Task.Delay(100).ConfigureAwait(false); - } - } - } - - public Task CopyToAsync(Stream stream) - { - var result = new QueueStream(stream, _logger) - { - OnFinished = OnFinished - }; - - lock (_outputStreams) - { - _outputStreams.Add(result); - } - - result.Start(_cancellationToken); - - return result.TaskCompletion.Task; - } - - public void RemoveOutputStream(QueueStream stream) - { - lock (_outputStreams) - { - _outputStreams.Remove(stream); - } - } - - private void OnFinished(QueueStream queueStream) - { - RemoveOutputStream(queueStream); - } - } -} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs deleted file mode 100644 index c1566b9006..0000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts -{ - public class QueueStream - { - private readonly Stream _outputStream; - private readonly ConcurrentQueue<byte[]> _queue = new ConcurrentQueue<byte[]>(); - private CancellationToken _cancellationToken; - public TaskCompletionSource<bool> TaskCompletion { get; private set; } - - public Action<QueueStream> OnFinished { get; set; } - private readonly ILogger _logger; - - public QueueStream(Stream outputStream, ILogger logger) - { - _outputStream = outputStream; - _logger = logger; - TaskCompletion = new TaskCompletionSource<bool>(); - } - - public void Queue(byte[] bytes) - { - _queue.Enqueue(bytes); - } - - public void Start(CancellationToken cancellationToken) - { - _cancellationToken = cancellationToken; - Task.Run(() => StartInternal()); - } - - private byte[] Dequeue() - { - byte[] bytes; - if (_queue.TryDequeue(out bytes)) - { - return bytes; - } - - return null; - } - - private async Task StartInternal() - { - var cancellationToken = _cancellationToken; - - try - { - while (!cancellationToken.IsCancellationRequested) - { - var bytes = Dequeue(); - if (bytes != null) - { - await _outputStream.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false); - } - else - { - await Task.Delay(50, cancellationToken).ConfigureAwait(false); - } - } - - TaskCompletion.TrySetResult(true); - _logger.Debug("QueueStream complete"); - } - catch (OperationCanceledException) - { - _logger.Debug("QueueStream cancelled"); - TaskCompletion.TrySetCanceled(); - } - catch (Exception ex) - { - _logger.ErrorException("Error in QueueStream", ex); - TaskCompletion.TrySetException(ex); - } - finally - { - if (OnFinished != null) - { - OnFinished(this); - } - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs index 8dca261a38..55101ce10f 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Emby.Server.Implementations.LiveTv.TunerHosts; using MediaBrowser.Model.IO; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; @@ -20,7 +21,6 @@ using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Serialization; -using MediaBrowser.Server.Implementations.LiveTv.EmbyTV; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp { |
