diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2015-04-04 15:35:29 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2015-04-04 15:35:29 -0400 |
| commit | 2b7a80cfb5b9212260734c095a5b3439af7d64e2 (patch) | |
| tree | ab746cd05a2244b4c8c8432a30090b85c9d4d986 /MediaBrowser.Server.Implementations | |
| parent | 8c61abf6d23510da8eaddf3894f9e14f88dc5f22 (diff) | |
improve direct play of live streams
Diffstat (limited to 'MediaBrowser.Server.Implementations')
| -rw-r--r-- | MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs | 81 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs | 4 |
2 files changed, 80 insertions, 5 deletions
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index d549cad46..18cc172cc 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; @@ -18,12 +19,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv private readonly IJsonSerializer _jsonSerializer; private readonly ILogger _logger; private readonly IMediaSourceManager _mediaSourceManager; + private readonly IMediaEncoder _mediaEncoder; - public LiveTvMediaSourceProvider(ILiveTvManager liveTvManager, IJsonSerializer jsonSerializer, ILogManager logManager, IMediaSourceManager mediaSourceManager) + public LiveTvMediaSourceProvider(ILiveTvManager liveTvManager, IJsonSerializer jsonSerializer, ILogManager logManager, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder) { _liveTvManager = liveTvManager; _jsonSerializer = jsonSerializer; _mediaSourceManager = mediaSourceManager; + _mediaEncoder = mediaEncoder; _logger = logManager.GetLogger(GetType().Name); } @@ -90,14 +93,86 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task<MediaSourceInfo> OpenMediaSource(string openToken, CancellationToken cancellationToken) { + MediaSourceInfo stream; + var isAudio = false; + var keys = openToken.Split(new[] { '|' }, 2); if (string.Equals(keys[0], typeof(LiveTvChannel).Name, StringComparison.OrdinalIgnoreCase)) { - return await _liveTvManager.GetChannelStream(keys[1], cancellationToken).ConfigureAwait(false); + stream = await _liveTvManager.GetChannelStream(keys[1], cancellationToken).ConfigureAwait(false); + } + else + { + stream = await _liveTvManager.GetRecordingStream(keys[1], cancellationToken).ConfigureAwait(false); + } + + try + { + await AddMediaInfo(stream, isAudio, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error probing live tv stream", ex); + } + + return stream; + } + + private async Task AddMediaInfo(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken) + { + var inputPaths = new[] { mediaSource.Path }; + + var info = await _mediaEncoder.GetMediaInfo(inputPaths, mediaSource.Path, mediaSource.Protocol, isAudio, 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; + + 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; } - return await _liveTvManager.GetRecordingStream(keys[1], cancellationToken).ConfigureAwait(false); + // Try to estimate this + if (!mediaSource.Bitrate.HasValue) + { + var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Video); + if (videoStream != null) + { + var width = videoStream.Width ?? 1920; + + if (width >= 1900) + { + mediaSource.Bitrate = 10000000; + } + + else if (width >= 1260) + { + mediaSource.Bitrate = 6000000; + } + + else if (width >= 700) + { + mediaSource.Bitrate = 4000000; + } + } + } } public Task CloseMediaSource(string liveStreamId, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 185c3464e..d8fc425d1 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -493,7 +493,7 @@ namespace MediaBrowser.Server.Implementations.Sync conversionOptions.ItemId = item.Id.ToString("N"); conversionOptions.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList(); - var streamInfo = new StreamBuilder().BuildVideoItem(conversionOptions); + var streamInfo = new StreamBuilder(_logger).BuildVideoItem(conversionOptions); var mediaSource = streamInfo.MediaSource; // No sense creating external subs if we're already burning one into the video @@ -690,7 +690,7 @@ namespace MediaBrowser.Server.Implementations.Sync conversionOptions.ItemId = item.Id.ToString("N"); conversionOptions.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList(); - var streamInfo = new StreamBuilder().BuildAudioItem(conversionOptions); + var streamInfo = new StreamBuilder(_logger).BuildAudioItem(conversionOptions); var mediaSource = streamInfo.MediaSource; jobItem.MediaSourceId = streamInfo.MediaSourceId; |
