diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index bfaa1f289c..d7af675aa0 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -312,31 +312,6 @@ namespace MediaBrowser.Api.Playback.Hls return 0; } - protected override bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) - { - if (videoStream.KeyFrames == null || videoStream.KeyFrames.Count == 0) - { - Logger.Debug("Cannot stream copy video due to missing keyframe info"); - return false; - } - - var previousSegment = 0; - foreach (var frame in videoStream.KeyFrames) - { - var length = frame - previousSegment; - - // Don't allow really long segments because this could result in long download times - if (length > 10000) - { - Logger.Debug("Cannot stream copy video due to long segment length of {0}ms", length); - return false; - } - previousSegment = frame; - } - - return base.CanStreamCopyVideo(request, videoStream); - } - protected override bool CanStreamCopyAudio(VideoStreamRequest request, MediaStream audioStream, List supportedAudioCodecs) { return false; diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index cbea1ca0ca..0353508f10 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -960,5 +960,30 @@ namespace MediaBrowser.Api.Playback.Hls { return isOutputVideo ? ".ts" : ".ts"; } + + protected override bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream) + { + if (videoStream.KeyFrames == null || videoStream.KeyFrames.Count == 0) + { + Logger.Debug("Cannot stream copy video due to missing keyframe info"); + return false; + } + + var previousSegment = 0; + foreach (var frame in videoStream.KeyFrames) + { + var length = frame - previousSegment; + + // Don't allow really long segments because this could result in long download times + if (length > 10000) + { + Logger.Debug("Cannot stream copy video due to long segment length of {0}ms", length); + return false; + } + previousSegment = frame; + } + + return base.CanStreamCopyVideo(request, videoStream); + } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 1786d14e47..c5edb212b4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -8,7 +8,9 @@ using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.FileOrganization; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; @@ -47,10 +49,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private readonly ILibraryManager _libraryManager; private readonly IProviderManager _providerManager; private readonly IFileOrganizationService _organizationService; + private readonly IMediaEncoder _mediaEncoder; public static EmbyTV Current; - public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ISecurityManager security, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService) + public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ISecurityManager security, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder) { Current = this; @@ -64,6 +67,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _libraryMonitor = libraryMonitor; _providerManager = providerManager; _organizationService = organizationService; + _mediaEncoder = mediaEncoder; _liveTvManager = (LiveTvManager)liveTvManager; _jsonSerializer = jsonSerializer; @@ -428,6 +432,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (mediaSourceInfo != null) { + await AddMediaInfo(mediaSourceInfo, false, cancellationToken).ConfigureAwait(false); + mediaSourceInfo.Id = Guid.NewGuid().ToString("N"); return mediaSourceInfo; } @@ -458,6 +464,84 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV throw new NotImplementedException(); } + private async Task AddMediaInfo(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken) + { + var originalRuntime = mediaSource.RunTimeTicks; + + var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest + { + InputPath = mediaSource.Path, + Protocol = mediaSource.Protocol, + MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video, + ExtractChapters = false + + }, cancellationToken).ConfigureAwait(false); + + 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 == 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 == 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; + } + } + } + + // Try to estimate this + if (!mediaSource.Bitrate.HasValue) + { + var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum(); + + if (total > 0) + { + mediaSource.Bitrate = total; + } + } + } + public Task> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken) { throw new NotImplementedException(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index d53c081500..b96aa52264 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -216,20 +216,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings // Helper.logger.Info("Modifyin channel " + channel.Number); if (_channelPair.ContainsKey(channel.Number)) { - string channelName; if (_channelPair[channel.Number].logo != null) { channel.ImageUrl = _channelPair[channel.Number].logo.URL; channel.HasImage = true; } - if (_channelPair[channel.Number].affiliate != null) - { - channelName = _channelPair[channel.Number].affiliate; - } - else - { - channelName = _channelPair[channel.Number].name; - } + string channelName = _channelPair[channel.Number].name; channel.Name = channelName; } else diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index bccb0db0a0..02b3080e47 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -325,8 +325,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun BitRate = 128000 } }, - RequiresOpening = false, - RequiresClosing = false, + RequiresOpening = true, + RequiresClosing = true, BufferMs = 1000, Container = "ts", Id = profile