diff options
| author | stefan <stefan@hegedues.at> | 2018-09-12 19:26:21 +0200 |
|---|---|---|
| committer | stefan <stefan@hegedues.at> | 2018-09-12 19:26:21 +0200 |
| commit | 48facb797ed912e4ea6b04b17d1ff190ac2daac4 (patch) | |
| tree | 8dae77a31670a888d733484cb17dd4077d5444e8 /Emby.Server.Implementations/Library/LiveStreamHelper.cs | |
| parent | c32d8656382a0eacb301692e0084377fc433ae9b (diff) | |
Update to 3.5.2 and .net core 2.1
Diffstat (limited to 'Emby.Server.Implementations/Library/LiveStreamHelper.cs')
| -rw-r--r-- | Emby.Server.Implementations/Library/LiveStreamHelper.cs | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/Library/LiveStreamHelper.cs b/Emby.Server.Implementations/Library/LiveStreamHelper.cs new file mode 100644 index 000000000..e027e133f --- /dev/null +++ b/Emby.Server.Implementations/Library/LiveStreamHelper.cs @@ -0,0 +1,181 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.MediaInfo; +using System.Collections.Generic; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Common.Configuration; +using System.IO; +using MediaBrowser.Common.Extensions; + +namespace Emby.Server.Implementations.Library +{ + public class LiveStreamHelper + { + private readonly IMediaEncoder _mediaEncoder; + private readonly ILogger _logger; + + private IJsonSerializer _json; + private IApplicationPaths _appPaths; + + public LiveStreamHelper(IMediaEncoder mediaEncoder, ILogger logger, IJsonSerializer json, IApplicationPaths appPaths) + { + _mediaEncoder = mediaEncoder; + _logger = logger; + _json = json; + _appPaths = appPaths; + } + + public async Task AddMediaInfoWithProbe(MediaSourceInfo mediaSource, bool isAudio, string cacheKey, bool addProbeDelay, CancellationToken cancellationToken) + { + var originalRuntime = mediaSource.RunTimeTicks; + + var now = DateTime.UtcNow; + + MediaInfo mediaInfo = null; + var cacheFilePath = string.IsNullOrEmpty(cacheKey) ? null : Path.Combine(_appPaths.CachePath, "mediainfo", cacheKey.GetMD5().ToString("N") + ".json"); + + if (!string.IsNullOrEmpty(cacheKey)) + { + try + { + mediaInfo = _json.DeserializeFromFile<MediaInfo>(cacheFilePath); + + //_logger.Debug("Found cached media info"); + } + catch + { + } + } + + if (mediaInfo == null) + { + if (addProbeDelay) + { + var delayMs = mediaSource.AnalyzeDurationMs ?? 0; + delayMs = Math.Max(3000, delayMs); + if (delayMs > 0) + { + _logger.Info("Waiting {0}ms before probing the live stream", delayMs); + await Task.Delay(delayMs, cancellationToken).ConfigureAwait(false); + } + } + + mediaSource.AnalyzeDurationMs = 3000; + + mediaInfo = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest + { + MediaSource = mediaSource, + MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video, + ExtractChapters = false + + }, cancellationToken).ConfigureAwait(false); + + if (cacheFilePath != null) + { + Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); + _json.SerializeToFile(mediaInfo, cacheFilePath); + + //_logger.Debug("Saved media info to {0}", cacheFilePath); + } + } + + var mediaStreams = mediaInfo.MediaStreams; + + if (!string.IsNullOrEmpty(cacheKey)) + { + var newList = new List<MediaStream>(); + newList.AddRange(mediaStreams.Where(i => i.Type == MediaStreamType.Video).Take(1)); + newList.AddRange(mediaStreams.Where(i => i.Type == MediaStreamType.Audio).Take(1)); + + foreach (var stream in newList) + { + stream.Index = -1; + stream.Language = null; + } + + mediaStreams = newList; + } + + _logger.Info("Live tv media info probe took {0} seconds", (DateTime.UtcNow - now).TotalSeconds.ToString(CultureInfo.InvariantCulture)); + + mediaSource.Bitrate = mediaInfo.Bitrate; + mediaSource.Container = mediaInfo.Container; + mediaSource.Formats = mediaInfo.Formats; + mediaSource.MediaStreams = mediaStreams; + mediaSource.RunTimeTicks = mediaInfo.RunTimeTicks; + mediaSource.Size = mediaInfo.Size; + mediaSource.Timestamp = mediaInfo.Timestamp; + mediaSource.Video3DFormat = mediaInfo.Video3DFormat; + mediaSource.VideoType = mediaInfo.VideoType; + + mediaSource.DefaultSubtitleStreamIndex = null; + + // Null this out so that it will be treated like a live stream + if (!originalRuntime.HasValue) + { + mediaSource.RunTimeTicks = null; + } + + var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaBrowser.Model.Entities.MediaStreamType.Audio); + + if (audioStream == null || audioStream.Index == -1) + { + mediaSource.DefaultAudioStreamIndex = null; + } + else + { + mediaSource.DefaultAudioStreamIndex = audioStream.Index; + } + + var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaBrowser.Model.Entities.MediaStreamType.Video); + if (videoStream != null) + { + if (!videoStream.BitRate.HasValue) + { + var width = videoStream.Width ?? 1920; + + if (width >= 3000) + { + videoStream.BitRate = 30000000; + } + + else if (width >= 1900) + { + videoStream.BitRate = 20000000; + } + + else if (width >= 1200) + { + videoStream.BitRate = 8000000; + } + + else if (width >= 700) + { + videoStream.BitRate = 2000000; + } + } + + // This is coming up false and preventing stream copy + videoStream.IsAVC = null; + } + + mediaSource.AnalyzeDurationMs = 3000; + + // Try to estimate this + mediaSource.InferTotalBitrate(true); + } + + public Task AddMediaInfoWithProbe(MediaSourceInfo mediaSource, bool isAudio, bool addProbeDelay, CancellationToken cancellationToken) + { + return AddMediaInfoWithProbe(mediaSource, isAudio, null, addProbeDelay, cancellationToken); + } + } +} |
