From ad52df6be09837086036e46e89c02084de0b7ba2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 25 Mar 2015 14:29:21 -0400 Subject: re-org scripts --- MediaBrowser.Api/ApiEntryPoint.cs | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'MediaBrowser.Api/ApiEntryPoint.cs') diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index a21fc22fe..a6958b95d 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -274,32 +274,37 @@ namespace MediaBrowser.Api return null; } - job.ActiveRequestCount++; - - job.DisposeKillTimer(); + OnTranscodeBeginRequest(job); return job; } } + public void OnTranscodeBeginRequest(TranscodingJob job) + { + job.ActiveRequestCount++; + + job.DisposeKillTimer(); + } + public void OnTranscodeEndRequest(TranscodingJob job) { job.ActiveRequestCount--; if (job.ActiveRequestCount == 0) { - if (job.Type == TranscodingJobType.Progressive) - { - const int timerDuration = 1000; + // TODO: Lower this hls timeout + var timerDuration = job.Type == TranscodingJobType.Progressive ? + 1000 : + 14400000; - if (job.KillTimer == null) - { - job.KillTimer = new Timer(OnTranscodeKillTimerStopped, job, timerDuration, Timeout.Infinite); - } - else - { - job.KillTimer.Change(timerDuration, Timeout.Infinite); - } + if (job.KillTimer == null) + { + job.KillTimer = new Timer(OnTranscodeKillTimerStopped, job, timerDuration, Timeout.Infinite); + } + else + { + job.KillTimer.Change(timerDuration, Timeout.Infinite); } } } @@ -498,7 +503,7 @@ namespace MediaBrowser.Api .ToList(); Exception e = null; - + foreach (var file in filesToDelete) { try -- cgit v1.2.3 From dd8dd1938a990d9c4c9bac384665dc9d82c4bc35 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 Mar 2015 14:16:40 -0400 Subject: update live stream generation --- MediaBrowser.Api/ApiEntryPoint.cs | 2 +- MediaBrowser.Api/Playback/BaseStreamingService.cs | 4 ++++ MediaBrowser.Controller/LiveTv/LiveTvChannel.cs | 9 ++++++++ MediaBrowser.Model/ApiClient/IApiClient.cs | 7 +++++++ MediaBrowser.Model/Dlna/StreamInfo.cs | 3 +++ MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs | 19 +++++++++++++++++ MediaBrowser.Model/Session/PlaybackProgressInfo.cs | 5 +++++ MediaBrowser.Model/Session/PlaybackStopInfo.cs | 5 +++++ .../LiveTv/LiveTvManager.cs | 12 +++++++++-- .../Session/SessionManager.cs | 24 ++++++++++++++++++++++ Nuget/MediaBrowser.Common.Internal.nuspec | 4 ++-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 ++-- 14 files changed, 93 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Api/ApiEntryPoint.cs') diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index a6958b95d..9f4ad5893 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -187,7 +187,7 @@ namespace MediaBrowser.Api if (!string.IsNullOrWhiteSpace(deviceId)) { - var audioCodec = state.ActualOutputVideoCodec; + var audioCodec = state.ActualOutputAudioCodec; var videoCodec = state.ActualOutputVideoCodec; _sessionManager.ReportTranscodingInfo(deviceId, new TranscodingInfo diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 5a4cdaaa9..34c5e5f7c 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1513,6 +1513,10 @@ namespace MediaBrowser.Api.Playback { request.StreamId = val; } + else if (i == 22) + { + request.LiveStreamId = val; + } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index 1e13d8f3f..cb10003ed 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -82,6 +82,15 @@ namespace MediaBrowser.Controller.LiveTv /// null if [has image] contains no value, true if [has image]; otherwise, false. public bool? HasProviderImage { get; set; } + public override LocationType LocationType + { + get + { + // TODO: This should be removed + return LocationType.Remote; + } + } + protected override string CreateSortName() { double number = 0; diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 19d6acf33..58af01615 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -1486,5 +1486,12 @@ namespace MediaBrowser.Model.ApiClient /// The query. /// Task<List<RecommendationDto>>. Task> GetMovieRecommendations(MovieRecommendationQuery query); + /// + /// Opens the live stream. + /// + /// The request. + /// The cancellation token. + /// Task<LiveStreamResponse>. + Task OpenLiveStream(LiveStreamRequest request, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 60615d1da..dc2462796 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -210,6 +210,9 @@ namespace MediaBrowser.Model.Dlna list.Add(new NameValuePair("StreamId", streamId ?? string.Empty)); list.Add(new NameValuePair("api_key", accessToken ?? string.Empty)); + string liveStreamId = item.MediaSource == null ? null : item.MediaSource.LiveStreamId; + list.Add(new NameValuePair("LiveStreamId", liveStreamId ?? string.Empty)); + return list; } diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs index 8078219d8..563006a4d 100644 --- a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs +++ b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs @@ -12,5 +12,24 @@ namespace MediaBrowser.Model.MediaInfo public int? SubtitleStreamIndex { get; set; } public string ItemId { get; set; } public DeviceProfile DeviceProfile { get; set; } + + public LiveStreamRequest() + { + + } + + public LiveStreamRequest(AudioOptions options) + { + MaxStreamingBitrate = options.MaxBitrate; + ItemId = options.ItemId; + DeviceProfile = options.Profile; + + VideoOptions videoOptions = options as VideoOptions; + if (videoOptions != null) + { + AudioStreamIndex = videoOptions.AudioStreamIndex; + SubtitleStreamIndex = videoOptions.SubtitleStreamIndex; + } + } } } diff --git a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs index f04dea1ea..a029df4a9 100644 --- a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs +++ b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs @@ -78,5 +78,10 @@ namespace MediaBrowser.Model.Session /// /// The play method. public PlayMethod PlayMethod { get; set; } + /// + /// Gets or sets the live stream identifier. + /// + /// The live stream identifier. + public string LiveStreamId { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Model/Session/PlaybackStopInfo.cs b/MediaBrowser.Model/Session/PlaybackStopInfo.cs index 38025f183..a3bdc9a96 100644 --- a/MediaBrowser.Model/Session/PlaybackStopInfo.cs +++ b/MediaBrowser.Model/Session/PlaybackStopInfo.cs @@ -36,5 +36,10 @@ namespace MediaBrowser.Model.Session /// /// The position ticks. public long? PositionTicks { get; set; } + /// + /// Gets or sets the live stream identifier. + /// + /// The live stream identifier. + public string LiveStreamId { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 86b31e0e5..b30db6092 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -356,7 +356,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv _logger.Info("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId); info = await service.GetChannelStream(channel.ExternalId, null, cancellationToken).ConfigureAwait(false); info.RequiresClosing = true; - info.LiveStreamId = info.Id; + + if (info.RequiresClosing) + { + info.LiveStreamId = info.Id; + } } else { @@ -367,7 +371,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.RecordingInfo.Id); info = await service.GetRecordingStream(recording.RecordingInfo.Id, null, cancellationToken).ConfigureAwait(false); info.RequiresClosing = true; - info.LiveStreamId = info.Id; + + if (info.RequiresClosing) + { + info.LiveStreamId = info.Id; + } } _logger.Info("Live stream info: {0}", _jsonSerializer.SerializeToString(info)); diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 16fc42063..cc5aef54a 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -679,6 +679,18 @@ namespace MediaBrowser.Server.Implementations.Session } } + if (!string.IsNullOrWhiteSpace(info.LiveStreamId)) + { + try + { + await _mediaSourceManager.PingLiveStream(info.LiveStreamId, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error closing live stream", ex); + } + } + EventHelper.FireEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs { Item = libraryItem, @@ -769,6 +781,18 @@ namespace MediaBrowser.Server.Implementations.Session } } + if (!string.IsNullOrWhiteSpace(info.LiveStreamId)) + { + try + { + await _mediaSourceManager.CloseLiveStream(info.LiveStreamId, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error closing live stream", ex); + } + } + EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs { Item = libraryItem, diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index e1659bfb2..ee3bdd2b6 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.603 + 3.0.606 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption. Copyright © Emby 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 294bc519e..a8f3ea1f3 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.603 + 3.0.606 MediaBrowser.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index bcbd1d5be..7bd4a090d 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.603 + 3.0.606 MediaBrowser.Model - Signed Edition Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index ee3925db5..3f39ace9d 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.603 + 3.0.606 Media Browser.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - + -- cgit v1.2.3 From 10b9a865b7baed2fb83ec7a71e0524ffe80ea609 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 Mar 2015 14:31:28 -0400 Subject: update live stream handling --- MediaBrowser.Api/ApiEntryPoint.cs | 18 +++++++++--------- MediaBrowser.Api/Playback/BaseStreamingService.cs | 6 +++--- MediaBrowser.Api/Playback/Dash/MpegDashService.cs | 2 +- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 2 +- MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs | 6 +++--- MediaBrowser.Api/Playback/MediaInfoService.cs | 2 +- MediaBrowser.Api/Playback/StreamRequest.cs | 2 +- MediaBrowser.Model/Dlna/StreamInfo.cs | 4 ++-- MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs | 6 +++--- Nuget/MediaBrowser.Common.Internal.nuspec | 4 ++-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 ++-- 13 files changed, 30 insertions(+), 30 deletions(-) (limited to 'MediaBrowser.Api/ApiEntryPoint.cs') diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 9f4ad5893..444977e35 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -132,7 +132,7 @@ namespace MediaBrowser.Api /// Called when [transcode beginning]. /// /// The path. - /// The stream identifier. + /// The play session identifier. /// The transcoding job identifier. /// The type. /// The process. @@ -141,7 +141,7 @@ namespace MediaBrowser.Api /// The cancellation token source. /// TranscodingJob. public TranscodingJob OnTranscodeBeginning(string path, - string streamId, + string playSessionId, string transcodingJobId, TranscodingJobType type, Process process, @@ -160,7 +160,7 @@ namespace MediaBrowser.Api DeviceId = deviceId, CancellationTokenSource = cancellationTokenSource, Id = transcodingJobId, - StreamId = streamId + PlaySessionId = playSessionId }; _activeTranscodingJobs.Add(job); @@ -324,10 +324,10 @@ namespace MediaBrowser.Api /// Kills the single transcoding job. /// /// The device id. - /// The stream identifier. + /// The play session identifier. /// The delete files. /// Task. - internal void KillTranscodingJobs(string deviceId, string streamId, Func deleteFiles) + internal void KillTranscodingJobs(string deviceId, string playSessionId, Func deleteFiles) { if (string.IsNullOrEmpty(deviceId)) { @@ -338,7 +338,7 @@ namespace MediaBrowser.Api { if (string.Equals(deviceId, j.DeviceId, StringComparison.OrdinalIgnoreCase)) { - return string.IsNullOrWhiteSpace(streamId) || string.Equals(streamId, j.StreamId, StringComparison.OrdinalIgnoreCase); + return string.IsNullOrWhiteSpace(playSessionId) || string.Equals(playSessionId, j.PlaySessionId, StringComparison.OrdinalIgnoreCase); } return false; @@ -539,10 +539,10 @@ namespace MediaBrowser.Api public class TranscodingJob { /// - /// Gets or sets the stream identifier. + /// Gets or sets the play session identifier. /// - /// The stream identifier. - public string StreamId { get; set; } + /// The play session identifier. + public string PlaySessionId { get; set; } /// /// Gets or sets the path. /// diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 34c5e5f7c..c4cdfc9ed 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -126,7 +126,7 @@ namespace MediaBrowser.Api.Playback var data = GetCommandLineArguments("dummy\\dummy", state, false); data += "-" + (state.Request.DeviceId ?? string.Empty); - data += "-" + (state.Request.StreamId ?? string.Empty); + data += "-" + (state.Request.PlaySessionId ?? string.Empty); data += "-" + (state.Request.ClientTime ?? string.Empty); var dataHash = data.GetMD5().ToString("N"); @@ -1009,7 +1009,7 @@ namespace MediaBrowser.Api.Playback } var transcodingJob = ApiEntryPoint.Instance.OnTranscodeBeginning(outputPath, - state.Request.StreamId, + state.Request.PlaySessionId, transcodingId, TranscodingJobType, process, @@ -1511,7 +1511,7 @@ namespace MediaBrowser.Api.Playback } else if (i == 21) { - request.StreamId = val; + request.PlaySessionId = val; } else if (i == 22) { diff --git a/MediaBrowser.Api/Playback/Dash/MpegDashService.cs b/MediaBrowser.Api/Playback/Dash/MpegDashService.cs index 692e8d4e7..ba3f17257 100644 --- a/MediaBrowser.Api/Playback/Dash/MpegDashService.cs +++ b/MediaBrowser.Api/Playback/Dash/MpegDashService.cs @@ -160,7 +160,7 @@ namespace MediaBrowser.Api.Playback.Dash // If the playlist doesn't already exist, startup ffmpeg try { - ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.StreamId, p => false); + ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.PlaySessionId, p => false); if (currentTranscodingIndex.HasValue) { diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 4f7c0444b..4f043d321 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -135,7 +135,7 @@ namespace MediaBrowser.Api.Playback.Hls // If the playlist doesn't already exist, startup ffmpeg try { - ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.StreamId, p => false); + ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.PlaySessionId, p => false); if (currentTranscodingIndex.HasValue) { diff --git a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs index 1fe0661d9..5d8c67abe 100644 --- a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs +++ b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs @@ -54,8 +54,8 @@ namespace MediaBrowser.Api.Playback.Hls [ApiMember(Name = "DeviceId", Description = "The device id of the client requesting. Used to stop encoding processes when needed.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")] public string DeviceId { get; set; } - [ApiMember(Name = "StreamId", Description = "The stream id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")] - public string StreamId { get; set; } + [ApiMember(Name = "PlaySessionId", Description = "The play session id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")] + public string PlaySessionId { get; set; } } /// @@ -95,7 +95,7 @@ namespace MediaBrowser.Api.Playback.Hls public void Delete(StopEncodingProcess request) { - ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.StreamId, path => true); + ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.PlaySessionId, path => true); } /// diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index 6f8c2cc50..c6678d1ed 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -194,7 +194,7 @@ namespace MediaBrowser.Api.Playback } else { - result.StreamId = Guid.NewGuid().ToString("N"); + result.PlaySessionId = Guid.NewGuid().ToString("N"); } return result; diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs index 7ed4fcd96..75242e604 100644 --- a/MediaBrowser.Api/Playback/StreamRequest.cs +++ b/MediaBrowser.Api/Playback/StreamRequest.cs @@ -71,7 +71,7 @@ namespace MediaBrowser.Api.Playback public string Params { get; set; } public string ClientTime { get; set; } - public string StreamId { get; set; } + public string PlaySessionId { get; set; } public string LiveStreamId { get; set; } } diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index dc2462796..12319a122 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -206,8 +206,8 @@ namespace MediaBrowser.Model.Dlna list.Add(new NameValuePair("Profile", item.VideoProfile ?? string.Empty)); list.Add(new NameValuePair("Cabac", item.Cabac.HasValue ? item.Cabac.Value.ToString() : string.Empty)); - string streamId = item.PlaybackInfo == null ? null : item.PlaybackInfo.StreamId; - list.Add(new NameValuePair("StreamId", streamId ?? string.Empty)); + string playSessionId = item.PlaybackInfo == null ? null : item.PlaybackInfo.PlaySessionId; + list.Add(new NameValuePair("PlaySessionId", playSessionId ?? string.Empty)); list.Add(new NameValuePair("api_key", accessToken ?? string.Empty)); string liveStreamId = item.MediaSource == null ? null : item.MediaSource.LiveStreamId; diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs index ed0824e8a..1f8936d01 100644 --- a/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs +++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs @@ -13,10 +13,10 @@ namespace MediaBrowser.Model.MediaInfo public List MediaSources { get; set; } /// - /// Gets or sets the stream identifier. + /// Gets or sets the play session identifier. /// - /// The stream identifier. - public string StreamId { get; set; } + /// The play session identifier. + public string PlaySessionId { get; set; } /// /// Gets or sets the error code. diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index ee3bdd2b6..57a1db722 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.606 + 3.0.607 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption. Copyright © Emby 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index a8f3ea1f3..9ad9c18ca 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.606 + 3.0.607 MediaBrowser.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 7bd4a090d..261ddd37d 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.606 + 3.0.607 MediaBrowser.Model - Signed Edition Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 3f39ace9d..49a38aaeb 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.606 + 3.0.607 Media Browser.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - + -- cgit v1.2.3 From 07de09f350ab5ba089a27d94cc10b1a8e6f0a700 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 30 Mar 2015 15:57:37 -0400 Subject: sync updates --- MediaBrowser.Api/ApiEntryPoint.cs | 2 +- MediaBrowser.Api/Playback/MediaInfoService.cs | 38 ++++++++- MediaBrowser.Dlna/Didl/DidlBuilder.cs | 7 +- MediaBrowser.Model/Dlna/StreamInfo.cs | 96 ++++++++-------------- MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs | 1 + MediaBrowser.Model/Entities/MediaStream.cs | 14 +++- .../Sync/CloudSyncProfile.cs | 5 ++ .../Sync/SyncJobProcessor.cs | 2 +- .../Sync/SyncManager.cs | 2 +- 9 files changed, 97 insertions(+), 70 deletions(-) (limited to 'MediaBrowser.Api/ApiEntryPoint.cs') diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 444977e35..08ac5671d 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -296,7 +296,7 @@ namespace MediaBrowser.Api // TODO: Lower this hls timeout var timerDuration = job.Type == TranscodingJobType.Progressive ? 1000 : - 14400000; + 7200000; if (job.KillTimer == null) { diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index b833dd735..6eba19545 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -272,6 +272,11 @@ namespace MediaBrowser.Api.Playback // Set this back to what it was mediaSource.SupportsDirectStream = supportsDirectStream; + + if (streamInfo != null) + { + SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); + } } if (mediaSource.SupportsDirectStream) @@ -285,6 +290,11 @@ namespace MediaBrowser.Api.Playback { mediaSource.SupportsDirectStream = false; } + + if (streamInfo != null) + { + SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); + } } if (mediaSource.SupportsTranscoding) @@ -297,10 +307,36 @@ namespace MediaBrowser.Api.Playback if (streamInfo != null && streamInfo.PlayMethod == PlayMethod.Transcode) { streamInfo.StartPositionTicks = startTimeTicks; - mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).Substring(1); + mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-'); mediaSource.TranscodingContainer = streamInfo.Container; mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol; } + + if (streamInfo != null) + { + SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); + } + } + } + + private void SetDeviceSpecificSubtitleInfo(StreamInfo info, MediaSourceInfo mediaSource, string accessToken) + { + var profiles = info.GetSubtitleProfiles(false, "-", accessToken); + + foreach (var profile in profiles) + { + foreach (var stream in mediaSource.MediaStreams) + { + if (stream.Type == MediaStreamType.Subtitle && stream.Index == profile.Index) + { + stream.DeliveryMethod = profile.DeliveryMethod; + + if (profile.DeliveryMethod == SubtitleDeliveryMethod.External) + { + stream.DeliveryUrl = profile.Url.TrimStart('-'); + } + } + } } } diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs index 7f696f300..b364414d1 100644 --- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs +++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs @@ -167,9 +167,12 @@ namespace MediaBrowser.Dlna.Didl AddVideoResource(container, video, deviceId, filter, contentFeature, streamInfo); } - foreach (var subtitle in streamInfo.GetExternalSubtitles(_serverAddress, _accessToken, false)) + foreach (var subtitle in streamInfo.GetSubtitleProfiles(false, _serverAddress, _accessToken)) { - AddSubtitleElement(container, subtitle); + if (subtitle.DeliveryMethod == SubtitleDeliveryMethod.External) + { + AddSubtitleElement(container, subtitle); + } } } diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index feee2d765..9bfa684be 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -51,7 +51,7 @@ namespace MediaBrowser.Model.Dlna public int? MaxVideoBitDepth { get; set; } public int? MaxRefFrames { get; set; } - + public float? MaxFramerate { get; set; } public DeviceProfile DeviceProfile { get; set; } @@ -81,7 +81,8 @@ namespace MediaBrowser.Model.Dlna public bool IsDirectStream { - get { + get + { return PlayMethod == PlayMethod.DirectStream || PlayMethod == PlayMethod.DirectPlay; } @@ -175,7 +176,7 @@ namespace MediaBrowser.Model.Dlna { list.Add(pair.Value); } - + return string.Format("Params={0}", string.Join(";", list.ToArray())); } @@ -199,7 +200,7 @@ namespace MediaBrowser.Model.Dlna list.Add(new NameValuePair("MaxHeight", item.MaxHeight.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxHeight.Value) : string.Empty)); list.Add(new NameValuePair("StartTimeTicks", StringHelper.ToStringCultureInvariant(item.StartPositionTicks))); list.Add(new NameValuePair("Level", item.VideoLevel.HasValue ? StringHelper.ToStringCultureInvariant(item.VideoLevel.Value) : string.Empty)); - + list.Add(new NameValuePair("ClientTime", item.IsDirectStream ? string.Empty : DateTime.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture))); list.Add(new NameValuePair("MaxRefFrames", item.MaxRefFrames.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxRefFrames.Value) : string.Empty)); list.Add(new NameValuePair("MaxVideoBitDepth", item.MaxVideoBitDepth.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxVideoBitDepth.Value) : string.Empty)); @@ -216,53 +217,25 @@ namespace MediaBrowser.Model.Dlna return list; } - public List GetExternalSubtitles(bool includeSelectedTrackOnly) + public List GetExternalSubtitles(bool includeSelectedTrackOnly, string baseUrl, string accessToken) { - List list = new List(); + List list = GetSubtitleProfiles(includeSelectedTrackOnly, baseUrl, accessToken); + List newList = new List(); // First add the selected track - if (SubtitleStreamIndex.HasValue) + foreach (SubtitleStreamInfo stream in list) { - foreach (MediaStream stream in MediaSource.MediaStreams) - { - if (stream.Type == MediaStreamType.Subtitle && stream.Index == SubtitleStreamIndex.Value) - { - SubtitleStreamInfo info = GetSubtitleStreamInfo(stream); - - if (info != null) - { - list.Add(info); - } - } - } - } - - if (!includeSelectedTrackOnly) - { - foreach (MediaStream stream in MediaSource.MediaStreams) + if (stream.DeliveryMethod == SubtitleDeliveryMethod.External) { - if (stream.Type == MediaStreamType.Subtitle && (!SubtitleStreamIndex.HasValue || stream.Index != SubtitleStreamIndex.Value)) - { - SubtitleStreamInfo info = GetSubtitleStreamInfo(stream); - - if (info != null) - { - list.Add(info); - } - } + newList.Add(stream); } } - return list; + return newList; } - public List GetExternalSubtitles(string baseUrl, string accessToken, bool includeSelectedTrackOnly) + public List GetSubtitleProfiles(bool includeSelectedTrackOnly, string baseUrl, string accessToken) { - if (string.IsNullOrEmpty(baseUrl)) - { - throw new ArgumentNullException(baseUrl); - } - List list = new List(); // HLS will preserve timestamps so we can just grab the full subtitle stream @@ -279,10 +252,7 @@ namespace MediaBrowser.Model.Dlna { SubtitleStreamInfo info = GetSubtitleStreamInfo(stream, baseUrl, accessToken, startPositionTicks); - if (info != null) - { - list.Add(info); - } + list.Add(info); } } } @@ -295,14 +265,11 @@ namespace MediaBrowser.Model.Dlna { SubtitleStreamInfo info = GetSubtitleStreamInfo(stream, baseUrl, accessToken, startPositionTicks); - if (info != null) - { - list.Add(info); - } + list.Add(info); } } } - + return list; } @@ -310,15 +277,22 @@ namespace MediaBrowser.Model.Dlna { SubtitleStreamInfo info = GetSubtitleStreamInfo(stream); - if (info != null) + if (info.DeliveryMethod == SubtitleDeliveryMethod.External) { - info.Url = string.Format("{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}", - baseUrl, - ItemId, - MediaSourceId, - StringHelper.ToStringCultureInvariant(stream.Index), - StringHelper.ToStringCultureInvariant(startPositionTicks), - SubtitleFormat); + if (MediaSource.Protocol == MediaProtocol.Http) + { + info.Url = stream.Path; + } + else if (!string.IsNullOrEmpty(baseUrl)) + { + info.Url = string.Format("{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}", + baseUrl, + ItemId, + MediaSourceId, + StringHelper.ToStringCultureInvariant(stream.Index), + StringHelper.ToStringCultureInvariant(startPositionTicks), + SubtitleFormat); + } } return info; @@ -328,18 +302,14 @@ namespace MediaBrowser.Model.Dlna { SubtitleProfile subtitleProfile = StreamBuilder.GetSubtitleProfile(stream, DeviceProfile.SubtitleProfiles, Context); - if (subtitleProfile.Method != SubtitleDeliveryMethod.External) - { - return null; - } - return new SubtitleStreamInfo { IsForced = stream.IsForced, Language = stream.Language, Name = stream.Language ?? "Unknown", Format = SubtitleFormat, - Index = stream.Index + Index = stream.Index, + DeliveryMethod = subtitleProfile.Method }; } diff --git a/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs b/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs index a7a8da3ba..602858ccc 100644 --- a/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs +++ b/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs @@ -8,5 +8,6 @@ namespace MediaBrowser.Model.Dlna public bool IsForced { get; set; } public string Format { get; set; } public int Index { get; set; } + public SubtitleDeliveryMethod DeliveryMethod { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index fa075490a..760829ebf 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Extensions; using System.Diagnostics; namespace MediaBrowser.Model.Entities @@ -135,6 +136,17 @@ namespace MediaBrowser.Model.Entities /// true if this instance is external; otherwise, false. public bool IsExternal { get; set; } + /// + /// Gets or sets the method. + /// + /// The method. + public SubtitleDeliveryMethod? DeliveryMethod { get; set; } + /// + /// Gets or sets the delivery URL. + /// + /// The delivery URL. + public string DeliveryUrl { get; set; } + public bool IsTextSubtitleStream { get diff --git a/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs b/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs index c3e8cf944..43fb10df0 100644 --- a/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs +++ b/MediaBrowser.Server.Implementations/Sync/CloudSyncProfile.cs @@ -227,6 +227,11 @@ namespace MediaBrowser.Server.Implementations.Sync { Format = "srt", Method = SubtitleDeliveryMethod.External + }, + new SubtitleProfile + { + Format = "vtt", + Method = SubtitleDeliveryMethod.External } }; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index b73e0e85f..7eb015ae7 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -495,7 +495,7 @@ namespace MediaBrowser.Server.Implementations.Sync // No sense creating external subs if we're already burning one into the video var externalSubs = streamInfo.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode ? new List() : - streamInfo.GetExternalSubtitles(false); + streamInfo.GetExternalSubtitles(false, null, null); // Mark as requiring conversion if transcoding the video, or if any subtitles need to be extracted var requiresVideoTranscoding = streamInfo.PlayMethod == PlayMethod.Transcode && jobOptions.IsConverting; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 5e5a0d2fc..3acc79088 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -677,7 +677,6 @@ namespace MediaBrowser.Server.Implementations.Sync syncedItem.Item.MediaSources = new List(); syncedItem.OriginalFileName = Path.GetFileName(libraryItem.Path); - if (string.IsNullOrWhiteSpace(syncedItem.OriginalFileName)) { syncedItem.OriginalFileName = Path.GetFileName(mediaSource.Path); @@ -686,6 +685,7 @@ namespace MediaBrowser.Server.Implementations.Sync // This will be null for items that are not audio/video if (mediaSource != null) { + syncedItem.OriginalFileName = Path.ChangeExtension(syncedItem.OriginalFileName, Path.GetExtension(mediaSource.Path)); syncedItem.Item.MediaSources.Add(mediaSource); } -- cgit v1.2.3