commit
073fdd6d4f
|
@ -1482,6 +1482,17 @@ namespace MediaBrowser.Api.Playback
|
|||
videoRequest.CopyTimestamps = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
else if (i == 25)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(val) && videoRequest != null)
|
||||
{
|
||||
SubtitleDeliveryMethod method;
|
||||
if (Enum.TryParse(val, out method))
|
||||
{
|
||||
videoRequest.SubtitleMethod = method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -529,7 +529,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
"subs" :
|
||||
null;
|
||||
|
||||
AppendPlaylist(builder, playlistUrl, totalBitrate, subtitleGroup);
|
||||
AppendPlaylist(builder, state, playlistUrl, totalBitrate, subtitleGroup);
|
||||
|
||||
if (EnableAdaptiveBitrateStreaming(state, isLiveStream))
|
||||
{
|
||||
|
@ -540,12 +540,12 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
|
||||
var newBitrate = totalBitrate - variation;
|
||||
var variantUrl = ReplaceBitrate(playlistUrl, requestedVideoBitrate, (requestedVideoBitrate - variation));
|
||||
AppendPlaylist(builder, variantUrl, newBitrate, subtitleGroup);
|
||||
AppendPlaylist(builder, state, variantUrl, newBitrate, subtitleGroup);
|
||||
|
||||
variation *= 2;
|
||||
newBitrate = totalBitrate - variation;
|
||||
variantUrl = ReplaceBitrate(playlistUrl, requestedVideoBitrate, (requestedVideoBitrate - variation));
|
||||
AppendPlaylist(builder, variantUrl, newBitrate, subtitleGroup);
|
||||
AppendPlaylist(builder, state, variantUrl, newBitrate, subtitleGroup);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(subtitleGroup))
|
||||
|
@ -635,9 +635,15 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
//return state.VideoRequest.VideoBitRate.HasValue;
|
||||
}
|
||||
|
||||
private void AppendPlaylist(StringBuilder builder, string url, int bitrate, string subtitleGroup)
|
||||
private void AppendPlaylist(StringBuilder builder, StreamState state, string url, int bitrate, string subtitleGroup)
|
||||
{
|
||||
var header = "#EXT-X-STREAM-INF:BANDWIDTH=" + bitrate.ToString(UsCulture);
|
||||
var header = "#EXT-X-STREAM-INF:BANDWIDTH=" + bitrate.ToString(UsCulture) + ",AVERAGE-BANDWIDTH=" + bitrate.ToString(UsCulture);
|
||||
|
||||
// tvos wants resolution, codecs, framerate
|
||||
//if (state.TargetFramerate.HasValue)
|
||||
//{
|
||||
// header += string.Format(",FRAME-RATE=\"{0}\"", state.TargetFramerate.Value.ToString(CultureInfo.InvariantCulture));
|
||||
//}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(subtitleGroup))
|
||||
{
|
||||
|
@ -694,6 +700,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
var builder = new StringBuilder();
|
||||
|
||||
builder.AppendLine("#EXTM3U");
|
||||
builder.AppendLine("#EXT-X-PLAYLIST-TYPE:VOD");
|
||||
builder.AppendLine("#EXT-X-VERSION:3");
|
||||
builder.AppendLine("#EXT-X-TARGETDURATION:" + Math.Ceiling((segmentLengths.Length > 0 ? segmentLengths.Max() : state.SegmentLength)).ToString(UsCulture));
|
||||
builder.AppendLine("#EXT-X-MEDIA-SEQUENCE:0");
|
||||
|
|
|
@ -423,7 +423,24 @@ namespace MediaBrowser.Model.Dlna
|
|||
playlistItem.Container = transcodingProfile.Container;
|
||||
playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
|
||||
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
|
||||
playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',')[0];
|
||||
|
||||
// TODO: We should probably preserve the full list and sent it tp the server that way
|
||||
string[] supportedAudioCodecs = transcodingProfile.AudioCodec.Split(',');
|
||||
string inputAudioCodec = audioStream == null ? null : audioStream.Codec;
|
||||
foreach (string supportedAudioCodec in supportedAudioCodecs)
|
||||
{
|
||||
if (StringHelper.EqualsIgnoreCase(supportedAudioCodec, inputAudioCodec))
|
||||
{
|
||||
playlistItem.AudioCodec = supportedAudioCodec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(playlistItem.AudioCodec))
|
||||
{
|
||||
playlistItem.AudioCodec = supportedAudioCodecs[0];
|
||||
}
|
||||
|
||||
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
|
||||
playlistItem.CopyTimestamps = transcodingProfile.CopyTimestamps;
|
||||
playlistItem.SubProtocol = transcodingProfile.Protocol;
|
||||
|
@ -761,7 +778,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
// Look for an external profile that matches the stream type (text/graphical)
|
||||
foreach (SubtitleProfile profile in subtitleProfiles)
|
||||
{
|
||||
if (profile.Method != SubtitleDeliveryMethod.External)
|
||||
if (profile.Method != SubtitleDeliveryMethod.External && profile.Method != SubtitleDeliveryMethod.Hls)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -771,7 +788,8 @@ namespace MediaBrowser.Model.Dlna
|
|||
continue;
|
||||
}
|
||||
|
||||
if (subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format))
|
||||
if ((profile.Method == SubtitleDeliveryMethod.External && subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format)) ||
|
||||
(profile.Method == SubtitleDeliveryMethod.Hls && subtitleStream.IsTextSubtitleStream))
|
||||
{
|
||||
bool requiresConversion = !StringHelper.EqualsIgnoreCase(subtitleStream.Codec, profile.Format);
|
||||
|
||||
|
|
|
@ -234,6 +234,7 @@ namespace MediaBrowser.Model.Dlna
|
|||
}
|
||||
|
||||
list.Add(new NameValuePair("CopyTimestamps", (item.CopyTimestamps).ToString().ToLower()));
|
||||
list.Add(new NameValuePair("SubtitleMethod", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleDeliveryMethod.ToString() : string.Empty));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Weavers>
|
||||
<PropertyChanged />
|
||||
</Weavers>
|
|
@ -14,6 +14,7 @@
|
|||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<ReleaseVersion>
|
||||
</ReleaseVersion>
|
||||
<NuGetPackageImportStamp>60e95275</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -441,7 +442,6 @@
|
|||
<Compile Include="Users\UserAction.cs" />
|
||||
<Compile Include="Users\UserActionType.cs" />
|
||||
<Compile Include="Users\UserPolicy.cs" />
|
||||
<None Include="FodyWeavers.xml" />
|
||||
<None Include="MediaBrowser.Model.snk" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -458,13 +458,6 @@
|
|||
<PropertyGroup>
|
||||
<PostBuildEvent />
|
||||
</PropertyGroup>
|
||||
<Import Project="..\packages\Fody.1.29.2\build\dotnet\Fody.targets" Condition="Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Fody.1.29.2\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.29.2\build\dotnet\Fody.targets'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
|
@ -12,25 +12,21 @@ namespace MediaBrowser.Model.Session
|
|||
/// </summary>
|
||||
/// <value>The item.</value>
|
||||
public BaseItemInfo Item { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item identifier.
|
||||
/// </summary>
|
||||
/// <value>The item identifier.</value>
|
||||
public string ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the session id.
|
||||
/// </summary>
|
||||
/// <value>The session id.</value>
|
||||
public string SessionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the media version identifier.
|
||||
/// </summary>
|
||||
/// <value>The media version identifier.</value>
|
||||
public string MediaSourceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the position ticks.
|
||||
/// </summary>
|
||||
|
@ -46,5 +42,10 @@ namespace MediaBrowser.Model.Session
|
|||
/// </summary>
|
||||
/// <value>The play session identifier.</value>
|
||||
public string PlaySessionId { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="PlaybackStopInfo"/> is failed.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if failed; otherwise, <c>false</c>.</value>
|
||||
public bool Failed { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Fody" version="1.29.2" targetFramework="net45" developmentDependency="true" />
|
||||
<package id="PropertyChanged.Fody" version="1.50.4" targetFramework="net45" developmentDependency="true" />
|
||||
</packages>
|
|
@ -28,6 +28,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
private string _targetPath;
|
||||
private Process _process;
|
||||
private readonly IJsonSerializer _json;
|
||||
private readonly TaskCompletionSource<bool> _taskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
public EncodedRecorder(ILogger logger, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IApplicationPaths appPaths, IJsonSerializer json)
|
||||
{
|
||||
|
@ -93,11 +94,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
// Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
|
||||
StartStreamingLog(process.StandardError.BaseStream, _logFileStream);
|
||||
|
||||
// Wait for the file to exist before proceeeding
|
||||
while (!_hasExited)
|
||||
{
|
||||
await Task.Delay(100, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
await _taskCompletionSource.Task.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private string GetCommandLineArgs(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration)
|
||||
|
@ -197,16 +194,27 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
{
|
||||
_hasExited = true;
|
||||
|
||||
_logger.Debug("Disposing stream resources");
|
||||
DisposeLogStream();
|
||||
|
||||
try
|
||||
{
|
||||
_logger.Info("FFMpeg exited with code {0}", process.ExitCode);
|
||||
var exitCode = process.ExitCode;
|
||||
|
||||
_logger.Info("FFMpeg recording exited with code {0} for {1}", exitCode, _targetPath);
|
||||
|
||||
if (exitCode == 0)
|
||||
{
|
||||
_taskCompletionSource.TrySetResult(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_taskCompletionSource.TrySetException(new Exception(string.Format("Recording for {0} failed. Exit code {1}", _targetPath, exitCode)));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_logger.Error("FFMpeg exited with an error.");
|
||||
_logger.Error("FFMpeg recording exited with an error for {0}.", _targetPath);
|
||||
_taskCompletionSource.TrySetException(new Exception(string.Format("Recording for {0} failed", _targetPath)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,7 +228,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error disposing log stream", ex);
|
||||
_logger.ErrorException("Error disposing recording log stream", ex);
|
||||
}
|
||||
|
||||
_logFileStream = null;
|
||||
|
@ -250,7 +258,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error reading ffmpeg log", ex);
|
||||
_logger.ErrorException("Error reading ffmpeg recording log", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -865,10 +865,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (info.Status != RecordingStatus.InProgress)
|
||||
{
|
||||
_providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(_fileSystem)
|
||||
{
|
||||
MetadataRefreshMode = metadataRefreshMode
|
||||
});
|
||||
}
|
||||
|
||||
return item.Id;
|
||||
}
|
||||
|
|
|
@ -65,9 +65,9 @@
|
|||
<Reference Include="ServiceStack.Api.Swagger">
|
||||
<HintPath>..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SocketHttpListener, Version=1.0.5906.23695, Culture=neutral, processorArchitecture=MSIL">
|
||||
<Reference Include="SocketHttpListener, Version=1.0.5908.28560, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\SocketHttpListener.1.0.0.28\lib\net45\SocketHttpListener.dll</HintPath>
|
||||
<HintPath>..\packages\SocketHttpListener.1.0.0.29\lib\net45\SocketHttpListener.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
|
|
@ -813,7 +813,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
|
||||
foreach (var user in users)
|
||||
{
|
||||
playedToCompletion = await OnPlaybackStopped(user.Id, key, libraryItem, info.PositionTicks).ConfigureAwait(false);
|
||||
playedToCompletion = await OnPlaybackStopped(user.Id, key, libraryItem, info.PositionTicks, info.Failed).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -846,10 +846,13 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
await SendPlaybackStoppedNotification(session, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<bool> OnPlaybackStopped(Guid userId, string userDataKey, BaseItem item, long? positionTicks)
|
||||
private async Task<bool> OnPlaybackStopped(Guid userId, string userDataKey, BaseItem item, long? positionTicks, bool playbackFailed)
|
||||
{
|
||||
bool playedToCompletion = false;
|
||||
|
||||
if (!playbackFailed)
|
||||
{
|
||||
var data = _userDataRepository.GetUserData(userId, userDataKey);
|
||||
bool playedToCompletion;
|
||||
|
||||
if (positionTicks.HasValue)
|
||||
{
|
||||
|
@ -865,6 +868,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
}
|
||||
|
||||
await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return playedToCompletion;
|
||||
}
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
<package id="Mono.Nat" version="1.2.24.0" targetFramework="net45" />
|
||||
<package id="morelinq" version="1.4.0" targetFramework="net45" />
|
||||
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
|
||||
<package id="SocketHttpListener" version="1.0.0.28" targetFramework="net45" />
|
||||
<package id="SocketHttpListener" version="1.0.0.29" targetFramework="net45" />
|
||||
</packages>
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Common.Internal</id>
|
||||
<version>3.0.642</version>
|
||||
<version>3.0.643</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.642" />
|
||||
<dependency id="MediaBrowser.Common" version="3.0.643" />
|
||||
<dependency id="NLog" version="4.2.3" />
|
||||
<dependency id="SimpleInjector" version="3.1.2" />
|
||||
</dependencies>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Common</id>
|
||||
<version>3.0.642</version>
|
||||
<version>3.0.643</version>
|
||||
<title>MediaBrowser.Common</title>
|
||||
<authors>Emby Team</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Model.Signed</id>
|
||||
<version>3.0.642</version>
|
||||
<version>3.0.643</version>
|
||||
<title>MediaBrowser.Model - Signed Edition</title>
|
||||
<authors>Emby Team</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Server.Core</id>
|
||||
<version>3.0.642</version>
|
||||
<version>3.0.643</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.642" />
|
||||
<dependency id="MediaBrowser.Common" version="3.0.643" />
|
||||
<dependency id="Interfaces.IO" version="1.0.0.5" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
|
|
Loading…
Reference in New Issue
Block a user