Skip to content

Instantly share code, notes, and snippets.

@behringer24
Last active November 11, 2022 08:57
Show Gist options
  • Save behringer24/bb9c2b7100b27d9bb441ea2714c3f1a7 to your computer and use it in GitHub Desktop.
Save behringer24/bb9c2b7100b27d9bb441ea2714c3f1a7 to your computer and use it in GitHub Desktop.
Export Vegas Pro chapter markers to use as chapters in MP4 with ffMpeg
/**
* You can use this script to export Vegas markers to the ffMpeg format to use
* as chapters in mp4 metadata. You can also export the .xml, .csv and .txt format
* for use in other applications.
*
* Copy script to \Script Menu in your Vegas program path.
* If Vegas is running rescan via menu Tools>Scripting>Rescan Script Menu Folder
*
* To use this script:
*
* 1) Create named Vegas markers (M).
* 2) Vegas>Tools>Scripting>Export Chapters ffMpeg .FFC. Save
* 3) Render your MP4 video fileName
* 4) Export metadata from your rendered MP4 with ffMpeg:
* ffmpeg -y -i yourmp4file.mp4 -f ffmetadata FFMETADATAFILE
* 5) append the content of your .ffc file to the FFMETADATAFILE
* 4) use concatenated Metadata with ffMpeg options:
* -i FFMETADATAFILE -map_metadata 1
*
* Revision Date: Nov 11, 2022.
**/
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Windows.Forms;
using System.Globalization;
using ScriptPortal.Vegas;
using System.Xml;
public class EntryPoint
{
Vegas myVegas;
public void FromVegas(Vegas vegas) {
myVegas = vegas;
String projName;
String projFile = myVegas.Project.FilePath;
if (String.IsNullOrEmpty(projFile)) {
projName = "Untitled";
} else {
projName = Path.GetFileNameWithoutExtension(projFile);
}
String exportFile = ShowSaveFileDialog("ffMpeg Chapter List (*.ffc)|*.ffc|" +
"XML Chapters List (*.xml)|*.xml|" +
"CSV Chapters List (*.csv)|*.csv|" +
"TXT Chapter List (*.txt)|*.txt",
"Export Chapter Information", projName + "_chapters");
if (null != exportFile) {
String ext = Path.GetExtension(exportFile);
if ((null != ext) && (ext.ToUpper() == ".XML"))
{
ExportchaptersToXML(exportFile);
}
else if ((null != ext) && (ext.ToUpper() == ".TXT"))
{
ExportchaptersToTXT(exportFile);
}
else if ((null != ext) && (ext.ToUpper() == ".FFC"))
{
ExportchaptersToFFC(exportFile);
}
else
{ // should be CVS
ExportchaptersToCSV(exportFile);
}
}
}
StreamWriter CreateStreamWriter(String fileName, Encoding encoding) {
FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None);
StreamWriter sw = new StreamWriter(fs, encoding);
return sw;
}
void ExportchaptersToCSV(String exportFile)
{
StreamWriter streamWriter = null;
try {
streamWriter = CreateStreamWriter(exportFile, System.Text.Encoding.Unicode);
int tot_markers = myVegas.Project.Markers.Count;
int counter = 1;
foreach (Marker marker in myVegas.Project.Markers) {
StringBuilder tsv = new StringBuilder();
tsv.Append(marker.Position.ToString());
if(counter !=tot_markers)
tsv.Append(',');
counter++;
streamWriter.Write(tsv);
}
} finally {
if (null != streamWriter)
{
streamWriter.Close();
System.Windows.Forms.MessageBox.Show("Export successful. File name: " + exportFile, "Chapter File Export");
}
}
}
void ExportchaptersToTXT(String exportFile) {
StreamWriter streamWriter = null;
try {
streamWriter = CreateStreamWriter(exportFile, System.Text.Encoding.Unicode);
//streamWriter.WriteLine("Timecode");
foreach (Marker marker in myVegas.Project.Markers) {
StringBuilder tsv = new StringBuilder();
tsv.Append(marker.Position.ToString());
tsv.Append('\t');
streamWriter.WriteLine(tsv.ToString());
}
} finally {
if (null != streamWriter)
{
streamWriter.Close();
System.Windows.Forms.MessageBox.Show("Export successful. File name: " + exportFile, "Chapter File Export");
}
}
}
void ExportchaptersToFFC(String exportFile) {
StreamWriter streamWriter = null;
double lastposition = 0;
try {
streamWriter = CreateStreamWriter(exportFile, System.Text.Encoding.Unicode);
//streamWriter.WriteLine("Timecode");
foreach (Marker marker in myVegas.Project.Markers) {
double position = Math.Round(marker.Position.ToMilliseconds());
StringBuilder tsv = new StringBuilder();
streamWriter.WriteLine("[CHAPTER]");
streamWriter.WriteLine("TIMEBASE=1/1000");
tsv.Append("START=" + position + "\n");
tsv.Append("END=" + (position + 1) + "\n");
tsv.Append("title=" + marker.Label + "\n");
streamWriter.WriteLine(tsv.ToString());
lastposition = marker.Position.ToMilliseconds();
}
} finally {
if (null != streamWriter)
{
streamWriter.Close();
System.Windows.Forms.MessageBox.Show("Export successful. File name: " + exportFile, "Chapter File Export");
}
}
}
void ExportchaptersToXML(String exportFile)
{
XmlDocument doc = null;
try
{
doc = new XmlDocument();
XmlProcessingInstruction xmlPI = doc.CreateProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
doc.AppendChild(xmlPI);
XmlElement root = doc.CreateElement("Chapters");
System.Text.Encoding myCharacterEncoding = System.Text.Encoding.UTF8;
doc.AppendChild(root);
XmlElement chapter;
foreach (Marker marker in myVegas.Project.Markers)
{
chapter = doc.CreateElement("chapter");
chapter.SetAttribute("ID", marker.Index.ToString());
chapter.SetAttribute("Time-code", marker.Position.ToString());
root.AppendChild(chapter);
}
XmlTextWriter writer = new XmlTextWriter(exportFile, myCharacterEncoding);
writer.Formatting = Formatting.Indented;
writer.Indentation = 2;
writer.IndentChar = ' ';
doc.WriteTo(writer);
writer.Close();
}
catch {
doc = null;
}
finally
{
if (null != doc)
{
System.Windows.Forms.MessageBox.Show("Export successful. File name: " + exportFile, "Chapter File Export");
}
}
}
String ShowSaveFileDialog(String filter, String title, String defaultFilename) {
SaveFileDialog saveFileDialog = new SaveFileDialog();
if (null == filter) {
filter = "All Files (*.*)|*.*";
}
saveFileDialog.Filter = filter;
if (null != title)
saveFileDialog.Title = title;
saveFileDialog.CheckPathExists = true;
saveFileDialog.AddExtension = true;
if (null != defaultFilename) {
String initialDir = Path.GetDirectoryName(defaultFilename);
if (Directory.Exists(initialDir)) {
saveFileDialog.InitialDirectory = initialDir;
}
saveFileDialog.DefaultExt = Path.GetExtension(defaultFilename);
saveFileDialog.FileName = Path.GetFileName(defaultFilename);
}
if (System.Windows.Forms.DialogResult.OK == saveFileDialog.ShowDialog()) {
return Path.GetFullPath(saveFileDialog.FileName);
} else {
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment