Example #1
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);
            }
        }
        public void MapSetsOverlayFilterFormatOptionFor10BitSource()
        {
            var subtitleStream = new SubtitleStreamInfo()
            {
                Index        = 1,
                SubtitleType = SubtitleType.Graphic
            };

            _videoSource.BitDepth = 10;
            _transcodeJob.SourceInfo.Streams.Add(subtitleStream);
            _transcodeJob.HardSubtitles = new HardSubtitlesConfig()
            {
                SourceStreamIndex = subtitleStream.Index
            };

            var ffmpegJob = _jobRunner.CallMap(_transcodeJob, null);

            var filter = ffmpegJob.Filters.OfType <Filter>().FirstOrDefault(f => f.Name == "overlay");

            Assert.IsNotNull(filter);
            Assert.AreEqual(1, filter.Options?.Count);

            var option = filter.Options[0];

            Assert.IsNotNull(option);
            Assert.AreEqual("format", option.Name);
            Assert.AreEqual("yuv420p10", option.Value);
        }
Example #3
0
        public MediaStreamInfo ToStreamInfo()
        {
            MediaStreamInfo stream = null;

            if (CodecType == "audio")
            {
                stream = new AudioStreamInfo {
                    ChannelLayout = this.ChannelLayout,
                    ChannelCount  = this.ChannelCount,
                    SampleFormat  = FfmpegHelper.ParseSampleFormat(SampleFormat),
                    SampleRate    = SampleRate,
                };
            }
            else if (CodecType == "video")
            {
                stream = new VideoStreamInfo {
                    PixelFormat = PixelFormatHelper.Parse(PixelFormat),
                    Width       = this.Width,
                    Height      = this.Height
                };

                if (Tags != null && Tags.TryGetValue("rotate", out var rotate))
                {
                    ((VideoStreamInfo)stream).Rotate = (int)rotate;
                }
            }
            else if (CodecType == "subtitle")
            {
                stream = new SubtitleStreamInfo
                {
                };
            }
            else if (CodecType == "data")
            {
                stream = new DataStreamInfo
                {
                };
            }
            else
            {
                stream = new MediaStreamInfo();
            }

            stream.Codec = Profile != null?CodecInfo.Create(CodecIdHelper.Parse(CodecName), Profile).Name : CodecName;

            if (TimeBase != null && Rational.TryParse(TimeBase, out var timeBase))
            {
                stream.TimeBase = timeBase;
            }


            stream.Duration  = Duration ?? TimeSpan.Zero;
            stream.StartTime = StartTime ?? TimeSpan.Zero;

            stream.FrameCount = FrameCount;


            return(stream);
        }
        public ucSubtitleStreamDetail(SubtitleStreamInfo subtitleStreamInfo)
        {
            InitializeComponent();

            InitControls();
            RefreshControls(subtitleStreamInfo);

            cbLanguage.MouseWheel += Utils.Helpers.Combobox_OnMouseWheel;
        }
Example #5
0
 protected virtual MappedStream MapSubtitleStream(FFmpegConfig config,
                                                  SubtitleStreamInfo sourceStream,
                                                  SubtitleOutputStream outputStream)
 {
     return(new MappedStream(StreamType.Subtitle)
     {
         Input = GetStreamInput(sourceStream),
         Codec = new Codec(GetSubtitleCodecName(config, outputStream.Format))
     });
 }
        public void MapAddsGraphicSubtitleFilters()
        {
            var subtitleStream = new SubtitleStreamInfo()
            {
                Index        = 1,
                SubtitleType = SubtitleType.Graphic
            };

            _transcodeJob.SourceInfo.Streams.Add(subtitleStream);
            _transcodeJob.HardSubtitles = new HardSubtitlesConfig()
            {
                SourceStreamIndex = subtitleStream.Index
            };

            var ffmpegJob = _jobRunner.CallMap(_transcodeJob, null);

            Assert.AreEqual(2, ffmpegJob.Filters?.Count);

            var scale2RefFilter = ffmpegJob.Filters[0] as Filter;

            Assert.IsNotNull(scale2RefFilter);
            Assert.AreEqual("scale2ref", scale2RefFilter.Name);
            Assert.AreEqual(2, scale2RefFilter.Inputs?.Count);
            Assert.AreEqual(2, scale2RefFilter.OutputLabels?.Count);

            var streamInput = scale2RefFilter.Inputs[0] as StreamInput;

            Assert.IsNotNull(streamInput);
            Assert.AreEqual(0, streamInput.FileIndex);
            Assert.AreEqual(_transcodeJob.HardSubtitles.SourceStreamIndex, streamInput.StreamIndex);

            streamInput = scale2RefFilter.Inputs[1] as StreamInput;

            Assert.IsNotNull(streamInput);
            Assert.AreEqual(0, streamInput.FileIndex);
            Assert.AreEqual(_videoOutput.SourceStreamIndex, streamInput.StreamIndex);

            var overlayFilter = ffmpegJob.Filters[1] as Filter;

            Assert.IsNotNull(overlayFilter);
            Assert.AreEqual("overlay", overlayFilter.Name);
            Assert.IsTrue(overlayFilter.ChainToPrevious);
            Assert.AreEqual(2, overlayFilter.Inputs?.Count);

            var labeledInput = overlayFilter.Inputs[0] as LabeledInput;

            Assert.IsNotNull(labeledInput);
            Assert.AreEqual(labeledInput.Label, scale2RefFilter.OutputLabels[1]);

            labeledInput = overlayFilter.Inputs[1] as LabeledInput;

            Assert.IsNotNull(labeledInput);
            Assert.AreEqual(labeledInput.Label, scale2RefFilter.OutputLabels[0]);
        }
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 bool AddSubtitleElement(XmlWriter writer, 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>

                writer.WriteStartElement("sec", "CaptionInfoEx", null);
                writer.WriteAttributeString("sec", "type", null, info.Format.ToLowerInvariant());

                writer.WriteString(info.Url);
                writer.WriteFullEndElement();
            }
            else if (string.Equals(subtitleMode, "smi", StringComparison.OrdinalIgnoreCase))
            {
                writer.WriteStartElement(string.Empty, "res", NS_DIDL);

                writer.WriteAttributeString("protocolInfo", "http-get:*:smi/caption:*");

                writer.WriteString(info.Url);
                writer.WriteFullEndElement();
            }
            else
            {
                writer.WriteStartElement(string.Empty, "res", NS_DIDL);
                var protocolInfo = string.Format(
                    CultureInfo.InvariantCulture,
                    "http-get:*:text/{0}:*",
                    info.Format.ToLowerInvariant());
                writer.WriteAttributeString("protocolInfo", protocolInfo);

                writer.WriteString(info.Url);
                writer.WriteFullEndElement();
            }

            return(true);
        }
Example #9
0
        StreamInfo Map(Stream stream)
        {
            StreamInfo result = null;

            switch (stream.CodecType)
            {
                case "audio":
                    result = new AudioStreamInfo()
                    {
                        Format = GetAudioFormat(stream.CodecName, stream.Profile),
                        ChannelCount = GetInt(stream.Channels),
                        ProfileName = stream.Profile
                    };
                    break;
                case "subtitle":
                    result = new SubtitleStreamInfo()
                    {
                        SubtitleType = GetSubtitleType(stream.CodecName),
                        Format = GetSubtitleFormat(stream.CodecName)
                    };
                    break;
                case "video":
                    var storageDimensions = new Dimensions(GetInt(stream.Width), GetInt(stream.Height));
                    result = new VideoStreamInfo()
                    {
                        BitDepth = GetBitDepth(stream.PixFmt),
                        Dimensions = GetActualDimensions(storageDimensions, stream.SampleAspectRatio),
                        StorageDimensions = storageDimensions,
                        DynamicRange = stream.ColorTransfer == "smpte2084" ? DynamicRange.High : DynamicRange.Standard
                    };
                    break;
                default:
                    result = new StreamInfo();
                    break;
            }

            result.Index = (int)stream.Index;
            result.FormatName = stream.CodecName;

            if (stream.Tags != null)
            {
                result.Language = stream.Tags.TryGetValue("language", out var language) ? language : null;
            }

            return result;
        }
        public void MapAssignsCanvasSize()
        {
            var subtitleStream = new SubtitleStreamInfo()
            {
                Index = 1
            };

            _transcodeJob.SourceInfo.Streams.Add(subtitleStream);
            _videoSource.Dimensions     = new Dimensions(1920, 1080);
            _transcodeJob.HardSubtitles = new HardSubtitlesConfig()
            {
                SourceStreamIndex = subtitleStream.Index
            };

            var ffmpegJob = _jobRunner.CallMap(_transcodeJob, null);

            Assert.AreEqual(_videoSource.Dimensions, ffmpegJob.CanvasSize);
        }
        public void MapAssignsForcedSubtitlesOnly()
        {
            var subtitleStream = new SubtitleStreamInfo()
            {
                Index = 1
            };

            _transcodeJob.SourceInfo.Streams.Add(subtitleStream);
            _transcodeJob.HardSubtitles = new HardSubtitlesConfig()
            {
                SourceStreamIndex = subtitleStream.Index,
                ForcedOnly        = true
            };

            var ffmpegJob = _jobRunner.CallMap(_transcodeJob, null);

            Assert.AreEqual(_transcodeJob.HardSubtitles.ForcedOnly, ffmpegJob.ForcedSubtitlesOnly);
        }
        public void MapAddsTextSubtitleFilter()
        {
            var subtitleStream = new SubtitleStreamInfo()
            {
                Index        = 2,
                SubtitleType = SubtitleType.Text
            };

            _transcodeJob.SourceInfo.Streams.Add(new SubtitleStreamInfo()
            {
                Index = 1
            });
            _transcodeJob.SourceInfo.Streams.Add(subtitleStream);
            _transcodeJob.SourceInfo.Streams.Add(new SubtitleStreamInfo()
            {
                Index = 3
            });
            _transcodeJob.HardSubtitles = new HardSubtitlesConfig()
            {
                SourceStreamIndex = subtitleStream.Index
            };

            var ffmpegJob = _jobRunner.CallMap(_transcodeJob, null);

            Assert.AreEqual(1, ffmpegJob.Filters?.Count);

            var filter = ffmpegJob.Filters[0] as Filter;

            Assert.IsNotNull(filter);
            Assert.AreEqual("subtitles", filter.Name);
            Assert.AreEqual(2, filter.Options?.Count);

            var option = filter.Options[0];

            Assert.IsNotNull(option);
            Assert.IsNull(option.Name);
            Assert.AreEqual($"\"{_transcodeJob.SourceInfo.FileName}\"", option.Value);

            option = filter.Options[1];

            Assert.IsNotNull(option);
            Assert.AreEqual("si", option.Name);
            Assert.AreEqual("1", option.Value);
        }
        public void RefreshControls(SubtitleStreamInfo subtitleStreamInfo)
        {
            _bsControlsData.DataSource = subtitleStreamInfo;
            _bsControlsData.ResetBindings(false);

            ttTitleContent.RemoveAll();
            if (subtitleStreamInfo.HasTitle && !string.IsNullOrEmpty(subtitleStreamInfo.Title))
            {
                ttTitleContent.SetToolTip(chbTitle, subtitleStreamInfo.Title);
                chbTitle.Cursor = Cursors.Help;
            }
            else
            {
                ttTitleContent.RemoveAll();
                chbTitle.Cursor = Cursors.Default;
            }

            cbLanguage.SelectedItem = Languages.GetLanguageFromIdentifier(subtitleStreamInfo.Language);
        }
Example #14
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);

            _fileSystem.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 #15
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);
        }