/// <summary> /// Add a subtitle track. /// The Source track is set based on the following order. If null, it will skip to the next option. /// 1. Passed in Subitle param /// 2. First preferred Subtitle from source /// 3. First subtitle from source. /// Will not add a subtitle if the source has none. /// </summary> /// <param name="subtitle"> /// The subtitle. Use null to add preferred, or first from source (based on user preference) /// </param> private void Add(Subtitle subtitle) { string preferred = this.UserSettingService.GetUserSetting <string>(UserSettingConstants.NativeLanguageForSubtitles); Subtitle source = subtitle ?? ((this.SourceTracks != null) ? (this.SourceTracks.FirstOrDefault(l => l.Language == preferred) ?? this.SourceTracks.FirstOrDefault(s => s.SubtitleType != SubtitleType.ForeignAudioSearch)) : null); if (source == null) { source = ForeignAudioSearchTrack; } SubtitleTrack track = new SubtitleTrack { SubtitleType = SubtitleType.VobSub, SourceTrack = source, }; if ((source.SubtitleType == SubtitleType.PGS || source.SubtitleType == SubtitleType.VobSub) && this.Task != null && (this.Task.OutputFormat == OutputFormat.Mp4 || this.Task.OutputFormat == OutputFormat.M4V || this.Task.OutputFormat == OutputFormat.av_mp4)) { this.SelectBurnedInTrack(track); } this.Task.SubtitleTracks.Add(track); }
/// <summary> /// Add a subtitle track. /// The Source track is set based on the following order. If null, it will skip to the next option. /// 1. Passed in Subitle param /// 2. First preferred Subtitle from source /// 3. First subtitle from source. /// Will not add a subtitle if the source has none. /// </summary> /// <param name="subtitle"> /// The subtitle. Use null to add preferred, or first from source (based on user preference) /// </param> private void Add(Subtitle subtitle) { Subtitle source = subtitle ?? ((this.SourceTracks != null) ? (this.SourceTracks.FirstOrDefault(l => l.Language == this.GetPreferredSubtitleTrackLanguage()) ?? this.SourceTracks.FirstOrDefault( s => s.SubtitleType != SubtitleType.ForeignAudioSearch)) : null); if (source == null) { source = ForeignAudioSearchTrack; } SubtitleTrack track = new SubtitleTrack { SubtitleType = SubtitleType.VobSub, SourceTrack = source, }; if ((source.SubtitleType == SubtitleType.PGS || source.SubtitleType == SubtitleType.VobSub || source.SubtitleType == SubtitleType.ForeignAudioSearch) && this.Task != null && (this.Task.OutputFormat == OutputFormat.Mp4 || this.Task.OutputFormat == OutputFormat.M4V)) { if (track.CanBeBurned) { track.Burned = true; this.SetBurnedToFalseForAllExcept(track); } } this.Task.SubtitleTracks.Add(track); }
/// <summary> /// Helper method that creates a user friendly type from the internal interop structure. /// </summary> /// <param name="s">TrackDescriptionStructure from interop</param> /// <returns>public TrackDescription to be consumed by the user</returns> internal static MediaTrack Build(this MediaTrackStructure s) { AudioTrack audioTrack = default; VideoTrack videoTrack = default; SubtitleTrack subtitleTrack = default; switch (s.TrackType) { case TrackType.Audio: audioTrack = MarshalUtils.PtrToStructure <AudioTrack>(s.TrackData); break; case TrackType.Video: videoTrack = MarshalUtils.PtrToStructure <VideoTrack>(s.TrackData); break; case TrackType.Text: subtitleTrack = MarshalUtils.PtrToStructure <SubtitleTrackStructure>(s.TrackData).Build(); break; case TrackType.Unknown: break; } return(new MediaTrack(s.Codec, s.OriginalFourcc, s.Id, s.TrackType, s.Profile, s.Level, new MediaTrackData(audioTrack, videoTrack, subtitleTrack), s.Bitrate, s.Language.FromUtf8(), s.Description.FromUtf8())); }
/// <summary> /// Import an SRT File. /// </summary> public void Import() { OpenFileDialog dialog = new OpenFileDialog { Filter = "SRT files (*.srt)|*.srt", CheckFileExists = true, Multiselect = true }; dialog.ShowDialog(); foreach (var srtFile in dialog.FileNames) { SubtitleTrack track = new SubtitleTrack { SrtFileName = Path.GetFileNameWithoutExtension(srtFile), SrtOffset = 0, SrtCharCode = "UTF-8", SrtLang = "English", SubtitleType = SubtitleType.SRT, SrtPath = srtFile }; this.Task.SubtitleTracks.Add(track); } }
private string GetSubtitleDescription() { if (this.Task.AudioTracks.Count == 0) { return(ResourcesUI.SummaryView_NoSubtitleTracks); } StringBuilder desc = new StringBuilder(); if (this.Task.SubtitleTracks.Count >= 1) { SubtitleTrack track1 = this.Task.SubtitleTracks[0]; string subtitleName = track1.IsSrtSubtitle ? track1.SrtFileName : track1.SourceTrack.ToString(); string burned = track1.Burned ? ", " + ResourcesUI.SummaryView_Burned : string.Empty; desc.AppendLine(string.Format("{0}{1}", subtitleName, burned)); } if (this.Task.SubtitleTracks.Count >= 2) { SubtitleTrack track2 = this.Task.SubtitleTracks[1]; string subtitleName = track2.IsSrtSubtitle ? track2.SrtFileName : track2.SourceTrack.ToString(); string burned = track2.Burned ? ", " + ResourcesUI.SummaryView_Burned : string.Empty; desc.AppendLine(string.Format("{0}{1}", subtitleName, burned)); } if (this.Task.SubtitleTracks.Count > 2) { desc.AppendLine(string.Format("+ {0} {1}", this.Task.SubtitleTracks.Count - 2, ResourcesUI.SummaryView_AdditionalSubtitleTracks)); } return(desc.ToString().Trim()); }
/// <summary> /// Add a Subtitle track. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="e"> /// The e. /// </param> private void BtnAddSubTrackClick(object sender, EventArgs e) { // Logic string forcedVal = check_forced.CheckState == CheckState.Checked ? "Yes" : "No"; string defaultSub = check_default.CheckState == CheckState.Checked ? "Yes" : "No"; string burnedVal = check_burned.CheckState == CheckState.Checked && (drp_subtitleTracks.Text.Contains("(VOBSUB)") || drp_subtitleTracks.Text.Contains("(SSA)")) ? "Yes" : "No"; string srtCode = "-", srtLangVal = "-", srtPath = "-", srtFile = "-"; int srtOffsetMs = 0; if (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt")) { srtFiles.TryGetValue(drp_subtitleTracks.SelectedItem.ToString(), out srtPath); srtFile = drp_subtitleTracks.SelectedItem.ToString(); srtLangVal = srt_lang.SelectedItem.ToString(); srtCode = srt_charcode.SelectedItem.ToString(); srtOffsetMs = (int)srt_offset.Value; if (defaultSub == "Yes") { this.SetDefaultToOffForAllSRTTracks(); } } else { if (defaultSub == "Yes") { this.SetDefaultToOffForAllTracks(); } if (burnedVal == "Yes") { this.SetBurnedToOffForAllTracks(); } } string trackName = (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt")) ? srtLangVal + " (" + srtFile + ")" : drp_subtitleTracks.SelectedItem.ToString(); SubtitleTrack track = new SubtitleTrack { Track = trackName, Forced = check_forced.Checked, Burned = check_burned.Checked, Default = check_default.Checked, SrtLang = srtLangVal, SrtCharCode = srtCode, SrtOffset = srtOffsetMs, SrtPath = srtPath, SrtFileName = srtFile }; lv_subList.Items.Add(track.ListView); subList.Add(track); }
/// <summary> /// Select the burned in track. /// </summary> /// <param name="subtitle"> /// The subtitle. /// </param> public void SetBurnedToFalseForAllExcept(SubtitleTrack subtitle) { foreach (SubtitleTrack track in this.Task.SubtitleTracks) { if (track == subtitle) { continue; // Skip the track the user selected. } track.Burned = false; } this.NotifyOfPropertyChange(() => this.Task); }
/// <summary> /// Add a subtitle Track /// </summary> /// <param name="sender"> /// The Sender /// </param> /// <param name="e"> /// The Event Args /// </param> private void btn_addSubtitleTrack_Click(object sender, EventArgs e) { if (drp_subtitleTracks.SelectedItem == null) { MessageBox.Show("No Subtitle Track Selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Logic string srtCode = "-", srtLangVal = "-", srtPath = "-", srtFile = "-"; int srtOffsetMs = 0; // Make sure we only have 1 burned track. We'll always give the latest track added burned in. if (check_burned.Checked) { this.SetBurnedToOffForAllTracks(); } // Make sure we only have 1 default track if (check_default.Checked) { this.SetDefaultToOffForAllTracks(); } if (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt")) { srtFiles.TryGetValue(drp_subtitleTracks.SelectedItem.ToString(), out srtPath); srtFile = drp_subtitleTracks.SelectedItem.ToString(); srtLangVal = srt_lang.SelectedItem.ToString(); srtCode = srt_charcode.SelectedItem.ToString(); srtOffsetMs = (int)srt_offset.Value; } string trackName = (drp_subtitleTracks.SelectedItem.ToString().Contains(".srt")) ? srtLangVal + " (" + srtFile + ")" : drp_subtitleTracks.SelectedItem.ToString(); SubtitleTrack track = new SubtitleTrack { Track = trackName, Forced = check_forced.Checked, Burned = check_burned.Checked, Default = check_default.Checked, SrtLang = srtLangVal, SrtCharCode = srtCode, SrtOffset = srtOffsetMs, SrtPath = srtPath, SrtFileName = srtFile }; lv_subList.Items.Add(track.ListView); subList.Add(track); }
/// <summary> /// Select the default subtitle track. /// </summary> /// <param name="subtitle"> /// The subtitle. /// </param> public void SelectDefaultTrack(SubtitleTrack subtitle) { foreach (SubtitleTrack track in this.Task.SubtitleTracks) { if (track == subtitle) { continue; // Skip the track the user selected. } track.Default = false; } this.NotifyOfPropertyChange(() => this.Task); }
public OKEFile StartMuxing(string path, MediaFile mediaFile) { List <string> input = new List <string>(); string videoFps = ""; string videoName = ""; string timeCodeFile = null; List <string> audioLanguages = new List <string>(); List <string> audioNames = new List <string>(); List <string> subtitleLanguages = new List <string>(); List <string> subtitleNames = new List <string>(); foreach (var track in mediaFile.Tracks) { if (track.Info.MuxOption != MuxOption.Default && track.Info.MuxOption != MuxOption.Mka) { continue; } switch (track.TrackType) { case TrackType.Audio: AudioTrack audioTrack = track as AudioTrack; audioLanguages.Add(audioTrack.Info.Language); audioNames.Add(audioTrack.Info.Name); break; case TrackType.Video: VideoTrack videoTrack = track as VideoTrack; VideoInfo videoInfo = track.Info as VideoInfo; videoFps = $"{videoInfo.FpsNum}/{videoInfo.FpsDen}"; videoName = videoInfo.Name; timeCodeFile = videoInfo.TimeCodeFile; break; case TrackType.Subtitle: SubtitleTrack subtitleTrack = track as SubtitleTrack; subtitleLanguages.Add(subtitleTrack.Info.Language); subtitleNames.Add(subtitleTrack.Info.Name); break; } input.Add(track.File.GetFullPath()); } this.StartMerge(input, path, videoFps, videoName, timeCodeFile, audioLanguages, audioNames, subtitleLanguages, subtitleNames); OKEFile outFile = new OKEFile(path); outFile.AddCRC32(); return(outFile.Exists() ? outFile : null); }
/// <summary> /// The Subtitle List selected index has changed /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="e"> /// The e. /// </param> private void LbSubListSelectedIndexChanged(object sender, EventArgs e) { // Set the dropdown controls based on the selected item in the List. if (lv_subList.Items.Count != 0 && lv_subList.SelectedIndices.Count != 0) { SubtitleTrack track = subList[lv_subList.SelectedIndices[0]]; int c = 0; if (lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text.ToLower().Contains(".srt")) // We have an SRT { foreach (var item in drp_subtitleTracks.Items) { if (item.ToString() == track.SrtFileName) { drp_subtitleTracks.SelectedIndex = c; } c++; } srt_lang.SelectedItem = track.SrtLang; srt_offset.Value = track.SrtOffset; srt_charcode.SelectedItem = track.SrtCharCode; check_default.CheckState = track.Default ? CheckState.Checked : CheckState.Unchecked; SubGroupBox.Text = "Selected Track: " + track.Track; } else // We have Bitmap/CC { foreach (var item in drp_subtitleTracks.Items) { if (item.ToString() == track.Track) { drp_subtitleTracks.SelectedIndex = c; } c++; } check_forced.CheckState = track.Forced ? CheckState.Checked : CheckState.Unchecked; check_burned.CheckState = track.Burned ? CheckState.Checked : CheckState.Unchecked; check_default.CheckState = track.Default ? CheckState.Checked : CheckState.Unchecked; SubGroupBox.Text = "Selected Track: " + lv_subList.Items[lv_subList.SelectedIndices[0]].SubItems[0].Text; } } else { SubGroupBox.Text = "Selected Track: None (Click \"Add\" to add another track to the list)"; } }
/// <summary> /// Add a subtitle track. /// The Source track is set based on the following order. If null, it will skip to the next option. /// 1. Passed in Subitle param /// 2. First preferred Subtitle from source /// 3. First subtitle from source. /// Will not add a subtitle if the source has none. /// </summary> /// <param name="subtitle"> /// The subtitle. Use null to add preferred, or first from source (based on user preference) /// </param> private void Add(Subtitle subtitle) { Subtitle source = subtitle ?? ((this.SourceTracks != null) ? (this.SourceTracks.FirstOrDefault(l => l.Language == this.GetPreferredSubtitleTrackLanguage()) ?? this.SourceTracks.FirstOrDefault( s => s.SubtitleType != SubtitleType.ForeignAudioSearch)) : null); if (source == null) { source = ForeignAudioSearchTrack; } SubtitleTrack track = new SubtitleTrack { SubtitleType = SubtitleType.VobSub, SourceTrack = source, }; // Burn-in Behaviours if (this.SubtitleBehaviours.SelectedBurnInBehaviour == SubtitleBurnInBehaviourModes.ForeignAudio || this.SubtitleBehaviours.SelectedBurnInBehaviour == SubtitleBurnInBehaviourModes.ForeignAudioPreferred) { track.Burned = true; this.SetBurnedToFalseForAllExcept(track); } // For MP4, PGS Subtitles must be burned in. if (!track.Burned && (source.SubtitleType == SubtitleType.PGS) && this.Task != null && this.Task.OutputFormat == OutputFormat.Mp4) { if (track.CanBeBurned) { track.Burned = true; this.SetBurnedToFalseForAllExcept(track); } } var encodeTask = this.Task; if (encodeTask != null) { encodeTask.SubtitleTracks.Add(track); } }
private IEnumerable <ISubtitleTrack> PrepareSubtitleTracks(FileInfo fileInfo, IEnumerable <TrackInfoOutput> trackModels) { foreach (var model in trackModels) { var track = new SubtitleTrack { ID = model.ID, FileInfo = fileInfo, StreamOrder = model.StreamOrder, Format = model.Format, CodecId = model.CodecID, Duration = model.Duration, Bitrate = model.Bitrate, Language = model.Language }; yield return(track); } }
/// <summary> /// Helper method that creates a user friendly type from the internal interop structure. /// </summary> /// <param name="s">TrackDescriptionStructure from interop</param> /// <returns>public TrackDescription to be consumed by the user</returns> internal static MediaTrack Build(this MediaTrackStructure s) { AudioTrack audioTrack = default; VideoTrack videoTrack = default; SubtitleTrack subtitleTrack = default; switch (s.TrackType) { case TrackType.Audio: audioTrack = MarshalUtils.PtrToStructure <AudioTrack>(s.TrackData); break; case TrackType.Video: videoTrack = MarshalUtils.PtrToStructure <VideoTrack>(s.TrackData); break; case TrackType.Text: subtitleTrack = MarshalUtils.PtrToStructure <SubtitleTrackStructure>(s.TrackData).Build(); break; case TrackType.Unknown: break; } var language = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Language) as string; var des = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Description) as string; return(new MediaTrack(s.Codec, s.OriginalFourcc, s.Id, s.TrackType, s.Profile, s.Level, new MediaTrackData(audioTrack, videoTrack, subtitleTrack), s.Bitrate, language, des)); }
/// <summary> /// Add a subtitle track. /// The Source track is set based on the following order. If null, it will skip to the next option. /// 1. Passed in Subitle param /// 2. First preferred Subtitle from source /// 3. First subtitle from source. /// Will not add a subtitle if the source has none. /// </summary> /// <param name="subtitle"> /// The subtitle. Use null to add preferred, or first from source (based on user preference) /// </param> private void Add(Subtitle subtitle) { string preferred = this.UserSettingService.GetUserSetting <string>(UserSettingConstants.NativeLanguageForSubtitles); Subtitle source = subtitle ?? ((this.SourceTracks != null) ? (this.SourceTracks.FirstOrDefault(l => l.Language == preferred) ?? this.SourceTracks.FirstOrDefault(s => s.SubtitleType != SubtitleType.ForeignAudioSearch)) : null); if (source == null) { source = ForeignAudioSearchTrack; } SubtitleTrack track = new SubtitleTrack { SubtitleType = SubtitleType.VobSub, SourceTrack = source, }; this.Task.SubtitleTracks.Add(track); }
/// <summary> /// Encode and play a sample /// </summary> public void Play() { try { this.IsEncoding = true; if (File.Exists(this.CurrentlyPlaying)) { File.Delete(this.CurrentlyPlaying); } } catch (Exception) { this.IsEncoding = false; this.errorService.ShowMessageBox(Resources.StaticPreview_UnableToDeletePreview, Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error); } if (this.Task == null || string.IsNullOrEmpty(Task.Source)) { this.errorService.ShowMessageBox(Resources.StaticPreviewViewModel_ScanFirst, Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error); return; } EncodeTask encodeTask = new EncodeTask(this.Task) { PreviewEncodeDuration = this.Duration, PreviewEncodeStartAt = this.SelectedPreviewImage, PointToPointMode = PointToPointMode.Preview }; // Filename handling. if (string.IsNullOrEmpty(encodeTask.Destination)) { string filename = Path.ChangeExtension(Path.GetTempFileName(), encodeTask.OutputFormat == OutputFormat.Mkv ? "m4v" : "mkv"); encodeTask.Destination = filename; this.CurrentlyPlaying = filename; } else { string directory = Path.GetDirectoryName(encodeTask.Destination) ?? string.Empty; string filename = Path.GetFileNameWithoutExtension(encodeTask.Destination); string extension = Path.GetExtension(encodeTask.Destination); string previewFilename = string.Format("{0}_preview{1}", filename, extension); string previewFullPath = Path.Combine(directory, previewFilename); encodeTask.Destination = previewFullPath; this.CurrentlyPlaying = previewFullPath; } // Setup the encode task as a preview encode encodeTask.IsPreviewEncode = true; encodeTask.PreviewEncodeStartAt = this.SelectedPreviewImage + 1; encodeTask.PreviewEncodeDuration = this.Duration; SubtitleTrack scanTrack = null; foreach (var track in encodeTask.SubtitleTracks) { if (track.SourceTrack != null && track.SourceTrack.SubtitleType == SubtitleType.ForeignAudioSearch) { scanTrack = track; break; } } if (scanTrack != null) { encodeTask.SubtitleTracks.Remove(scanTrack); } QueueTask task = new QueueTask(encodeTask, HBConfigurationFactory.Create(), this.ScannedSource.ScanPath); ThreadPool.QueueUserWorkItem(this.CreatePreview, task); }
/// <summary> /// Remove a Track /// </summary> /// <param name="track"> /// The track. /// </param> public void Remove(SubtitleTrack track) { this.Task.SubtitleTracks.Remove(track); }
internal MediaTrackData(AudioTrack audio, VideoTrack video, SubtitleTrack subtitle) { Audio = audio; Video = video; Subtitle = subtitle; }
//========================================================================== internal SubtitleStream(SubtitleTrack subtitleTrack) : base(subtitleTrack) { // ... }