Display Time (CP2019)

Intro

Almost 10 years ago I wrote a blog post to answer user question  quote: “…. if there was anyway to insert running time”.
The user wanted a display on all slides of the time information you can find  in the TOC (total duration of the project and elapsed duration).  Total duration can be found also in the panel ‘Project Info’ in Captivate, which shows global project information (number of slides/frames). In this panel you can also check the expected size of the output file.
Total duration is calculated as the sum of slide durations. Similar the elapsed duration:is calculated as the sum of the duration of the slides before the currently viewed slide. I would call that type of duration ‘developer time’. 

Developer time can be very different from the real time spent by the user viewing slides in that project.  You’ll see in this refurbished article how to show both times, developer and real ones. It is a nice use case for System variables.  BTW, if you didn’t get my free table with System variables, maybe it is the right moment .

Contrary to the old post, which was meant for SWF output, I used JS this time instead of advanced actions with the Expression command.  Reason is that for SWF output the formatting of the variable values could be controlled by the number of characters to display when inserting the variable in a text container. That is not working for HTML5 output. Formatting of numbers is a typical use case (like random data) where I tend to use JavaScript.

Example output

Watch this published movie. The described workflow (from the original post) is working only for linear projects. Sorry for the use of TTS, those slides are based on a longe project….in Dutch.



 
The ‘developer time’ is shown in the top left corner: total project time (secs), time of the previously viewed slides (secs) and percentage viewed.

Real time workflow

The real time is visible at the bottom, next to my name. I used the Timer widget for the real time.  You have to be careful: set the maximum time to a high number, to avoid triggering the end of time action. Getting rid of the background is easy, have a look at my setup.:
 
 

Developer's time workflow

As I announced at the start, for several reasons I preferred to use JS instead of Expressions in an Advanced action as was the case for the older blog post. I propose two scripts. The first one is close to the older blog post, because I use the same system variables, and two methods of the JS interface for Captivate. Details can be found in this document.

In the second script I skipped using the known system variables, replaced them by some more methods of the same document.

Script 1

Variables

The system variables used in the first script are:

  • cpInfoFrameCount: its value is the total number of frames in the Project Info panel (see first screenshot in this article)
  • cpInfoFPS: each movie is played at a certaing speed, which defines its qualtiy. It is indicated as Frames per Second. The higher that rate, the higher the quality
  • cpInfoCurrentFrame: indicates the present frame number. Frames are numbered, starting with 0, not per slide but for the whole project. More details can be found in this blog post about Micro-navigation

In Captivate I created these user variables to display the results in the project:

  • v_total: total duration of the project in seconds
  • v_done: sum of the duration of the previous slides in seconds
  • v_perc: percentage of duration viewed, in %

To avoid confusion, variables in JavaScript used these names:

  • frames: will start with the value of cpInfoFrameCount and end after calculation return the total project duration (secs) 
  • start: will start with a frame number (frist frame of the present slide) and after calculation return the alreadu viewed duration (secs)
  • speed: will store the value of cpInfoFPS
  • percent: will return the percentage viewed after calculation

Javascript

This script has to be triggered On Enter for each slide. That can be directly with the command 'Execute JavaScript' as simple action if you don't need any other commands to be done on entering the slide. If no slide nneeds any extra commands, you can select all slides in the Filmstrip and attach the script to all slides at once. If you need more for some slides, it could be a good idea to use the script in an advanced action, where you can add more commands. Even a shared action is possible, but in this example had no real sense.

Have a look at the script:

I am using two methods from the Common JS Interface:

  • getVariableValue to store the values of Captivate's system variables in the JS variables frames, speed, start. (lines 1-3)
  • setVariableValue to return the results to the Captivate variables v_total, v_done and v_perc (lines 6-7,9)

The calculations in lines 4-5 and 8 are straightforward. To control the formatting of the numbers I used the method 'Number.toFixed(x)'. I didn't want to display two decimals for a simple reason: the first frame will be detected on each slide, and that would have led to a duration of 0,03 seconds on the first slide (30 seconds in a frame). It would be possible to split up the results in minutes and seconds as well. I wanted this example to be a simple introduction to JS newbies. I planned to use the formatting in a third article about numbers. The first two were 'Playing with numbers - part 1' and 'Playng with numbers - part 2'. Both were meant as simple intro to JS for newbies. However, since they didn't get a lot of viewers, I gave up spending more time on it.

Script 2

No system variables here, the user variables and variables in JS are the same as in the first script: v_total, v_done, v_perc, frames, speed, start, percent.. Have a look at the script:

I didn't need the method getVariableValue in this case but used three more methods on top of setVariableValue to return the results to Captivate:

  • getPlaySpeed: returns the same value as the system variable cpInfoFPS (line 1)
  • getCurrentFrame: returns the same value as the system variable cpInfoCurrentFrame (line 2)
  • getDurationInSeconds: spares me one calculation, this value doesn't exist as system variable. This time I don't have to divide the total number of frames (exists as getDurationInFrames) by the FPS value. (line 3)

The other lines in the script are similar to those explained in the first script.



Audio in Learning Interactions

Why?

A question posted recently pushed me at creating this short post: “....a way to stop the main slide audio when a tab on the interaction is clicked”. I pointed to an older blog where you can find some tips for using learning interactions. It offers a table, tells about their limitations etc. I want to explain why there is no simple solution for this question at all. The audio referred to in the question was slide audio, the used Learning interaction was Tabs. What I explain is also valid for Accordion and Timeline. As I explained in the mentioned blog post, the term ‘Learning Interactions’ was introduced to distinguish the widgets compatible with HTML5 output from the older ‘widgets’ which were created for SWF output. Both have however the same extension ‘wdgt’ and are sometimes both indicated as widget. Terminology can be confusing

Static and Interactive

It seems logical that Learning Interactions are interactive, because they allow the learner to click and interact, and they are listed under the Interactions big button. Indeed, they all have some of interactions internally. However not all are also ‘Interactive object’ in Capativate’s timeline. A Captivate interactive object can be recognized this way:

  • It has an Actions tab
  • Under the Actions tab you find up to two events (Success, Last Attempt)
  • A pausing point is automatically inserted at 1.5secs.

You know the common interactive objects: button, shape converted to button, Text Entry Box, click box. For those objects you’ll see the pausing point immediately on the slide timeline. Moreover the object timeline, when not selected will be green. Look at this screenshot, where I kept the original generic names to clarify the type of objects.

Learning Interactions are internally interactive but as objects in Captivate they also come in the two flavors: static and interactive. You can recognize them by the presence of the Actions tab, with the possibility of scoring and reporting. However the score in the game interactions are not linked with the game results (see article)

Interactive interactions can also be identified, based on the generic name in the Timeline panel. In this screenshot I have inserted two interactions: Tabs (static) and Jigsaw Puzzle (interactive). Look at the generic names:

Look carefully at this screenshot: you see that both interactions also have a colored timeline, but exactly the opposite of what you expect. Please, support me by logging this bug. You may also wonder about the presence of a pausing point? No pausing point for the interactions? The static interaction has indeed no pausing point, you need to add an interactive object like a button, to keep the slide paused. That is needed to allow time for the learner to explore the interaction. However the Interactive Interaction doesn have a pausing point which is not showing in the Timeline panel, you’ll find it in the Timing properties.

Audio Problem

The question was about avoiding having slide audio still playing when the user clicks one of the buttons in the Tabs interaction. That interaction allows  to add audio to a button, which is object audio.  Only object audio allows simultaneously playing of multiple audio clips, either from object audio or, in this case, slide audio. Pausing the slide audio, when a button is clicked in the Interaction would need access to the source code of the widget, which is not available. I can only propose two possible solution to avoid hearing two audio clips at the same time.  I will only explain the first solution in this article. The second solution, with a custom interaction will be explained in a later article.

Interaction available after Slide Audio

This is the easiest workflow. The learner would not be able to use the Interaction while the slide audio is playing. With a normal interactive object that would be easy: disable it for a certain time with and On Enter action for the slide and enable after a certain time corresponding with the audio length. However, even an Interactive Interaction cannot be disabled! You need a workaround.

Steps:

  1. Create a static image of the interaction, either using Captivate or another screen capture app like Snagit. Quality should be good to excellent.
  2. Resize that image to the exact size of the Interaction.
  3. Insert the image on the Timeline and time it for the duration of the slide audio.
  4. Move the learning interaction to appear just after the image.
  5. For a static interaction (like Tabs, Accordion….) you need to insert a button or click box to pause the slide. That is not necessary for an interactive Interaction.

Have a look at this screenshot of the Timeline, which illustrates the described steps:

The timelines from bottom to top:
  • Slide audio, about 3,5secs long
  • Tabs Interaction, starts at 3,4 seconds, extends till end of the slide
  • Image of the Tabs interaction, same location and size, starts from the first frame and ends at 3,8secs; overlap with the Interaction is meant to avoid seeing the transition
  • Click box – duration of the slide –  to pause the slide at its end; it could be a Next button as well.

Custom Interaction

Using shared actions, multistate objects, it is perfectly possible to recreate this interaction on a slide. At that moment you have full control over all objects. To avoid multiple audio clips playing at once, the easiest way is to use only audio started with ‘Play Audio’ command.  If you start a second audio with that command, the first one will be stopped automatically. For this example:

  1. Use Play Audio with the On Enter event to replace the slide audio.  That is possible if you don’t need Closed Captioning.
  2. Use Play Audio in the actions triggered by the Tabs buttons. Clicking the button will automatically stop the previous audio, whether it is the audio started On Enter, or the Audio started with another Tabs button. Object audio would also be possible, if you use the command ‘Stop Triggered Audio’ to stop the first audio clip started On Enter.

Do you want to see the setup for such a custom interaction? Post a comment, please.