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.Logging; namespace Emby.Server.Implementations.LiveTv { public class LiveStreamHelper { private readonly IMediaEncoder _mediaEncoder; private readonly ILogger _logger; public LiveStreamHelper(IMediaEncoder mediaEncoder, ILogger logger) { _mediaEncoder = mediaEncoder; _logger = logger; } public async Task AddMediaInfoWithProbe(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken) { var originalRuntime = mediaSource.RunTimeTicks; var now = DateTime.UtcNow; var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest { InputPath = mediaSource.Path, Protocol = mediaSource.Protocol, MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video, ExtractChapters = false, AnalyzeDurationSections = 3 }, cancellationToken).ConfigureAwait(false); _logger.Info("Live tv media info probe took {0} seconds", (DateTime.UtcNow - now).TotalSeconds.ToString(CultureInfo.InvariantCulture)); mediaSource.Bitrate = info.Bitrate; mediaSource.Container = info.Container; mediaSource.Formats = info.Formats; mediaSource.MediaStreams = info.MediaStreams; mediaSource.RunTimeTicks = info.RunTimeTicks; mediaSource.Size = info.Size; mediaSource.Timestamp = info.Timestamp; mediaSource.Video3DFormat = info.Video3DFormat; mediaSource.VideoType = info.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 = mediaSource.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 = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaBrowser.Model.Entities.MediaStreamType.Video); if (videoStream != null) { if (!videoStream.BitRate.HasValue) { var width = videoStream.Width ?? 1920; if (width >= 1900) { videoStream.BitRate = 8000000; } else if (width >= 1260) { videoStream.BitRate = 3000000; } else if (width >= 700) { videoStream.BitRate = 1000000; } } // This is coming up false and preventing stream copy videoStream.IsAVC = null; } // Try to estimate this if (!mediaSource.Bitrate.HasValue) { var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum(); if (total > 0) { mediaSource.Bitrate = total; } } } } }