public MovieBuilder ReplaceSubtitleStream(SubtitleStream stream) { _movie.SubtitleStreams = new List <SubtitleStream> { stream }; return(this); }
private void OnVideoFound(object sender, EventArgs args) { var videoFile = (args as VideoFoundEventArgs).VideoFile; try { using (FileStream videoStream = File.OpenRead(videoFile.FullName)) { SubtitleStream subtitleStream = DownloadSubtitle(videoStream); if (subtitleStream != null) { using (var subFileStream = subtitleStream.Stream) { SubtitleInfo subtitleFile = subtitleStream.WriteToFile(new FileInfo(Path.ChangeExtension(videoFile.FullName, subtitleStream.Format.Extension))); if (subtitleFile != null) { SubtitleDownloaded(SubtitleDownloaded.Target, new SubtitleDownloadedEventArgs(videoFile, subtitleFile)); } } } } } catch (Exception) { // File not ready (e.g.: still being downloaded/copied/etc) } CurrentJobs.Remove(videoFile.FullName); }
SubtitleStream IPluginSubtitles.OpenSubtitles(SubtitleStream stream) { if (stream.Tag == null || !(stream.Tag is OpenSubtitlesJson)) { return(null); } return((SubtitleStream)stream); }
public SubtitleStreamBuilder(string language) { _stream = new SubtitleStream { Language = language, Codec = "codec", DisplayTitle = language, Id = Guid.NewGuid().ToString(), IsDefault = false }; }
private SubtitleStream ParseSubtitleStream(JToken token) { SubtitleStream stream = new SubtitleStream(ParseBaseStream(token)) { Duration = ParseTimeSpan(token["duration"].Value <string>()), DurationTs = token["duration_ts"].Value <int?>() ?? -1 }; return(stream); }
public SubtitleStream OpenSubtitles(SubtitleStream stream) { foreach (var sstream in SubtitleStreams) { if (sstream.Tag == stream.Tag) { return(stream); } } return(null); }
public SubtitleStream OpenSubtitles(SubtitleStream stream) { if (stream.DecoderInput.StreamIndex == -1) { return(null); } foreach (var sstream in SubtitleStreams) { if (sstream.DecoderInput.StreamIndex == stream.DecoderInput.StreamIndex) { return(sstream); } } return(null); }
public bool Download(SubtitleStream stream) { if (stream.Tag == null || !(stream.Tag is OpenSubtitlesJson)) { return(false); } var sub = (OpenSubtitlesJson)stream.Tag; if (sub.Download() != 0) { return(false); } stream.DecoderInput.Url = sub.AvailableAt; return(true); }
internal static void ParseStreamSubtitleLine(IResourceAccessor file, string streamSubtitleLine, ref MetadataContainer info, Dictionary <string, CultureInfo> countryCodesMapping) { streamSubtitleLine = streamSubtitleLine.Trim(); SubtitleStream sub = new SubtitleStream(); Match match = Regex.Match(streamSubtitleLine, @"#[\d][\.:](?<stream>[\d]{1,2}).*\((?<lang>(\w+))\)[\.:]", RegexOptions.IgnoreCase); if (match.Success) { sub.StreamIndex = Convert.ToInt32(match.Groups["stream"].Value.Trim()); if (match.Groups.Count == 4) { string lang = match.Groups["lang"].Value.Trim().ToUpperInvariant(); if (countryCodesMapping.ContainsKey(lang)) { sub.Language = countryCodesMapping[lang].TwoLetterISOLanguageName.ToUpperInvariant(); } } } else { match = Regex.Match(streamSubtitleLine, @"#[\d][\.:](?<stream>[\d]{1,2}).*[\.:]", RegexOptions.IgnoreCase); if (match.Success) { sub.StreamIndex = Convert.ToInt32(match.Groups["stream"].Value.Trim()); } } string codecValue = streamSubtitleLine.Substring(streamSubtitleLine.IndexOf("Subtitle: ", StringComparison.InvariantCultureIgnoreCase) + 10).Split(' ')[0]; sub.Codec = FFMpegParseSubtitleCodec.ParseSubtitleCodec(codecValue); sub.Default = streamSubtitleLine.IndexOf("(default)", StringComparison.InvariantCultureIgnoreCase) > -1; if (!info.Subtitles[Editions.DEFAULT_EDITION].ContainsKey(0)) { info.Subtitles[Editions.DEFAULT_EDITION].Add(0, new List <SubtitleStream>()); } info.Subtitles[Editions.DEFAULT_EDITION][0].Add(sub); }
public bool Download(SubtitleStream stream) { return(true); }
public MovieBuilder AddSubtitleStream(SubtitleStream stream) { _movie.SubtitleStreams.Add(stream); return(this); }
public static Task <Stream> CreatePlaylistManifestAsync(VideoTranscoding video, SubtitleStream sub) { if (ServiceRegistration.IsRegistered <IMediaConverter>()) { IMediaConverter converter = ServiceRegistration.Get <IMediaConverter>(); TranscodedVideoMetadata metaData = converter.GetTranscodedVideoMetadata(video); double bitrate = 10000000; if (metaData.TargetVideoBitrate.HasValue && metaData.TargetAudioBitrate.HasValue) { bitrate += metaData.TargetVideoBitrate.Value; bitrate += metaData.TargetAudioBitrate.Value; bitrate = bitrate * 1024; //Bitrate in bits/s } int width = 1920; int height = 1080; if (metaData.TargetVideoMaxHeight.HasValue && metaData.TargetVideoMaxWidth.HasValue) { width = metaData.TargetVideoMaxHeight.Value; height = metaData.TargetVideoMaxWidth.Value; } string codec = "avc1.66.30,mp4a.40.2"; //H264 Baseline 3.0 and AAC if (metaData.TargetVideoCodec == VideoCodec.H264) { codec = "avc1."; if (metaData.TargetProfile == EncodingProfile.Baseline) { codec += "66."; } else if (metaData.TargetProfile == EncodingProfile.Main) { codec += "77."; } else //High { codec += "100."; } codec += ((metaData.TargetLevel ?? 0) * 10).ToString("0"); if (metaData.TargetAudioCodec == AudioCodec.Ac3) { codec += ",ac-3"; } else { codec += ",mp4a.40."; if (metaData.TargetAudioCodec == AudioCodec.Aac) { codec += "2"; } else if (metaData.TargetAudioCodec == AudioCodec.Mp3) { codec += "34"; } else //HE-ACC { codec += "5"; } } } StringBuilder manifestBuilder = new StringBuilder(); using (StringWriter writer = new StringWriter(manifestBuilder)) { writer.WriteLine("#EXTM3U"); writer.WriteLine(); if (sub != null) { CultureInfo culture = new CultureInfo(sub.Language); writer.WriteLine(string.Format("#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"{0}\",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO,LANGUAGE=\"{1}\",URI=\"{2}\"", culture.DisplayName, culture.TwoLetterISOLanguageName.ToLowerInvariant(), URL_PLACEHOLDER + converter.HLSSubtitlePlayListName)); writer.WriteLine(); } writer.WriteLine(string.Format("#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH={0},RESOLUTION={1},CODECS=\"{2}\"{3}", bitrate.ToString("0"), width + "x" + height, codec, sub != null ? ",SUBTITLES=\"subs\"" : "")); writer.WriteLine(URL_PLACEHOLDER + converter.HLSMediaPlayListName); writer.WriteLine(); } var memStream = new MemoryStream(Encoding.UTF8.GetBytes(manifestBuilder.ToString())); memStream.Position = 0; return(Task.FromResult <Stream>(memStream)); } return(Task.FromResult <Stream>(null)); }
/// <summary> /// Global Json parser manager /// </summary> /// <param name="json"></param> /// <returns></returns> internal MovieInfo ReadJson(string json) { MovieInfo movieInfo = new MovieInfo(); JObject movieObject = JObject.Parse(json); if (movieObject["streams"] == null) { Console.WriteLine("ERROR: No streams found because collection is null"); } else { foreach (JToken token in movieObject["streams"]) { try { if (token["codec_type"] == null) { Console.WriteLine("ERROR: Stream skipped because its null"); continue; } if (token["codec_type"].Value <string>().Equals("video", StringComparison.OrdinalIgnoreCase)) { VideoStream stream = ParseVideoStream(token); movieInfo.VideoStreams.Add(stream); } else if (token["codec_type"].Value <string>().Equals("audio", StringComparison.OrdinalIgnoreCase)) { AudioStream stream = ParseAudioStream(token); movieInfo.AudioStreams.Add(stream); } else if (token["codec_type"].Value <string>().Equals("subtitle", StringComparison.OrdinalIgnoreCase)) { SubtitleStream stream = ParseSubtitleStream(token); movieInfo.SubtitleStreams.Add(stream); } else { Console.WriteLine("ERROR: Unknown StreamType found: " + token["codec_type"].Value <string>()); } } catch (Exception ex) { Console.WriteLine("ERROR: Unhandled Exception in processing stream"); Console.WriteLine(ex.Message); Console.WriteLine(ex.Source); Console.WriteLine(ex.StackTrace); } } } if (movieObject["chapters"] == null) { Console.WriteLine("ERROR: No chapters found because collection is null"); } else { foreach (JToken token in movieObject["chapters"]) { try { if (token == null) { Console.WriteLine("ERROR: Chapter skipped because its null"); continue; } Chapter chapter = ParseChapter(token); movieInfo.Chapters.Add(chapter); } catch (Exception ex) { Console.WriteLine("ERROR: Unhandled Exception in processing chapters"); Console.WriteLine(ex.Message); Console.WriteLine(ex.Source); Console.WriteLine(ex.StackTrace); } } } return(movieInfo); }
protected override async Task <bool> ConvertSubtitleFileAsync(string clientId, VideoTranscoding video, double timeStart, string transcodingFile, SubtitleStream sourceSubtitle, SubtitleStream res) { SubtitleCodec targetCodec = video.TargetSubtitleCodec; if (targetCodec == SubtitleCodec.Unknown) { targetCodec = sourceSubtitle.Codec; } string tempFile = null; FFMpegTranscodeData data = new FFMpegTranscodeData(_cachePath) { TranscodeId = video.TranscodeId + "_sub", ClientId = clientId }; if (string.IsNullOrEmpty(video.TranscoderBinPath) == false) { data.TranscoderBinPath = video.TranscoderBinPath; } if (string.IsNullOrEmpty(video.TranscoderArguments) == false) { // TODO: not sure if this is working data.TranscoderArguments = video.TranscoderArguments; data.InputMediaFilePaths.Add(0, res.SourcePath); data.InputArguments.Add(0, new List <string>()); } else { tempFile = transcodingFile + ".tmp"; res = await ConvertSubtitleEncodingAsync(res, tempFile, video.TargetSubtitleCharacterEncoding).ConfigureAwait(false); // TODO: not sure if this is working _ffMpegCommandline.InitTranscodingParameters(false, new Dictionary <int, string> { { 0, res.SourcePath } }, ref data); data.InputArguments[0].Add(string.Format("-f {0}", FFMpegGetSubtitleContainer.GetSubtitleContainer(sourceSubtitle.Codec))); if (timeStart > 0) { data.OutputArguments.Add(string.Format(CultureInfo.InvariantCulture, "-ss {0:0.0}", timeStart)); } res.Codec = targetCodec; string subtitleEncoder = "copy"; if (res.Codec == SubtitleCodec.Unknown) { res.Codec = SubtitleCodec.Ass; } if (sourceSubtitle.Codec != res.Codec) { subtitleEncoder = FFMpegGetSubtitleContainer.GetSubtitleContainer(res.Codec); } string subtitleFormat = FFMpegGetSubtitleContainer.GetSubtitleContainer(res.Codec); data.OutputArguments.Add("-vn"); data.OutputArguments.Add("-an"); data.OutputArguments.Add(string.Format("-c:s {0}", subtitleEncoder)); data.OutputArguments.Add(string.Format("-f {0}", subtitleFormat)); } data.OutputFilePath = transcodingFile; _logger.Debug("FFMpegMediaConverter: Invoking transcoder to transcode subtitle file '{0}' for transcode '{1}'", res.SourcePath, data.TranscodeId); bool success = false; var path = ResourcePath.Deserialize(res.SourcePath); if (path.TryCreateLocalResourceAccessor(out var subRes)) { using (var rah = new LocalFsResourceAccessorHelper(subRes)) using (var access = rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess()) { var result = await FFMpegBinary.FFMpegExecuteWithResourceAccessAsync(rah.LocalFsResourceAccessor, data.TranscoderArguments, ProcessPriorityClass.Normal, _transcoderTimeout).ConfigureAwait(false); success = result.Success; } } if (success && File.Exists(transcodingFile) == true) { if (tempFile != null && File.Exists(tempFile)) { File.Delete(tempFile); } res.SourcePath = LocalFsResourceProviderBase.ToProviderPath(transcodingFile); return(true); } return(false); }
protected override Task <bool> ExtractSubtitleFileAsync(int sourceMediaIndex, VideoTranscoding video, SubtitleStream subtitle, string subtitleEncoding, string targetFilePath, double timeStart) { return(_ffMpegCommandline.ExtractSubtitleFileAsync(sourceMediaIndex, video, subtitle, subtitleEncoding, targetFilePath, timeStart)); }
private MovieInfo ConvertCoreObject(CoreRoot core) { MovieInfo movieInfo = new MovieInfo(); if (core.Streams != null && core.Streams.Any()) { foreach (CoreStream coreStream in core.Streams) { try { BaseStream baseStream = GenerateBaseStream(coreStream); switch (baseStream.StreamType) { case StreamType.None: break; case StreamType.Subtitle: SubtitleStream subtitleStream = new SubtitleStream(baseStream); subtitleStream.Duration = ParseTimeSpan(coreStream.Duration); subtitleStream.DurationTs = coreStream.DurationTs; movieInfo.SubtitleStreams.Add(subtitleStream); break; case StreamType.Audio: AudioStream audioStream = GenerateAudioStream(baseStream, coreStream); movieInfo.AudioStreams.Add(audioStream); break; case StreamType.Video: VideoStream videoStream = GenerateVideoStream(baseStream, coreStream); movieInfo.VideoStreams.Add(videoStream); break; case StreamType.Data: DataStream dataStream = new DataStream(); movieInfo.DataStreams.Add(dataStream); break; case StreamType.Attachment: AttachmentStream attachmentStream = new AttachmentStream(); movieInfo.AttachmentStreams.Add(attachmentStream); break; } } catch (Exception ex) { Console.WriteLine("ERROR: Unhandled Exception while parsing streams:"); Console.WriteLine(ex.Message); Console.WriteLine(ex.Source); Console.WriteLine(ex.StackTrace); } } } if (core.Chapters != null && core.Chapters.Any()) { foreach (CoreChapter coreChapter in core.Chapters) { try { Chapter chapter = new Chapter(); chapter.Id = coreChapter.Id; chapter.End = coreChapter.End; chapter.Start = coreChapter.Start; chapter.TimeBase = coreChapter.TimeBase; chapter.Tags = coreChapter.Tags; chapter.StartTime = ParseTimeSpan(coreChapter.StartTime); chapter.EndTime = ParseTimeSpan(coreChapter.EndTime); if (coreChapter.Tags != null && coreChapter.Tags.Any()) { if (coreChapter.Tags.ContainsKey("title")) { chapter.Title = coreChapter.Tags .FirstOrDefault(x => x.Key.Equals("title", StringComparison.OrdinalIgnoreCase)).Value; } } movieInfo.Chapters.Add(chapter); } catch (Exception ex) { Console.WriteLine("ERROR: Unhandled Exception while parsing streams:"); Console.WriteLine(ex.Message); Console.WriteLine(ex.Source); Console.WriteLine(ex.StackTrace); } } } return(movieInfo); }