Announcement

Collapse
No announcement yet.

playing random movie clips

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • playing random movie clips

    is there a way to convert a bunch of movie clips to the proper .gci format, name them sequentially (eg. 001.gci, 002.gci, 003.gci, etc...) and then have the code randomly pick one of the files, play it, and wait a couple of seconds before playing the next random clip?


    I think that I have most of the code written, but cannot figure out how load .gci files off of the microSD card to play them


    #platform "uLCD-32PTU"

    #inherit "4DGL_16bitColours.fnc"

    var sdFileHandle;
    var clipname;
    var counter;
    var sdMovieCount;
    var *disk;


    func main()

    gfx_screenmode(LANDSCAPE);

    if (!(disk := file_mount()))
    while (!(disk := file_mount()))
    putstr ("Drive not mounted...");
    pause (200);
    gfx_cls ();
    wend
    endif

    sdFileHandle := file_open ("moviecount.txt", 'r');

    // read the number of movie clips to randomize from 'filecnt.txt' file
    for (counter := 0; count < 1; counter ++)
    file_read (&sdMovieCount, 2, sdFileHandle);
    putstr (array);
    next
    file_close (sdFileHandle);

    while 1=1
    clipname := abs (rand () % sdMovieCount) + 1; // this gives us a random value between 1 and the value found in the 'filecnt.txt' file

    ?? I'm unsure of how to load the movie clip

    media_video (0,0); // play the video at position 0,0

    // pause 5 seconds before picking the next movie file to play
    pause (5000);

    repeat;

    forever;
    next

    endfunc

  • #2
    Hello,

    You can put all your videos in one GCI file if you are using Visi by clicking on Widgets, then System/Media and then click on the Video widget. Click on the object inspector, then load the video file in the open file window that will appear. Resize or position the video where necessary. Go to your code and click in the area of your code where you would like the video to play and then click on paste code in the object inspector.
    You will notice 2 lines like this,

    img_SetWord(hndl, iVideo1, IMAGE_INDEX, frame) ; // where frame is 0 to 52393
    img_Show(hndl,iVideo1) ;

    you can carry on adding more videos in the above steps

    and you could change the above code to,

    var videoNumber;

    img_SetWord(hndl, iVideo1 + videoNumber, IMAGE_INDEX, frame) ; // where frame is 0 to 52393
    img_Show(hndl,iVideo1 + videoNumber) ;

    I hope this helps

    Best regards

    Paul

    Comment


    • #3
      thank you for your response paul
      the only problem that I have with the single file method is that it requires that the .GCI and associated .DAT files be re-created every time that I want to add or remove a clip and that ViSi be used

      I really wanted to just do this using designer and the graphic composer. is there a way do what I initially asked using numbered files so that if I want to add, remove or substitute the pre-converted clips (using the graphic designer), I can simply dump them onto the microSD card and modify the 'filecnt.txt' file to indicate the number of clips that I want to randomize.

      if I could perform this task using the method that I'm trying it, it eliminates the need to know exactly how many frames are in each clip

      additionally, based on what you've stated above, it still looks like I could be able to use the "file_LoadImageControl", "img_setword" and "img_show" commands for each random file that I want to play. (is it possible to call "file_LoadImageControl" where after building the concatenated filenames

      from the function manual:
      file_LoadImageControl(fname1, fname2, mode);

      (can fname1 and fname2 be variables that have been "assembled" and assigned to another variable like this?

      var datname
      var gciname
      var clipnumber

      clipnumber := abs (rand () % sdMovieCount) + 1;

      datname := ' " ' + clipnumber + '.DAT" '
      gciname := ' " ' + clipnumber + '.GCI" '

      file_LoadImageControl ( datname, gciname, 1 );

      note: the additional spaces between the single and double quotes for the datname and gciname assignments are just for this example to show them easier


      ps
      I am already using something similar to what you've proposed [using one large .GCI file] for another project where I plan to animate certain portions of an image (using specific frame ranges)
      based on a GPIO signal using the following:

      hndl := file_LoadImageControl("video.dat", "video.gci", 1);

      label:

      for(frame := 0; frame <= 85; frame ++)
      img_SetWord(hndl, iVideo1, IMAGE_INDEX, frame) ; // where frame is 0 to 87
      img_Show(hndl,iVideo1) ;
      pause(33);
      next

      Comment


      • #4
        Hi


        Yes you can substitute variables (string) for the GCI an DAT in file_LoadImageControl ( datname, gciname, 1 ); allowing you to construct the filenames from within your code.

        You could also use to(); and print() to build a filename in an array and open that.


        Best regards

        Paul

        Comment


        • #5
          thank you paul for your speedy and informative replies. I'll let you know how it works out for us

          Comment


          • #6
            hi again paul,

            I've written the following and it compiles without any errors. I've downloaded it to the display but I cannot get any of the converted movies to play.
            I currently have following files on the 2GB microSD card that is inserted into the display:

            moviecnt.txt file (containing the single value "3" (quotes are not present in the file, just the value 3)
            1.GCI
            1.DAT
            2.GCI
            2.DAT
            3.GCI
            3.DAT
            4.GCI
            4.DAT

            the code is as follows:

            #platform "uLCD-32PTU"

            #inherit "4DGL_16bitColours.fnc"

            #inherit "VisualConst.inc"

            #inherit "random_movieConst.inc"

            func main()

            var disk;
            var clipname;
            var counter;
            var frame;
            var hndl;
            var MovieCount;
            var sdFileHandle;


            gfx_ScreenMode(LANDSCAPE) ; // change manually if orientation change

            putstr("Mounting...\n");
            if (!(disk:=file_Mount()))
            while (!(disk:=file_Mount()))
            putstr("Drive not mounted...");
            pause(200);
            gfx_Cls();
            pause(200);
            wend
            endif

            gfx_Cls();

            sdFileHandle:=file_Open("moviecnt.txt",'r');

            //read the number of movie clips to randomize from "moviecnt.txt" file
            for (counter:=0;counter<1;counter++)
            file_Read(MovieCount,1,sdFileHandle);
            putstr(MovieCount);
            next
            file_Close(sdFileHandle);

            label:

            gfx_Cls();

            // the following gives us a random value between 1 and the value found in the 'clipcnt.txt' file
            clipname:=ABS(RAND()%MovieCount)+1;

            hndl:=file_LoadImageControl(clipname+".DAT",clipname+".GCI",1);

            for(frame:=0;frame<500;frame++)
            img_SetWord(hndl, iVideo1, IMAGE_INDEX, frame);
            img_Show(hndl,iVideo1);
            next

            mem_Free(hndl);

            goto label;

            repeat
            forever

            endfunc

            Comment


            • #7
              paul,
              I modified the code and found that if I comment out the reading of my .txt file and hard code the file_LoadImageControl command (using double quotes around both the .dat and .gci filename, that I'm able to get a single file to play, so I know that the video files are good. I thought that I could use variables for fname1 and fname2 in the file_LoadImageControl command

              #platform "uLCD-32PTU"

              #inherit "4DGL_16bitColours.fnc"

              #inherit "VisualConst.inc"

              #inherit "random_movieConst.inc"

              func main()

              var disk;
              var clip_no;
              var counter;
              var datname;
              var frame;
              var frames;
              var gciname;
              var hndl;
              var MovieCount;
              var sdFileHandle;


              gfx_ScreenMode(LANDSCAPE) ; // change manually if orientation change

              putstr("Mounting...\n");
              if (!(disk:=file_Mount()))
              while (!(disk:=file_Mount()))
              putstr("Drive not mounted...");
              pause(200);
              gfx_Cls();
              pause(200);
              wend
              endif

              gfx_Cls();

              // sdFileHandle:=file_Open("moviecnt.txt",'r');

              //read the number of movie clips to randomize from "moviecnt.txt" file
              // for (counter:=0;counter<1;counter++)
              // file_Read(MovieCount,1,sdFileHandle);
              // putstr(MovieCount);
              // next
              // file_Close(sdFileHandle);

              label:

              gfx_Cls();

              // the following gives us a random value between 1 and the value found in the 'clipcnt.txt' file
              clip_no := ABS(RAND()%MovieCount)+1;

              datname := clip_no + ".dat";
              gciname := clip_no + ".gci";

              // hndl:=file_LoadImageControl(datname, gciname, 1);
              hndl:=file_LoadImageControl("1.dat", "1.gci", 1);

              frames := img_GetWord (hndl, 0, IMAGE_FRAMES);

              for(frame:=0; frame < frames; frame++)
              img_SetWord(hndl, iVideo1, IMAGE_INDEX, frame);
              img_Show(hndl,iVideo1);
              next

              mem_Free(hndl);

              goto label;

              endfunc

              Comment


              • #8
                Hi,

                Yes this should be possible to do. I am trying a couple of things at the moment.

                As it is we are trying to add an integer to a string ".DAT" which won't work. It wiil need to be converted to text.

                Also take a look through this appnote http://www.4dsystems.com.au/download...0056_R_1_0.pdf

                Paul

                Comment


                • #9
                  I guess the thing that I've having a hard time of wrapping my head around is the fact that their are no string vs. numeric variable types in the 4DGL language

                  I've been a programmer for almost 30 years now, and in every language that I've coded, if I want to declare a string or an integer variable, I can just do that
                  eg.
                  string ls_var1
                  integer li_var1

                  whereas 4DGL identifies all variables as simply type 'var' with no distinction of what type of variable it is

                  how does the 4DGL know what the types the variables are?

                  the other thing that I've had issues with is the #inherit statements at the top of the programs. for instance the 3 listed above in my source:
                  #inherit "4DGL_16bitColours.fnc"

                  #inherit "VisualConst.inc"

                  #inherit "random_movieConst.inc"


                  I just copied the first two from another program listing, but I until I took a [x]Const.inc file from another program and renamed it the same as what I was naming this project, the script would not compile. exactly where is this constants include supposed to come from and how is it supposed to get created?

                  I really like the 4D displays, but I feel like we have to pester you guys (which are awesome) for things that should be easier to figure out than what they are

                  Comment


                  • #10
                    Hi,

                    I understand what you are saying and it can be a bit hard to get your head around, but I think at the end of the day we all become better programmers by acheiving this without a string object as such. In the Arduino world strings are very much frowned upon and we are told to use char arrays instead of strings eventhough there is nothing more convenient than string manipulation eg. clipname := "1" + ".DAT", but string handling is not good on memory usage and not very efficient, as it is, compiled 4DGL code is very compact and efficient.

                    In the case of what we were trying to achieve. I suppose we could use if, endif, for the amount of expected videos you may load onto your SD card e.g


                    If(clipname == 1)
                    hndl:=file_LoadImageControl("1.dat", "1.gci", 1);
                    endif

                    If(clipname == 2)
                    hndl:=file_LoadImageControl("2.dat", "2.gci", 1);
                    endif

                    I should imagine after being compiled the code size for the above is that not much bigger.

                    I will look into your #inherit findings.

                    I hope this helps

                    Best regards

                    Paul

                    Comment


                    • #11
                      I did find this in the picaso internal functions .pdf which I believe will work better than having the moviecnt.txt file on the microSD

                      by using this:
                      MovieCount := file_Count ( "*.gci" );

                      I can eliminate this section from my code:
                      // sdFileHandle:=file_Open("moviecnt.txt",'r');

                      //read the number of movie clips to randomize from "moviecnt.txt" file
                      // for (counter:=0;counter<1;counter++)
                      // file_Read(MovieCount,1,sdFileHandle);
                      // putstr(MovieCount);
                      // next
                      // file_Close(sdFileHandle);

                      this should also allow me to just [dump] any newly converted files onto the microSD card without any further changes to the code (and no need to recompile and download to the flash memory)


                      one more question while I've got your ear
                      do you know if there are any plans to update the graphics composer software and allow for more file types to be read in to convert to .gci/.dat?
                      .mp4 and .mkv would be nice additions

                      currently, I'm getting error messages when attempting to open .wmv's and/or .mpg's and am having to convert the .wmv's to .gif files in photoshop in order to get the clips to be successfully converted

                      Comment


                      • #12
                        Hi,

                        You can do this in Workshop 4 which will support most windows video's formats, by starting a new project in ViSI and Clicking on Widgets then System/Media and then Video. Choose the video file in the open file dialog that appears. Place and resize if necessary then compile. It will ask you for a filename to save it as and a location. After that the GCI and DAT file will be available in the folder where the project is saved.

                        MovieCount := file_Count ( "*.gci" ); that was good find, thank you for sharing that with me.

                        Best regards

                        Paul

                        Comment


                        • #13
                          I have most everything working now, however there simply has to be a cleaner way of playing the random video files rather than checking the value of clip_no and playing a hard-coded .dat / .gci file combination

                          I'd like to put the delay time in an external file (so that it can be altered without having to recompile the code) but I think I'll wait until I get all of the clips converted and running before taking another stab at that

                          ps
                          ViSi - widgets - system/media - video worked fine for the .wmv files, but threw an error for the .mpg files. it also took my .mkv but make a mess of it (video-wise) after converting it to the .gci/.dat files



                          here's my code:

                          #platform "uLCD-32PTU"

                          #inherit "4DGL_16bitColours.fnc"

                          #inherit "VisualConst.inc"

                          #inherit "random_movieConst.inc"

                          func main()

                          var disk;
                          var clip_no;
                          var counter;
                          var frame;
                          var frames;
                          var hndl;
                          var MovieCount;


                          counter := 0;

                          // initialize the SEED function to help randomize the RAND function used below
                          SEED(sys_T());

                          gfx_ScreenMode(LANDSCAPE) ; // change manually if orientation change

                          putstr("Mounting microSD card...\n");

                          pause(500);

                          if (!(disk:=file_Mount()))
                          while (!(disk:=file_Mount()))
                          putstr("microSD card not mounted...\n");
                          pause(500);
                          gfx_Cls();
                          pause(500);
                          wend
                          endif

                          gfx_Cls();

                          // read in the number of movie clips to randomize
                          MovieCount := file_Count ( "clip*.gci" );

                          gfx_Cls ();

                          while ( MovieCount > 0 )
                          // display splash animation
                          hndl:=file_LoadImageControl( "splash.dat", "splash.gci", 1);

                          frames := img_GetWord ( hndl, 0, IMAGE_FRAMES );

                          for ( frame:=0; frame < frames; frame++ )
                          img_SetWord ( hndl, iVideo1, IMAGE_INDEX, frame );
                          img_Show ( hndl,iVideo1 );
                          next

                          pause(2500);

                          mem_Free ( hndl );


                          label:

                          counter++;

                          // the following gives us a random value between 1 and the value found in the 'clipcnt.txt' file
                          clip_no := ABS ( RAND () % MovieCount ) + 1;

                          if ( clip_no == 1 )
                          hndl:=file_LoadImageControl( "clip1.dat", "clip1.gci", 1);
                          endif

                          if ( clip_no == 2 )
                          hndl:=file_LoadImageControl( "clip2.dat", "clip2.gci", 1);
                          endif

                          if ( clip_no == 3 )
                          hndl:=file_LoadImageControl( "clip3.dat", "clip3.gci", 1);
                          endif

                          if ( clip_no == 4 )
                          hndl:=file_LoadImageControl( "clip4.dat", "clip4.gci", 1);
                          endif

                          if ( clip_no == 5 )
                          hndl:=file_LoadImageControl( "clip5.dat", "clip5.gci", 1);
                          endif

                          if ( clip_no == 6 )
                          hndl:=file_LoadImageControl( "clip6.dat", "clip6.gci", 1);
                          endif

                          if ( clip_no == 7 )
                          hndl:=file_LoadImageControl( "clip7.dat", "clip7.gci", 1);
                          endif

                          if ( clip_no == 8 )
                          hndl:=file_LoadImageControl( "clip8.dat", "clip8.gci", 1);
                          endif

                          if ( clip_no == 9 )
                          hndl:=file_LoadImageControl( "clip9.dat", "clip9.gci", 1);
                          endif

                          if ( clip_no == 10 )
                          hndl:=file_LoadImageControl( "clip10.dat", "clip10.gci", 1);
                          endif

                          // determine the number of frames for the selected movie clip to loop through
                          frames := img_GetWord ( hndl, 0, IMAGE_FRAMES );

                          // loop through the movie clip frames
                          for ( frame:=0; frame < frames; frame++ )
                          img_SetWord ( hndl, iVideo1, IMAGE_INDEX, frame );
                          img_Show ( hndl,iVideo1 );
                          next

                          gfx_Cls();
                          pause(5000);

                          mem_Free ( hndl );

                          // display the splash file after every 10th movie clip
                          if ( counter > 9)
                          hndl:=file_LoadImageControl( "splash.dat", "splash.gci", 1);

                          frames := img_GetWord ( hndl, 0, IMAGE_FRAMES );

                          for ( frame:=0; frame < frames; frame++ )
                          img_SetWord ( hndl, iVideo1, IMAGE_INDEX, frame );
                          img_Show ( hndl,iVideo1 );
                          next

                          pause(2500);

                          mem_Free ( hndl );

                          counter := 0;
                          endif

                          goto label;
                          wend

                          endfunc

                          Comment


                          • #14
                            String concatenation is, most simply, done like this Untested and useful as a sample only.
                            Code:
                                var gciname[7] ; // enough for an 8.3 filename and trailing null
                                to(gciname) ;
                                print("clip", clip_no, ".gci") ;
                            Then you need to use a string pointer when opening the file
                            Code:
                                hndl := file_LoadImageControl( str_Ptr(datname), str_Ptr(gciname), 1);
                            Mark

                            Comment


                            • #15
                              thanks mark

                              I'll give that a try tonight

                              Comment

                              Working...
                              X