public List <SubtitleStreamInfo> GetExternalSubtitles(string baseUrl, string accessToken, bool includeSelectedTrackOnly) { if (string.IsNullOrEmpty(baseUrl)) { throw new ArgumentNullException(baseUrl); } List <SubtitleStreamInfo> list = new List <SubtitleStreamInfo>(); // HLS will preserve timestamps so we can just grab the full subtitle stream long startPositionTicks = StringHelper.EqualsIgnoreCase(Protocol, "hls") ? 0 : StartPositionTicks; // First add the selected track if (SubtitleStreamIndex.HasValue) { foreach (MediaStream stream in MediaSource.MediaStreams) { if (stream.Type == MediaStreamType.Subtitle && stream.Index == SubtitleStreamIndex.Value) { SubtitleStreamInfo info = GetSubtitleStreamInfo(stream, baseUrl, accessToken, startPositionTicks); if (info != null) { list.Add(info); } } } } if (!includeSelectedTrackOnly) { foreach (MediaStream stream in MediaSource.MediaStreams) { if (stream.Type == MediaStreamType.Subtitle && (!SubtitleStreamIndex.HasValue || stream.Index != SubtitleStreamIndex.Value)) { SubtitleStreamInfo info = GetSubtitleStreamInfo(stream, baseUrl, accessToken, startPositionTicks); if (info != null) { list.Add(info); } } } } return(list); }
private SubtitleStreamInfo GetSubtitleStreamInfo(MediaStream stream, string baseUrl, string accessToken, long startPositionTicks) { SubtitleStreamInfo info = GetSubtitleStreamInfo(stream); if (info != null) { 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); }
private void AddSubtitleProfiles(List <SubtitleStreamInfo> list, MediaStream stream, ITranscoderSupport transcoderSupport, bool enableAllProfiles, string baseUrl, string accessToken, long startPositionTicks) { if (enableAllProfiles) { foreach (SubtitleProfile profile in DeviceProfile.SubtitleProfiles) { SubtitleStreamInfo info = GetSubtitleStreamInfo(stream, baseUrl, accessToken, startPositionTicks, new[] { profile }, transcoderSupport); list.Add(info); } } else { SubtitleStreamInfo info = GetSubtitleStreamInfo(stream, baseUrl, accessToken, startPositionTicks, DeviceProfile.SubtitleProfiles, transcoderSupport); list.Add(info); } }
private SubtitleStreamInfo GetSubtitleStreamInfo(MediaStream stream, string baseUrl, string accessToken, long startPositionTicks, SubtitleProfile[] subtitleProfiles, ITranscoderSupport transcoderSupport) { var subtitleProfile = StreamBuilder.GetSubtitleProfile(MediaSource, stream, subtitleProfiles, PlayMethod, transcoderSupport, Container, SubProtocol); var info = new SubtitleStreamInfo { IsForced = stream.IsForced, Language = stream.Language, Name = stream.Language ?? "Unknown", Format = subtitleProfile.Format, Index = stream.Index, DeliveryMethod = subtitleProfile.Method, DisplayTitle = stream.DisplayTitle }; if (info.DeliveryMethod == SubtitleDeliveryMethod.External) { if (MediaSource.Protocol == MediaProtocol.File || !string.Equals(stream.Codec, subtitleProfile.Format, StringComparison.OrdinalIgnoreCase) || !stream.IsExternal) { info.Url = string.Format( CultureInfo.InvariantCulture, "{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}", baseUrl, ItemId, MediaSourceId, stream.Index.ToString(CultureInfo.InvariantCulture), startPositionTicks.ToString(CultureInfo.InvariantCulture), subtitleProfile.Format); if (!string.IsNullOrEmpty(accessToken)) { info.Url += "?api_key=" + accessToken; } info.IsExternalUrl = false; } else { info.Url = stream.Path; info.IsExternalUrl = true; } } return(info); }
private SubtitleStreamInfo GetSubtitleStreamInfo(MediaStream stream, string baseUrl, string accessToken, long startPositionTicks, SubtitleProfile[] subtitleProfiles) { SubtitleProfile subtitleProfile = StreamBuilder.GetSubtitleProfile(stream, subtitleProfiles, PlayMethod, SubProtocol, Container); SubtitleStreamInfo info = new SubtitleStreamInfo { IsForced = stream.IsForced, Language = stream.Language, Name = stream.Language ?? "Unknown", Format = subtitleProfile.Format, Index = stream.Index, DeliveryMethod = subtitleProfile.Method, DisplayTitle = stream.DisplayTitle }; if (info.DeliveryMethod == SubtitleDeliveryMethod.External) { if (MediaSource.Protocol == MediaProtocol.File || !StringHelper.EqualsIgnoreCase(stream.Codec, subtitleProfile.Format)) { info.Url = string.Format("{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}", baseUrl, ItemId, MediaSourceId, StringHelper.ToStringCultureInvariant(stream.Index), StringHelper.ToStringCultureInvariant(startPositionTicks), subtitleProfile.Format); if (!string.IsNullOrEmpty(accessToken)) { info.Url += "?api_key=" + accessToken; } info.IsExternalUrl = false; } else { info.Url = stream.Path; info.IsExternalUrl = true; } } return(info); }
public List <SubtitleStreamInfo> GetExternalSubtitles(bool includeSelectedTrackOnly) { List <SubtitleStreamInfo> list = new List <SubtitleStreamInfo>(); // First add the selected track if (SubtitleStreamIndex.HasValue) { 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.Type == MediaStreamType.Subtitle && (!SubtitleStreamIndex.HasValue || stream.Index != SubtitleStreamIndex.Value)) { SubtitleStreamInfo info = GetSubtitleStreamInfo(stream); if (info != null) { list.Add(info); } } } } return(list); }
private bool AddSubtitleElement(XmlElement container, SubtitleStreamInfo info) { var subtitleProfile = _profile.SubtitleProfiles .FirstOrDefault(i => string.Equals(info.Format, i.Format, StringComparison.OrdinalIgnoreCase) && i.Method == SubtitleDeliveryMethod.External); if (subtitleProfile == null) { return false; } var subtitleMode = subtitleProfile.DidlMode; if (string.Equals(subtitleMode, "CaptionInfoEx", StringComparison.OrdinalIgnoreCase)) { // <sec:CaptionInfoEx sec:type="srt">http://192.168.1.3:9999/video.srt</sec:CaptionInfoEx> // <sec:CaptionInfo sec:type="srt">http://192.168.1.3:9999/video.srt</sec:CaptionInfo> var res = container.OwnerDocument.CreateElement("CaptionInfoEx", "sec"); res.InnerText = info.Url; //// TODO: attribute needs SEC: res.SetAttribute("type", "sec", info.Format.ToLower()); container.AppendChild(res); } else if (string.Equals(subtitleMode, "smi", StringComparison.OrdinalIgnoreCase)) { var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL); res.InnerText = info.Url; res.SetAttribute("protocolInfo", "http-get:*:smi/caption:*"); container.AppendChild(res); } else { var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL); res.InnerText = info.Url; var protocolInfo = string.Format("http-get:*:text/{0}:*", info.Format.ToLower()); res.SetAttribute("protocolInfo", protocolInfo); container.AppendChild(res); } return true; }
private void AddSubtitleElement(XmlElement container, SubtitleStreamInfo info) { var subtitleProfile = _profile.SubtitleProfiles .FirstOrDefault(i => string.Equals(info.Format, i.Format, StringComparison.OrdinalIgnoreCase) && i.Method == SubtitleDeliveryMethod.External); if (subtitleProfile == null) { return; } var subtitleMode = subtitleProfile.DidlMode; if (string.Equals(subtitleMode, "CaptionInfoEx", StringComparison.OrdinalIgnoreCase)) { //var res = container.OwnerDocument.CreateElement("SEC", "CaptionInfoEx"); //res.InnerText = info.Url; //// TODO: attribute needs SEC: //res.SetAttribute("type", info.Format.ToLower()); //container.AppendChild(res); } else { var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL); res.InnerText = info.Url; var protocolInfo = string.Format("http-get:*:text/{0}:*", info.Format.ToLower()); res.SetAttribute("protocolInfo", protocolInfo); container.AppendChild(res); } }
private SubtitleStreamInfo GetSubtitleStreamInfo(MediaStream stream, string baseUrl, string accessToken, long startPositionTicks, SubtitleProfile[] subtitleProfiles) { SubtitleProfile subtitleProfile = StreamBuilder.GetSubtitleProfile(stream, subtitleProfiles, PlayMethod); SubtitleStreamInfo info = new SubtitleStreamInfo { IsForced = stream.IsForced, Language = stream.Language, Name = stream.Language ?? "Unknown", Format = subtitleProfile.Format, Index = stream.Index, DeliveryMethod = subtitleProfile.Method, DisplayTitle = stream.DisplayTitle }; if (info.DeliveryMethod == SubtitleDeliveryMethod.External) { if (MediaSource.Protocol == MediaProtocol.File || !StringHelper.EqualsIgnoreCase(stream.Codec, subtitleProfile.Format)) { info.Url = string.Format("{0}/Videos/{1}/{2}/Subtitles/{3}/{4}/Stream.{5}", baseUrl, ItemId, MediaSourceId, StringHelper.ToStringCultureInvariant(stream.Index), StringHelper.ToStringCultureInvariant(startPositionTicks), subtitleProfile.Format); if (!string.IsNullOrEmpty(accessToken)) { info.Url += "?api_key=" + accessToken; } info.IsExternalUrl = false; } else { info.Url = stream.Path; info.IsExternalUrl = true; } } return info; }
private async Task<ItemFileInfo> ConvertSubtitles(string temporaryPath, StreamInfo streamInfo, SubtitleStreamInfo subtitleStreamInfo, CancellationToken cancellationToken) { var subtitleStreamIndex = subtitleStreamInfo.Index; var filename = Guid.NewGuid() + "." + subtitleStreamInfo.Format.ToLower(); var path = Path.Combine(temporaryPath, filename); Directory.CreateDirectory(Path.GetDirectoryName(path)); using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, cancellationToken).ConfigureAwait(false)) { using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) { await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false); } } return new ItemFileInfo { Name = Path.GetFileName(path), Path = path, Type = ItemFileType.Subtitles, Index = subtitleStreamIndex }; }
private bool RequiresExtraction(SubtitleStreamInfo stream, MediaSourceInfo mediaSource) { var originalStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Subtitle && i.Index == stream.Index); return originalStream != null && !originalStream.IsExternal; }