Skip to content

Commit

Permalink
Merge pull request #10682 from barronpm/livetv-warnings
Browse files Browse the repository at this point in the history
Fix some warnings in LiveTV
  • Loading branch information
Bond-009 committed Dec 18, 2023
2 parents f039de0 + 192559d commit 053c339
Show file tree
Hide file tree
Showing 17 changed files with 141 additions and 80 deletions.
7 changes: 6 additions & 1 deletion Emby.Server.Implementations/Library/ExclusiveLiveStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace Emby.Server.Implementations.Library
{
public class ExclusiveLiveStream : ILiveStream
public sealed class ExclusiveLiveStream : ILiveStream
{
private readonly Func<Task> _closeFn;

Expand Down Expand Up @@ -51,5 +51,10 @@ public Task Open(CancellationToken openCancellationToken)
{
return Task.CompletedTask;
}

/// <inheritdoc />
public void Dispose()
{
}
}
}
45 changes: 30 additions & 15 deletions Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
public class DirectRecorder : IRecorder
public sealed class DirectRecorder : IRecorder
{
private readonly ILogger _logger;
private readonly IHttpClientFactory _httpClientFactory;
Expand Down Expand Up @@ -46,7 +46,15 @@ private async Task RecordFromDirectStreamProvider(IDirectStreamProvider directSt
{
Directory.CreateDirectory(Path.GetDirectoryName(targetFile) ?? throw new ArgumentException("Path can't be a root directory.", nameof(targetFile)));

await using (var output = new FileStream(targetFile, FileMode.CreateNew, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
var output = new FileStream(
targetFile,
FileMode.CreateNew,
FileAccess.Write,
FileShare.Read,
IODefaults.FileStreamBufferSize,
FileOptions.Asynchronous);

await using (output.ConfigureAwait(false))
{
onStarted();

Expand Down Expand Up @@ -80,24 +88,31 @@ private async Task RecordFromMediaSource(MediaSourceInfo mediaSource, string tar

Directory.CreateDirectory(Path.GetDirectoryName(targetFile) ?? throw new ArgumentException("Path can't be a root directory.", nameof(targetFile)));

await using var output = new FileStream(targetFile, FileMode.CreateNew, FileAccess.Write, FileShare.Read, IODefaults.CopyToBufferSize, FileOptions.Asynchronous);
var output = new FileStream(targetFile, FileMode.CreateNew, FileAccess.Write, FileShare.Read, IODefaults.CopyToBufferSize, FileOptions.Asynchronous);
await using (output.ConfigureAwait(false))
{
onStarted();

onStarted();
_logger.LogInformation("Copying recording stream to file {0}", targetFile);

_logger.LogInformation("Copying recording stream to file {0}", targetFile);
// The media source if infinite so we need to handle stopping ourselves
using var durationToken = new CancellationTokenSource(duration);
using var linkedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token);
cancellationToken = linkedCancellationToken.Token;

// The media source if infinite so we need to handle stopping ourselves
using var durationToken = new CancellationTokenSource(duration);
using var linkedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token);
cancellationToken = linkedCancellationToken.Token;
await _streamHelper.CopyUntilCancelled(
await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false),
output,
IODefaults.CopyToBufferSize,
cancellationToken).ConfigureAwait(false);

await _streamHelper.CopyUntilCancelled(
await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false),
output,
IODefaults.CopyToBufferSize,
cancellationToken).ConfigureAwait(false);
_logger.LogInformation("Recording completed to file {0}", targetFile);
}
}

_logger.LogInformation("Recording completed to file {0}", targetFile);
/// <inheritdoc />
public void Dispose()
{
}
}
}
18 changes: 4 additions & 14 deletions Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,11 @@
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Querying;
using Microsoft.Extensions.Logging;

namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
public class EmbyTV : ILiveTvService, ISupportsDirectStreamProvider, ISupportsNewTimerIds, IDisposable
public sealed class EmbyTV : ILiveTvService, ISupportsDirectStreamProvider, ISupportsNewTimerIds, IDisposable
{
public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss";

Expand Down Expand Up @@ -74,7 +73,7 @@ public class EmbyTV : ILiveTvService, ISupportsDirectStreamProvider, ISupportsNe

private readonly SemaphoreSlim _recordingDeleteSemaphore = new SemaphoreSlim(1, 1);

private bool _disposed = false;
private bool _disposed;

public EmbyTV(
IServerApplicationHost appHost,
Expand Down Expand Up @@ -1270,7 +1269,7 @@ private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, Acti
directStreamProvider = liveStreamResponse.Item2;
}

var recorder = GetRecorder(mediaStreamInfo);
using var recorder = GetRecorder(mediaStreamInfo);

recordPath = recorder.GetOutputPath(mediaStreamInfo, recordPath);
recordPath = EnsureFileUnique(recordPath, timer.Id);
Expand Down Expand Up @@ -2524,22 +2523,13 @@ private bool IsProgramAlreadyInLibrary(TimerInfo program)

/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}

if (disposing)
{
_recordingDeleteSemaphore.Dispose();
}
_recordingDeleteSemaphore.Dispose();

foreach (var pair in _activeRecordings.ToList())
{
Expand Down
8 changes: 4 additions & 4 deletions Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
public class EncodedRecorder : IRecorder, IDisposable
public class EncodedRecorder : IRecorder
{
private readonly ILogger _logger;
private readonly IMediaEncoder _mediaEncoder;
Expand All @@ -34,10 +34,10 @@ public class EncodedRecorder : IRecorder, IDisposable
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options;
private bool _hasExited;
private Stream _logFileStream;
private FileStream _logFileStream;
private string _targetPath;
private Process _process;
private bool _disposed = false;
private bool _disposed;

public EncodedRecorder(
ILogger logger,
Expand Down Expand Up @@ -308,7 +308,7 @@ private void OnFfMpegProcessExited(Process process)
}
}

private async Task StartStreamingLog(Stream source, Stream target)
private async Task StartStreamingLog(Stream source, FileStream target)
{
try
{
Expand Down
2 changes: 1 addition & 1 deletion Emby.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
public interface IRecorder
public interface IRecorder : IDisposable
{
/// <summary>
/// Records the specified media source.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ private ProgramInfo GetProgram(string channelId, ProgramDto programInfo, Program
IsMovie = IsMovie(details),
Etag = programInfo.Md5,
IsLive = string.Equals(programInfo.LiveTapeDelay, "live", StringComparison.OrdinalIgnoreCase),
IsPremiere = programInfo.Premiere || (programInfo.IsPremiereOrFinale ?? string.Empty).IndexOf("premiere", StringComparison.OrdinalIgnoreCase) != -1
IsPremiere = programInfo.Premiere || (programInfo.IsPremiereOrFinale ?? string.Empty).Contains("premiere", StringComparison.OrdinalIgnoreCase)
};

var showId = programId;
Expand Down Expand Up @@ -414,7 +414,7 @@ private static string GetProgramImage(string apiUrl, IEnumerable<ImageDataDto> i
return null;
}

if (uri.IndexOf("http", StringComparison.OrdinalIgnoreCase) != -1)
if (uri.Contains("http", StringComparison.OrdinalIgnoreCase))
{
return uri;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,38 +84,53 @@ private async Task<string> GetXml(ListingsProviderInfo info, CancellationToken c
_logger.LogInformation("Downloading xmltv listings from {Path}", info.Path);

using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(info.Path, cancellationToken).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
return await UnzipIfNeededAndCopy(info.Path, stream, cacheFile, cancellationToken).ConfigureAwait(false);
var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
await using (stream.ConfigureAwait(false))
{
return await UnzipIfNeededAndCopy(info.Path, stream, cacheFile, cancellationToken).ConfigureAwait(false);
}
}
else
{
await using var stream = AsyncFile.OpenRead(info.Path);
return await UnzipIfNeededAndCopy(info.Path, stream, cacheFile, cancellationToken).ConfigureAwait(false);
var stream = AsyncFile.OpenRead(info.Path);
await using (stream.ConfigureAwait(false))
{
return await UnzipIfNeededAndCopy(info.Path, stream, cacheFile, cancellationToken).ConfigureAwait(false);
}
}
}

private async Task<string> UnzipIfNeededAndCopy(string originalUrl, Stream stream, string file, CancellationToken cancellationToken)
{
await using var fileStream = new FileStream(file, FileMode.CreateNew, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);

if (Path.GetExtension(originalUrl.AsSpan().LeftPart('?')).Equals(".gz", StringComparison.OrdinalIgnoreCase))
var fileStream = new FileStream(
file,
FileMode.CreateNew,
FileAccess.Write,
FileShare.None,
IODefaults.FileStreamBufferSize,
FileOptions.Asynchronous);

await using (fileStream.ConfigureAwait(false))
{
try
if (Path.GetExtension(originalUrl.AsSpan().LeftPart('?')).Equals(".gz", StringComparison.OrdinalIgnoreCase))
{
using var reader = new GZipStream(stream, CompressionMode.Decompress);
await reader.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
try
{
using var reader = new GZipStream(stream, CompressionMode.Decompress);
await reader.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error extracting from gz file {File}", originalUrl);
}
}
catch (Exception ex)
else
{
_logger.LogError(ex, "Error extracting from gz file {File}", originalUrl);
await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
}
}
else
{
await stream.CopyToAsync(fileStream, cancellationToken).ConfigureAwait(false);
}

return file;
return file;
}
}

public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
Expand Down
2 changes: 1 addition & 1 deletion Emby.Server.Implementations/LiveTv/LiveTvManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,7 @@ private async Task RefreshChannelsInternal(IProgress<double> progress, Cancellat
progress.Report(100);
}

private async Task<Tuple<List<Guid>, List<Guid>>> RefreshChannelsInternal(ILiveTvService service, IProgress<double> progress, CancellationToken cancellationToken)
private async Task<Tuple<List<Guid>, List<Guid>>> RefreshChannelsInternal(ILiveTvService service, ActionableProgress<double> progress, CancellationToken cancellationToken)
{
progress.Report(10);

Expand Down
25 changes: 16 additions & 9 deletions Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public async Task<List<ChannelInfo>> GetChannels(TunerHostInfo tuner, bool enabl
return list;
}

protected virtual List<TunerHostInfo> GetTunerHosts()
protected virtual IList<TunerHostInfo> GetTunerHosts()
{
return GetConfiguration().TunerHosts
.Where(i => string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase))
Expand Down Expand Up @@ -96,8 +96,11 @@ public async Task<List<ChannelInfo>> GetChannels(bool enableCache, CancellationT
try
{
Directory.CreateDirectory(Path.GetDirectoryName(channelCacheFile));
await using var writeStream = AsyncFile.OpenWrite(channelCacheFile);
await JsonSerializer.SerializeAsync(writeStream, channels, cancellationToken: cancellationToken).ConfigureAwait(false);
var writeStream = AsyncFile.OpenWrite(channelCacheFile);
await using (writeStream.ConfigureAwait(false))
{
await JsonSerializer.SerializeAsync(writeStream, channels, cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
catch (IOException)
{
Expand All @@ -112,10 +115,14 @@ public async Task<List<ChannelInfo>> GetChannels(bool enableCache, CancellationT
{
try
{
await using var readStream = AsyncFile.OpenRead(channelCacheFile);
var channels = await JsonSerializer.DeserializeAsync<List<ChannelInfo>>(readStream, cancellationToken: cancellationToken)
.ConfigureAwait(false);
list.AddRange(channels);
var readStream = AsyncFile.OpenRead(channelCacheFile);
await using (readStream.ConfigureAwait(false))
{
var channels = await JsonSerializer
.DeserializeAsync<List<ChannelInfo>>(readStream, cancellationToken: cancellationToken)
.ConfigureAwait(false);
list.AddRange(channels);
}
}
catch (IOException)
{
Expand Down Expand Up @@ -159,9 +166,9 @@ public async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string cha
return new List<MediaSourceInfo>();
}

protected abstract Task<ILiveStream> GetChannelStream(TunerHostInfo tunerHost, ChannelInfo channel, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);
protected abstract Task<ILiveStream> GetChannelStream(TunerHostInfo tunerHost, ChannelInfo channel, string streamId, IList<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);

public async Task<ILiveStream> GetChannelStream(string channelId, string streamId, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
public async Task<ILiveStream> GetChannelStream(string channelId, string streamId, IList<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(channelId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public bool SupportsTranscoding
{
var model = ModelNumber ?? string.Empty;

if (model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1)
if (model.Contains("hdtc", StringComparison.OrdinalIgnoreCase))
{
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSource
return list;
}

protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo tunerHost, ChannelInfo channel, string streamId, List<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;

Expand Down
17 changes: 16 additions & 1 deletion Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,21 @@ public Stream GetStream()
return stream;
}

/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool dispose)
{
if (dispose)
{
LiveStreamCancellationTokenSource?.Dispose();
}
}

protected async Task DeleteTempFiles(string path, int retryCount = 0)
{
if (retryCount == 0)
Expand All @@ -134,7 +149,7 @@ protected async Task DeleteTempFiles(string path, int retryCount = 0)
}
}

private void TrySeek(Stream stream, long offset)
private void TrySeek(FileStream stream, long offset)
{
if (!stream.CanSeek)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationT
return Task.FromResult(list);
}

protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo tunerHost, ChannelInfo channel, string streamId, List<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;

Expand Down
Loading

0 comments on commit 053c339

Please sign in to comment.