10 Replies Latest reply on Jun 17, 2013 8:35 AM by Mads Juul

    Can I read/write inpoint and outpoint of clips in a Video Group with scripting?

    Mads Juul

      I am a Prefessional 2d Storyboarder and I just got Photoshop CS6 through the Creative Cloud. I am very Impressed by the new Video Group .

      There is a lot of function I would like to customize  For instance there is a go to next Frame. I would like to script which go to first frame of the next clip in the video group layer and select this layer. So I can draw my next storyboard panel on ot.

       

      so Is it possible though to access and Manipulate the video Group Information Through Scripting?

       

      For instance this

      app.activeDocument.activeLayer.typename;

      return "LayerSet"

      So It seems like I cannot tell an odinairy LayerSet from a "Video Group" Layer Set. Is this Correct?

       

      Then if I go throught the Properties of the first layer in the Video group like this

       

      var firstLayer = app.activeDocument.activeLayer.layers[0];

          

         for (prop in firstLayer){

                  alert(prop);

           }

       

      It seems there is no inpoint or outpint . So I guess it is nor possible to read/write inpint and outpoint of Clip in Viedeo Group, or is there another way?

      Kind Regards Mads

        • 1. Re: Can I read/write inpoint and outpoint of clips in a Video Group with scripting?
          Paul Riggott Level 6

          You would need to use the ScriptListener plugin to see what code is generated when you do those actions.

          You should be able to look at all the keys available of the selected layers and see what might be of use to you.

           

          Here is some of Mikes code that you could run from ExtendScript Toolkit on a selected layer.

           

           

          #target photoshop
          var ref = new ActionReference();
          ref.putEnumerated( zTID("Lyr "), zTID("Ordn"), zTID("Trgt") ); 
          var desc = executeActionGet(ref);
          $.writeln(desc);
          var c = desc.count
          if(desc.typename == 'ActionReference'){
              var c = desc.count;
              for(var i=0;i<c;i++){ //enumerate reference. use getForm() to determine which get method to use
                $.writeln('AR '+zeroPad( i+1, 2 )+' = '+desc.getReference(i).getIndex()); 
              }
          }
          if(desc.typename == 'ActionList'){
              var c = desc.count;
              for(var i=0;i<c;i++){ //enumerate list
               $.writeln('AL '+zeroPad( i+1, 2 )+' = '+desc.getType(i)/* added desc.getPath(i) for aliastype */ +' - ' + typeIDToStringID(desc.getClass (i)));
              }
          }
          if(desc.typename == 'ActionDescriptor'){
              var c = desc.count;
              for(var i=0;i<c;i++){ //enumerate descriptor's keys
                $.writeln('AD '+zeroPad( i+1, 2 )+' = '+IDTz(desc.getKey(i)) +' : '+desc.getType(desc.getKey(i))); 
              }
          }
          function IDTz(id){
               try {
                    var res = typeIDToStringID( id );
                    if(res == '' ){
                         var res = typeIDToCharID( id );
                    }
               }catch(e){}
               return res;
          }
          function zTID( s ){
               if( s.length == 4 ) var res = charIDToTypeID( s );
               if( s.length > 4 ) var res = stringIDToTypeID( s );
               return res;
          }
          function zeroPad(num,pad) {
               var z = Math.pow(10,Number(pad))
               return num <= z ? ((Number( num) + z).toString().substr(1)): num
          }
          
          
          • 2. Re: Can I read/write inpoint and outpoint of clips in a Video Group with scripting?
            Mads Juul Level 1

            So you are verifying there is no scriptcode to directly get/Set information about the timeline in the Video Group?

            I thought so. Have have briefly Loooked aty the Scriptlistener output. It didnt seem to give the neccessaty output. For instance Which is the current frame and what layer is present at a specific time.

            But I will ook into it with the code you have provided and another post if I find something. thank you for the help.

            • 3. Re: Can I read/write inpoint and outpoint of clips in a Video Group with scripting?
              Paul Riggott Level 6

              There is no easy way, here are a few functions that might be of use....

               

               

              function gotoFrame(Seconds,Frame,frameRate) {
                  var desc69 = new ActionDescriptor();
                      var ref33 = new ActionReference();
                      ref33.putProperty( charIDToTypeID('Prpr'), stringIDToTypeID('time') );
                      ref33.putClass( stringIDToTypeID('timeline') );
                  desc69.putReference( charIDToTypeID('null'), ref33 );
                      var desc70 = new ActionDescriptor();
                      desc70.putInteger( stringIDToTypeID('seconds'), Seconds );
                      desc70.putInteger( stringIDToTypeID('frame'),Frame );
                      desc70.putDouble( stringIDToTypeID('frameRate'), frameRate );
                  desc69.putObject( charIDToTypeID('T   '), stringIDToTypeID('timecode'), desc70 );
                  executeAction( charIDToTypeID('setd'), desc69, DialogModes.NO );
              };
              function gotoNextFrame(toNextSecond) {
              if(toNextSecond == undefined) toNextSecond = false;
                  var desc = new ActionDescriptor();
                  desc.putBoolean( stringIDToTypeID('toNextWholeSecond'), toNextSecond);
                  executeAction( stringIDToTypeID('nextFrame'), desc, DialogModes.NO );
              };
              function gotoPreviousFrame(toNextSecond) {
              if(toNextSecond == undefined) toNextSecond = false;
              var desc = new ActionDescriptor();
              desc.putBoolean( stringIDToTypeID('toNextWholeSecond'), toNextSecond);
              executeAction( stringIDToTypeID('previousFrame'), desc, DialogModes.NO );
              };
              function getCurrentFrame(){
                 try{
                    var ref = new ActionReference();
                    ref.putProperty(charIDToTypeID('Prpr'), stringIDToTypeID('currentFrame'));
                    ref.putClass(stringIDToTypeID('timeline'));
                    var desc=new ActionDescriptor();
                    desc.putReference(charIDToTypeID('null'), ref);         
                    var TC=executeAction(charIDToTypeID('getd'), desc, DialogModes.NO); 
                    return TC.getInteger(stringIDToTypeID('currentFrame')); 
                 }catch(e){return null;}
              };
              function trimStartOfClip(seconds, frame, framerate) {
              var desc45 = new ActionDescriptor();
              var desc46 = new ActionDescriptor();
              desc46.putInteger( stringIDToTypeID('seconds'), seconds );
              desc46.putInteger( stringIDToTypeID('frame'), frame );
              desc46.putDouble( stringIDToTypeID('frameRate'), framerate );
              desc45.putObject( stringIDToTypeID('timeOffset'), stringIDToTypeID('timecode'), desc46 );
              executeAction( stringIDToTypeID('moveInTime'), desc45, DialogModes.NO );
              };
              function trimEndOfClip(seconds, frame, framerate) {
              var desc42 = new ActionDescriptor();
              var desc43 = new ActionDescriptor();
              desc43.putInteger( stringIDToTypeID('seconds'), seconds);
              desc43.putInteger( stringIDToTypeID('frame'), frame );
              desc43.putDouble( stringIDToTypeID('frameRate'), framerate );
              desc42.putObject( stringIDToTypeID('timeOffset'), stringIDToTypeID('timecode'), desc43 );
              executeAction( stringIDToTypeID('moveOutTime'), desc42, DialogModes.NO );
              };
              //trimEndOfClip(-10,0,200);
              function videoInfo(){
              var Info= new Array();  
              var ref = new ActionReference();
              ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') ); 
              var desc = executeActionGet(ref);
              if(desc.hasKey (stringIDToTypeID('videoLayer'))){
              var desc = executeActionGet(ref).getObjectValue(stringIDToTypeID('videoLayer'));
              var footageInfo = desc.getObjectValue(stringIDToTypeID('footageInfo'));
              var duration = footageInfo.getObjectValue(stringIDToTypeID('duration'));
              var FilmDuration  = duration.getInteger (stringIDToTypeID('numerator')) / duration.getInteger (stringIDToTypeID('denominator'));
              var fRate = footageInfo.getObjectValue(stringIDToTypeID('frameRate'));
              var frameRate  = fRate.getInteger (stringIDToTypeID('numerator')) / fRate.getInteger (stringIDToTypeID('denominator'));
              var Path = footageInfo.getString( stringIDToTypeID('path'));
              var Alpha = footageInfo.getBoolean( stringIDToTypeID('hasAlpha'));
              Info.push([[frameRate],[FilmDuration],[Alpha],[Path]]);
              return Info;
                  }
              return null;
              };
              
              
               
              • 5. Re: Can I read/write inpoint and outpoint of clips in a Video Group with scripting?
                Mads Juul Level 1

                I can see I can obtain what I want through scripting. But I just realized the Photoshop Script is executing to slow to do a thing like this, the main reason is the GUI is refreshing while Im running a script. And It seems like I cannot disable this. . I think it is a better plan to use Photoshop as it is and then make Feature request for the thing I think could mprove the workflow. I made my first here

                http://feedback.photoshop.com/photoshop_family/topics/video_group_timeline_go_to_first_fra me_of_next_clip

                and here

                http://feedback.photoshop.com/photoshop_family/topics/suppert_rolling_edit_in_photoshop_vi deo_group

                 

                And then I think I make another for sppeding up Execution of action/Scripts . and part of this disabling refresh of display during run.

                -Mads

                • 6. Re: Can I read/write inpoint and outpoint of clips in a Video Group with scripting?
                  Mads Juul Level 1

                  Hi Paul

                  The VideoInfo() Function return Null when I use ir. I guess its because Im not using video. Im a storyboarder and Im using the video group to time my Layers to create an animatic. I have ttache a photo to illustrate my workflow.

                  Is it possible to make a LayerInfo() function that would return the duration inpoint/outpoint of an artlayer used in a video group?

                   

                   

                   

                  psdexanpel.PNG

                  Kind regards Mads

                  • 7. Re: Can I read/write inpoint and outpoint of clips in a Video Group with scripting?
                    Paul Riggott Level 6

                    I don't use video and have only 2 clips to do any testing so I don't know what I'am doing most of the time. I have put together a few more functions.

                    I still haven't found a way of finding where one clip finishes and one starts.

                     

                     

                    function exportComments(file) {//html format
                    var desc41 = new ActionDescriptor();
                    desc41.putPath( charIDToTypeID('Usng'), new File(file) );
                    executeAction( stringIDToTypeID('exportTimelineComments'), desc41, DialogModes.NO );
                    };
                    function getTimelineLength(){
                    var ref=new ActionReference();
                    ref.putProperty(charIDToTypeID('Prpr'),stringIDToTypeID('duration'));
                    ref.putClass(stringIDToTypeID('timeline'));
                    var desc=new ActionDescriptor();
                    desc.putReference(charIDToTypeID('null'),ref);
                    var TC=executeAction(charIDToTypeID('getd'),desc,DialogModes.NO);
                    TC=TC.getObjectValue(stringIDToTypeID('duration'));
                    var M=0;
                    try{M=TC.getInteger(stringIDToTypeID('minutes'));}catch(e){}
                    var S=0;
                    try{S=TC.getInteger(stringIDToTypeID('seconds'));}catch(e){}
                    var F=TC.getInteger(stringIDToTypeID('frame'));
                    var FR=TC.getInteger(stringIDToTypeID('frameRate'));
                    var A = new Array();
                    A.push([[M],[S],[F],[FR]]);
                    return A;
                    }
                    function timeNow(){
                    var a = new Array();
                    var ref = new ActionReference();
                    ref.putProperty(charIDToTypeID('Prpr'), stringIDToTypeID('time'));
                    ref.putClass(stringIDToTypeID('timeline'));
                    var desc1=new ActionDescriptor();
                    desc1.putReference(charIDToTypeID('null'), ref);         
                    var desc=executeAction(charIDToTypeID('getd'), desc1, DialogModes.NO);
                    desc =desc.getObjectValue (stringIDToTypeID('time'));
                    var Minutes = 0;
                    try{ Minutes = desc.getInteger(stringIDToTypeID('minutes'));}catch(e){}
                    var Seconds = 0;
                    try{Seconds = desc.getInteger(stringIDToTypeID('seconds'));}catch(e){}
                    var Frame = desc.getInteger(stringIDToTypeID('frame'));
                    var Framerate = desc.getUnitDoubleValue (stringIDToTypeID('frameRate'));
                    a.push([[Minutes],[Seconds],[Frame],[Framerate]]);
                    return a;
                    };
                    function getworkOutTime(){
                       try{
                    var ref = new ActionReference();
                    ref.putProperty(charIDToTypeID('Prpr'), stringIDToTypeID('workOutTime'));
                    ref.putClass(stringIDToTypeID('timeline'));
                    var desc=new ActionDescriptor();
                    desc.putReference(charIDToTypeID('null'), ref);         
                    var Timeline=executeAction(charIDToTypeID('getd'), desc, DialogModes.NO); 
                    Timeline=Timeline.getObjectValue(stringIDToTypeID('workOutTime'));
                    var M=0;
                    try{M=Timeline.getInteger(stringIDToTypeID('minutes'));}catch(e){}
                    var S=0;
                    try{S=Timeline.getInteger(stringIDToTypeID('seconds'));}catch(e){}
                    var F=Timeline.getInteger(stringIDToTypeID('frame'));
                    var FR=Timeline.getInteger(stringIDToTypeID('frameRate'));
                    var A = new Array();
                    A.push([[M],[S],[F],[FR]]);
                    return A;
                       }catch(e){return null;}
                    };
                    function getworkInTime(){
                       try{
                    var ref = new ActionReference();
                    ref.putProperty(charIDToTypeID('Prpr'), stringIDToTypeID('workInTime'));
                    ref.putClass(stringIDToTypeID('timeline'));
                    var desc=new ActionDescriptor();
                    desc.putReference(charIDToTypeID('null'), ref);         
                    var Timeline=executeAction(charIDToTypeID('getd'), desc, DialogModes.NO); 
                    Timeline=Timeline.getObjectValue(stringIDToTypeID('workInTime'));
                    var M=0;
                    try{M=Timeline.getInteger(stringIDToTypeID('minutes'));}catch(e){}
                    var S=0;
                    try{S=Timeline.getInteger(stringIDToTypeID('seconds'));}catch(e){}
                    var F=Timeline.getInteger(stringIDToTypeID('frame'));
                    var FR=Timeline.getInteger(stringIDToTypeID('frameRate'));
                    var A = new Array();
                    A.push([[M],[S],[F],[FR]]);
                    return A;
                       }catch(e){return null;}
                    };
                    
                    
                    • 8. Re: Can I read/write inpoint and outpoint of clips in a Video Group with scripting?
                      Mads Juul Level 1

                      I made this script. Which moves the playhead to first frame of the next layer and slects this layer. The behavior I want. But the script is to slow obvious. I obtained the result by detecting whether or not the playhead is at the selected layer by generating an error with a fill command. The same way I could find the inoint and outpoint of the selected layer. But again it is to slow. But I just wanted to shre my amateur scriptinf thoughts

                      -Mads

                       

                       

                       

                       

                      app.displayDialogs = DialogModes.NO

                      try{

                       

                       

                                if(app.documents.length<1){

                                                    alert("Please Open A Document");

                                }else{

                              nextLayer();

                           }

                      }catch(e) {

                           alert(e);

                      }

                       

                       

                      function getCurrentFrame(){

                         try{

                            var ref = new ActionReference();

                            ref.putProperty(charIDToTypeID('Prpr'), stringIDToTypeID('currentFrame'));

                            ref.putClass(stringIDToTypeID('timeline'));

                            var desc=new ActionDescriptor();

                            desc.putReference(charIDToTypeID('null'), ref);        

                            var TC=executeAction(charIDToTypeID('getd'), desc, DialogModes.NO);

                            return TC.getInteger(stringIDToTypeID('currentFrame'));

                         }catch(e){return null;}

                      };

                       

                       

                      function gotoNextFrame(toNextSecond) {

                      if(toNextSecond == undefined) toNextSecond = false;

                          var desc = new ActionDescriptor();

                          desc.putBoolean( stringIDToTypeID('toNextWholeSecond'), toNextSecond);

                          executeAction( stringIDToTypeID('nextFrame'), desc, DialogModes.NO );

                      };

                       

                       

                      function playheadOnActiveLayer(){

                          app.displayDialogs = DialogModes.NO

                           var curDoc = app.activeDocument;

                           var myLayer = curDoc.activeLayer;

                          

                          curDoc.activeLayer=myLayer;

                           var startLocked = myLayer.allLocked;

                           try{

                          myLayer.allLocked=true;

                          } catch(e){

                                     app.activeDocument.activeLayer=app.activeDocument.layers[1];

                                       myLayer.allLocked=true;

                              }

                          var errornumber = 1;

                           try{

                              app.activeDocument.selection.fill(app.foregroundColor);

                          } catch(e){

                              errornumber=e.number;

                           }

                       

                       

                          myLayer.allLocked = startLocked;

                          if(errornumber==-25920  ){

                               return false;

                           } else {

                                  return true;

                                  }

                        

                      }

                       

                       

                      function selectLayerAtPlayhead(){

                           var curDoc = app.activeDocument;

                           var myLayer = curDoc.activeLayer;

                           var myLayerSet = false;

                           if(myLayer.typename=="LayerSet"){

                               var myLayerSet = myLayer;

                               } else {

                                   var myLayerSet = myLayer.parent;

                                   }

                           if (myLayerSet.typename=="LayerSet"){

                               var layers = myLayerSet.layers;

                               var i = 0;

                               var run = 1;

                               var length = layers.length-1;

                               while (run){

                                      curDoc.activeLayer=layers[i];

                                      var isON = playheadOnActiveLayer();

                                      if(isON){

                                          run=0;

                                      }

                                      i++;

                                      if(i>length){

                                          run=0;

                                          }

                                   }

                             

                               } else {

                                   gotoFrame(0,0,12);

                                   }

                          }

                       

                       

                       

                       

                       

                       

                       

                       

                      function nextLayer(){

                         

                          var next =  getCurrentFrame();

                       

                       

                          var run=1;

                          while(run){

                              var prev = next;

                                   var isON = playheadOnActiveLayer();

                              if(!isON){

                                    selectLayerAtPlayhead();

                                     run=0;

                                  } else {

                                       gotoNextFrame();

                                        var next = getCurrentFrame();

                                       if(next==prev){

                                           run=0;

                                           }

                                      }

                              }

                          }

                      • 9. Re: Can I read/write inpoint and outpoint of clips in a Video Group with scripting?
                        bertrandG

                        hi,

                        i'm very interested in your problem. Did you find a solution about that?

                         

                        the only function that does work for me is playheadOnActiveLayer(). I'm curious to know how you found this trick with the fill command. That's great.

                         

                        I tried to find a way to get Inpoint and outpoint of a layer (I though it could help a lot) with the scriptListiner and the "down arrow" shortcut, but had no chance. It looks like the value pop up from nowhere.

                        • 10. Re: Can I read/write inpoint and outpoint of clips in a Video Group with scripting?
                          Mads Juul Level 1

                          I have not found a solution, only this hack methods which is to slow. the proper solution is not supported by action script, so I abandoned the idea(and is storyboarding in another software) If it becomes possible in a future update of photoshop, maybe I will look into it again. If somebody finds a solution please post it at this thread. I invented the trick with the fill commands my self.

                          -Mads