Merge pull request #1538 from MediaBrowser/dev

Dev
pull/702/head
Luke 9 years ago
commit 2b060987c6

@ -214,7 +214,7 @@ namespace MediaBrowser.Api.Playback
args += " -map -0:a"; args += " -map -0:a";
} }
if (state.SubtitleStream == null) if (state.SubtitleStream == null || state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Hls)
{ {
args += " -map -0:s"; args += " -map -0:s";
} }
@ -477,7 +477,7 @@ namespace MediaBrowser.Api.Playback
var pts = string.Empty; var pts = string.Empty;
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && !state.VideoRequest.CopyTimestamps) if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode && !state.VideoRequest.CopyTimestamps)
{ {
var seconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds; var seconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds;
@ -575,7 +575,7 @@ namespace MediaBrowser.Api.Playback
var output = string.Empty; var output = string.Empty;
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream) if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode)
{ {
var subParam = GetTextSubtitleParam(state); var subParam = GetTextSubtitleParam(state);
@ -865,7 +865,7 @@ namespace MediaBrowser.Api.Playback
{ {
var arg = string.Format("-i {0}", GetInputPathArgument(state)); var arg = string.Format("-i {0}", GetInputPathArgument(state));
if (state.SubtitleStream != null) if (state.SubtitleStream != null && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode)
{ {
if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream) if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
{ {

@ -529,6 +529,11 @@ namespace MediaBrowser.Api.Playback.Hls
"subs" : "subs" :
null; null;
if (!string.IsNullOrWhiteSpace(subtitleGroup))
{
AddSubtitles(state, subtitleStreams, builder);
}
AppendPlaylist(builder, state, playlistUrl, totalBitrate, subtitleGroup); AppendPlaylist(builder, state, playlistUrl, totalBitrate, subtitleGroup);
if (EnableAdaptiveBitrateStreaming(state, isLiveStream)) if (EnableAdaptiveBitrateStreaming(state, isLiveStream))
@ -548,11 +553,6 @@ namespace MediaBrowser.Api.Playback.Hls
AppendPlaylist(builder, state, variantUrl, newBitrate, subtitleGroup); AppendPlaylist(builder, state, variantUrl, newBitrate, subtitleGroup);
} }
if (!string.IsNullOrWhiteSpace(subtitleGroup))
{
AddSubtitles(state, subtitleStreams, builder);
}
return builder.ToString(); return builder.ToString();
} }
@ -566,11 +566,11 @@ namespace MediaBrowser.Api.Playback.Hls
private void AddSubtitles(StreamState state, IEnumerable<MediaStream> subtitles, StringBuilder builder) private void AddSubtitles(StreamState state, IEnumerable<MediaStream> subtitles, StringBuilder builder)
{ {
var selectedIndex = state.SubtitleStream == null ? (int?)null : state.SubtitleStream.Index; var selectedIndex = state.SubtitleStream == null || state.VideoRequest.SubtitleMethod != SubtitleDeliveryMethod.Hls ? (int?)null : state.SubtitleStream.Index;
foreach (var stream in subtitles) foreach (var stream in subtitles)
{ {
const string format = "#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"{0}\",DEFAULT={1},FORCED={2},URI=\"{3}\",LANGUAGE=\"{4}\""; const string format = "#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"{0}\",DEFAULT={1},FORCED={2},AUTOSELECT=YES,URI=\"{3}\",LANGUAGE=\"{4}\"";
var name = stream.Language; var name = stream.Language;
@ -579,10 +579,11 @@ namespace MediaBrowser.Api.Playback.Hls
if (string.IsNullOrWhiteSpace(name)) name = stream.Codec ?? "Unknown"; if (string.IsNullOrWhiteSpace(name)) name = stream.Codec ?? "Unknown";
var url = string.Format("{0}/Subtitles/{1}/subtitles.m3u8?SegmentLength={2}", var url = string.Format("{0}/Subtitles/{1}/subtitles.m3u8?SegmentLength={2}&api_key={3}",
state.Request.MediaSourceId, state.Request.MediaSourceId,
stream.Index.ToString(UsCulture), stream.Index.ToString(UsCulture),
30.ToString(UsCulture)); 30.ToString(UsCulture),
AuthorizationContext.GetAuthorizationInfo(Request).Token);
var line = string.Format(format, var line = string.Format(format,
name, name,
@ -827,7 +828,7 @@ namespace MediaBrowser.Api.Playback.Hls
var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"", var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
state.SegmentLength.ToString(UsCulture)); state.SegmentLength.ToString(UsCulture));
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream; var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode;
args += " " + GetVideoQualityParam(state, GetH264Encoder(state)) + keyFrameArg; args += " " + GetVideoQualityParam(state, GetH264Encoder(state)) + keyFrameArg;
@ -853,7 +854,7 @@ namespace MediaBrowser.Api.Playback.Hls
private bool EnableCopyTs(StreamState state) private bool EnableCopyTs(StreamState state)
{ {
return state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream; return state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode;
} }
protected override string GetCommandLineArguments(string outputPath, StreamState state, bool isEncoding) protected override string GetCommandLineArguments(string outputPath, StreamState state, bool isEncoding)

@ -9,6 +9,7 @@ using MediaBrowser.Model.Serialization;
using ServiceStack; using ServiceStack;
using System; using System;
using CommonIO; using CommonIO;
using MediaBrowser.Model.Dlna;
namespace MediaBrowser.Api.Playback.Hls namespace MediaBrowser.Api.Playback.Hls
{ {
@ -104,7 +105,7 @@ namespace MediaBrowser.Api.Playback.Hls
var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"", var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
state.SegmentLength.ToString(UsCulture)); state.SegmentLength.ToString(UsCulture));
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream; var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode;
args += " " + GetVideoQualityParam(state, GetH264Encoder(state)) + keyFrameArg; args += " " + GetVideoQualityParam(state, GetH264Encoder(state)) + keyFrameArg;

@ -13,6 +13,7 @@ using System;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using CommonIO; using CommonIO;
using MediaBrowser.Model.Dlna;
namespace MediaBrowser.Api.Playback.Progressive namespace MediaBrowser.Api.Playback.Progressive
{ {
@ -161,7 +162,7 @@ namespace MediaBrowser.Api.Playback.Progressive
args += keyFrameArg; args += keyFrameArg;
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream; var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode;
var hasCopyTs = false; var hasCopyTs = false;
// Add resolution params, if specified // Add resolution params, if specified

@ -164,6 +164,8 @@ namespace MediaBrowser.Api.Subtitles
long positionTicks = 0; long positionTicks = 0;
var segmentLengthTicks = TimeSpan.FromSeconds(request.SegmentLength).Ticks; var segmentLengthTicks = TimeSpan.FromSeconds(request.SegmentLength).Ticks;
var accessToken = AuthorizationContext.GetAuthorizationInfo(Request).Token;
while (positionTicks < runtime) while (positionTicks < runtime)
{ {
var remaining = runtime - positionTicks; var remaining = runtime - positionTicks;
@ -173,9 +175,10 @@ namespace MediaBrowser.Api.Subtitles
var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks); var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks);
var url = string.Format("stream.srt?StartPositionTicks={0}&EndPositionTicks={1}", var url = string.Format("stream.vtt?StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}",
positionTicks.ToString(CultureInfo.InvariantCulture), positionTicks.ToString(CultureInfo.InvariantCulture),
endPositionTicks.ToString(CultureInfo.InvariantCulture)); endPositionTicks.ToString(CultureInfo.InvariantCulture),
accessToken);
builder.AppendLine(url); builder.AppendLine(url);

@ -1835,8 +1835,8 @@ namespace MediaBrowser.Controller.Entities
ProviderIds = ProviderIds, ProviderIds = ProviderIds,
IndexNumber = IndexNumber, IndexNumber = IndexNumber,
ParentIndexNumber = ParentIndexNumber, ParentIndexNumber = ParentIndexNumber,
Year = ProductionYear, Year = ProductionYear,
PremiereDate = PremiereDate PremiereDate = PremiereDate
}; };
} }
@ -1985,5 +1985,14 @@ namespace MediaBrowser.Controller.Entities
{ {
return LibraryManager.DeleteItem(this, options); return LibraryManager.DeleteItem(this, options);
} }
public virtual Task OnFileDeleted()
{
// Remove from database
return Delete(new DeleteOptions
{
DeleteFileLocation = false
});
}
} }
} }

@ -390,5 +390,12 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="options">The options.</param> /// <param name="options">The options.</param>
/// <param name="user">The user.</param> /// <param name="user">The user.</param>
void AddChannelInfo(BaseItemDto dto, LiveTvChannel channel, DtoOptions options, User user); void AddChannelInfo(BaseItemDto dto, LiveTvChannel channel, DtoOptions options, User user);
/// <summary>
/// Called when [recording file deleted].
/// </summary>
/// <param name="recording">The recording.</param>
/// <returns>Task.</returns>
Task OnRecordingFileDeleted(ILiveTvRecording recording);
} }
} }

@ -151,5 +151,10 @@ namespace MediaBrowser.Controller.LiveTv
{ {
return LiveTvManager.DeleteRecording(this); return LiveTvManager.DeleteRecording(this);
} }
public override Task OnFileDeleted()
{
return LiveTvManager.OnRecordingFileDeleted(this);
}
} }
} }

@ -166,5 +166,10 @@ namespace MediaBrowser.Controller.LiveTv
{ {
return LiveTvManager.DeleteRecording(this); return LiveTvManager.DeleteRecording(this);
} }
public override Task OnFileDeleted()
{
return LiveTvManager.OnRecordingFileDeleted(this);
}
} }
} }

@ -90,8 +90,7 @@ namespace MediaBrowser.Controller.MediaEncoding
Cabac = info.Cabac; Cabac = info.Cabac;
Context = info.Context; Context = info.Context;
if (info.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode || if (info.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External)
info.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Embed)
{ {
SubtitleStreamIndex = info.SubtitleStreamIndex; SubtitleStreamIndex = info.SubtitleStreamIndex;
} }

@ -20,6 +20,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using CommonIO; using CommonIO;
using MediaBrowser.Model.Dlna;
namespace MediaBrowser.MediaEncoding.Encoder namespace MediaBrowser.MediaEncoding.Encoder
{ {
@ -456,7 +457,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{ {
var arg = string.Format("-i {0}", GetInputPathArgument(state)); var arg = string.Format("-i {0}", GetInputPathArgument(state));
if (state.SubtitleStream != null) if (state.SubtitleStream != null && state.Options.SubtitleMethod == SubtitleDeliveryMethod.Encode)
{ {
if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream) if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
{ {
@ -826,7 +827,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
args += " -map -0:a"; args += " -map -0:a";
} }
if (state.SubtitleStream == null) if (state.SubtitleStream == null || state.Options.SubtitleMethod == SubtitleDeliveryMethod.Hls)
{ {
args += " -map -0:s"; args += " -map -0:s";
} }
@ -933,7 +934,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
var output = string.Empty; var output = string.Empty;
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream) if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.Options.SubtitleMethod == SubtitleDeliveryMethod.Encode)
{ {
var subParam = GetTextSubtitleParam(state); var subParam = GetTextSubtitleParam(state);
@ -1018,7 +1019,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
var pts = string.Empty; var pts = string.Empty;
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream) if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.Options.SubtitleMethod == SubtitleDeliveryMethod.Encode && !state.Options.CopyTimestamps)
{ {
var seconds = TimeSpan.FromTicks(state.Options.StartTimeTicks ?? 0).TotalSeconds; var seconds = TimeSpan.FromTicks(state.Options.StartTimeTicks ?? 0).TotalSeconds;

@ -88,7 +88,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
args += keyFrameArg; args += keyFrameArg;
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream; var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.Options.SubtitleMethod == SubtitleDeliveryMethod.Encode;
// Add resolution params, if specified // Add resolution params, if specified
if (!hasGraphicalSubs) if (!hasGraphicalSubs)

@ -783,6 +783,11 @@ namespace MediaBrowser.Model.Dlna
continue; continue;
} }
if (profile.Method == SubtitleDeliveryMethod.Hls && playMethod != PlayMethod.Transcode)
{
continue;
}
if (!profile.SupportsLanguage(subtitleStream.Language)) if (!profile.SupportsLanguage(subtitleStream.Language))
{ {
continue; continue;
@ -799,12 +804,6 @@ namespace MediaBrowser.Model.Dlna
{ {
return profile; return profile;
} }
// For sync we can handle the longer extraction times
if (context == EncodingContext.Static && subtitleStream.IsTextSubtitleStream)
{
return profile;
}
} }
} }
} }

@ -926,16 +926,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var queryResult = _libraryManager.QueryItems(internalQuery); var queryResult = _libraryManager.QueryItems(internalQuery);
var returnArray = queryResult.Items var returnArray = _dtoService.GetBaseItemDtos(queryResult.Items, options, user).ToArray();
.Cast<LiveTvProgram>()
.Select(i => new Tuple<BaseItemDto, string, string>(_dtoService.GetBaseItemDto(i, options, user), i.ServiceName, i.ExternalId))
.ToArray();
await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {
Items = returnArray.Select(i => i.Item1).ToArray(), Items = returnArray,
TotalRecordCount = queryResult.TotalRecordCount TotalRecordCount = queryResult.TotalRecordCount
}; };
@ -1006,15 +1001,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var user = _userManager.GetUserById(query.UserId); var user = _userManager.GetUserById(query.UserId);
var returnArray = internalResult.Items var returnArray = _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ToArray();
.Select(i => new Tuple<BaseItemDto, string, string>(_dtoService.GetBaseItemDto(i, options, user), i.ServiceName, i.ExternalId))
.ToArray();
await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {
Items = returnArray.Select(i => i.Item1).ToArray(), Items = returnArray,
TotalRecordCount = internalResult.TotalRecordCount TotalRecordCount = internalResult.TotalRecordCount
}; };
@ -1635,18 +1626,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var internalResult = await GetInternalRecordings(query, cancellationToken).ConfigureAwait(false); var internalResult = await GetInternalRecordings(query, cancellationToken).ConfigureAwait(false);
var tuples = internalResult.Items var returnArray = _dtoService.GetBaseItemDtos(internalResult.Items, options, user).ToArray();
.Select(i => new Tuple<BaseItem, BaseItemDto>(i, _dtoService.GetBaseItemDto(i, options, user)))
.ToArray();
if (user != null)
{
_dtoService.FillSyncInfo(tuples, new DtoOptions(), user);
}
return new QueryResult<BaseItemDto> return new QueryResult<BaseItemDto>
{ {
Items = tuples.Select(i => i.Item2).ToArray(), Items = returnArray,
TotalRecordCount = internalResult.TotalRecordCount TotalRecordCount = internalResult.TotalRecordCount
}; };
} }
@ -1707,6 +1691,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}; };
} }
public Task OnRecordingFileDeleted(ILiveTvRecording recording)
{
var service = GetService(recording);
if (service is EmbyTV.EmbyTV)
{
// We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says
return service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None);
}
return Task.FromResult(true);
}
public async Task DeleteRecording(string recordingId) public async Task DeleteRecording(string recordingId)
{ {
var recording = await GetInternalRecording(recordingId, CancellationToken.None).ConfigureAwait(false); var recording = await GetInternalRecording(recordingId, CancellationToken.None).ConfigureAwait(false);

@ -239,11 +239,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
typeof(Year).Name, typeof(Year).Name,
typeof(Channel).Name, typeof(Channel).Name,
typeof(AggregateFolder).Name, typeof(AggregateFolder).Name,
typeof(CollectionFolder).Name, typeof(CollectionFolder).Name
// LiveTVManager handles recordings
typeof(LiveTvAudioRecording).Name,
typeof(LiveTvVideoRecording).Name
} }
}); });
@ -279,11 +275,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
_logger.Info("Deleting item from database {0} because path no longer exists. type: {1} path: {2}", libraryItem.Name, libraryItem.GetType().Name, libraryItem.Path ?? string.Empty); _logger.Info("Deleting item from database {0} because path no longer exists. type: {1} path: {2}", libraryItem.Name, libraryItem.GetType().Name, libraryItem.Path ?? string.Empty);
await libraryItem.Delete(new DeleteOptions await libraryItem.OnFileDeleted().ConfigureAwait(false);
{
DeleteFileLocation = false
}).ConfigureAwait(false);
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {

Loading…
Cancel
Save