From df7eb126ad9853b2df9f4b5125c867f7b17b3fc8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 20 Jun 2014 13:02:34 -0400 Subject: [PATCH] dlna playlist fixes --- MediaBrowser.Dlna/PlayTo/Device.cs | 17 ++++ MediaBrowser.Dlna/PlayTo/PlayToController.cs | 77 ++++++++++++++----- .../PlayTo/PlaybackStoppedEventArgs.cs | 6 ++ 3 files changed, 82 insertions(+), 18 deletions(-) diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs index a9c161c226..72ea1d70e2 100644 --- a/MediaBrowser.Dlna/PlayTo/Device.cs +++ b/MediaBrowser.Dlna/PlayTo/Device.cs @@ -901,6 +901,7 @@ namespace MediaBrowser.Dlna.PlayTo public event EventHandler PlaybackStart; public event EventHandler PlaybackProgress; public event EventHandler PlaybackStopped; + public event EventHandler MediaChanged; public uBaseObject CurrentMediaInfo { get; private set; } @@ -918,6 +919,10 @@ namespace MediaBrowser.Dlna.PlayTo OnPlaybackStart(mediaInfo); } } + else if (mediaInfo != null && previousMediaInfo != null && !mediaInfo.Equals(previousMediaInfo)) + { + OnMediaChanged(previousMediaInfo, mediaInfo); + } else if (mediaInfo == null && previousMediaInfo != null) { OnPlaybackStop(previousMediaInfo); @@ -961,6 +966,18 @@ namespace MediaBrowser.Dlna.PlayTo } } + private void OnMediaChanged(uBaseObject old, uBaseObject newMedia) + { + if (MediaChanged != null) + { + MediaChanged.Invoke(this, new MediaChangedEventArgs + { + OldMediaInfo = old, + NewMediaInfo = newMedia + }); + } + } + #region IDisposable bool _disposed; diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs index 7a46a1f643..2a58ad8d6b 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs @@ -72,6 +72,7 @@ namespace MediaBrowser.Dlna.PlayTo _device.PlaybackStart += _device_PlaybackStart; _device.PlaybackProgress += _device_PlaybackProgress; _device.PlaybackStopped += _device_PlaybackStopped; + _device.MediaChanged += _device_MediaChanged; _device.Start(); _ssdpHandler.MessageReceived += _SsdpHandler_MessageReceived; @@ -131,25 +132,38 @@ namespace MediaBrowser.Dlna.PlayTo } } + void _device_MediaChanged(object sender, MediaChangedEventArgs e) + { + var streamInfo = StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager); + var progress = GetProgressInfo(e.OldMediaInfo, streamInfo); + + var positionTicks = progress.PositionTicks; + + ReportPlaybackStopped(e.OldMediaInfo, streamInfo, positionTicks); + } + async void _device_PlaybackStopped(object sender, PlaybackStoppedEventArgs e) { - try - { - await _sessionManager.OnPlaybackStopped(new PlaybackStopInfo - { - ItemId = e.MediaInfo.Id, - SessionId = _session.Id, - PositionTicks = _device.Position.Ticks + var streamInfo = StreamParams.ParseFromUrl(e.MediaInfo.Url, _libraryManager); + var progress = GetProgressInfo(e.MediaInfo, streamInfo); - }).ConfigureAwait(false); - } - catch (Exception ex) + var positionTicks = progress.PositionTicks; + + ReportPlaybackStopped(e.MediaInfo, streamInfo, positionTicks); + + var duration = streamInfo.MediaSource == null ? + (_device.Duration == null ? (long?)null : _device.Duration.Value.Ticks) : + streamInfo.MediaSource.RunTimeTicks; + + var playedToCompletion = (positionTicks.HasValue && positionTicks.Value == 0); + + if (!playedToCompletion && duration.HasValue && positionTicks.HasValue) { - _logger.ErrorException("Error reporting progress", ex); - } + double percent = positionTicks.Value; + percent /= duration.Value; - var playedToCompletion = _device.Position.Ticks == 0 || - (_device.Duration.HasValue && _device.Position.Ticks >= _device.Duration.Value.Ticks); + playedToCompletion = Math.Abs(1 - percent) <= .1; + } if (playedToCompletion) { @@ -161,6 +175,25 @@ namespace MediaBrowser.Dlna.PlayTo } } + private async void ReportPlaybackStopped(uBaseObject mediaInfo, StreamParams streamInfo, long? positionTicks) + { + try + { + await _sessionManager.OnPlaybackStopped(new PlaybackStopInfo + { + ItemId = mediaInfo.Id, + SessionId = _session.Id, + PositionTicks = positionTicks, + MediaSourceId = streamInfo.MediaSourceId + + }).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error reporting progress", ex); + } + } + async void _device_PlaybackStart(object sender, PlaybackStartEventArgs e) { var info = GetProgressInfo(e.MediaInfo); @@ -191,10 +224,15 @@ namespace MediaBrowser.Dlna.PlayTo private PlaybackStartInfo GetProgressInfo(uBaseObject mediaInfo) { - var ticks = _device.Position.Ticks; - var info = StreamParams.ParseFromUrl(mediaInfo.Url, _libraryManager); + return GetProgressInfo(mediaInfo, info); + } + + private PlaybackStartInfo GetProgressInfo(uBaseObject mediaInfo, StreamParams info) + { + var ticks = _device.Position.Ticks; + if (!info.IsDirectStream) { ticks += info.StartPositionTicks; @@ -573,6 +611,7 @@ namespace MediaBrowser.Dlna.PlayTo _device.PlaybackStart -= _device_PlaybackStart; _device.PlaybackProgress -= _device_PlaybackProgress; _device.PlaybackStopped -= _device_PlaybackStopped; + _device.MediaChanged -= _device_MediaChanged; _ssdpHandler.MessageReceived -= _SsdpHandler_MessageReceived; DisposeUpdateTimer(); @@ -679,10 +718,11 @@ namespace MediaBrowser.Dlna.PlayTo if (media != null) { var info = StreamParams.ParseFromUrl(media.Url, _libraryManager); + var progress = GetProgressInfo(media, info); if (info.Item != null && !info.IsDirectStream) { - var newPosition = _device.Position.Ticks; + var newPosition = progress.PositionTicks ?? 0; var user = _session.UserId.HasValue ? _userManager.GetUserById(_session.UserId.Value) : null; var newItem = CreatePlaylistItem(info.Item, user, newPosition, GetServerAddress(), info.MediaSourceId, newIndex, info.SubtitleStreamIndex); @@ -704,10 +744,11 @@ namespace MediaBrowser.Dlna.PlayTo if (media != null) { var info = StreamParams.ParseFromUrl(media.Url, _libraryManager); + var progress = GetProgressInfo(media, info); if (info.Item != null && !info.IsDirectStream) { - var newPosition = _device.Position.Ticks; + var newPosition = progress.PositionTicks ?? 0; var user = _session.UserId.HasValue ? _userManager.GetUserById(_session.UserId.Value) : null; var newItem = CreatePlaylistItem(info.Item, user, newPosition, GetServerAddress(), info.MediaSourceId, info.AudioStreamIndex, newIndex); diff --git a/MediaBrowser.Dlna/PlayTo/PlaybackStoppedEventArgs.cs b/MediaBrowser.Dlna/PlayTo/PlaybackStoppedEventArgs.cs index aac08cd6f0..5cf89a5bb1 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaybackStoppedEventArgs.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaybackStoppedEventArgs.cs @@ -6,4 +6,10 @@ namespace MediaBrowser.Dlna.PlayTo { public uBaseObject MediaInfo { get; set; } } + + public class MediaChangedEventArgs : EventArgs + { + public uBaseObject OldMediaInfo { get; set; } + public uBaseObject NewMediaInfo { get; set; } + } } \ No newline at end of file