Here’s a bash script that creates an XML file for FLVTool2:
#!/bin/bash # # /usr/local/bin/cuepoints # # Generate an XML file used by FLVTool2 to add cuepoints to a flash file # The XML file adds a cuepoint every ten seconds, to line up with timestamps # # Syntax: cuepoints [<seconds>] [<filename>] # cuepoints 1800 cuepoints-1800.xml # cuepoints 7200 # cuepoints # # Options for start time and interval could be added # # ----------------------------------------------------------------------------- # Add a help screen if [ "$1" = "-h" -o "$1" = "--help" -o "$1" = "help" ] then echo -e "\ncuepoints [<seconds>] [<filename>]" echo -e "\tThe cuepoints script creates an XML file used by FLVTool2 to add cuepoints to a flash file" echo -e "\nSyntax:" echo -e "\tcuepoints \t\t(defaults to 3600 seconds, or one hour, written to cuepoints.xml)" echo -e "\tcuepoints 1800 \t\t(create cuepoints for a half-hour file)" echo -e "\tcuepoints 1800 cuepoints-1800.xml\t(specify a filename)\n" exit fi echo -e "\nCreating cuepoints.xml, used by FLVTool2 to add cuepoints to a flash file \ (see \"cuepoints help\" for syntax and options)\n" # Check for length if [ "$1" = "" ] then LENGTH="3600" else LENGTH="$1" fi # Check for filename if [ "$2" = "" ] then FIL="cuepoints.xml" else FIL="$2" fi # Write the header echo "<?xml version=\"1.0\"?>" > $FIL echo "<tags>" >> $FIL echo " <!-- navigation cue points -->" >> $FIL # Write the body for N in $(seq 0 10 $LENGTH) do NAME="$( echo $(date -d "+$N seconds"\ 00:00:00 +%H:%M:%S) )" echo " <metatag event=\"onCuePoint\">" >> $FIL echo " <name>"$NAME"</name>" >> $FIL echo " <timestamp>"$N"000</timestamp>" >> $FIL echo " <type>navigation</type>" >> $FIL echo " </metatag>" >> $FIL done # Write the footer echo "</tags>" >> $FIL echo -e "An XML file specifying $LENGTH timestamps has been written to $FIL\n" echo -e "To create a flash file with these cuepoints, use \"flvtool2 -AUPt cuepoints.xml input.flv output.flv\"\n" #EOF
Here’s another xslt-script which generates FLVTool2 cuepoints from Motion project-files (*.motn), tested with Apple Motion 2.0.1. Use the generated XML like flvtool2 -AUPktv mymeta.cue.xml test.flv testout.flv.
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" /> <xsl:template match="/ozml"> <tags> <xsl:for-each select="./scene/timemarkerset/timemarker"> <metatag event="onCuePoint" overwrite="true"> <name><xsl:value-of select="./label/text()" /></name> <timestamp><xsl:value-of select="round(./inpoint/text() div 25 * 1000)" /></timestamp> <type>event</type> </metatag> </xsl:for-each> </tags> </xsl:template> </xsl:stylesheet>
After Effects Script (tested on AE CS3): Convert all markers of the selected layer to a flvtool2-xml. Save and rename to activelayer_to_cuepoints.jsx and place in your scripts folder.
/**
* Original author: Mathis Moder (mathis.moder at gmail.com)
* Date: 07/19/2008
*/
var layer = app.project.activeItem.selectedLayers[0];
var cues = layer.property("Marker");
var out = filePutDialog("Select an Output File", "cuepoint_"+layer.name+".xml", "xml");
if (out == null){
alert("No output file selected. Aborting.");
} else {
out.open("w");
out.writeln('<?xml version="1.0" encoding="UTF-8"?>');
out.writeln('<tags>');
out.writeln('<!-- source="'+layer.name+'"-->');
//loop through activeComp by markers
for(var i=0;i<cues.numKeys; i++){
//for(var i=0;i<app.project.activeItem.workAreaDuration;i+=app.project.activeItem.frameDuration) {
var marker = cues.valueAtTime(cues.keyTime(i+1),true);
if(marker.comment == "") continue;
var time = Math.round(cues.keyTime(i+1)*1000);
out.writeln('<metatag event="onCuePoint" overwrite="true">');
out.writeln("<timestamp>" + time + "</timestamp>");
out.writeln("<name>" + marker.comment + "</name>");
out.writeln("<type>event</type>");
out.writeln("<parameters>");
for (var j in marker){
if (typeof(marker[j]) != "function") {
out.writeln("<"+j+">"+marker[j]+"</"+j+">");
}
}
out.writeln("</parameters>");
out.writeln("</metatag>");
}
out.write("</tags>");
out.close();
}