Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
            }
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        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;
        }
Example #8
0
        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);
            }
        }
Example #9
0
        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;
        }
Example #10
0
        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
            };
        }
Example #11
0
        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;
        }