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); }
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; }
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]); }
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 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); }
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); }
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 }); }
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); }