Author: andre
Date: 2010-02-03 11:21:26 +0100 (Wed, 03 Feb 2010)
New Revision: 40831

Modified:
   
mmbase/trunk/applications/streams/src/main/config/builders/streams/audiostreamsourcescaches.xml
   
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsources.fields.xml
   
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsources.functions.xml
   
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsourcescaches.fields.xml
   
mmbase/trunk/applications/streams/src/main/config/builders/streams/videostreamsourcescaches.xml
   mmbase/trunk/applications/streams/src/main/config/components/streams.xml
   
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/CreateCachesFunction.java
   
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/DeleteCachesProcessor.java
   
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/Job.java
   
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/JobDefinition.java
   
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/Processor.java
   
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/AbstractTranscoder.java
   
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/AnalyzerUtils.java
   
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/CommandTranscoder.java
   
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/FFMpegAnalyzer.java
   
mmbase/trunk/applications/streams/src/main/webapp/mmbase/components/streams/admin.jspx
   
mmbase/trunk/applications/streams/src/main/webapp/mmbase/components/streams/fragment.trs.jspx
Log:
ported from 1.9, issue MMB-1878 mainly

Modified: 
mmbase/trunk/applications/streams/src/main/config/builders/streams/audiostreamsourcescaches.xml
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/config/builders/streams/audiostreamsourcescaches.xml
     2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/config/builders/streams/audiostreamsourcescaches.xml
     2010-02-03 10:21:26 UTC (rev 40831)
@@ -17,6 +17,7 @@
   </descriptions>
 
   <properties>
+    <property 
name="org.mmbase.streams.cachestype">audiostreamsourcescaches</property>
   </properties>
 
   <xi:include href="streamsourcescaches.fields.xml" />

Modified: 
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsources.fields.xml
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsources.fields.xml
 2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsources.fields.xml
 2010-02-03 10:21:26 UTC (rev 40831)
@@ -7,6 +7,21 @@
     >
 
   <field name="state" state="system">
+    <descriptions>
+      <description xml:lang="en">State of the transcoded file.</description>
+      <description xml:lang="nl">Status van het getranscodeerde 
bestand.</description>
+    </descriptions>
+    <gui>
+      <guiname xml:lang="en">State</guiname>
+      <guiname xml:lang="nl">Status</guiname>
+    </gui>
+    <editor>
+      <positions>
+        <list>9</list>
+        <input>3</input>
+        <search>3</search>
+      </positions>
+    </editor>
     <datatype xmlns="http://www.mmbase.org/xmlns/datatypes";>
       <default value="SOURCE" />
       <enumeration enforce="onchange">
@@ -18,6 +33,12 @@
   </field>
 
   <field name="url">
+    <editor>
+      <positions>
+        <input>3</input>
+        <search>3</search>
+      </positions>
+    </editor>
     <datatype base="file" xmlns="http://www.mmbase.org/xmlns/datatypes";>
       <unique value="false" />
       <required value="true">
@@ -40,10 +61,31 @@
   </field>
 
   <field name="mimetype" state="system">
+    <descriptions>
+      <description xml:lang="en">Internet media type, two-part identifier for 
the file format</description>
+      <description xml:lang="nl">Internet media type, een tweedelig kenmerk 
voor het bestandsformaat.</description>
+    </descriptions>
+    <gui>
+      <guiname xml:lang="en">MIME type</guiname>
+      <guiname xml:lang="nl">MIME type</guiname>
+    </gui>
+    <editor>
+      <positions>
+        <list>3</list>
+        <input>3</input>
+        <search>3</search>
+      </positions>
+    </editor>
     <datatype base="eline" xmlns="http://www.mmbase.org/xmlns/datatypes"; />
   </field>
 
   <field name="objecttype" state="virtual">
+    <editor>
+      <positions>
+        <input>9</input>
+        <search>9</search>
+      </positions>
+    </editor>
     <datatype base="objecttype" xmlns="http://www.mmbase.org/xmlns/datatypes";>
       <pattern 
value="audiostreamsources|videostreamsources|streamsources|imagesources" />
       <commitprocessor>

Modified: 
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsources.functions.xml
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsources.functions.xml
      2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsources.functions.xml
      2010-02-03 10:21:26 UTC (rev 40831)
@@ -5,10 +5,15 @@
                         http://www.mmbase.org/xmlns/builder.xsd";
     xmlns:xi="http://www.w3.org/2001/XInclude";
     >
-  <function name="trigger">
+  
+  <function name="triggerCaches">
     <class>org.mmbase.streams.CreateCachesFunction</class>
   </function>
 
+  <function name="triggerRecache">
+    <class>org.mmbase.streams.RecreateCacheFunction</class>
+  </function>
+
   <function name="waitUntilRecognized">
     <class>org.mmbase.streams.createcaches.WaitUntilRecognizedFunction</class>
   </function>

Modified: 
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsourcescaches.fields.xml
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsourcescaches.fields.xml
   2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/config/builders/streams/streamsourcescaches.fields.xml
   2010-02-03 10:21:26 UTC (rev 40831)
@@ -7,6 +7,21 @@
     >
 
   <field name="state" state="system">
+    <descriptions>
+      <description xml:lang="en">State of the transcoded file</description>
+      <description xml:lang="nl">Status van het getranscodeerde 
bestand.</description>
+    </descriptions>
+    <gui>
+      <guiname xml:lang="en">State</guiname>
+      <guiname xml:lang="nl">Status</guiname>
+    </gui>
+    <editor>
+      <positions>
+        <list>9</list>
+        <input>3</input>
+        <search>3</search>
+      </positions>
+    </editor>
     <datatype xmlns="http://www.mmbase.org/xmlns/datatypes";>
       <default value="REQUEST" />
       <enumeration enforce="onchange">
@@ -18,14 +33,28 @@
   </field>
 
   <field name="key">
+    <descriptions>
+      <description xml:lang="en">Transcoding settings used: transcoder and 
parameters.</description>
+      <description xml:lang="nl">Instellingen van de transcodering: 
transcorder en parameters.</description>
+    </descriptions>
+    <gui>
+      <guiname xml:lang="en">Key</guiname>
+      <guiname xml:lang="nl">Sleutel</guiname>
+    </gui>
+    <editor>
+      <positions>
+        <input>8</input>
+        <search>8</search>
+      </positions>
+    </editor>
     <datatype base="eline" xmlns="http://www.mmbase.org/xmlns/datatypes"; />
   </field>
 
 
   <field name="id">
     <descriptions>
-      <description xml:lang="en">Reference to the original stream</description>
-      <description xml:lang="nl">Referentie naar de originel 
stream</description>
+      <description xml:lang="en">Reference to the original this cache was 
transcoded from.</description>
+      <description xml:lang="nl">Referentie naar het origineele waarvan deze 
cache getranscodeerd is.</description>
     </descriptions>
     <gui>
       <guiname xml:lang="en">ID</guiname>
@@ -35,7 +64,11 @@
       <guiname xml:lang="it">ID</guiname>
     </gui>
     <editor>
-      <positions><list>3</list></positions>
+      <positions>
+        <list>9</list>
+        <input>9</input>
+        <search>9</search>
+      </positions>
     </editor>
     <datatype base="nodenumber" xmlns="http://www.mmbase.org/xmlns/datatypes";>
       <required value="true" enforce="never" />
@@ -46,11 +79,40 @@
   </field>
 
   <field name="mimetype" state="system">
+    <descriptions>
+      <description xml:lang="en">Internet media type, two-part identifier for 
the file format</description>
+      <description xml:lang="nl">Internet media type, een tweedelig kenmerk 
voor het bestandsformaat.</description>
+    </descriptions>
+    <gui>
+      <guiname xml:lang="en">MIME type</guiname>
+      <guiname xml:lang="nl">MIME type</guiname>
+    </gui>
+    <editor>
+      <positions>
+        <list>3</list>
+        <input>3</input>
+        <search>3</search>
+      </positions>
+    </editor>
     <datatype base="eline" xmlns="http://www.mmbase.org/xmlns/datatypes"; />
   </field>
 
 
   <field name="url" readonly="true">
+    <descriptions>
+      <description xml:lang="en">Location of the file</description>
+      <description xml:lang="nl">Locatie van het bestand</description>
+    </descriptions>
+    <gui>
+      <guiname xml:lang="en">URL</guiname>
+      <guiname xml:lang="nl">URL</guiname>
+    </gui>
+    <editor>
+      <positions>
+        <input>3</input>
+        <search>3</search>
+      </positions>
+    </editor>
     <datatype base="eline" xmlns="http://www.mmbase.org/xmlns/datatypes";>
       <getprocessor type="binary">
         <class name="org.mmbase.datatypes.processors.BinaryFile$Getter" />

Modified: 
mmbase/trunk/applications/streams/src/main/config/builders/streams/videostreamsourcescaches.xml
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/config/builders/streams/videostreamsourcescaches.xml
     2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/config/builders/streams/videostreamsourcescaches.xml
     2010-02-03 10:21:26 UTC (rev 40831)
@@ -14,6 +14,10 @@
     <plural xml:lang="nl">Streamscaches: Video</plural>
   </names>
 
+  <properties>
+    <property 
name="org.mmbase.streams.cachestype">videostreamsourcescaches</property>
+  </properties>
+
   <xi:include href="streamsourcescaches.fields.xml" />
   <xi:include 
href="http://www.mmbase.org/builders/media/mediasources.virtual.fields.xml"; />
   <xi:include href="streamsourcescaches.virtual.fields.xml" />

Modified: 
mmbase/trunk/applications/streams/src/main/config/components/streams.xml
===================================================================
--- mmbase/trunk/applications/streams/src/main/config/components/streams.xml    
2010-02-03 10:12:55 UTC (rev 40830)
+++ mmbase/trunk/applications/streams/src/main/config/components/streams.xml    
2010-02-03 10:21:26 UTC (rev 40831)
@@ -45,6 +45,7 @@
     <body jsp="admin.jspx">
       <param name="trigger" />
       <param name="interrupt" />
+      <param name="recache" />
       <param name="page"  type="java.lang.Integer" />
     </body>
   </block>
@@ -59,6 +60,7 @@
     <body jsp="myfragments.jspx">
       <param name="trigger" />
       <param name="interrupt" />
+      <param name="recache" />
       <param name="page"  type="java.lang.Integer" />
     </body>
   </block>

Modified: 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/CreateCachesFunction.java
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/CreateCachesFunction.java
        2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/CreateCachesFunction.java
        2010-02-03 10:21:26 UTC (rev 40831)
@@ -45,11 +45,11 @@
     }
 
 
-    Processor getCacheCreator(final Field url) {
+    protected static Processor getCacheCreator(final Field url) {
         CommitProcessor commitProcessor = 
url.getDataType().getCommitProcessor();
         if (commitProcessor instanceof ChainedCommitProcessor) {
             ChainedCommitProcessor chain = (ChainedCommitProcessor) 
commitProcessor;
-            LOG.info("Lookin in " + chain.getProcessors());
+            LOG.service("Lookin in " + chain.getProcessors());
             for (CommitProcessor cp : chain.getProcessors()) {
                 if (cp instanceof Processor) {
                     return (Processor) cp;
@@ -67,23 +67,35 @@
 
     @Override
     protected Boolean getFunctionValue(final Node node, final Parameters 
parameters) {
-        if (node.getNumber() > 0 && 
node.getCloud().may(ActionRepository.getInstance().get("streams", 
"retrigger_jobs"), null)) {
-            LOG.info("Recreating caches for " + node.getNumber());
+        if (node.getNumber() > 0 
+                && 
node.getCloud().may(ActionRepository.getInstance().get("streams", 
"retrigger_jobs"), null)) {
+            LOG.info("Recreating caches for #" + node.getNumber());
             final Field url = node.getNodeManager().getField("url");
 
             {
-                NodeList list = SearchUtil.findNodeList(node.getCloud(), 
node.getNodeManager().getProperty("org.mmbase.streams.cachestype"), "id", 
node.getNumber());
-                // BUG: when the streamsourcescaches are initially of the 
wrong type, they don't get deleted
+                Node mediafragment = node.getNodeValue("mediafragment");
+                String cachestype = 
node.getNodeManager().getProperty("org.mmbase.streams.cachestype");
+                NodeList list = SearchUtil.findRelatedNodeList(mediafragment, 
cachestype, "related"); 
+                
+                // when the streamsourcescaches are initially of the wrong 
type they don't get deleted, this helps a bit
+                if (list.size() < 1) {
+                    if (cachestype.startsWith("video")) {
+                        list = SearchUtil.findRelatedNodeList(mediafragment, 
"audiostreamsourcescaches", "related");
+                    } else if (cachestype.startsWith("audio")) {
+                        list = SearchUtil.findRelatedNodeList(mediafragment, 
"videostreamsourcescaches", "related");
+                    }
+                }
+                
                 for (Node cache : list) {
                     cache.delete(true);
-                    LOG.service("Deleted " + cache.getNumber());
+                    LOG.service("deleted streamsourcescaches #" + 
cache.getNumber());
                 }
             }
 
             {
                 final Processor cc = getCacheCreator(url);
                 if (cc != null) {
-                    LOG.info("Calling " + cc);
+                    LOG.service("Calling " + cc);
                     
cc.createCaches(node.getCloud().getNonTransactionalCloud(), node.getNumber());
                     return true;
                 } else {

Modified: 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/DeleteCachesProcessor.java
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/DeleteCachesProcessor.java
       2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/DeleteCachesProcessor.java
       2010-02-03 10:21:26 UTC (rev 40831)
@@ -55,7 +55,7 @@
             NodeQuery q = caches.createQuery();
             Queries.addConstraint(q, Queries.createConstraint(q, "id", 
FieldCompareConstraint.EQUAL, node));
             for (Node cache : caches.getList(q)) {
-                LOG.info("deleting streamsourcescaches #" + cache.getNumber());
+                LOG.service("deleting streamsourcescaches #" + 
cache.getNumber());
                 if (cache.mayDelete()) {
                     cache.delete(true);
                 } else {

Modified: 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/Job.java
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/Job.java
    2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/Job.java
    2010-02-03 10:21:26 UTC (rev 40831)
@@ -53,6 +53,7 @@
     private Node mediaprovider;
     private Node mediafragment;
     final BufferedLogger logger;
+    private static Map<String, JobDefinition> jobdefs = new 
LinkedHashMap<String, JobDefinition>();
     private final Map<String, Result> lookup = new LinkedHashMap<String, 
Result>();
     private final List<Result>        results = new ArrayList<Result>();
     private final long number = lastJobNumber++;
@@ -69,16 +70,21 @@
     final Processor processor;
 
     public Job(Processor processor, Cloud cloud, ChainedLogger chain) {
+        this(processor, processor.list, cloud, chain);
+    }
+    
+    public Job(Processor processor, Map<String, JobDefinition> list, Cloud 
cloud, ChainedLogger chain) {
         user = cloud.getUser().getIdentifier();
         logger = new BufferedLogger();
         logger.setLevel(Level.DEBUG);
         logger.setMaxSize(100);
         logger.setMaxAge(60000);
         chain.addLogger(logger);
-        for (Map.Entry<String, JobDefinition> dum : processor.list.entrySet()) 
{
+        for (Map.Entry<String, JobDefinition> dum : list.entrySet()) {
             results.add(null);
         }
         this.processor = processor;
+        this.jobdefs = list;
     }
 
     /**
@@ -88,19 +94,19 @@
      */
     protected void findResults() {
         int i = -1;
-        for (Map.Entry<String, JobDefinition> entry : 
processor.list.entrySet()) {
+        for (Map.Entry<String, JobDefinition> entry : jobdefs.entrySet()) {
             i++;
             if (results.get(i) == null) {
                 JobDefinition jd = entry.getValue();
                 URI inURI;
                 Node inNode; // inNode (input stream) to be used
 
-                if (jd.getInId() == null) {
+                if (jd.getInId() == null) { // using the original source node
                     String url = node.getStringValue("url");
                     if (url.length() < 0) LOG.error("No value for field url: " 
+ url);
                     assert url.length() > 0;
                     File f = new File(processor.getDirectory(), url);
-                    LOG.info("New file: " + f);
+                    LOG.service("New (in)file: " + f);
                     assert f.exists() : "No such file " + f;
                     
                     // make sure there is an in file to use
@@ -118,44 +124,72 @@
                     
                     inURI = f.toURI();
                     inNode = node;
-                } else {
-                    if (! processor.list.containsKey(jd.getInId())) {
-                        LOG.warn("Configuration error, no such job definition 
with id '" + jd.getInId());
+                
+                } else {    // using a previously cached node
+                    String inId = jd.getInId();
+                    
+                    if (! jobdefs.containsKey(inId) && 
node.getCloud().hasNode(inId)) {
+                        // use an existing cache node
+                        LOG.service("Using cache #" + inId + " as input");
+                        
+                        inNode = node.getCloud().getNode(inId);
+                        String url = inNode.getStringValue("url");
+                        if (url.length() < 0) {
+                            LOG.error("No value for field url: " + url);
+                            break;
+                        }
+
+                        File f = new File(processor.getDirectory(), url);
+                        LOG.service("Using (in)file: " + f);
+                        
+                        if (!f.exists() && !f.isFile()) {
+                            LOG.error("NO INFILE! '" + f );
+                            break;
+                        }
+                        
+                        inURI = f.toURI();
+                        
+                    } else {    // use inId from config
+                        if (! jobdefs.containsKey(inId)) {
+                            LOG.warn("Configuration error, no such job 
definition with id '" + inId);
                         continue;
                     }
-                    Result prevResult = lookup.get(jd.getInId());
+                        Result prevResult = lookup.get(inId);
                     if (prevResult == null || ! prevResult.isReady()) {
                         // no result possible yet.
                         continue;
                     }
                     inURI = prevResult.getOut();
                     inNode = prevResult.getDestination();
+                    
+                    }
+                    
                     if (inNode == null) {
                         inNode = node;
                     }
 
-                    if (prevResult.isReady() && inNode.getIntValue("state") == 
State.FAILED.getValue()) {
-                        LOG.warn("BREAK, transcoding of inNode failed " + 
inNode);
+                    if (inNode.getIntValue("state") > State.SOURCE.getValue()) 
{
+                        LOG.warn("BREAK, transcoding of inNode failed, it is 
removed, interrupted or unsupported #" + inNode);
                         break;
                     }
                 }
 
-                // mimetype: skip when no match
+                // mimetype: skip when there is no match between current jd 
and inNode
                 if (! jd.getMimeType().matches(new 
MimeType(inNode.getStringValue("mimetype")))) {
                     LOG.debug("SKIPPING " + jd);
                     results.set(i, new SkippedResult(jd, inURI));
                     skipped++;
                     continue;
                 } else {
-                    LOG.info("NOT SKIPPING " + jd);
+                    LOG.service("NOT SKIPPING " + jd);
                 }
 
                 assert inURI != null;
-                // not a recognizer (it has a transcoder key)
-                if (jd.transcoder.getKey() != null) {
-                    LOG.info(jd.getMimeType());
-                    LOG.info("" + inNode);
-                    Node dest = getCacheNode(jd.transcoder.getKey());   // 
gets node (and creates when yet not present)
+               
+                if (jd.transcoder.getKey() != null) {  // not a recognizer (it 
has a transcoder key)
+                    LOG.service(jd.getMimeType());
+                    LOG.service("inNode: " + inNode);
+                    Node dest = getCacheNode(inNode, jd.transcoder.getKey());  
 // gets node (and creates when yet not present)
                     if (dest == null) {
                         LOG.warn("Could not create cache node from " + 
node.getNodeManager().getName() + " " + node.getNumber() + " for " + 
jd.transcoder.getKey());
                         continue;
@@ -187,7 +221,7 @@
                         outFileName = outFileName.substring(1);
                     }
                     
-                    LOG.info("outFileName: '" + outFileName + "'");
+                    LOG.service("outFileName: '" + outFileName + "'");
                     assert outFileName != null;
                     assert outFileName.length() > 0;
                     dest.setStringValue("url", outFileName);
@@ -224,12 +258,19 @@
                     if (destFileName.length() < 1) {
                         LOG.error("Still empty destFileName: '" + destFileName 
+ "' of #" + dest.getNumber());
                     } else {
-                        LOG.info("destFileName: '" + destFileName + "'");
+                        LOG.service("destFileName: '" + destFileName + "'");
                     }
                     assert destFileName != null;
                     assert destFileName.length() > 0;
                     
                     File outFile = new File(processor.getDirectory(), 
destFileName);
+                    if (outFile.exists()) { 
+                        if (outFile.delete()) {
+                            LOG.service("Former version of file '" + outFile + 
"' deleted");
+                        } else {
+                            LOG.error("Could not remove former version of file 
'" + outFile + "'");
+                        }
+                    }
 
                     if (FileServlet.getInstance() != null) {
                         File inMeta = 
FileServlet.getInstance().getMetaFile(inFile);
@@ -252,7 +293,7 @@
                     URI outURI = outFile.toURI();
                     Result result = new 
TranscoderResult(processor.getDirectory(), jd, dest, inURI, outURI);
 
-                    LOG.info("Added result to results list with key: " + 
dest.getStringValue("key"));
+                    LOG.service("Added result to results list with key: " + 
dest.getStringValue("key"));
                     results.set(i, result);
                     lookup.put(jd.getId(), result);
                 } else {
@@ -344,9 +385,9 @@
      */
     void submit(final JobCallable jc)  {
        if (getStage() == Stage.READY) {
-           LOG.info("Will not submit, because we're ready" + jc);
+           LOG.service("Will not submit, because we're ready " + jc);
        } else {
-           LOG.info("Will submit " + jc);
+           LOG.service("Will submit " + jc);
            ThreadPools.jobsExecutor.execute(new Runnable() {
                    public void run() {
                        jc.init();
@@ -384,9 +425,9 @@
      * see the builder property 'org.mmbase.streams.cachestype'. It first 
looks if it already
      * exists in the cloud or otherwise will create one.
      *
-     * @param src   source node to create stream from
-     * @param key   representation of the way the stream was created from its 
source, f.e. trancoding parameters
-     * @return cached stream node
+     * @param src   source node to create cache stream from, can be another 
cache
+     * @param key   representation of the way the stream was created from its 
source, f.e. transcoding parameters
+     * @return cache stream node, in builder specified in 
'org.mmbase.streams.cachestype'.
      */
     protected Node getCacheNode(Node src, final String key) {
         String ct = 
src.getNodeManager().getProperty("org.mmbase.streams.cachestype");
@@ -413,7 +454,7 @@
             newNode.setStringValue("key", key);
 
             newNode.commit();
-            LOG.info("CREATED " + newNode.getNumber() + " (" + src.getNumber() 
+ "/" + key + ")");
+            LOG.service("CREATED " + newNode.getNumber() + " (" + 
src.getNumber() + "/" + key + ")");
 
             logger.service("Created new node for " + key + "(" + 
src.getNumber() + "): " + newNode.getNumber());
             return newNode;
@@ -462,10 +503,10 @@
         }
         interrupted = true;
         if (thread != null) {
-            logger.info("Interrupting " + thread);
+            logger.service("Interrupting " + thread);
             thread.interrupt();
         } else {
-            logger.info("No Thread in " + this);
+            logger.service("No Thread in " + this);
         }
     }
     public boolean isInterrupted() {

Modified: 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/JobDefinition.java
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/JobDefinition.java
  2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/JobDefinition.java
  2010-02-03 10:21:26 UTC (rev 40831)
@@ -30,13 +30,13 @@
 
 
 /**
- * The description or definition of one 'transcoding' sub jobs that's doing 
the transcoding. This
- * combines a transcoder, with a mime type for which it must be valid, and a 
list of analyzers.
+ * The description or definition of one 'transcoding' sub job that's doing the 
transcoding. This
+ * combines a {...@link Transcoder}, with a mime type for which it must be 
valid, and a list of analyzers.
  *
  * @author Michiel Meeuwissen
  * @version $Id$
  */
-class JobDefinition implements Serializable {
+public class JobDefinition implements Serializable {
     private static final long serialVersionUID = 0L;
     final Transcoder transcoder;
     final List<Analyzer> analyzers;
@@ -49,7 +49,16 @@
     final Stage stage;
 
     /**
-     * Creates an JobDefinition template (used in the configuration container).
+     * Creates a JobDefinition template as used in the configuration container 
or to kick-start
+     * a transcoding.
+     * @param id    identifier of this job, normally matches the one in 
configuration 
+     * @param inId  identifier of the jobdefinition or cache that is used as 
input. 
+                    If no inId is found the orginal source is used, otherwise 
it should match with
+                    a preceding jobdefinition id in config or a node number of 
an already existing cache.
+     * @param label description for user purposes of the result
+     * @param t     transcoder to perform the job
+     * @param mt    mime type for which the jobdefinition is valid
+     * @param s     stage the jobdefinition applies to
      */
     public JobDefinition(String id, String inId, String label, Transcoder t, 
MimeType mt, Stage s) {
         assert id != null;
@@ -73,7 +82,6 @@
         return Collections.unmodifiableList(analyzers);
     }
 
-
     public MimeType getMimeType() {
         return mimeType;
     }
@@ -94,4 +102,5 @@
     public String toString() {
         return "" + transcoder + " " + analyzers + (label == null ? "" : (" (" 
+ label + ")"));
     }
+
 }

Modified: 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/Processor.java
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/Processor.java
      2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/createcaches/Processor.java
      2010-02-03 10:21:26 UTC (rev 40831)
@@ -65,10 +65,10 @@
     }
 
     /**
+     * List with the configured JobDefinitions.
      */
     protected final Map<String, JobDefinition> list = 
Collections.synchronizedMap(new LinkedHashMap<String, JobDefinition>());
 
-
     String[] cacheManagers = new String[] {"streamsourcescaches", 
"videostreamsourcescaches", "audiostreamsourcescaches"};
 
     private File fileServletDirectory;
@@ -216,7 +216,7 @@
                         executors.clear();
                         executors.addAll(newExecutors);
                     }
-                    LOG.service("Reading of configuration file " + resource + 
" successfull. Transcoders now " + list + ". Executors " + executors + ". Max 
simultaneous transcoders: " + totals);
+                    LOG.service("Reading of configuration file " + resource + 
" successfull. JobDefinitions now " + list + ". Executors " + executors + ". 
Max simultaneous transcoders: " + totals);
                 } catch (Exception e)  {
                     LOG.error(e.getClass() + " " + e.getMessage() + " In " + 
resource + " Transcoders now " + list + " (not changed)", e);
                 }
@@ -317,15 +317,15 @@
      * @param logger    a logger that keeps track
      * @return job trans coding a source stream in (an)other stream(s)
      */
-    private Job createJob(final Cloud ntCloud, final int node, final 
ChainedLogger logger) {
+    private Job createJob(final Cloud ntCloud, final int node, final 
Map<String, JobDefinition> jdlist, final ChainedLogger logger) {
         synchronized(runningJobs) {
             Job job = runningJobs.get(node);
             if (job != null) {  // already running?
-                LOG.warn("This job is already running, node #" + node);
+                LOG.warn("There is already a job running for node #" + node);
                 return null;
             }
             assert node > 0;
-            final Job thisJob = new Job(this, ntCloud, logger);
+            final Job thisJob = new Job(this, jdlist, ntCloud, logger);
             runningJobs.put(node, thisJob);
             thisJob.submit(ntCloud, node, logger);
 
@@ -333,18 +333,22 @@
         }
     }
 
+    public Job createCaches(final Cloud ntCloud, final int node) {
+        return createCaches(ntCloud, node, this.list);
+    }
 
     /**
-     * Creates caches nodes when not existing by creating a transcoding Job
+     * Creates caches nodes when not existing (or recreate) by making a 
transcoding Job
      * @param ntCloud   a non transactional cloud
      * @param int       node number of a source node
+     * @param jdlist    jobdefinitions
      * @return Job recognizing and/or transcoding the source stream
      */
-    public Job createCaches(final Cloud ntCloud, final int node) {
+    public Job createCaches(final Cloud ntCloud, final int node, final 
Map<String, JobDefinition> jdlist) {
         final ChainedLogger logger = new ChainedLogger(LOG);
-        final Job thisJob = createJob(ntCloud, node, logger);
+        final Job thisJob = createJob(ntCloud, node, jdlist, logger);
 
-        LOG.info("Triggering caches for " + list + "  -> " + thisJob);
+        LOG.info("Triggering caches for " + jdlist + "  -> " + thisJob);
         if (thisJob != null) {
             // If the node happens to be deleted before the future with cache 
creations is ready, cancel the future
             EventManager.getInstance().addEventListener(new 
WeakNodeEventListener() {
@@ -376,6 +380,7 @@
             return;
         }
         if (node.getNumber() > 0) {
+            LOG.debug("url: " + node.getStringValue("url"));
             if (node.isChanged(field.getName())) {
                 LOG.service("For node " + node.getNumber() + ", the field '" + 
field.getName() + "' is changed " + node.getChanged() + ". That means that we 
must schedule create caches");
 

Modified: 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/AbstractTranscoder.java
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/AbstractTranscoder.java
      2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/AbstractTranscoder.java
      2010-02-03 10:21:26 UTC (rev 40831)
@@ -57,9 +57,13 @@
             } catch (ClassNotFoundException cnfe) {
                 clazz  = Class.forName(PACKAGE + idWithClass[1]);
             }
+            
+            if (!"".equals(idWithClass[0])) {
             Constructor constructor = clazz.getConstructor(String.class);
-
             trans = (Transcoder) constructor.newInstance(idWithClass[0]);
+            } else {
+                trans = (Transcoder) clazz.newInstance();
+            }
         }
         {
             String[] props = split[1].split(", ");

Modified: 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/AnalyzerUtils.java
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/AnalyzerUtils.java
   2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/AnalyzerUtils.java
   2010-02-03 10:21:26 UTC (rev 40831)
@@ -224,14 +224,12 @@
     public boolean duration(String l, Node source, Node dest) {
         Matcher m = PATTERN_DURATION.matcher(l);
         if (m.matches()) {
-            //log.debug("### Duration match: " + l);
-
             Node fragment = source.getNodeValue("mediafragment");
-            // log.debug("mediafragment: " + 
source.getNodeValue("mediafragment"));
 
             if (! source.getNodeManager().hasField("length")) {
                 toVideo(source, dest);
             }
+            
             if (log.isDebugEnabled()) log.debug("duration: " + m.group(1));
             long length = getLength(m.group(1));
             if (updateSource) {
@@ -258,8 +256,6 @@
                     fragment.setLongValue("start", start);
                     fragment.commit();
                     if (log.isDebugEnabled()) log.debug("Set mediafragment's 
field start: " + start);
-                } else {
-                    //log.warn("mediafragment still null");
                 }
             }
             return true;
@@ -307,7 +303,7 @@
     public boolean image2(String l, Node source, Node dest) {
         Matcher m = IMAGE2_PATTERN.matcher(l);
         if (m.matches()) {
-            log.info("image2 match: " + l);
+            //log.info("image2 match: " + l);
             toImage(source, dest);
             return true;
         } else {
@@ -325,7 +321,7 @@
     public boolean dimensions(String l, Node source, Node dest) {
         Matcher m = PATTERN_DIMENSIONS.matcher(l);
         if (m.matches()) {
-            //log.info("### Dimensions match: " + l);
+            //log.info("dimensions match: " + l);
 
             if (! source.getNodeManager().getName().equals(IMAGE)) {
                 toVideo(source, dest);

Modified: 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/CommandTranscoder.java
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/CommandTranscoder.java
       2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/CommandTranscoder.java
       2010-02-03 10:21:26 UTC (rev 40831)
@@ -32,7 +32,7 @@
 
 
 /**
- * A trancoder base on an external command, like <code>ffmpeg</code> or 
<code>ffmpeg2theora</code>
+ * A transcoder based on an external command, like <code>ffmpeg</code> or 
<code>ffmpeg2theora</code>.
  *
  * @author Michiel Meeuwissen
  * @version $Id$

Modified: 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/FFMpegAnalyzer.java
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/FFMpegAnalyzer.java
  2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/java/org/mmbase/streams/transcoders/FFMpegAnalyzer.java
  2010-02-03 10:21:26 UTC (rev 40831)
@@ -46,17 +46,12 @@
 
 public class FFMpegAnalyzer implements Analyzer {
 
-
     private static final Logger LOG = 
Logging.getLoggerInstance(FFMpegAnalyzer.class);
 
     private final ChainedLogger log = new ChainedLogger(LOG);
-
     private final AnalyzerUtils util = new AnalyzerUtils(log);
-
-
     private List<Throwable> errors = new ArrayList<Throwable>();
 
-
     public void setUpdateSource(boolean b) {
         util.setUpdateSource(b);
     }
@@ -94,6 +89,9 @@
             }
 
             if (util.dimensions(l, source, des)) {
+                if (! canbe.equals(AnalyzerUtils.IMAGE)) {    /* no image2 
seen yet, so it can be video */
+                    canbe = AnalyzerUtils.VIDEO;
+                }
                 return;
             }
 
@@ -108,7 +106,7 @@
 
     public void ready(Node sourceNode, Node destNode) {
         synchronized(util) {
-            log.service("Ready() " + sourceNode + (destNode == null ? "" : (" 
-> " + destNode.getNumber())) + ", canbe: " + canbe);
+            log.service("Ready() " + sourceNode + (destNode == null ? "" : (" 
-> " + destNode.getNumber())) + " = canbe: " + canbe);
 
             if (canbe.equals(AnalyzerUtils.IMAGE) 
                             && (sourceNode.isNull("bitrate") || 
sourceNode.getIntValue("bitrate") <= 0)) {

Modified: 
mmbase/trunk/applications/streams/src/main/webapp/mmbase/components/streams/admin.jspx
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/webapp/mmbase/components/streams/admin.jspx
      2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/webapp/mmbase/components/streams/admin.jspx
      2010-02-03 10:21:26 UTC (rev 40831)
@@ -8,11 +8,13 @@
     xmlns:mm="http://www.mmbase.org/mmbase-taglib-2.0";>
   <jsp:output omit-xml-declaration="true" />
   <mm:cloud rank="basic user" jspvar="cloud">
+    
     
<h3>${mm:string(requestScope['org.mmbase.framework.state'].renderer.block.title)}</h3>
     
<p>${mm:string(requestScope['org.mmbase.framework.state'].renderer.block.description)}</p>
 
     <mm:import from="request" externid="trigger" />
     <mm:import from="request" externid="interrupt" vartype="integer" />
+    <mm:import from="request" externid="recache" />
     <mm:import from="request" externid="page">0</mm:import>
 
     <mm:import id="pagesize" vartype="integer">50</mm:import>
@@ -22,26 +24,21 @@
         <caption>Configuration of creation of streamscaches</caption>
           <tr>
             <th>id</th>
-            <th>value</th>
+            <th>label</th>
+            <th>mimetype</th>
+            <th>transcoder</th>
           </tr>
         <c:forEach 
items="${status.current.dataType.commitProcessor.processors[2].configuration}" 
var="jobdef">
           <tr>
             <td>${jobdef.key}</td>
-            <td>${jobdef.value}</td>
-<!-- 
-            <td>${jobdef.value.transcoder}</td>
+            <td>${jobdef.value.label}</td>
             <td>${jobdef.value.mimeType}</td>
- -->
+            <td>${jobdef.value.transcoder}</td>
           </tr>
-<!--      <tr>
-            <td />
-            <td colspan="2">${jobdef.value.analyzers}</td>
-          </tr> -->
         </c:forEach>
       </table>
     </mm:fieldlist>
 
-
     <table summary="mediafragments">
       <caption>Recent mediafragments</caption>
       <mm:listnodescontainer type="${type}">

Modified: 
mmbase/trunk/applications/streams/src/main/webapp/mmbase/components/streams/fragment.trs.jspx
===================================================================
--- 
mmbase/trunk/applications/streams/src/main/webapp/mmbase/components/streams/fragment.trs.jspx
       2010-02-03 10:12:55 UTC (rev 40830)
+++ 
mmbase/trunk/applications/streams/src/main/webapp/mmbase/components/streams/fragment.trs.jspx
       2010-02-03 10:21:26 UTC (rev 40831)
@@ -7,45 +7,48 @@
 
   <mm:listnodes id="fragment">
     <tr>
-      <th colspan="100">
+      <th>
         <mm:nodeinfo type="nodemanager"/>
-        <jsp:text> </jsp:text>
+      </th><th>
         <mm:field name="number" />
-        <jsp:text>: </jsp:text>
+      </th><th colspan="4">
         <mm:nodeinfo type="gui" />
-      </th>
+      </th><th colspan="99" />
     </tr>
-    <mm:listfunction name="filteredurls" id="uc">
+    <mm:listfunction name="filteredurls">
+      <c:if test="${_.main}">
+        <c:set var="source"  value="${_.source.number}" />
       <tr>
-        <th>${_.source.builder.tableName} ${_.source.number}</th>
+          <th>${_.source.builder.tableName}</th>
+          <td>${_.source.number}</td>
         <td>
           <jsp:text>${_.state}</jsp:text>
+            ${_.mimeType}
           ${_.dimension}
         </td>
         <td>
           <a href="${mm:escape('text/xml', 
_.URL)}"><mm:escape>${_.URL}</mm:escape></a>
-          ${_.mimeType}
         </td>
-        <c:choose>
-          <c:when test="${_.main}">
             <td colspan="2">
               <mm:function set="streams" name="getJob" referids="_n...@node">
-                JOB: ${_.class}
+              JOB: ${_.class}<br />  
               </mm:function>
               <mm:function set="streams" name="runningJobs">
                 JOB: ${_.class}
               </mm:function>
+          </td>
+          <td>
               <mm:node number="${_.source.number}">
                 <c:set var="triggervalue" value="${fragment}:${_node}" />
                 <c:choose>
                   <c:when test="${trigger eq triggervalue}">
                     <mm:log> CALLING TRIGGER FOR ${trigger}</mm:log>
-                    <mm:voidfunction name="trigger" />
-                    <jsp:text>Triggered conversion</jsp:text>
+                  <mm:voidfunction name="triggerCaches" />
+                  <div class="msg">Triggered transcoding</div>
                   </c:when>
                   <c:otherwise>
                     <mm:link referids="triggerva...@trigger">
-                      <a href="${_}">Trigger</a>
+                    <a href="${_}">Trigger all</a>
                     </mm:link>
                   </c:otherwise>
                 </c:choose>
@@ -62,25 +65,64 @@
                 </c:choose>
               </mm:node>
             </td>
-          </c:when>
-          <c:otherwise>
-            <mm:node number="${_.source.number}" notfound="skip">
+        </tr>
+      </c:if>
+    </mm:listfunction>
+    <mm:listfunction name="filteredurls">
+      <c:if test="${!_.main}">
+        <tr>
+          <th>${_.source.builder.tableName}</th>
+          <td>${_.source.number}</td>
+          <td>
+            <jsp:text>${_.state}</jsp:text>
+            ${_.mimeType}
+            ${_.dimension}
+          </td>
+          <td>
+            <a href="${mm:escape('text/xml', 
_.URL)}"><mm:escape>${_.URL}</mm:escape></a>
+          </td>          
+          <mm:node number="${_.source.number}" notfound="skip" id="cache">
               <td>
+              <mm:hasfield name="label">
+                <mm:field name="label" /><br />
+              </mm:hasfield>
                 <mm:hasfield name="id">
                   <mm:field name="id" />
                 </mm:hasfield>
               </td>
               <td>
-                <mm:hasfield name="id">
+              <mm:hasfield name="key">
                   <mm:field name="key" />
                 </mm:hasfield>
               </td>
+            <td>
+              <mm:hasfield name="id">
+                <c:set var="recachevalue" value="${fragment}:${cache}" />
+                <c:choose>
+                  <c:when test="${recache eq recachevalue}">
+                    <mm:field name="id">
+                      <mm:node number="${source}">
+                        <mm:booleanfunction name="triggerRecache" 
referids="ca...@recache">
+                          <div class="msg">Triggered transcoding</div>
+                        </mm:booleanfunction>
             </mm:node>
+                    </mm:field>
+                  </c:when>
+                  <c:otherwise>
+                    <mm:link referids="recacheva...@recache">
+                      <a href="${_}">Retrigger cache</a>
+                    </mm:link>
           </c:otherwise>
         </c:choose>
+              </mm:hasfield>
+            </td>
+          </mm:node>
       </tr>
+      </c:if>
     </mm:listfunction>
+  
   </mm:listnodes>
+  
   <tr cols="100">
     <mm:previousbatches id="pb">
       <mm:link>
@@ -97,7 +139,6 @@
         <a href="${_}"><mm:index /></a>
       </mm:link>
     </mm:nextbatches>
-
   </tr>
 
 </jsp:root>

_______________________________________________
Cvs mailing list
[email protected]
http://lists.mmbase.org/mailman/listinfo/cvs

Reply via email to