Merge pull request #2219 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-10-11 02:47:51 -04:00 committed by GitHub
commit 88150e461c
34 changed files with 362 additions and 136 deletions

View File

@ -819,10 +819,10 @@ namespace MediaBrowser.Api.Playback
{
if (state.PlayableStreamFileNames.Count > 0)
{
return MediaEncoder.GetProbeSizeArgument(state.PlayableStreamFileNames.ToArray(), state.InputProtocol);
return MediaEncoder.GetProbeSizeAndAnalyzeDurationArgument(state.PlayableStreamFileNames.ToArray(), state.InputProtocol);
}
return MediaEncoder.GetProbeSizeArgument(new[] { state.MediaPath }, state.InputProtocol);
return MediaEncoder.GetProbeSizeAndAnalyzeDurationArgument(new[] { state.MediaPath }, state.InputProtocol);
}
/// <summary>

View File

@ -45,6 +45,15 @@ namespace MediaBrowser.Controller.Entities
return false;
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return false;
}
}
/// <summary>
/// The _virtual children
/// </summary>

View File

@ -17,6 +17,9 @@ namespace MediaBrowser.Controller.Entities.Audio
/// </summary>
public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo<AlbumInfo>, IMetadataContainer
{
public List<string> AlbumArtists { get; set; }
public List<string> Artists { get; set; }
public MusicAlbum()
{
Artists = new List<string>();
@ -48,6 +51,15 @@ namespace MediaBrowser.Controller.Entities.Audio
}
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return false;
}
}
[IgnoreDataMember]
public override bool SupportsCumulativeRunTimeTicks
{
@ -83,8 +95,6 @@ namespace MediaBrowser.Controller.Entities.Audio
get { return false; }
}
public List<string> AlbumArtists { get; set; }
/// <summary>
/// Gets the tracks.
/// </summary>
@ -103,8 +113,6 @@ namespace MediaBrowser.Controller.Entities.Audio
return Tracks;
}
public List<string> Artists { get; set; }
public override List<string> GetUserDataKeys()
{
var list = base.GetUserDataKeys();

View File

@ -48,6 +48,15 @@ namespace MediaBrowser.Controller.Entities.Audio
get { return true; }
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return false;
}
}
public override bool CanDelete()
{
return !IsAccessedByName;

View File

@ -129,6 +129,15 @@ namespace MediaBrowser.Controller.Entities
get { return false; }
}
[IgnoreDataMember]
public virtual bool SupportsPlayedStatus
{
get
{
return false;
}
}
public bool DetectIsInMixedFolder()
{
if (SupportsIsInMixedFolderDetection)

View File

@ -38,6 +38,15 @@ namespace MediaBrowser.Controller.Entities
}
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return false;
}
}
public override bool CanDelete()
{
return false;

View File

@ -61,6 +61,15 @@ namespace MediaBrowser.Controller.Entities
get { return false; }
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return true;
}
}
/// <summary>
/// Gets a value indicating whether this instance is folder.
/// </summary>

View File

@ -26,6 +26,15 @@ namespace MediaBrowser.Controller.Entities
}
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return false;
}
}
/// <summary>
/// Gets or sets the game system.
/// </summary>

View File

@ -20,5 +20,7 @@ namespace MediaBrowser.Controller.Entities
Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user);
bool EnableRememberingTrackSelections { get; }
bool SupportsPlayedStatus { get; }
}
}

View File

@ -29,13 +29,13 @@ namespace MediaBrowser.Controller.Entities
{
get
{
return Album;
return AlbumEntity;
}
}
[IgnoreDataMember]
public PhotoAlbum Album
public PhotoAlbum AlbumEntity
{
get
{

View File

@ -16,6 +16,15 @@ namespace MediaBrowser.Controller.Entities
}
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return false;
}
}
protected override bool GetBlockUnratedValue(UserPolicy config)
{
return config.BlockUnratedItems.Contains(UnratedItem.Other);

View File

@ -33,6 +33,15 @@ namespace MediaBrowser.Controller.Entities
}
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return false;
}
}
private void ClearCache()
{
lock (_childIdsLock)

View File

@ -44,6 +44,15 @@ namespace MediaBrowser.Controller.Entities
return list;
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return false;
}
}
public override int GetChildCount(User user)
{
return GetChildren(user, true).Count();

View File

@ -44,6 +44,15 @@ namespace MediaBrowser.Controller.Entities
}
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return true;
}
}
public override string CreatePresentationUniqueKey()
{
if (!string.IsNullOrWhiteSpace(PrimaryVersionId))

View File

@ -54,6 +54,15 @@ namespace MediaBrowser.Controller.LiveTv
}
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return Status == RecordingStatus.Completed && base.SupportsPlayedStatus;
}
}
[IgnoreDataMember]
public override LocationType LocationType
{

View File

@ -84,7 +84,7 @@ namespace MediaBrowser.Controller.MediaEncoding
/// <param name="inputFiles">The input files.</param>
/// <param name="protocol">The protocol.</param>
/// <returns>System.String.</returns>
string GetProbeSizeArgument(string[] inputFiles, MediaProtocol protocol);
string GetProbeSizeAndAnalyzeDurationArgument(string[] inputFiles, MediaProtocol protocol);
/// <summary>
/// Gets the input argument.

View File

@ -15,6 +15,7 @@ namespace MediaBrowser.Controller.MediaEncoding
public IIsoMount MountedIso { get; set; }
public VideoType VideoType { get; set; }
public List<string> PlayableStreamFileNames { get; set; }
public int AnalyzeDurationSections { get; set; }
public MediaInfoRequest()
{

View File

@ -31,6 +31,15 @@ namespace MediaBrowser.Controller.Playlists
}
}
[IgnoreDataMember]
public override bool SupportsPlayedStatus
{
get
{
return string.Equals(MediaType, "Video", StringComparison.OrdinalIgnoreCase);
}
}
[IgnoreDataMember]
public override bool AlwaysScanInternalMetadataPath
{

View File

@ -431,10 +431,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
if (state.PlayableStreamFileNames.Count > 0)
{
return MediaEncoder.GetProbeSizeArgument(state.PlayableStreamFileNames.ToArray(), state.InputProtocol);
return MediaEncoder.GetProbeSizeAndAnalyzeDurationArgument(state.PlayableStreamFileNames.ToArray(), state.InputProtocol);
}
return MediaEncoder.GetProbeSizeArgument(new[] { state.MediaPath }, state.InputProtocol);
return MediaEncoder.GetProbeSizeAndAnalyzeDurationArgument(new[] { state.MediaPath }, state.InputProtocol);
}
/// <summary>

View File

@ -26,6 +26,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
return string.Format("\"{0}\"", url);
}
if (protocol == MediaProtocol.Udp)
{
var url = inputFiles.First();
return string.Format("\"{0}\"", url);
}
return GetConcatInputArgument(inputFiles);
}
@ -74,9 +80,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
return path.Replace("\"", "\\\"");
}
public static string GetProbeSizeArgument(bool isDvd)
public static string GetProbeSizeArgument(int numInputFiles)
{
return isDvd ? "-probesize 1G -analyzeduration 200M" : "";
return numInputFiles > 1 ? "-probesize 1G" : "";
}
public static string GetAnalyzeDurationArgument(int numInputFiles)
{
return numInputFiles > 1 ? "-analyzeduration 200M" : "";
}
}
}

View File

@ -426,10 +426,24 @@ namespace MediaBrowser.MediaEncoding.Encoder
var inputFiles = MediaEncoderHelpers.GetInputArgument(FileSystem, request.InputPath, request.Protocol, request.MountedIso, request.PlayableStreamFileNames);
var probeSizeArgument = GetProbeSizeArgument(inputFiles, request.Protocol);
var probeSize = EncodingUtils.GetProbeSizeArgument(inputFiles.Length);
string analyzeDuration;
if (request.AnalyzeDurationSections > 0)
{
analyzeDuration = "-analyzeduration " +
(request.AnalyzeDurationSections*1000000).ToString(CultureInfo.InvariantCulture);
}
else
{
analyzeDuration = EncodingUtils.GetAnalyzeDurationArgument(inputFiles.Length);
}
probeSize = probeSize + " " + analyzeDuration;
probeSize = probeSize.Trim();
return GetMediaInfoInternal(GetInputArgument(inputFiles, request.Protocol), request.InputPath, request.Protocol, extractChapters,
probeSizeArgument, request.MediaType == DlnaProfileType.Audio, request.VideoType, cancellationToken);
probeSize, request.MediaType == DlnaProfileType.Audio, request.VideoType, cancellationToken);
}
/// <summary>
@ -450,9 +464,23 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <param name="inputFiles">The input files.</param>
/// <param name="protocol">The protocol.</param>
/// <returns>System.String.</returns>
public string GetProbeSizeArgument(string[] inputFiles, MediaProtocol protocol)
public string GetProbeSizeAndAnalyzeDurationArgument(string[] inputFiles, MediaProtocol protocol)
{
return EncodingUtils.GetProbeSizeArgument(inputFiles.Length > 1);
var results = new List<string>();
var probeSize = EncodingUtils.GetProbeSizeArgument(inputFiles.Length);
var analyzeDuration = EncodingUtils.GetAnalyzeDurationArgument(inputFiles.Length);
if (!string.IsNullOrWhiteSpace(probeSize))
{
results.Add(probeSize);
}
if (!string.IsNullOrWhiteSpace(analyzeDuration))
{
results.Add(analyzeDuration);
}
return string.Join(" ", results.ToArray());
}
/// <summary>
@ -871,7 +899,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
var args = useIFrame ? string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}{4}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, thumbnail) :
string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg);
var probeSize = GetProbeSizeArgument(new[] { inputPath }, protocol);
var probeSize = GetProbeSizeAndAnalyzeDurationArgument(new[] { inputPath }, protocol);
if (!string.IsNullOrEmpty(probeSize))
{
@ -982,7 +1010,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
var args = string.Format("-i {0} -threads 0 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf);
var probeSize = GetProbeSizeArgument(new[] { inputArgument }, protocol);
var probeSize = GetProbeSizeAndAnalyzeDurationArgument(new[] { inputArgument }, protocol);
if (!string.IsNullOrEmpty(probeSize))
{

View File

@ -5,6 +5,7 @@ namespace MediaBrowser.Model.MediaInfo
File = 0,
Http = 1,
Rtmp = 2,
Rtsp = 3
Rtsp = 3,
Udp = 4
}
}

View File

@ -598,7 +598,7 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.Altitude = item.Altitude;
dto.IsoSpeedRating = item.IsoSpeedRating;
var album = item.Album;
var album = item.AlbumEntity;
if (album != null)
{

View File

@ -269,9 +269,10 @@ namespace MediaBrowser.Server.Implementations.Library
positionTicks = 0;
}
if (item is Audio)
if (!item.SupportsPlayedStatus)
{
positionTicks = 0;
data.Played = false;
}
data.PlaybackPositionTicks = positionTicks;

View File

@ -27,6 +27,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using CommonIO;
using MediaBrowser.Common.Events;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
@ -59,8 +60,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
public static EmbyTV Current;
public event EventHandler DataSourceChanged { add { } remove { } }
public event EventHandler<RecordingStatusChangedEventArgs> RecordingStatusChanged { add { } remove { } }
public event EventHandler DataSourceChanged;
public event EventHandler<RecordingStatusChangedEventArgs> RecordingStatusChanged;
private readonly ConcurrentDictionary<string, ActiveRecordingInfo> _activeRecordings =
new ConcurrentDictionary<string, ActiveRecordingInfo>(StringComparer.OrdinalIgnoreCase);
@ -1009,7 +1010,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
throw new NotImplementedException();
}
public Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken)
public async Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken)
{
ActiveRecordingInfo info;
@ -1017,22 +1018,27 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
if (_activeRecordings.TryGetValue(recordingId, out info))
{
return Task.FromResult(new List<MediaSourceInfo>
var stream = new MediaSourceInfo
{
new MediaSourceInfo
{
Path = _appHost.GetLocalApiUrl("localhost") + "/LiveTv/LiveRecordings/" + recordingId + "/stream",
Id = recordingId,
SupportsDirectPlay = false,
SupportsDirectStream = true,
SupportsTranscoding = true,
IsInfiniteStream = true,
RequiresOpening = false,
RequiresClosing = false,
Protocol = Model.MediaInfo.MediaProtocol.Http,
BufferMs = 0
}
});
Path = _appHost.GetLocalApiUrl("localhost") + "/LiveTv/LiveRecordings/" + recordingId + "/stream",
Id = recordingId,
SupportsDirectPlay = false,
SupportsDirectStream = true,
SupportsTranscoding = true,
IsInfiniteStream = true,
RequiresOpening = false,
RequiresClosing = false,
Protocol = Model.MediaInfo.MediaProtocol.Http,
BufferMs = 0
};
var isAudio = false;
await new LiveStreamHelper(_mediaEncoder, _logger).AddMediaInfoWithProbe(stream, isAudio, cancellationToken).ConfigureAwait(false);
return new List<MediaSourceInfo>
{
stream
};
}
throw new FileNotFoundException();
@ -1258,6 +1264,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
string liveStreamId = null;
OnRecordingStatusChanged();
try
{
var allMediaSources = await GetChannelStreamMediaSources(timer.ChannelId, CancellationToken.None).ConfigureAwait(false);
@ -1353,6 +1361,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
_timerProvider.Delete(timer);
}
OnRecordingStatusChanged();
}
private void OnRecordingStatusChanged()
{
EventHelper.FireEventIfNotNull(RecordingStatusChanged, this, new RecordingStatusChangedEventArgs
{
}, _logger);
}
private async void EnforceKeepUpTo(TimerInfo timer)

View File

@ -0,0 +1,110 @@
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 MediaBrowser.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 = 2
}, 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 == 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;
}
}
// 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;
}
}
}
}
}

View File

@ -121,9 +121,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv
foreach (var service in _services)
{
service.DataSourceChanged += service_DataSourceChanged;
service.RecordingStatusChanged += Service_RecordingStatusChanged;
}
}
private void Service_RecordingStatusChanged(object sender, RecordingStatusChangedEventArgs e)
{
_lastRecordingRefreshTime = DateTime.MinValue;
}
public List<ITunerHost> TunerHosts
{
get { return _tunerHosts; }
@ -2299,6 +2305,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var info = await service.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false);
info.RecordAnyChannel = true;
info.RecordAnyTime = true;
info.Days = new List<DayOfWeek>
{
DayOfWeek.Sunday,
DayOfWeek.Monday,
DayOfWeek.Tuesday,
DayOfWeek.Wednesday,
DayOfWeek.Thursday,
DayOfWeek.Friday,
DayOfWeek.Saturday
};
info.Id = null;
return new Tuple<SeriesTimerInfo, ILiveTvService>(info, service);

View File

@ -146,7 +146,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
else
{
await AddMediaInfoWithProbe(stream, isAudio, cancellationToken).ConfigureAwait(false);
await new LiveStreamHelper(_mediaEncoder, _logger).AddMediaInfoWithProbe(stream, isAudio, cancellationToken).ConfigureAwait(false);
}
}
catch (Exception ex)
@ -216,92 +216,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
}
private 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
}, 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 == 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;
}
}
// 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;
}
}
}
public Task CloseMediaSource(string liveStreamId)
{
return _liveTvManager.CloseLiveStream(liveStreamId);

View File

@ -234,6 +234,7 @@
<Compile Include="LiveTv\EmbyTV\TimerManager.cs" />
<Compile Include="LiveTv\Listings\SchedulesDirect.cs" />
<Compile Include="LiveTv\Listings\XmlTvListingsProvider.cs" />
<Compile Include="LiveTv\LiveStreamHelper.cs" />
<Compile Include="LiveTv\LiveTvConfigurationFactory.cs" />
<Compile Include="LiveTv\LiveTvDtoService.cs" />
<Compile Include="LiveTv\LiveTvManager.cs" />

View File

@ -633,10 +633,14 @@ namespace MediaBrowser.Server.Implementations.Session
data.PlayCount++;
data.LastPlayedDate = DateTime.UtcNow;
if (!(item is Video))
if (!(item is Video) && item.SupportsPlayedStatus)
{
data.Played = true;
}
else
{
data.Played = false;
}
await _userDataManager.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None).ConfigureAwait(false);
}
@ -847,11 +851,11 @@ namespace MediaBrowser.Server.Implementations.Session
{
playedToCompletion = _userDataManager.UpdatePlayState(item, data, positionTicks.Value);
}
else
else
{
// If the client isn't able to report this, then we'll just have to make an assumption
data.PlayCount++;
data.Played = true;
data.Played = item.SupportsPlayedStatus;
data.PlaybackPositionTicks = 0;
playedToCompletion = true;
}

View File

@ -704,7 +704,7 @@ namespace MediaBrowser.ServerApplication
WindowStyle = ProcessWindowStyle.Hidden,
Verb = "runas",
ErrorDialog = false,
Arguments = String.Format("/c sc stop {0} & sc start {0}", BackgroundService.GetExistingServiceName())
Arguments = String.Format("/c sc stop {0} & sc start {0} & sc start {0}", BackgroundService.GetExistingServiceName())
};
Process.Start(startInfo);
}

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
<version>3.0.661</version>
<version>3.0.662</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.661" />
<dependency id="MediaBrowser.Common" version="3.0.662" />
<dependency id="NLog" version="4.3.8" />
<dependency id="SimpleInjector" version="3.2.2" />
</dependencies>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
<version>3.0.661</version>
<version>3.0.662</version>
<title>MediaBrowser.Common</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
<version>3.0.661</version>
<version>3.0.662</version>
<title>Media Browser.Server.Core</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Emby Server.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.661" />
<dependency id="MediaBrowser.Common" version="3.0.662" />
<dependency id="Interfaces.IO" version="1.0.0.5" />
</dependencies>
</metadata>