mirror of https://github.com/jellyfin/jellyfin.git
Remove unused Live TV code
This commit is contained in:
parent
c23a038ba8
commit
c101d287f2
|
@ -95,12 +95,5 @@ namespace MediaBrowser.Controller.Channels
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>The item media sources.</returns>
|
/// <returns>The item media sources.</returns>
|
||||||
IEnumerable<MediaSourceInfo> GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken);
|
IEnumerable<MediaSourceInfo> GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the item supports media probe.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The item.</param>
|
|
||||||
/// <returns>Whether media probe should be enabled.</returns>
|
|
||||||
bool EnableMediaProbe(BaseItem item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,14 +140,6 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task CloseLiveStream(string id, CancellationToken cancellationToken);
|
Task CloseLiveStream(string id, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Records the live stream.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The identifier.</param>
|
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
|
||||||
/// <returns>Task.</returns>
|
|
||||||
Task RecordLiveStream(string id, CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resets the tuner.
|
/// Resets the tuner.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -180,9 +172,4 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
{
|
{
|
||||||
Task<ILiveStream> GetChannelStreamWithDirectStreamProvider(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);
|
Task<ILiveStream> GetChannelStreamWithDirectStreamProvider(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ISupportsUpdatingDefaults
|
|
||||||
{
|
|
||||||
Task UpdateTimerDefaults(SeriesTimerInfo info, CancellationToken cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,13 +35,6 @@ namespace MediaBrowser.Controller.LiveTv
|
||||||
/// <returns>Task<IEnumerable<ChannelInfo>>.</returns>
|
/// <returns>Task<IEnumerable<ChannelInfo>>.</returns>
|
||||||
Task<List<ChannelInfo>> GetChannels(bool enableCache, CancellationToken cancellationToken);
|
Task<List<ChannelInfo>> GetChannels(bool enableCache, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the tuner infos.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
|
||||||
/// <returns>Task<List<LiveTvTunerInfo>>.</returns>
|
|
||||||
Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the channel stream.
|
/// Gets the channel stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using MediaBrowser.Model.LiveTv;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.LiveTv
|
|
||||||
{
|
|
||||||
public class LiveTvServiceStatusInfo
|
|
||||||
{
|
|
||||||
public LiveTvServiceStatusInfo()
|
|
||||||
{
|
|
||||||
Tuners = new List<LiveTvTunerInfo>();
|
|
||||||
IsVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the status.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The status.</value>
|
|
||||||
public LiveTvServiceStatus Status { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the status message.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The status message.</value>
|
|
||||||
public string StatusMessage { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the version.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The version.</value>
|
|
||||||
public string Version { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance has update available.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance has update available; otherwise, <c>false</c>.</value>
|
|
||||||
public bool HasUpdateAvailable { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the tuners.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The tuners.</value>
|
|
||||||
public List<LiveTvTunerInfo> Tuners { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is visible.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is visible; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsVisible { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using MediaBrowser.Model.LiveTv;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.LiveTv
|
|
||||||
{
|
|
||||||
public class LiveTvTunerInfo
|
|
||||||
{
|
|
||||||
public LiveTvTunerInfo()
|
|
||||||
{
|
|
||||||
Clients = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the type of the source.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The type of the source.</value>
|
|
||||||
public string SourceType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The name.</value>
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The identifier.</value>
|
|
||||||
public string Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the URL.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The URL.</value>
|
|
||||||
public string Url { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the status.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The status.</value>
|
|
||||||
public LiveTvTunerStatus Status { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the channel identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The channel identifier.</value>
|
|
||||||
public string ChannelId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the recording identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The recording identifier.</value>
|
|
||||||
public string RecordingId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name of the program.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The name of the program.</value>
|
|
||||||
public string ProgramName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the clients.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The clients.</value>
|
|
||||||
public List<string> Clients { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance can reset.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance can reset; otherwise, <c>false</c>.</value>
|
|
||||||
public bool CanReset { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,210 +0,0 @@
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using MediaBrowser.Model.LiveTv;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.LiveTv
|
|
||||||
{
|
|
||||||
public class RecordingInfo
|
|
||||||
{
|
|
||||||
public RecordingInfo()
|
|
||||||
{
|
|
||||||
Genres = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the id of the recording.
|
|
||||||
/// </summary>
|
|
||||||
public string Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the series timer identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The series timer identifier.</value>
|
|
||||||
public string SeriesTimerId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the timer identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The timer identifier.</value>
|
|
||||||
public string TimerId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the channelId of the recording.
|
|
||||||
/// </summary>
|
|
||||||
public string ChannelId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the type of the channel.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The type of the channel.</value>
|
|
||||||
public ChannelType ChannelType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name of the recording.
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the path.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The path.</value>
|
|
||||||
public string Path { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the URL.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The URL.</value>
|
|
||||||
public string Url { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the overview.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The overview.</value>
|
|
||||||
public string Overview { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the start date of the recording, in UTC.
|
|
||||||
/// </summary>
|
|
||||||
public DateTime StartDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the end date of the recording, in UTC.
|
|
||||||
/// </summary>
|
|
||||||
public DateTime EndDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the program identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The program identifier.</value>
|
|
||||||
public string ProgramId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the status.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The status.</value>
|
|
||||||
public RecordingStatus Status { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the genre of the program.
|
|
||||||
/// </summary>
|
|
||||||
public List<string> Genres { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is repeat.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is repeat; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsRepeat { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the episode title.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The episode title.</value>
|
|
||||||
public string EpisodeTitle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is hd.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is hd; otherwise, <c>false</c>.</value>
|
|
||||||
public bool? IsHD { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the audio.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The audio.</value>
|
|
||||||
public ProgramAudio? Audio { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the original air date.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The original air date.</value>
|
|
||||||
public DateTime? OriginalAirDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is movie.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is movie; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsMovie { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is sports.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is sports; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsSports { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is series.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsSeries { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is live.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is live; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsLive { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is news.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is news; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsNews { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is kids.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is kids; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsKids { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance is premiere.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>true</c> if this instance is premiere; otherwise, <c>false</c>.</value>
|
|
||||||
public bool IsPremiere { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the official rating.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The official rating.</value>
|
|
||||||
public string OfficialRating { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the community rating.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The community rating.</value>
|
|
||||||
public float? CommunityRating { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the image path if it can be accessed directly from the file system.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The image path.</value>
|
|
||||||
public string ImagePath { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the image url if it can be downloaded.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The image URL.</value>
|
|
||||||
public string ImageUrl { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether this instance has image.
|
|
||||||
/// </summary>
|
|
||||||
/// <value><c>null</c> if [has image] contains no value, <c>true</c> if [has image]; otherwise, <c>false</c>.</value>
|
|
||||||
public bool? HasImage { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the show identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The show identifier.</value>
|
|
||||||
public string ShowId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the date last updated.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The date last updated.</value>
|
|
||||||
public DateTime DateLastUpdated { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using MediaBrowser.Model.LiveTv;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.LiveTv
|
|
||||||
{
|
|
||||||
public class RecordingStatusChangedEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
public string RecordingId { get; set; }
|
|
||||||
|
|
||||||
public RecordingStatus NewStatus { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,8 +13,6 @@ namespace MediaBrowser.Model.IO
|
||||||
|
|
||||||
Task CopyToAsync(Stream source, Stream destination, int bufferSize, int emptyReadLimit, CancellationToken cancellationToken);
|
Task CopyToAsync(Stream source, Stream destination, int bufferSize, int emptyReadLimit, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task CopyToAsync(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
Task CopyUntilCancelled(Stream source, Stream target, int bufferSize, CancellationToken cancellationToken);
|
Task CopyUntilCancelled(Stream source, Stream target, int bufferSize, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
namespace MediaBrowser.Model.LiveTv
|
|
||||||
{
|
|
||||||
public enum LiveTvTunerStatus
|
|
||||||
{
|
|
||||||
Available = 0,
|
|
||||||
Disabled = 1,
|
|
||||||
RecordingTv = 2,
|
|
||||||
LiveTv = 3
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -113,15 +113,6 @@ namespace Jellyfin.LiveTv.Channels
|
||||||
return channel is ISupportsDelete supportsDelete && supportsDelete.CanDelete(item);
|
return channel is ISupportsDelete supportsDelete && supportsDelete.CanDelete(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool EnableMediaProbe(BaseItem item)
|
|
||||||
{
|
|
||||||
var internalChannel = _libraryManager.GetItemById(item.ChannelId);
|
|
||||||
var channel = Channels.FirstOrDefault(i => GetInternalChannelId(i.Name).Equals(internalChannel.Id));
|
|
||||||
|
|
||||||
return channel is ISupportsMediaProbe;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task DeleteItem(BaseItem item)
|
public Task DeleteItem(BaseItem item)
|
||||||
{
|
{
|
||||||
|
@ -562,18 +553,6 @@ namespace Jellyfin.LiveTv.Channels
|
||||||
return GetChannelFeaturesDto(channel, channelProvider, channelProvider.GetChannelFeatures());
|
return GetChannelFeaturesDto(channel, channelProvider, channelProvider.GetChannelFeatures());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks whether the provided Guid supports external transfer.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="channelId">The Guid.</param>
|
|
||||||
/// <returns>Whether or not the provided Guid supports external transfer.</returns>
|
|
||||||
public bool SupportsExternalTransfer(Guid channelId)
|
|
||||||
{
|
|
||||||
var channelProvider = GetChannelProvider(channelId);
|
|
||||||
|
|
||||||
return channelProvider.GetChannelFeatures().SupportsContentDownloading;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the provided channel's supported features.
|
/// Gets the provided channel's supported features.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1215,19 +1194,6 @@ namespace Jellyfin.LiveTv.Channels
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IChannel GetChannelProvider(Guid internalChannelId)
|
|
||||||
{
|
|
||||||
var result = GetAllChannels()
|
|
||||||
.FirstOrDefault(i => internalChannelId.Equals(GetInternalChannelId(i.Name)));
|
|
||||||
|
|
||||||
if (result is null)
|
|
||||||
{
|
|
||||||
throw new ResourceNotFoundException("No channel provider found for channel id " + internalChannelId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1023,11 +1023,6 @@ namespace Jellyfin.LiveTv.EmbyTV
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task RecordLiveStream(string id, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task ResetTuner(string id, CancellationToken cancellationToken)
|
public Task ResetTuner(string id, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
|
@ -81,36 +81,6 @@ namespace Jellyfin.LiveTv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CopyToAsync(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
byte[] buffer = ArrayPool<byte>.Shared.Rent(IODefaults.CopyToBufferSize);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int bytesRead;
|
|
||||||
|
|
||||||
while ((bytesRead = await source.ReadAsync(buffer, cancellationToken).ConfigureAwait(false)) != 0)
|
|
||||||
{
|
|
||||||
var bytesToWrite = Math.Min(bytesRead, copyLength);
|
|
||||||
|
|
||||||
if (bytesToWrite > 0)
|
|
||||||
{
|
|
||||||
await destination.WriteAsync(buffer.AsMemory(0, Convert.ToInt32(bytesToWrite)), cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
copyLength -= bytesToWrite;
|
|
||||||
|
|
||||||
if (copyLength <= 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
ArrayPool<byte>.Shared.Return(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task CopyUntilCancelled(Stream source, Stream target, int bufferSize, CancellationToken cancellationToken)
|
public async Task CopyUntilCancelled(Stream source, Stream target, int bufferSize, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
byte[] buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
|
byte[] buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
@ -16,7 +15,6 @@ using System.Threading.Tasks;
|
||||||
using Jellyfin.Extensions;
|
using Jellyfin.Extensions;
|
||||||
using Jellyfin.Extensions.Json;
|
using Jellyfin.Extensions.Json;
|
||||||
using Jellyfin.Extensions.Json.Converters;
|
using Jellyfin.Extensions.Json.Converters;
|
||||||
using Jellyfin.LiveTv.Configuration;
|
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
|
@ -164,152 +162,6 @@ namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<List<LiveTvTunerInfo>> GetTunerInfosHttp(TunerHostInfo info, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
|
|
||||||
.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}/tuners.html", GetApiUrl(info)), HttpCompletionOption.ResponseHeadersRead, cancellationToken)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
var tuners = new List<LiveTvTunerInfo>();
|
|
||||||
var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
|
||||||
await using (stream.ConfigureAwait(false))
|
|
||||||
{
|
|
||||||
using var sr = new StreamReader(stream, System.Text.Encoding.UTF8);
|
|
||||||
await foreach (var line in sr.ReadAllLinesAsync().ConfigureAwait(false))
|
|
||||||
{
|
|
||||||
string stripedLine = StripXML(line);
|
|
||||||
if (stripedLine.Contains("Channel", StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
LiveTvTunerStatus status;
|
|
||||||
var index = stripedLine.IndexOf("Channel", StringComparison.OrdinalIgnoreCase);
|
|
||||||
var name = stripedLine.Substring(0, index - 1);
|
|
||||||
var currentChannel = stripedLine.Substring(index + 7);
|
|
||||||
if (string.Equals(currentChannel, "none", StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
status = LiveTvTunerStatus.LiveTv;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = LiveTvTunerStatus.Available;
|
|
||||||
}
|
|
||||||
|
|
||||||
tuners.Add(new LiveTvTunerInfo
|
|
||||||
{
|
|
||||||
Name = name,
|
|
||||||
SourceType = string.IsNullOrWhiteSpace(model.ModelNumber) ? Name : model.ModelNumber,
|
|
||||||
ProgramName = currentChannel,
|
|
||||||
Status = status
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tuners;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string StripXML(string source)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(source))
|
|
||||||
{
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new string(buffer, 0, bufferIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<List<LiveTvTunerInfo>> GetTunerInfosUdp(TunerHostInfo info, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
var tuners = new List<LiveTvTunerInfo>(model.TunerCount);
|
|
||||||
|
|
||||||
var uri = new Uri(GetApiUrl(info));
|
|
||||||
|
|
||||||
using (var manager = new HdHomerunManager())
|
|
||||||
{
|
|
||||||
// Legacy HdHomeruns are IPv4 only
|
|
||||||
var ipInfo = IPAddress.Parse(uri.Host);
|
|
||||||
|
|
||||||
for (int i = 0; i < model.TunerCount; i++)
|
|
||||||
{
|
|
||||||
var name = string.Format(CultureInfo.InvariantCulture, "Tuner {0}", i + 1);
|
|
||||||
var currentChannel = "none"; // TODO: Get current channel and map back to Station Id
|
|
||||||
var isAvailable = await manager.CheckTunerAvailability(ipInfo, i, cancellationToken).ConfigureAwait(false);
|
|
||||||
var status = isAvailable ? LiveTvTunerStatus.Available : LiveTvTunerStatus.LiveTv;
|
|
||||||
tuners.Add(new LiveTvTunerInfo
|
|
||||||
{
|
|
||||||
Name = name,
|
|
||||||
SourceType = string.IsNullOrWhiteSpace(model.ModelNumber) ? Name : model.ModelNumber,
|
|
||||||
ProgramName = currentChannel,
|
|
||||||
Status = status
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tuners;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var list = new List<LiveTvTunerInfo>();
|
|
||||||
|
|
||||||
foreach (var host in Config.GetLiveTvConfiguration().TunerHosts
|
|
||||||
.Where(i => string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
list.AddRange(await GetTunerInfos(host, cancellationToken).ConfigureAwait(false));
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.LogError(ex, "Error getting tuner info");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<LiveTvTunerInfo>> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
// TODO Need faster way to determine UDP vs HTTP
|
|
||||||
var channels = await GetChannels(info, true, cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
var hdHomerunChannelInfo = channels.FirstOrDefault() as HdHomerunChannelInfo;
|
|
||||||
|
|
||||||
if (hdHomerunChannelInfo is null || hdHomerunChannelInfo.IsLegacyTuner)
|
|
||||||
{
|
|
||||||
return await GetTunerInfosUdp(info, cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await GetTunerInfosHttp(info, cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetApiUrl(TunerHostInfo info)
|
private static string GetApiUrl(TunerHostInfo info)
|
||||||
{
|
{
|
||||||
var url = info.Url;
|
var url = info.Url;
|
||||||
|
@ -575,40 +427,24 @@ namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
|
||||||
_streamHelper);
|
_streamHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
var enableHttpStream = true;
|
mediaSource.Protocol = MediaProtocol.Http;
|
||||||
if (enableHttpStream)
|
|
||||||
|
var httpUrl = channel.Path;
|
||||||
|
|
||||||
|
// If raw was used, the tuner doesn't support params
|
||||||
|
if (!string.IsNullOrWhiteSpace(profile) && !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
mediaSource.Protocol = MediaProtocol.Http;
|
httpUrl += "?transcode=" + profile;
|
||||||
|
|
||||||
var httpUrl = channel.Path;
|
|
||||||
|
|
||||||
// If raw was used, the tuner doesn't support params
|
|
||||||
if (!string.IsNullOrWhiteSpace(profile) && !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
httpUrl += "?transcode=" + profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaSource.Path = httpUrl;
|
|
||||||
|
|
||||||
return new SharedHttpStream(
|
|
||||||
mediaSource,
|
|
||||||
tunerHost,
|
|
||||||
streamId,
|
|
||||||
FileSystem,
|
|
||||||
_httpClientFactory,
|
|
||||||
Logger,
|
|
||||||
Config,
|
|
||||||
_appHost,
|
|
||||||
_streamHelper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HdHomerunUdpStream(
|
mediaSource.Path = httpUrl;
|
||||||
|
|
||||||
|
return new SharedHttpStream(
|
||||||
mediaSource,
|
mediaSource,
|
||||||
tunerHost,
|
tunerHost,
|
||||||
streamId,
|
streamId,
|
||||||
new HdHomerunChannelCommands(hdhomerunChannel.Number, profile),
|
|
||||||
modelInfo.TunerCount,
|
|
||||||
FileSystem,
|
FileSystem,
|
||||||
|
_httpClientFactory,
|
||||||
Logger,
|
Logger,
|
||||||
Config,
|
Config,
|
||||||
_appHost,
|
_appHost,
|
||||||
|
|
|
@ -80,22 +80,6 @@ namespace Jellyfin.LiveTv.TunerHosts
|
||||||
.ConfigureAwait(false);
|
.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", CultureInfo.InvariantCulture),
|
|
||||||
Url = i.Url
|
|
||||||
})
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
return Task.FromResult(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo tunerHost, ChannelInfo channel, string streamId, IList<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
|
protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo tunerHost, ChannelInfo channel, string streamId, IList<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var tunerCount = tunerHost.TunerCount;
|
var tunerCount = tunerHost.TunerCount;
|
||||||
|
|
Loading…
Reference in New Issue