SatIpHost.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using Emby.Server.Implementations.LiveTv.TunerHosts;
  8. using MediaBrowser.Model.IO;
  9. using MediaBrowser.Common.Configuration;
  10. using MediaBrowser.Common.Extensions;
  11. using MediaBrowser.Common.IO;
  12. using MediaBrowser.Common.Net;
  13. using MediaBrowser.Controller;
  14. using MediaBrowser.Controller.Configuration;
  15. using MediaBrowser.Controller.IO;
  16. using MediaBrowser.Controller.LiveTv;
  17. using MediaBrowser.Controller.MediaEncoding;
  18. using MediaBrowser.Model.Dto;
  19. using MediaBrowser.Model.Entities;
  20. using MediaBrowser.Model.LiveTv;
  21. using MediaBrowser.Model.Logging;
  22. using MediaBrowser.Model.MediaInfo;
  23. using MediaBrowser.Model.Serialization;
  24. namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
  25. {
  26. public class SatIpHost : BaseTunerHost, ITunerHost
  27. {
  28. private readonly IFileSystem _fileSystem;
  29. private readonly IHttpClient _httpClient;
  30. private readonly IServerApplicationHost _appHost;
  31. public SatIpHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost)
  32. : base(config, logger, jsonSerializer, mediaEncoder)
  33. {
  34. _fileSystem = fileSystem;
  35. _httpClient = httpClient;
  36. _appHost = appHost;
  37. }
  38. private const string ChannelIdPrefix = "sat_";
  39. protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken)
  40. {
  41. if (!string.IsNullOrWhiteSpace(tuner.M3UUrl))
  42. {
  43. return await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(tuner.M3UUrl, ChannelIdPrefix, tuner.Id, false, cancellationToken).ConfigureAwait(false);
  44. }
  45. var channels = await new ChannelScan(Logger).Scan(tuner, cancellationToken).ConfigureAwait(false);
  46. return channels;
  47. }
  48. public static string DeviceType
  49. {
  50. get { return "satip"; }
  51. }
  52. public override string Type
  53. {
  54. get { return DeviceType; }
  55. }
  56. protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
  57. {
  58. var urlHash = tuner.Url.GetMD5().ToString("N");
  59. var prefix = ChannelIdPrefix + urlHash;
  60. if (!channelId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
  61. {
  62. return null;
  63. }
  64. var channels = await GetChannels(tuner, true, cancellationToken).ConfigureAwait(false);
  65. var m3uchannels = channels.Cast<M3UChannel>();
  66. var channel = m3uchannels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase));
  67. if (channel != null)
  68. {
  69. var path = channel.Path;
  70. MediaProtocol protocol = MediaProtocol.File;
  71. if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
  72. {
  73. protocol = MediaProtocol.Http;
  74. }
  75. else if (path.StartsWith("rtmp", StringComparison.OrdinalIgnoreCase))
  76. {
  77. protocol = MediaProtocol.Rtmp;
  78. }
  79. else if (path.StartsWith("rtsp", StringComparison.OrdinalIgnoreCase))
  80. {
  81. protocol = MediaProtocol.Rtsp;
  82. }
  83. var mediaSource = new MediaSourceInfo
  84. {
  85. Path = channel.Path,
  86. Protocol = protocol,
  87. MediaStreams = new List<MediaStream>
  88. {
  89. new MediaStream
  90. {
  91. Type = MediaStreamType.Video,
  92. // Set the index to -1 because we don't know the exact index of the video stream within the container
  93. Index = -1,
  94. IsInterlaced = true
  95. },
  96. new MediaStream
  97. {
  98. Type = MediaStreamType.Audio,
  99. // Set the index to -1 because we don't know the exact index of the audio stream within the container
  100. Index = -1
  101. }
  102. },
  103. RequiresOpening = false,
  104. RequiresClosing = false
  105. };
  106. mediaSource.InferTotalBitrate();
  107. return new List<MediaSourceInfo> { mediaSource };
  108. }
  109. return new List<MediaSourceInfo>();
  110. }
  111. protected override async Task<LiveStream> GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken)
  112. {
  113. var sources = await GetChannelStreamMediaSources(tuner, channelId, cancellationToken).ConfigureAwait(false);
  114. var liveStream = new LiveStream(sources.First());
  115. return liveStream;
  116. }
  117. protected override async Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
  118. {
  119. var updatedInfo = await SatIpDiscovery.Current.GetInfo(tuner.InfoUrl, cancellationToken).ConfigureAwait(false);
  120. return updatedInfo.TunersAvailable > 0;
  121. }
  122. protected override bool IsValidChannelId(string channelId)
  123. {
  124. return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase);
  125. }
  126. public string Name
  127. {
  128. get { return "Sat IP"; }
  129. }
  130. public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken)
  131. {
  132. var list = GetTunerHosts()
  133. .SelectMany(i => GetTunerInfos(i, cancellationToken))
  134. .ToList();
  135. return Task.FromResult(list);
  136. }
  137. public List<LiveTvTunerInfo> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken)
  138. {
  139. var list = new List<LiveTvTunerInfo>();
  140. for (var i = 0; i < info.Tuners; i++)
  141. {
  142. list.Add(new LiveTvTunerInfo
  143. {
  144. Name = info.FriendlyName ?? Name,
  145. SourceType = Type,
  146. Status = LiveTvTunerStatus.Available,
  147. Id = info.Url.GetMD5().ToString("N") + i.ToString(CultureInfo.InvariantCulture),
  148. Url = info.Url
  149. });
  150. }
  151. return list;
  152. }
  153. public string ApplyDuration(string streamPath, TimeSpan duration)
  154. {
  155. return streamPath;
  156. }
  157. }
  158. }