DirectRecorder.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using System;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4. using MediaBrowser.Common.Net;
  5. using MediaBrowser.Controller.Library;
  6. using MediaBrowser.Model.Dto;
  7. using MediaBrowser.Model.IO;
  8. using Microsoft.Extensions.Logging;
  9. namespace Emby.Server.Implementations.LiveTv.EmbyTV
  10. {
  11. public class DirectRecorder : IRecorder
  12. {
  13. private readonly ILogger _logger;
  14. private readonly IHttpClient _httpClient;
  15. private readonly IFileSystem _fileSystem;
  16. private readonly IStreamHelper _streamHelper;
  17. public DirectRecorder(ILogger logger, IHttpClient httpClient, IFileSystem fileSystem, IStreamHelper streamHelper)
  18. {
  19. _logger = logger;
  20. _httpClient = httpClient;
  21. _fileSystem = fileSystem;
  22. _streamHelper = streamHelper;
  23. }
  24. public string GetOutputPath(MediaSourceInfo mediaSource, string targetFile)
  25. {
  26. return targetFile;
  27. }
  28. public Task Record(IDirectStreamProvider directStreamProvider, MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
  29. {
  30. if (directStreamProvider != null)
  31. {
  32. return RecordFromDirectStreamProvider(directStreamProvider, targetFile, duration, onStarted, cancellationToken);
  33. }
  34. return RecordFromMediaSource(mediaSource, targetFile, duration, onStarted, cancellationToken);
  35. }
  36. private async Task RecordFromDirectStreamProvider(IDirectStreamProvider directStreamProvider, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
  37. {
  38. _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(targetFile));
  39. using (var output = _fileSystem.GetFileStream(targetFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
  40. {
  41. onStarted();
  42. _logger.LogInformation("Copying recording stream to file {0}", targetFile);
  43. // The media source is infinite so we need to handle stopping ourselves
  44. var durationToken = new CancellationTokenSource(duration);
  45. cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;
  46. await directStreamProvider.CopyToAsync(output, cancellationToken).ConfigureAwait(false);
  47. }
  48. _logger.LogInformation("Recording completed to file {0}", targetFile);
  49. }
  50. private async Task RecordFromMediaSource(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
  51. {
  52. var httpRequestOptions = new HttpRequestOptions
  53. {
  54. Url = mediaSource.Path,
  55. BufferContent = false,
  56. // Some remote urls will expect a user agent to be supplied
  57. UserAgent = "Emby/3.0",
  58. // Shouldn't matter but may cause issues
  59. EnableHttpCompression = false
  60. };
  61. using (var response = await _httpClient.SendAsync(httpRequestOptions, "GET").ConfigureAwait(false))
  62. {
  63. _logger.LogInformation("Opened recording stream from tuner provider");
  64. _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(targetFile));
  65. using (var output = _fileSystem.GetFileStream(targetFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
  66. {
  67. onStarted();
  68. _logger.LogInformation("Copying recording stream to file {0}", targetFile);
  69. // The media source if infinite so we need to handle stopping ourselves
  70. var durationToken = new CancellationTokenSource(duration);
  71. cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;
  72. await _streamHelper.CopyUntilCancelled(response.Content, output, 81920, cancellationToken).ConfigureAwait(false);
  73. }
  74. }
  75. _logger.LogInformation("Recording completed to file {0}", targetFile);
  76. }
  77. }
  78. }