Added German language file - thx JW 301 :)

Also some cleanup + some shortcuts (+ some testing of TS files)


git-svn-id: https://subtitleedit.googlecode.com/svn/trunk@716 99eadd0c-20b8-1223-b5c4-2a2b2df33de2
This commit is contained in:
niksedk 2011-10-13 20:26:18 +00:00
parent bfc04f7a70
commit 68397dbd57
16 changed files with 2437 additions and 88 deletions

View File

@ -128,6 +128,8 @@ namespace Nikse.SubtitleEdit.Controls
public bool Locked { get; set; }
public double VerticalZoomPercent { get; set; }
public double EndPositionSeconds
{
get
@ -198,6 +200,7 @@ namespace Nikse.SubtitleEdit.Controls
AllowNewSelection = true;
ShowSpectrogram = true;
ShowWaveform = true;
VerticalZoomPercent = 1.0;
}
public void NearestSubtitles(Subtitle subtitle, double currentVideoPositionSeconds, int subtitleIndex)
@ -316,6 +319,9 @@ namespace Nikse.SubtitleEdit.Controls
}
int imageHeight = Height;
int maxHeight = (int)(Math.Max(Math.Abs(_wavePeaks.DataMinValue), Math.Abs(_wavePeaks.DataMaxValue)) + 0.5);
maxHeight = (int)(maxHeight * VerticalZoomPercent);
if (maxHeight < 0)
maxHeight = 1000;
Pen pen = new System.Drawing.Pen(Color);
DrawBackground(graphics);

View File

@ -123,6 +123,8 @@ namespace Nikse.SubtitleEdit.Forms
public void Initialize(Subtitle subtitle)
{
_autoDetectGoogleLanguage = Utilities.AutoDetectGoogleLanguage(subtitle);
if (_autoDetectGoogleLanguage.ToLower() == "zh")
_autoDetectGoogleLanguage = "zh-CHS"; // Note that "zh-CHS" (Simplified Chinese) and "zh-CHT" (Traditional Chinese) are neutral cultures
CultureInfo ci = CultureInfo.GetCultureInfo(_autoDetectGoogleLanguage);
string threeLetterISOLanguageName = ci.ThreeLetterISOLanguageName;

View File

@ -157,8 +157,8 @@
this.pointSyncViaOtherSubtitleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemChangeFrameRate2 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemAutoTranslate = new System.Windows.Forms.ToolStripMenuItem();
this.translatepoweredByMicrosoftToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.translateByGoogleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.translatepoweredByMicrosoftToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.translateFromSwedishToDanishToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -1505,13 +1505,6 @@
this.toolStripMenuItemAutoTranslate.Size = new System.Drawing.Size(97, 20);
this.toolStripMenuItemAutoTranslate.Text = "Auto-translate";
//
// translatepoweredByMicrosoftToolStripMenuItem
//
this.translatepoweredByMicrosoftToolStripMenuItem.Name = "translatepoweredByMicrosoftToolStripMenuItem";
this.translatepoweredByMicrosoftToolStripMenuItem.Size = new System.Drawing.Size(414, 22);
this.translatepoweredByMicrosoftToolStripMenuItem.Text = "Translate (powered by Microsoft)...";
this.translatepoweredByMicrosoftToolStripMenuItem.Click += new System.EventHandler(this.translatepoweredByMicrosoftToolStripMenuItem_Click);
//
// translateByGoogleToolStripMenuItem
//
this.translateByGoogleToolStripMenuItem.Name = "translateByGoogleToolStripMenuItem";
@ -1521,6 +1514,13 @@
this.translateByGoogleToolStripMenuItem.Text = "Translate (powered by Google)...";
this.translateByGoogleToolStripMenuItem.Click += new System.EventHandler(this.TranslateByGoogleToolStripMenuItemClick);
//
// translatepoweredByMicrosoftToolStripMenuItem
//
this.translatepoweredByMicrosoftToolStripMenuItem.Name = "translatepoweredByMicrosoftToolStripMenuItem";
this.translatepoweredByMicrosoftToolStripMenuItem.Size = new System.Drawing.Size(414, 22);
this.translatepoweredByMicrosoftToolStripMenuItem.Text = "Translate (powered by Microsoft)...";
this.translatepoweredByMicrosoftToolStripMenuItem.Click += new System.EventHandler(this.translatepoweredByMicrosoftToolStripMenuItem_Click);
//
// translateFromSwedishToDanishToolStripMenuItem
//
this.translateFromSwedishToDanishToolStripMenuItem.Name = "translateFromSwedishToDanishToolStripMenuItem";

View File

@ -91,6 +91,10 @@ namespace Nikse.SubtitleEdit.Forms
Keys _mainAdjustSetStartAndOffsetTheRest = Keys.None;
Keys _mainAdjustSetEndAndGotoNext = Keys.None;
Keys _mainAdjustInsertViaEndAutoStartAndGoToNext = Keys.None;
Keys _mainInsertAfter = Keys.None;
Keys _mainInsertBefore = Keys.None;
Keys _mainListViewToggleDashes = Keys.None;
Keys _waveformVerticalZoom = Keys.None;
bool _videoLoadedGoToSubPosAndPause = false;
bool _makeHistory = true;
string _cutText = string.Empty;
@ -1434,11 +1438,11 @@ namespace Nikse.SubtitleEdit.Forms
var fi = new FileInfo(fileName);
if (Path.GetExtension(fileName).ToLower() == ".ts" && fi.Length > 10000)
{
//ImportSubtitleFromTransportStream();
//return;
}
//if (Path.GetExtension(fileName).ToLower() == ".ts" && fi.Length > 10000 && IsTransportStream(fileName)) //TODO: Also check mpg, mpeg - and file header!
//{
// ImportSubtitleFromTransportStream();
// return;
//}
if ((Path.GetExtension(fileName).ToLower() == ".mp4" || Path.GetExtension(fileName).ToLower() == ".m4v" || Path.GetExtension(fileName).ToLower() == ".3gp")
&& fi.Length > 10000)
@ -1699,26 +1703,37 @@ namespace Nikse.SubtitleEdit.Forms
}
}
private bool IsTransportStream(string fileName)
{
try
{
var buffer = new byte[1];
var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read) { Position = 0 };
fs.Read(buffer, 0, buffer.Length);
fs.Close();
return buffer[0] == 0x47; // 47hex (71 dec) == TS sync byte
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return false;
}
}
private void SetUndockedWindowsTitle()
{
string title = Configuration.Settings.Language.General.NoVideoLoaded;
if (!string.IsNullOrEmpty(_videoFileName))
title = Path.GetFileNameWithoutExtension(_videoFileName);
try //TODO: Remove in 3.2 final
{
if (_videoControlsUnDocked != null && !_videoControlsUnDocked.IsDisposed)
_videoControlsUnDocked.Text = string.Format(Configuration.Settings.Language.General.ControlsWindowTitle, title);
if (_videoControlsUnDocked != null && !_videoControlsUnDocked.IsDisposed)
_videoControlsUnDocked.Text = string.Format(Configuration.Settings.Language.General.ControlsWindowTitle, title);
if (_videoPlayerUnDocked != null && !_videoPlayerUnDocked.IsDisposed)
_videoPlayerUnDocked.Text = string.Format(Configuration.Settings.Language.General.VideoWindowTitle, title);
if (_videoPlayerUnDocked != null && !_videoPlayerUnDocked.IsDisposed)
_videoPlayerUnDocked.Text = string.Format(Configuration.Settings.Language.General.VideoWindowTitle, title);
if (_waveFormUnDocked != null && !_waveFormUnDocked.IsDisposed)
_waveFormUnDocked.Text = string.Format(Configuration.Settings.Language.General.AudioWindowTitle, title);
}
catch
{
}
if (_waveFormUnDocked != null && !_waveFormUnDocked.IsDisposed)
_waveFormUnDocked.Text = string.Format(Configuration.Settings.Language.General.AudioWindowTitle, title);
}
private void ImportAndOcrBdnXml(string fileName, BdnXml bdnXml, List<string> list)
@ -5818,16 +5833,69 @@ namespace Nikse.SubtitleEdit.Forms
}
}
private void ImportSubtitleFromTransportStream()
private bool ImportSubtitleFromTransportStream()
{
//TransportStreamParser tsParser = new TransportStreamParser();
//tsParser.ParseTsFile(openFileDialog1.FileName);
var tsParser = new Nikse.SubtitleEdit.Logic.TransportStream.TransportStreamParser();
tsParser.ParseTsFile(openFileDialog1.FileName);
//var vobSubOcr = new VobSubOcr();
//vobSubOcr.Initialize(tsParser.MergeVobSubPacks(), null, Configuration.Settings.VobSubOcr, null);
//if (vobSubOcr.ShowDialog(this) == DialogResult.OK)
//{
//}
if (tsParser.SubtitlePacketIds.Count == 0)
{
MessageBox.Show(_language.NoSubtitlesFound);
return false;
}
var log = new StringBuilder();
List<BluRaySupPicture> subtitles = new List<BluRaySupPicture>();
var pesList = tsParser.GetSubtitlePesPackets(tsParser.SubtitlePacketIds[0]);
foreach (var sp in pesList)
{
if (sp.DataBuffer != null)
{
MemoryStream ms = new MemoryStream(sp.DataBuffer);
var list = BluRaySupParser.ParseBluRaySup(ms, log, true);
foreach (var sup in list)
{
//sup.StartTime = p.StartMilliseconds;
//sup.EndTime = p.EndMilliseconds;
subtitles.Add(sup);
// fix overlapping
//if (subtitles.Count > 1 && sub[subtitles.Count - 2].EndMilliseconds > sub[subtitles.Count - 1].StartMilliseconds)
// subtitles[subtitles.Count - 2].EndTime = subtitles[subtitles.Count - 1].StartTime - 1;
}
ms.Close();
}
}
var formSubOcr = new VobSubOcr();
formSubOcr.Initialize(subtitles, Configuration.Settings.VobSubOcr);
if (formSubOcr.ShowDialog(this) == DialogResult.OK)
{
MakeHistoryForUndo(_language.BeforeImportingDvdSubtitle);
_subtitle.Paragraphs.Clear();
SetCurrentFormat(new SubRip().FriendlyName);
_subtitle.WasLoadedWithFrameNumbers = false;
_subtitle.CalculateFrameNumbersFromTimeCodes(CurrentFrameRate);
foreach (Paragraph p in formSubOcr.SubtitleFromOcr.Paragraphs)
{
_subtitle.Paragraphs.Add(p);
}
ShowSource();
SubtitleListview1.Fill(_subtitle, _subtitleAlternate);
_change = true;
_subtitleListViewIndex = -1;
SubtitleListview1.FirstVisibleIndex = -1;
SubtitleListview1.SelectIndexAndEnsureVisible(0);
_fileName = string.Empty;
Text = Title;
Configuration.Settings.Save();
return true;
}
return false;
}
private bool ImportSubtitleFromMp4(string fileName)
@ -6437,18 +6505,28 @@ namespace Nikse.SubtitleEdit.Forms
bool inListView = tabControlSubtitle.SelectedIndex == TabControlListView;
if (e.Modifiers == Keys.Alt && e.KeyCode == Keys.Insert && inListView)
if (audioVisualizer != null && audioVisualizer.Visible)
{
InsertAfter();
e.SuppressKeyPress = true;
textBoxListViewText.Focus();
if (e.KeyData == _waveformVerticalZoom)
{
if (audioVisualizer.VerticalZoomPercent > 0.2)
audioVisualizer.VerticalZoomPercent -= 0.1;
else
audioVisualizer.VerticalZoomPercent = 1;
e.SuppressKeyPress = true;
}
}
else if (e.Modifiers == (Keys.Shift | Keys.Control) && e.KeyCode == Keys.Insert && inListView)
else if (_mainInsertBefore == e.KeyData && inListView)
{
InsertBefore();
e.SuppressKeyPress = true;
textBoxListViewText.Focus();
}
else if (_mainListViewToggleDashes == e.KeyData && inListView)
{
ToggleDashes();
e.SuppressKeyPress = true;
}
else if (e.Modifiers == Keys.Control && e.KeyCode == Keys.Z)
{
ShowHistoryforUndoToolStripMenuItemClick(null, null);
@ -6871,6 +6949,74 @@ namespace Nikse.SubtitleEdit.Forms
// put new entries above tabs
}
private void ToggleDashes()
{
int index = FirstSelectedIndex;
if (index >= 0)
{
bool hasStartDash = false;
var p = _subtitle.Paragraphs[index];
string[] lines = p.Text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (string line in lines)
{
if (line.Trim().StartsWith("-") || line.Trim().StartsWith("<i>-") || line.Trim().StartsWith("<i> -"))
hasStartDash = true;
}
if (hasStartDash)
RemoveDashes();
else
AddDashes();
}
}
private void AddDashes()
{
foreach (int index in SubtitleListview1.SelectedIndices)
{
var p = _subtitle.Paragraphs[index];
string[] lines = p.Text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var sb = new StringBuilder();
foreach (string line in lines)
{
if (line.Trim().StartsWith("-") || line.Trim().StartsWith("<i>-") || line.Trim().StartsWith("<i> -"))
sb.AppendLine(line);
else if (line.Trim().StartsWith("<i>") && line.Trim().Length > 3)
sb.AppendLine("<i>-" + line.Substring(3));
else
sb.AppendLine("- " + line);
}
string text = sb.ToString().Trim(); ;
_subtitle.Paragraphs[index].Text = text;
SubtitleListview1.SetText(index, text);
if (index == _subtitleListViewIndex)
textBoxListViewText.Text = text;
}
}
private void RemoveDashes()
{
foreach (int index in SubtitleListview1.SelectedIndices)
{
var p = _subtitle.Paragraphs[index];
string[] lines = p.Text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var sb = new StringBuilder();
foreach (string line in lines)
{
if (line.Trim().StartsWith("-"))
sb.AppendLine(line.TrimStart().TrimStart('-').TrimStart());
else if (line.Trim().StartsWith("<i>-") || line.Trim().StartsWith("<i> -"))
sb.AppendLine("<i>" + line.TrimStart().Substring(3).TrimStart().TrimStart('-').TrimStart());
else
sb.AppendLine(line);
}
string text = sb.ToString().Trim(); ;
_subtitle.Paragraphs[index].Text = text;
SubtitleListview1.SetText(index, text);
if (index == _subtitleListViewIndex)
textBoxListViewText.Text = text;
}
}
private void SetTitle()
{
Text = Title;
@ -6981,12 +7127,12 @@ namespace Nikse.SubtitleEdit.Forms
{
ToolStripMenuItemDeleteClick(null, null);
}
else if (e.Modifiers == Keys.Shift && e.KeyCode == Keys.Insert)
else if (e.KeyData == _mainInsertBefore)
{
InsertBefore();
e.SuppressKeyPress = true;
}
else if (e.KeyCode == Keys.Insert)
else if (e.KeyData == _mainInsertAfter)
{
InsertAfter();
e.SuppressKeyPress = true;
@ -8992,10 +9138,14 @@ namespace Nikse.SubtitleEdit.Forms
toolStripMenuItemAdjustAllTimes.ShortcutKeys = Utilities.GetKeys(Configuration.Settings.Shortcuts.MainSynchronizationAdjustTimes);
italicToolStripMenuItem.ShortcutKeys = Utilities.GetKeys(Configuration.Settings.Shortcuts.MainListViewItalic);
_mainListViewToggleDashes = Utilities.GetKeys(Configuration.Settings.Shortcuts.MainListViewToggleDashes);
italicToolStripMenuItem1.ShortcutKeys = Utilities.GetKeys(Configuration.Settings.Shortcuts.MainTextBoxItalic);
_mainAdjustSetStartAndOffsetTheRest = Utilities.GetKeys(Configuration.Settings.Shortcuts.MainAdjustSetStartAndOffsetTheRest);
_mainAdjustSetEndAndGotoNext = Utilities.GetKeys(Configuration.Settings.Shortcuts.MainAdjustSetEndAndGotoNext);
_mainAdjustInsertViaEndAutoStartAndGoToNext = Utilities.GetKeys(Configuration.Settings.Shortcuts.MainAdjustViaEndAutoStartAndGoToNext);
_mainInsertAfter = Utilities.GetKeys(Configuration.Settings.Shortcuts.MainInsertAfter);
_mainInsertBefore = Utilities.GetKeys(Configuration.Settings.Shortcuts.MainInsertBefore);
_waveformVerticalZoom = Utilities.GetKeys(Configuration.Settings.Shortcuts.WaveformVerticalZoom);
}
private void LoadPlugins()

View File

@ -681,7 +681,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAD2
CAAAAk1TRnQBSQFMAgEBAgEAAYgBCwGIAQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
CAAAAk1TRnQBSQFMAgEBAgEAAagBCwGoAQsBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA

View File

@ -51,7 +51,6 @@ namespace Nikse.SubtitleEdit.Forms
labelMaxCharacters.Text = Configuration.Settings.Language.MergedShortLines.MaximumCharacters;
labelMaxMillisecondsBetweenLines.Text = Configuration.Settings.Language.MergedShortLines.MaximumMillisecondsBetween;
checkBoxOnlyContinuationLines.Visible = !string.IsNullOrEmpty(Configuration.Settings.Language.MergedShortLines.OnlyMergeContinuationLines); //TODO: Remove in se 3.2
checkBoxOnlyContinuationLines.Text = Configuration.Settings.Language.MergedShortLines.OnlyMergeContinuationLines;
listViewFixes.Columns[0].Text = Configuration.Settings.Language.General.Apply;

View File

@ -423,10 +423,6 @@ namespace Nikse.SubtitleEdit.Forms
comboBoxSpectrogramAppearance.SelectedIndex = 1;
//<MainFileNew>Control+N</MainFileNew>
//<MainFileOpen>Control+O</MainFileOpen>
//<MainFileSave>Control+S</MainFileSave>
//<MainFileSaveAs>Control+Shift+S</MainFileSaveAs>
TreeNode fileNode = new TreeNode(Configuration.Settings.Language.Main.Menu.File.Title);
fileNode.Nodes.Add(Configuration.Settings.Language.Main.Menu.File.New + GetShortcutText(Configuration.Settings.Shortcuts.MainFileNew));
fileNode.Nodes.Add(Configuration.Settings.Language.Main.Menu.File.Open + GetShortcutText(Configuration.Settings.Shortcuts.MainFileOpen));
@ -435,10 +431,6 @@ namespace Nikse.SubtitleEdit.Forms
fileNode.Nodes.Add(Configuration.Settings.Language.Main.Menu.File.Export + " -> " + Configuration.Settings.Language.Main.Menu.File.ExportEbu + GetShortcutText(Configuration.Settings.Shortcuts.MainFileExportEbu));
treeViewShortcuts.Nodes.Add(fileNode);
//<MainEditFind>Control+F</MainEditFind>
//<MainEditFindNext>F3</MainEditFindNext>
//<MainEditReplace>Control+H</MainEditReplace>
//<MainEditGoToLineNumber>Control+G</MainEditGoToLineNumber>
TreeNode editNode = new TreeNode(Configuration.Settings.Language.Main.Menu.Edit.Title);
editNode.Nodes.Add(Configuration.Settings.Language.Main.Menu.Edit.Find + GetShortcutText(Configuration.Settings.Shortcuts.MainEditFind));
editNode.Nodes.Add(Configuration.Settings.Language.Main.Menu.Edit.FindNext + GetShortcutText(Configuration.Settings.Shortcuts.MainEditFindNext));
@ -450,23 +442,22 @@ namespace Nikse.SubtitleEdit.Forms
toolsNode.Nodes.Add(Configuration.Settings.Language.Main.Menu.Tools.FixCommonErrors + GetShortcutText(Configuration.Settings.Shortcuts.MainToolsFixCommonErrors));
treeViewShortcuts.Nodes.Add(toolsNode);
//<MainVideoShowHideVideo>Control+Q</MainVideoShowHideVideo>
TreeNode videoNode = new TreeNode(Configuration.Settings.Language.Main.Menu.Video.Title);
videoNode.Nodes.Add(Configuration.Settings.Language.Main.Menu.Video.ShowHideVideo + GetShortcutText(Configuration.Settings.Shortcuts.MainVideoShowHideVideo));
videoNode.Nodes.Add(Configuration.Settings.Language.Settings.ToggleDockUndockOfVideoControls + GetShortcutText(Configuration.Settings.Shortcuts.MainVideoToggleVideoControls));
treeViewShortcuts.Nodes.Add(videoNode);
//<MainSynchronizationAdjustTimes>Control+Shift+A</MainSynchronizationAdjustTimes>
TreeNode SyncNode = new TreeNode(Configuration.Settings.Language.Main.Menu.Synchronization.Title);
SyncNode.Nodes.Add(Configuration.Settings.Language.Main.Menu.Synchronization.AdjustAllTimes + GetShortcutText(Configuration.Settings.Shortcuts.MainSynchronizationAdjustTimes));
treeViewShortcuts.Nodes.Add(SyncNode);
//<MainListViewItalic>Control+G</MainListViewItalic>
TreeNode ListViewNode = new TreeNode(Configuration.Settings.Language.Main.Controls.ListView);
ListViewNode.Nodes.Add(Configuration.Settings.Language.General.Italic + GetShortcutText(Configuration.Settings.Shortcuts.MainListViewItalic));
ListViewNode.Nodes.Add(Configuration.Settings.Language.Main.Menu.ContextMenu.InsertAfter + GetShortcutText(Configuration.Settings.Shortcuts.MainInsertAfter));
ListViewNode.Nodes.Add(Configuration.Settings.Language.Main.Menu.ContextMenu.InsertBefore + GetShortcutText(Configuration.Settings.Shortcuts.MainInsertBefore));
ListViewNode.Nodes.Add("Toggle dashes" + GetShortcutText(Configuration.Settings.Shortcuts.MainListViewToggleDashes));
treeViewShortcuts.Nodes.Add(ListViewNode);
//<MainTextBoxItalic>Control+I</MainTextBoxItalic>
TreeNode TextBoxNode = new TreeNode(Configuration.Settings.Language.Settings.TextBox);
TextBoxNode.Nodes.Add(Configuration.Settings.Language.General.Italic + GetShortcutText(Configuration.Settings.Shortcuts.MainTextBoxItalic));
treeViewShortcuts.Nodes.Add(TextBoxNode);
@ -477,6 +468,11 @@ namespace Nikse.SubtitleEdit.Forms
adjustNode.Nodes.Add(Configuration.Settings.Language.Settings.AdjustViaEndAutoStartAndGoToNext + GetShortcutText(Configuration.Settings.Shortcuts.MainAdjustViaEndAutoStartAndGoToNext));
treeViewShortcuts.Nodes.Add(adjustNode);
TreeNode audioVisualizerNode = new TreeNode(Configuration.Settings.Language.Settings.WaveformAndSpectrogram);
audioVisualizerNode.Nodes.Add("Vertical zoom" + GetShortcutText(Configuration.Settings.Shortcuts.WaveformVerticalZoom));
treeViewShortcuts.Nodes.Add(audioVisualizerNode);
foreach (TreeNode node in treeViewShortcuts.Nodes)
{
node.Text = node.Text.Replace("&", string.Empty);
@ -886,6 +882,12 @@ namespace Nikse.SubtitleEdit.Forms
string text = node.Text.Substring(0, node.Text.IndexOf("[")).Trim();
if (text == Configuration.Settings.Language.General.Italic.Replace("&", string.Empty))
Configuration.Settings.Shortcuts.MainListViewItalic = GetShortcut(node.Text);
else if (text == Configuration.Settings.Language.Main.Menu.ContextMenu.InsertAfter.Replace("&", string.Empty))
Configuration.Settings.Shortcuts.MainInsertAfter = GetShortcut(node.Text);
else if (text == Configuration.Settings.Language.Main.Menu.ContextMenu.InsertBefore.Replace("&", string.Empty))
Configuration.Settings.Shortcuts.MainInsertBefore = GetShortcut(node.Text);
else if (text == ("Toggle dashes").Replace("&", string.Empty))
Configuration.Settings.Shortcuts.MainListViewToggleDashes = GetShortcut(node.Text);
}
}
@ -915,6 +917,17 @@ namespace Nikse.SubtitleEdit.Forms
}
}
//Audio-visualizer
foreach (TreeNode node in treeViewShortcuts.Nodes[8].Nodes)
{
if (node.Text.Contains("["))
{
string text = node.Text.Substring(0, node.Text.IndexOf("[")).Trim();
if (text == ("Vertical zoom").Replace("&", string.Empty))
Configuration.Settings.Shortcuts.WaveformVerticalZoom = GetShortcut(node.Text);
}
}
Configuration.Settings.Save();
}

View File

@ -29,7 +29,6 @@ namespace Nikse.SubtitleEdit.Forms
public WaveFormUnDocked()
{
// TODO: Complete member initialization
}
private void WaveFormUnDocked_FormClosing(object sender, FormClosingEventArgs e)

1283
src/Languages/de-DE.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -427,10 +427,14 @@ namespace Nikse.SubtitleEdit.Logic
public string MainVideoToggleVideoControls { get; set; }
public string MainSynchronizationAdjustTimes { get; set; }
public string MainListViewItalic { get; set; }
public string MainListViewToggleDashes { get; set; }
public string MainTextBoxItalic { get; set; }
public string MainAdjustSetStartAndOffsetTheRest { get; set; }
public string MainAdjustSetEndAndGotoNext { get; set; }
public string MainAdjustViaEndAutoStartAndGoToNext { get; set; }
public string MainInsertAfter { get; set; }
public string MainInsertBefore { get; set; }
public string WaveformVerticalZoom { get; set; }
public Shortcuts()
{
@ -451,6 +455,9 @@ namespace Nikse.SubtitleEdit.Logic
MainAdjustSetStartAndOffsetTheRest = "Control+Space";
MainAdjustSetEndAndGotoNext = "Shift+Space";
MainAdjustViaEndAutoStartAndGoToNext = "Shift+End";
MainInsertAfter = "Alt+Ins";
MainInsertBefore = "Control+Shift+Ins";
WaveformVerticalZoom = string.Empty;
}
}
@ -530,10 +537,8 @@ namespace Nikse.SubtitleEdit.Logic
public void Save()
{
//slow
//Serialize(Configuration.BaseDirectory + "Settings.xml", this);
//this is too slow: Serialize(Configuration.BaseDirectory + "Settings.xml", this);
//Fast - TODO: Fix in release
CustomSerialize(Configuration.SettingsFileName, this);
}
@ -553,11 +558,9 @@ namespace Nikse.SubtitleEdit.Logic
{
try
{
//TODO: Fix in release
settings = CustomDeserialize(settingsFileName); // 15 msecs
//too slow... :(
//settings = Deserialize(Configuration.BaseDirectory + "Settings.xml"); // 688 msecs
//too slow... :( - settings = Deserialize(Configuration.BaseDirectory + "Settings.xml"); // 688 msecs
}
catch
{
@ -1138,6 +1141,9 @@ namespace Nikse.SubtitleEdit.Logic
subNode = node.SelectSingleNode("MainListViewItalic");
if (subNode != null)
settings.Shortcuts.MainListViewItalic = subNode.InnerText;
subNode = node.SelectSingleNode("MainListViewToggleDashes");
if (subNode != null)
settings.Shortcuts.MainListViewToggleDashes = subNode.InnerText;
subNode = node.SelectSingleNode("MainTextBoxItalic");
if (subNode != null)
settings.Shortcuts.MainTextBoxItalic = subNode.InnerText;
@ -1150,6 +1156,15 @@ namespace Nikse.SubtitleEdit.Logic
subNode = node.SelectSingleNode("MainAdjustViaEndAutoStartAndGoToNext");
if (subNode != null)
settings.Shortcuts.MainAdjustViaEndAutoStartAndGoToNext = subNode.InnerText;
subNode = node.SelectSingleNode("MainInsertAfter");
if (subNode != null)
settings.Shortcuts.MainInsertAfter = subNode.InnerText;
subNode = node.SelectSingleNode("MainInsertBefore");
if (subNode != null)
settings.Shortcuts.MainInsertBefore = subNode.InnerText;
subNode = node.SelectSingleNode("WaveformVerticalZoom");
if (subNode != null)
settings.Shortcuts.WaveformVerticalZoom = subNode.InnerText;
}
settings.RemoveTextForHearingImpaired = new RemoveTextForHearingImpairedSettings();
@ -1410,10 +1425,14 @@ namespace Nikse.SubtitleEdit.Logic
textWriter.WriteElementString("MainVideoToggleVideoControls", settings.Shortcuts.MainVideoToggleVideoControls);
textWriter.WriteElementString("MainSynchronizationAdjustTimes", settings.Shortcuts.MainSynchronizationAdjustTimes);
textWriter.WriteElementString("MainListViewItalic", settings.Shortcuts.MainListViewItalic);
textWriter.WriteElementString("MainListViewToggleDashes", settings.Shortcuts.MainListViewToggleDashes);
textWriter.WriteElementString("MainTextBoxItalic", settings.Shortcuts.MainTextBoxItalic);
textWriter.WriteElementString("MainAdjustSetStartAndOffsetTheRest", settings.Shortcuts.MainAdjustSetStartAndOffsetTheRest);
textWriter.WriteElementString("MainAdjustSetEndAndGotoNext", settings.Shortcuts.MainAdjustSetEndAndGotoNext);
textWriter.WriteElementString("MainAdjustViaEndAutoStartAndGoToNext", settings.Shortcuts.MainAdjustViaEndAutoStartAndGoToNext);
textWriter.WriteElementString("MainInsertAfter", settings.Shortcuts.MainInsertAfter);
textWriter.WriteElementString("MainInsertBefore", settings.Shortcuts.MainInsertBefore);
textWriter.WriteElementString("WaveformVerticalZoom", settings.Shortcuts.WaveformVerticalZoom);
textWriter.WriteEndElement();
textWriter.WriteStartElement("RemoveTextForHearingImpaired", "");

View File

@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Nikse.SubtitleEdit.Logic.TransportStream
{
public class AdaptationField
{
/// <summary>
/// Number of bytes in the adaptation field immediately following the Length
/// </summary>
public int Length { get; set; }
public bool DiscontinuityIndicator { get; set; }
public bool RandomAccessIndicator { get; set; }
public bool ElementaryStreamPriorityIndicator { get; set; }
/// <summary>
/// '1' indicates that the adaptation field contains a PCR field coded in two parts
/// </summary>
public bool PcrFlag { get; set; }
/// <summary>
/// '1' indicates that the adaptation field contains an OPCR field coded in two parts
/// </summary>
public bool OpcrFlag { get; set; }
/// <summary>
/// '1' indicates that a splice countdown field shall be present in the associated adaptation field
/// </summary>
public bool SplicingPointFlag { get; set; }
/// <summary>
/// 1' indicates that the adaptation field contains one or more private data bytes
/// </summary>
public bool TransportPrivateDataFlag { get; set; }
/// <summary>
/// '1' indicates the presence of an adaptation field extension
/// </summary>
public bool AdaptationFieldExtensionFlag { get; set; }
public int ProgramClockReferenceBase { get; set; }
public int ProgramClockReferenceExtension { get; set; }
public int OriginalProgramClockReferenceBase { get; set; }
public int OriginalProgramClockReferenceExtension { get; set; }
public int SpliceCountdown { get; set; }
public int TransportPrivateDataLength { get; set; }
public byte[] TransportPrivateData { get; set; }
public int AdaptationFieldExtensionLength { get; set; }
public AdaptationField(byte[] packetBuffer)
{
Length = packetBuffer[4];
DiscontinuityIndicator = 1 == packetBuffer[5] >> 7;
RandomAccessIndicator = 1 == (packetBuffer[5] & 64); // and with 01000000 to get second byte
ElementaryStreamPriorityIndicator = 1 == (packetBuffer[5] & 32); // and with 00100000 to get third byte
PcrFlag = 1 == (packetBuffer[5] & 16); // and with 00010000 to get fourth byte
OpcrFlag = 1 == (packetBuffer[5] & 8); // and with 00001000 to get fifth byte
SplicingPointFlag = 1 == (packetBuffer[5] & 4); // and with 00000100 to get sixth byte
TransportPrivateDataFlag = 1 == (packetBuffer[5] & 2); // and with 00000100 to get seventh byte
AdaptationFieldExtensionFlag = 1 == (packetBuffer[5] & 1); // and with 00000010 to get 8th byte
int index = 6;
if (PcrFlag)
{
ProgramClockReferenceBase = (packetBuffer[index] * 256 + packetBuffer[index + 1]) << 1;
ProgramClockReferenceBase += packetBuffer[index + 2] >> 7;
ProgramClockReferenceExtension = (packetBuffer[index + 2] & Helper.B00000001) * 256 + packetBuffer[index + 3];
index += 4;
}
if (OpcrFlag)
{
OriginalProgramClockReferenceBase = (packetBuffer[index] * 256 + packetBuffer[index + 1]) << 1;
OriginalProgramClockReferenceBase += packetBuffer[index + 2] >> 7;
OriginalProgramClockReferenceExtension = (packetBuffer[index + 2] & Helper.B00000001) * 256 + packetBuffer[index + 3];
index += 4;
}
if (SplicingPointFlag)
{
SpliceCountdown = packetBuffer[index];
index++;
}
if (TransportPrivateDataFlag)
{
TransportPrivateDataLength = packetBuffer[index];
index++;
TransportPrivateData = new byte[TransportPrivateDataLength];
Buffer.BlockCopy(packetBuffer, index, TransportPrivateData, 0, TransportPrivateDataLength);
index += TransportPrivateDataLength;
}
if (AdaptationFieldExtensionFlag)
{
AdaptationFieldExtensionLength = packetBuffer[index];
}
}
}
}

View File

@ -0,0 +1,329 @@
using System;
using System.Text;
namespace Nikse.SubtitleEdit.Logic.TransportStream
{
public static class Helper
{
#region Binary constants
public const int B00000000 = 0;
public const int B00000001 = 1;
public const int B00000010 = 2;
public const int B00000011 = 3;
public const int B00000100 = 4;
public const int B00000101 = 5;
public const int B00000110 = 6;
public const int B00000111 = 7;
public const int B00001000 = 8;
public const int B00001001 = 9;
public const int B00001010 = 10;
public const int B00001011 = 11;
public const int B00001100 = 12;
public const int B00001101 = 13;
public const int B00001110 = 14;
public const int B00001111 = 15;
public const int B00010000 = 16;
public const int B00010001 = 17;
public const int B00010010 = 18;
public const int B00010011 = 19;
public const int B00010100 = 20;
public const int B00010101 = 21;
public const int B00010110 = 22;
public const int B00010111 = 23;
public const int B00011000 = 24;
public const int B00011001 = 25;
public const int B00011010 = 26;
public const int B00011011 = 27;
public const int B00011100 = 28;
public const int B00011101 = 29;
public const int B00011110 = 30;
public const int B00011111 = 31;
public const int B00100000 = 32;
public const int B00100001 = 33;
public const int B00100010 = 34;
public const int B00100011 = 35;
public const int B00100100 = 36;
public const int B00100101 = 37;
public const int B00100110 = 38;
public const int B00100111 = 39;
public const int B00101000 = 40;
public const int B00101001 = 41;
public const int B00101010 = 42;
public const int B00101011 = 43;
public const int B00101100 = 44;
public const int B00101101 = 45;
public const int B00101110 = 46;
public const int B00101111 = 47;
public const int B00110000 = 48;
public const int B00110001 = 49;
public const int B00110010 = 50;
public const int B00110011 = 51;
public const int B00110100 = 52;
public const int B00110101 = 53;
public const int B00110110 = 54;
public const int B00110111 = 55;
public const int B00111000 = 56;
public const int B00111001 = 57;
public const int B00111010 = 58;
public const int B00111011 = 59;
public const int B00111100 = 60;
public const int B00111101 = 61;
public const int B00111110 = 62;
public const int B00111111 = 63;
public const int B01000000 = 64;
public const int B01000001 = 65;
public const int B01000010 = 66;
public const int B01000011 = 67;
public const int B01000100 = 68;
public const int B01000101 = 69;
public const int B01000110 = 70;
public const int B01000111 = 71;
public const int B01001000 = 72;
public const int B01001001 = 73;
public const int B01001010 = 74;
public const int B01001011 = 75;
public const int B01001100 = 76;
public const int B01001101 = 77;
public const int B01001110 = 78;
public const int B01001111 = 79;
public const int B01010000 = 80;
public const int B01010001 = 81;
public const int B01010010 = 82;
public const int B01010011 = 83;
public const int B01010100 = 84;
public const int B01010101 = 85;
public const int B01010110 = 86;
public const int B01010111 = 87;
public const int B01011000 = 88;
public const int B01011001 = 89;
public const int B01011010 = 90;
public const int B01011011 = 91;
public const int B01011100 = 92;
public const int B01011101 = 93;
public const int B01011110 = 94;
public const int B01011111 = 95;
public const int B01100000 = 96;
public const int B01100001 = 97;
public const int B01100010 = 98;
public const int B01100011 = 99;
public const int B01100100 = 100;
public const int B01100101 = 101;
public const int B01100110 = 102;
public const int B01100111 = 103;
public const int B01101000 = 104;
public const int B01101001 = 105;
public const int B01101010 = 106;
public const int B01101011 = 107;
public const int B01101100 = 108;
public const int B01101101 = 109;
public const int B01101110 = 110;
public const int B01101111 = 111;
public const int B01110000 = 112;
public const int B01110001 = 113;
public const int B01110010 = 114;
public const int B01110011 = 115;
public const int B01110100 = 116;
public const int B01110101 = 117;
public const int B01110110 = 118;
public const int B01110111 = 119;
public const int B01111000 = 120;
public const int B01111001 = 121;
public const int B01111010 = 122;
public const int B01111011 = 123;
public const int B01111100 = 124;
public const int B01111101 = 125;
public const int B01111110 = 126;
public const int B01111111 = 127;
public const int B10000000 = 128;
public const int B10000001 = 129;
public const int B10000010 = 130;
public const int B10000011 = 131;
public const int B10000100 = 132;
public const int B10000101 = 133;
public const int B10000110 = 134;
public const int B10000111 = 135;
public const int B10001000 = 136;
public const int B10001001 = 137;
public const int B10001010 = 138;
public const int B10001011 = 139;
public const int B10001100 = 140;
public const int B10001101 = 141;
public const int B10001110 = 142;
public const int B10001111 = 143;
public const int B10010000 = 144;
public const int B10010001 = 145;
public const int B10010010 = 146;
public const int B10010011 = 147;
public const int B10010100 = 148;
public const int B10010101 = 149;
public const int B10010110 = 150;
public const int B10010111 = 151;
public const int B10011000 = 152;
public const int B10011001 = 153;
public const int B10011010 = 154;
public const int B10011011 = 155;
public const int B10011100 = 156;
public const int B10011101 = 157;
public const int B10011110 = 158;
public const int B10011111 = 159;
public const int B10100000 = 160;
public const int B10100001 = 161;
public const int B10100010 = 162;
public const int B10100011 = 163;
public const int B10100100 = 164;
public const int B10100101 = 165;
public const int B10100110 = 166;
public const int B10100111 = 167;
public const int B10101000 = 168;
public const int B10101001 = 169;
public const int B10101010 = 170;
public const int B10101011 = 171;
public const int B10101100 = 172;
public const int B10101101 = 173;
public const int B10101110 = 174;
public const int B10101111 = 175;
public const int B10110000 = 176;
public const int B10110001 = 177;
public const int B10110010 = 178;
public const int B10110011 = 179;
public const int B10110100 = 180;
public const int B10110101 = 181;
public const int B10110110 = 182;
public const int B10110111 = 183;
public const int B10111000 = 184;
public const int B10111001 = 185;
public const int B10111010 = 186;
public const int B10111011 = 187;
public const int B10111100 = 188;
public const int B10111101 = 189;
public const int B10111110 = 190;
public const int B10111111 = 191;
public const int B11000000 = 192;
public const int B11000001 = 193;
public const int B11000010 = 194;
public const int B11000011 = 195;
public const int B11000100 = 196;
public const int B11000101 = 197;
public const int B11000110 = 198;
public const int B11000111 = 199;
public const int B11001000 = 200;
public const int B11001001 = 201;
public const int B11001010 = 202;
public const int B11001011 = 203;
public const int B11001100 = 204;
public const int B11001101 = 205;
public const int B11001110 = 206;
public const int B11001111 = 207;
public const int B11010000 = 208;
public const int B11010001 = 209;
public const int B11010010 = 210;
public const int B11010011 = 211;
public const int B11010100 = 212;
public const int B11010101 = 213;
public const int B11010110 = 214;
public const int B11010111 = 215;
public const int B11011000 = 216;
public const int B11011001 = 217;
public const int B11011010 = 218;
public const int B11011011 = 219;
public const int B11011100 = 220;
public const int B11011101 = 221;
public const int B11011110 = 222;
public const int B11011111 = 223;
public const int B11100000 = 224;
public const int B11100001 = 225;
public const int B11100010 = 226;
public const int B11100011 = 227;
public const int B11100100 = 228;
public const int B11100101 = 229;
public const int B11100110 = 230;
public const int B11100111 = 231;
public const int B11101000 = 232;
public const int B11101001 = 233;
public const int B11101010 = 234;
public const int B11101011 = 235;
public const int B11101100 = 236;
public const int B11101101 = 237;
public const int B11101110 = 238;
public const int B11101111 = 239;
public const int B11110000 = 240;
public const int B11110001 = 241;
public const int B11110010 = 242;
public const int B11110011 = 243;
public const int B11110100 = 244;
public const int B11110101 = 245;
public const int B11110110 = 246;
public const int B11110111 = 247;
public const int B11111000 = 248;
public const int B11111001 = 249;
public const int B11111010 = 250;
public const int B11111011 = 251;
public const int B11111100 = 252;
public const int B11111101 = 253;
public const int B11111110 = 254;
public const int B11111111 = 255;
#endregion
public static string IntToHex(UInt64 value, int digits)
{
return value.ToString("X").PadLeft(digits, '0');
}
public static string IntToHex(int value, int digits)
{
return value.ToString("X").PadLeft(digits, '0');
}
public static string IntToBin(long value, int digits)
{
return Convert.ToString(value, 2).PadLeft(digits, '0');
}
public static UInt32 GetEndian(byte[] buffer, int index, int count)
{
UInt32 result = 0;
for (int i = 0; i < count; i++)
result = (result << 8) + buffer[index + i];
return result;
}
public static int GetLittleEndian32(byte[] buffer, int index)
{
return ((int)buffer[index + 3] << 24 | (int)buffer[index + 2] << 16 | (int)buffer[index + 1] << 8 | (int)buffer[index + 0]);
}
//private int Swap4Bytes(byte[] b)
//{
// return ((int)b[3] << 24 | (int)b[2] << 16 | (int)b[1] << 8 | (int)b[0]);
//}
/// <summary>
/// Get two bytes word stored in endian order
/// </summary>
/// <param name="buffer">Byte array</param>
/// <param name="index">Index in byte array</param>
/// <returns>Word as int</returns>
public static int GetEndianWord(byte[] buffer, int index)
{
if (index +1 < buffer.Length)
return (buffer[index] << 8) + buffer[index+1];
return 0;
}
public static string GetBinaryString(byte[] buffer, int index, int count)
{
var sb = new StringBuilder();
for (int i=0; i < count; i++)
sb.Append(Convert.ToString(buffer[index + i], 2).PadLeft(8, '0'));
return sb.ToString();
}
public static UInt64 GetUInt32FromBinaryString(string binaryValue)
{
return Convert.ToUInt32(binaryValue, 2);
}
}
}

View File

@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Nikse.SubtitleEdit.Logic.TransportStream
{
/// <summary>
/// MPEG transport stream packet
/// </summary>
public class Packet
{
/// <summary>
/// ID byte of TS Packet
/// </summary>
public const byte SynchronizationByte = 0x47; // 74 decimal, or 01000111 binary
/// <summary>
/// Null packets can ensure that the stream maintains a constant bitrate. Null packets is to be ignored
/// </summary>
public const int NullPacketId = 0x1FFF;
/// <summary>
/// Program Association Table: lists all programs available in the transport stream.
/// </summary>
public const int ProgramAssociationTablePacketId = 0;
/// <summary>
///
/// </summary>
public const int ConditionalAccessTablePacketId = 1;
/// <summary>
///
/// </summary>
public const int TransportStreamDescriptionTablePacketId = 2;
/// <summary>
/// Set by demodulator if can't correct errors in the stream, to tell the demultiplexer that the packet has an uncorrectable error
/// </summary>
public bool TransportErrorIndicator { get; set; }
/// <summary>
/// Start of PES data or PSI
/// </summary>
public bool PayloadUnitStartIndicator { get; set; }
/// <summary>
/// Higher priority than other packets with the same PID
/// </summary>
public bool TransportPriority { get; set; }
public int PacketId { get; set; }
/// <summary>
/// 1 = Reserved for future use, 10 = Scrambled with even key, 11 = Scrambled with odd key
/// </summary>
public int ScramblingControl { get; set; }
/// <summary>
/// 1 = no adaptation fields (payload only), 10 = adaptation field only, 11 = adaptation field and payload
/// </summary>
public int AdaptationFieldControl { get; set; }
/// <summary>
/// Incremented only when a payload is present (AdaptationFieldExist = 10 or 11). Starts at 0.
/// </summary>
public int ContinuityCounter { get; set; }
public int AdaptionFieldLength { get; set; }
public AdaptationField AdaptationField { get; private set; }
public bool IsNullPacket { get { return PacketId == NullPacketId; } }
public bool IsProgramAssociationTable { get { return PacketId == ProgramAssociationTablePacketId; } }
public byte[] Payload { get; private set; }
public bool IsPrivateStream1
{
get
{
if (Payload == null || Payload.Length < 4)
return false;
return Payload[0] == 0 &&
Payload[1] == 0 &&
Payload[2] == 1 &&
Payload[3] == 0xbd; // 0xbd == 189 - MPEG-2 Private stream 1 (non MPEG audio, subpictures)
}
}
public ProgramAssociationTable ProgramAssociationTable { get; private set; }
public Packet(byte[] packetBuffer)
{
TransportErrorIndicator = 1 == packetBuffer[1] >> 7; // Set by demodulator if can't correct errors in the stream, to tell the demultiplexer that the packet has an uncorrectable error
PayloadUnitStartIndicator = 1 == ((packetBuffer[1] & 64) >> 6); // and with 01000000 to get second byte - 1 means start of PES data or PSI otherwise zero
TransportPriority = 1 == ((packetBuffer[1] & 32) >> 5); // and with 00100000 to get third byte - 1 means higher priority than other packets with the same PID
PacketId = (packetBuffer[1] & 31) * 256 + packetBuffer[2];// and with 00011111 to get last 5 bytes
ScramblingControl = packetBuffer[3] >> 6; // '00' = Not scrambled. The following per DVB spec:[12] '01' = Reserved for future use, '10' = Scrambled with even key, '11' = Scrambled with odd key
AdaptationFieldControl = (packetBuffer[3] & 48) >> 4; // and with 00110000, 01 = no adaptation fields (payload only), 10 = adaptation field only, 11 = adaptation field and payload
ContinuityCounter = packetBuffer[3] & 15;
AdaptionFieldLength = AdaptationFieldControl > 1 ? (0xFF & packetBuffer[4]) + 1 : 0;
if (AdaptationFieldControl == Helper.B00000010 || AdaptationFieldControl == Helper.B00000011)
AdaptationField = new AdaptationField(packetBuffer);
if (AdaptationFieldControl == Helper.B00000001 || AdaptationFieldControl == Helper.B00000011) // Payload exists - binary '01' || '11'
{
int payloadStart = 4;
if (AdaptationField != null)
payloadStart += (1 + AdaptationField.Length);
if (PacketId == ProgramAssociationTablePacketId) // PAT = Program Association Table: lists all programs available in the transport stream.
{
ProgramAssociationTable = new ProgramAssociationTable(packetBuffer, payloadStart+1); // TODO: what index?
}
//if (PayloadUnitStartIndicator)
// payloadStart += packetBuffer[payloadStart];
// Save payload
Payload = new byte[packetBuffer.Length - payloadStart];
Buffer.BlockCopy(packetBuffer, payloadStart, Payload, 0, Payload.Length);
}
}
}
}

View File

@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Nikse.SubtitleEdit.Logic.TransportStream
{
/// <summary>
/// http://www.mpucoder.com/DVD/pes-hdr.html
/// </summary>
public class PacketizedElementaryStream
{
public const int HeaderLength = 6;
public const int Mpeg2HeaderLength = 14;
public readonly UInt32 StartCode;
public readonly int StreamId;
public readonly int Length;
public readonly int ScramblingControl;
public readonly int Priority;
public readonly int DataAlignmentIndicator;
public readonly int Copyright;
public readonly int OriginalOrCopy;
public readonly int PresentationTimeStampDecodeTimeStampFlags;
public readonly int ElementaryStreamClockReferenceFlag;
public readonly int EsRateFlag;
public readonly int DsmTrickModeFlag;
public readonly int AdditionalCopyInfoFlag;
public readonly int CrcFlag;
public readonly int ExtensionFlag;
public readonly int HeaderDataLength;
public readonly UInt64? PresentationTimeStamp;
public readonly UInt64? DecodeTimeStamp;
public readonly int? SubPictureStreamId;
public readonly byte[] DataBuffer;
public PacketizedElementaryStream(byte[] buffer, int index)
{
StartCode = Helper.GetEndian(buffer, index + 0, 3);
StreamId = buffer[index + 3];
Length = Helper.GetEndianWord(buffer, index + 4);
ScramblingControl = (buffer[index + 6] >> 4) & Helper.B00000011;
Priority = buffer[index + 6] & Helper.B00001000;
DataAlignmentIndicator = buffer[index + 6] & Helper.B00000100;
Copyright = buffer[index + 6] & Helper.B00000010;
OriginalOrCopy = buffer[index + 6] & Helper.B00000001;
PresentationTimeStampDecodeTimeStampFlags = buffer[index + 7] >> 6;
ElementaryStreamClockReferenceFlag = buffer[index + 7] & Helper.B00100000;
EsRateFlag = buffer[index + 7] & Helper.B00010000;
DsmTrickModeFlag = buffer[index + 7] & Helper.B00001000;
AdditionalCopyInfoFlag = buffer[index + 7] & Helper.B00000100;
CrcFlag = buffer[index + 7] & Helper.B00001000;
ExtensionFlag = buffer[index + 7] & Helper.B00000010;
HeaderDataLength = buffer[index + 8];
if (StreamId == 0xBD) // 10111101 binary = 189 decimal = 0xBD hex -> private_stream_1
{
int id = buffer[index + 9 + HeaderDataLength];
if (id >= 0x20 && id <= 0x40) // x3f 0r x40 ?
SubPictureStreamId = id;
}
int tempIndex = index + 9;
if (PresentationTimeStampDecodeTimeStampFlags == Helper.B00000010 ||
PresentationTimeStampDecodeTimeStampFlags == Helper.B00000011)
{
string bString = Helper.GetBinaryString(buffer, tempIndex, 5);
bString = bString.Substring(4, 3) + bString.Substring(8, 15) + bString.Substring(24, 15);
PresentationTimeStamp = Convert.ToUInt64(bString, 2);
tempIndex += 5;
}
if (PresentationTimeStampDecodeTimeStampFlags == Helper.B00000011)
{
string bString = Helper.GetBinaryString(buffer, tempIndex, 5);
bString = bString.Substring(4, 3) + bString.Substring(8, 15) + bString.Substring(24, 15);
DecodeTimeStamp = Convert.ToUInt64(bString, 2);
}
int dataIndex = index + HeaderDataLength + 24 - Mpeg2HeaderLength;
int dataSize = Length - (4 + HeaderDataLength);
if (dataSize < 0 || (dataSize + dataIndex > buffer.Length)) // to fix bad subs...
{
dataSize = buffer.Length - dataIndex;
if (dataSize < 0)
return;
}
DataBuffer = new byte[dataSize+1];
//Buffer.BlockCopy(buffer, dataIndex, DataBuffer, 0, dataSize);
Buffer.BlockCopy(buffer, dataIndex - 1, DataBuffer, 0, DataBuffer.Length); // why subtract one from dataIndex ?????
}
}
}

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Nikse.SubtitleEdit.Logic.TransportStream
{
public class ProgramAssociationTable
{
public int TableId { get; set; }
public int SectionLength { get; set; }
public int TransportStreamId { get; set; }
public int VersionNumber { get; set; }
public int CurrentNextIndicator { get; set; }
public int SectionNumber { get; set; }
public int LastSectionNumber { get; set; }
public List<int> ProgramNumbers { get; set; }
public List<int> ProgramIds { get; set; }
public ProgramAssociationTable(byte[] packetBuffer, int index)
{
TableId = packetBuffer[index];
SectionLength = (packetBuffer[index + 1] & Helper.B00000011) * 256 + packetBuffer[index + 2];
TransportStreamId = packetBuffer[index + 3] * 256 + packetBuffer[index + 4];
VersionNumber = (packetBuffer[index + 5] & Helper.B00111110) >> 1;
CurrentNextIndicator = packetBuffer[index + 5] & 1;
SectionNumber = packetBuffer[index + 6];
LastSectionNumber = packetBuffer[index + 7];
ProgramNumbers = new List<int>();
ProgramIds = new List<int>();
index = index + 8;
for (int i = 0; i < (SectionLength - 5) / 8; i++)
{
int programNumber = packetBuffer[index] * 256 + packetBuffer[index + 1];
int programId = (packetBuffer[index + 2] & Helper.B00011111) * 256 + packetBuffer[index + 3];
ProgramNumbers.Add(programNumber);
ProgramIds.Add(programId);
index += 8;
}
}
}
}

View File

@ -0,0 +1,168 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace Nikse.SubtitleEdit.Logic.TransportStream
{
/// <summary>
/// MPEG transport stream parser
/// </summary>
public class TransportStreamParser
{
public int NumberOfNullPackets { get; private set; }
public long TotalNumberOfPackets { get; private set; }
public long TotalNumberOfPrivateStream1 { get; private set; }
public long TotalNumberOfPrivateStream1Continuation0 { get; private set; }
public List<int> SubtitlePacketIds { get; private set; }
public List<Packet> SubtitlePackets { get; private set; }
public void ParseTsFile(string fileName)
{
var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
ParseTsFile(fs);
fs.Close();
}
/// <summary>
/// Can be used with e.g. MemoryStream or FileStream
/// </summary>
/// <param name="ms">Input stream</param>
public void ParseTsFile(Stream ms)
{
NumberOfNullPackets = 0;
TotalNumberOfPackets = 0;
TotalNumberOfPrivateStream1 = 0;
TotalNumberOfPrivateStream1Continuation0 = 0;
SubtitlePacketIds = new List<int>();
SubtitlePackets = new List<Packet>();
ms.Position = 0;
int packetLength = DeterminePacketLength(ms);
var packetBuffer = new byte[packetLength];
long position = 0;
while (position < ms.Length)
{
ms.Seek(position, SeekOrigin.Begin);
ms.Read(packetBuffer, 0, packetLength);
byte syncByte = packetBuffer[0];
if (syncByte == Packet.SynchronizationByte)
{
Packet packet = new Packet(packetBuffer);
if (packet.IsNullPacket)
{
NumberOfNullPackets++;
}
else if (packet.IsProgramAssociationTable)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("PacketNo: " + TotalNumberOfPackets + 1);
sb.AppendLine("PacketId: " + packet.PacketId);
sb.AppendLine();
sb.AppendLine("TransportErrorIndicator: " + packet.TransportErrorIndicator);
sb.AppendLine("PayloadUnitStartIndicator: " + packet.PayloadUnitStartIndicator);
sb.AppendLine("TransportPriority: " + packet.TransportPriority);
sb.AppendLine("ScramblingControl: " + packet.ScramblingControl);
sb.AppendLine("AdaptationFieldExist: " + packet.AdaptationFieldControl);
sb.AppendLine("ContinuityCounter: " + packet.ContinuityCounter);
sb.AppendLine();
if (packet.AdaptationField != null)
{
sb.AppendLine("AdaptationFieldLength: " + packet.AdaptationField.Length);
sb.AppendLine("DiscontinuityIndicator: " + packet.AdaptationField.DiscontinuityIndicator);
sb.AppendLine("RandomAccessIndicator: " + packet.AdaptationField.RandomAccessIndicator);
sb.AppendLine("ElementaryStreamPriorityIndicator: " + packet.AdaptationField.ElementaryStreamPriorityIndicator);
sb.AppendLine("PcrFlag: " + packet.AdaptationField.PcrFlag);
sb.AppendLine("OpcrFlag: " + packet.AdaptationField.OpcrFlag);
sb.AppendLine("SplicingPointFlag: " + packet.AdaptationField.SplicingPointFlag);
sb.AppendLine("TransportPrivateDataFlag: " + packet.AdaptationField.TransportPrivateDataFlag);
sb.AppendLine("AdaptationFieldExtensionFlag: " + packet.AdaptationField.AdaptationFieldExtensionFlag);
sb.AppendLine();
}
sb.AppendLine("TableId: " + packet.ProgramAssociationTable.TableId);
sb.AppendLine("SectionLength: " + packet.ProgramAssociationTable.SectionLength);
sb.AppendLine("TransportStreamId: " + packet.ProgramAssociationTable.TransportStreamId);
sb.AppendLine("VersionNumber: " + packet.ProgramAssociationTable.VersionNumber);
sb.AppendLine("CurrentNextIndicator: " + packet.ProgramAssociationTable.CurrentNextIndicator);
sb.AppendLine("SectionNumber: " + packet.ProgramAssociationTable.SectionNumber);
sb.AppendLine("LastSectionNumber: " + packet.ProgramAssociationTable.LastSectionNumber);
// MessageBox.Show(sb.ToString());
}
else if (packet.IsPrivateStream1 || SubtitlePacketIds.Contains(packet.PacketId))
{
TotalNumberOfPrivateStream1++;
SubtitlePackets.Add(packet);
if (!SubtitlePacketIds.Contains(packet.PacketId))
{
SubtitlePacketIds.Add(packet.PacketId);
// MessageBox.Show("Subtitle packet id=" + packet.PacketId);
}
if (packet.ContinuityCounter == 0)
{
TotalNumberOfPrivateStream1Continuation0++;
int pes_extensionlength = 0xFF & packetBuffer[12 + packet.AdaptionFieldLength];
int pes_offset = 13 + packet.AdaptionFieldLength + pes_extensionlength;
bool isTeletext = (pes_extensionlength == 0x24 && (0xFF & packetBuffer[pes_offset])>>4 == 1);
// workaround uk freesat teletext
if (!isTeletext)
isTeletext = (pes_extensionlength == 0x24 && (0xFF & packetBuffer[pes_offset]) == 0x99);
//if (isTeletext)
// MessageBox.Show(TotalNumberOfPackets.ToString() + ": Teletext!");
//if (!isTeletext)
// pes_subID = ((0xFF & ts_packet[pes_offset]) == 0x20 && (0xFF & ts_packet[pes_offset + 1]) == 0 && (0xFF & ts_packet[pes_offset + 2]) == 0xF) ? 0x20 : 0;
}
}
TotalNumberOfPackets++;
position += packetLength;
}
else
{
position++;
break;
}
}
//MessageBox.Show("Done parsing " + Environment.NewLine +
// Environment.NewLine +
// "#Packets: " + TotalNumberOfPackets.ToString() + Environment.NewLine +
// "#Null packets: " + NumberOfNullPackets.ToString() + Environment.NewLine +
// "#Private stream 1's: " + TotalNumberOfPrivateStream1.ToString() + Environment.NewLine +
// "#Private stream 1's with continuation=0: " + TotalNumberOfPrivateStream1Continuation0.ToString());
}
public List<PacketizedElementaryStream> GetSubtitlePesPackets(int packetId)
{
var list = new List<PacketizedElementaryStream>();
var buffer = new byte[20000];
int index =0;
foreach (Packet packet in SubtitlePackets)
{
if (packet.ContinuityCounter == 0)
{
if (index > 0)
{
var pes = new PacketizedElementaryStream(buffer, 0);
list.Add(pes);
}
index = 0;
}
Buffer.BlockCopy(packet.Payload, 0, buffer, index, packet.Payload.Length);
index += packet.Payload.Length;
}
return list;
}
private int DeterminePacketLength(Stream ms)
{
return 188;
}
}
}