Importing Courses into Engine

E-learning courses are usually distributed in a self-contained unit called a "package", typically in the form of a ZIP file. Although the structure of a package varies between the different learning standards, you usually don't have to know about these differences when working with Engine.

To launch a course in Engine, you first have to make Engine aware of your course by importing it. For most customers, importing a course into Engine is as simple as uploading the ZIP file package and letting Engine handle the rest.

However, Engine does support a variety of other ways to import your courses, such as providing the path to a course already extracted somewhere, or the URL to download the zip file. You can read about those import methods below, but for now, let's stick to the most common import behaviors.

Importing by ZIP

An important distinction to understand is that Engine does not host your course content files. When Engine imports a course, it will just unzip the course, parse and record its details according to the appropriate learning standard, and drop the course files onto your content server. Unless you want to use Engine's remote hosted player, you should ensure that your content server is on the same domain as Engine, or else Engine's player will be inhibited by browser same-origin policies.

Required Settings

There are a few settings that you'll need to configure for this type of import process to work correctly:

  • FilePathToUploadedZippedPackage - This setting should be the directory that Engine can use as a place to temporarily store the ZIP files while they are being imported. They will be deleted after the import process is completed.
  • FilePathToContentRoot - The directory to which Engine should extract the contents of your courses. Within this directory, a folder for each course will be created. The name of the course folder will be based on your course id, and a subfolder under that for the version (e.g., /mycourseid/0).

    Note: This directory should be hosted by a web server so that all of your course content is accessible to your learners in the browser.

  • WebPathToContentRoot- Engine uses this value to calculate the web path to a course's content once it has been imported. This should be the URL where the directory you specified in FilePathToContentRoot is being hosted. This value is often a relative URL for the current domain (e.g. /courses/content/), but can also be a fully-qualified URL (e.g. http://example.org/courses/content/) if needed.

Posting the ZIP File Directly

Once you've set those values, you can import a course by sending a POST to the /courses/importJobs/upload resource, taking special note of the courseId query string parameter. This parameter should provide a unique identifier for the course being imported.

The body of the request will have the contents of your zip file, and the Content-Type of the request should be multipart/form-data.

Have Engine Download the ZIP File

If you don't want to POST the contents of your course directly to Engine, you can also have the import process fetch the ZIP file itself. To do this, you need to host the course on a web server that Engine can access or on the server's local file system. Once you've done that, you can POST a JSON object (as Content-Type application/json) to /courses/importJobs endpoint with a URL pointing to the location of your zipped course file.

Additionally, if you include Basic Auth credentials in the URL you give us for the zip file, Engine will add them as a standard HTTP "Authorization" header for the request it makes to download the course.

http://username:password@example.com/MyCourse.zip

Checking Import Status

It's important to note that when you call the importJobs endpoint through one of the methods above, the course is not immediately ready for use. Since the processing of a course package may take a while, Engine will queue the import job to process it asynchronously and will return a job ID to you in the response.

You should verify that the import job completed successfully before trying to launch it. There are two main ways to do that:

  • Using the job ID that was returned to you, check the status by querying the /courses/importJobs/{importJobId} resource in the API. You may have your UI wait while it periodically checks to see whether the job is finished before continuing.
  • Alternatively, you could have Engine update your application directly when the import is finished. If you set the value of ApiImportResultsPostBackUrl to the URL of an endpoint in your application, then Engine will POST a JSON object describing the results of the course import whenever an import has been completed.

Advanced Import

Importing by Manifest

If your application is already handling the ZIP extraction and the course content is already hosted on a web server, then you can simply point Engine to the manifest of your course and import from that.

To do this, you will POST a JSON object to /courses with the referenceRequest property set to an object containing two values:

  • the url property should point to a SCORM/xAPI/cmi5 manifest or one of the AICC course structure files
  • the webPathToCourse should provide the URL to the root directory of the course's content. This can be an absolute path (e.g., /courses/myCourseOneFolder) as long as it lives on the same domain as Engine's player.

Example:

{
    "referenceRequest": {
        "url": "http://example.org/courses/mycourse/imsmanifest.xml",
        "webPathToCourse": "http://example.org/courses/mycourse"
    }
}

Since Engine is not handling the actual content files for the course (only the manifest), you must ensure that the content is already available at the path specified.

Unlike the importJobs endpoints, importing by manifest will run synchronously . This means that you won't have to wait for the import job to complete -- the HTTP request will not return until your manifest has been imported.

Ad Hoc Import

You can sometimes have e-learning content that lives on a web server somewhere, but you do not have an actual zip package with a manifest inside it. This is much more likely with standards like AICC or xAPI where the content can communicate directly back to Engine outside the context of a 'player'.

Engine has a way to 'import' a course such as this so that you can launch and track it along with your normally imported course zip packages.

To do this, you will have to POST a JSON object to /courses and include the adHocReferenceRequest property.

Here is an example of what this object could look like and a brief description of what value each of these properties should have.

{
    "launchUrl": "http://example.com/courses/tenant-21048/RuntimeBasicCalls_SCORM12/shared/launchpage.html",
    "webPathToCourse": "http://example.com/courses/tenant-21048/RuntimeBasicCalls_SCORM12/",
    "learningStandard": "scorm12",
    "title": "Golf Example - SCORM 1.2"
}
  • launchUrl - The URL of the launch page of the course.
  • webPathToCourse - The root folder of the course's content. This is folder that a course manifest would go in, if one existed.
  • learningStandard - The learning standard of the course being imported. Acceptable values are aicc, scorm11, scorm12, scorm2004,scorm20042ndedition, scorm20043rdedition, scorm20044thedition, tincan, and cmi5 (values are case insensitive, and Engine will ignore any spaces in the name).
  • title - The title of the course. Will be used as the body of the <title> of the player page in the browser when the course is launched, and possibly displayed in the player UI.

Using the course that you've described in the JSON body, Engine will generate a placeholder manifest in memory and import your course using that. Like importing with a manifest, an ad-hoc import will run synchronously.

Validating a Course Zip or Manifest

Before importing a course for real, some customers like to validate that the to-be-imported course is, in fact, valid and would be imported successfully.

Engine provides a parameter named dryRun that you can pass (with a value of true) to any of our synchronous import methods (i.e., POST to /courses or /courses/upload). When you set this to true, Engine will not extract your course files to FilePathToContentRoot or save any course information to the database. It will only check that the manifest file is valid for its learning standard and that the course would be imported without issue.

Media Content Courses

You can import, play and track launches of video/audio files, and PDF documents similarly to how you would for normal standards-based course packages. Engine automatically collects and stores completion and duration data for .mp4, .mp3 and .pdf files types. You can retrieve that data using the same registration results API or postback that you would use for any other registration.

To import a media course, use the same endpoints described in the above sections with a few minor considerations to differentiate media from zipped course packages.

The resource content types used in the import syntax are one of three types:

  • video/mp4
  • audio/mpeg
  • application/pdf

Posting the Media File Directly

To post a media file directly to Engine, POST to /courses/importJobs/upload. The body of the request contains the media file. You must also include a request header, uploadedContentType, which should be one of the three supported resource content types mentioned earlier.

Optionally, you can add a second item to the request body called contentMetadata, a string of JSON that represents a mediaFileMetadata object.

{
    "title": "Workplace Violence",
    "description": "A course that teaches one how to identify that different forms of workplace violence."
}

Have Engine Download the Media File

In contrast, Engine can fetch the media file during the import process. To do this, you need to host the media file on a web server that Engine can access or on the server's local file system. Once you've done that, you can POST a JSON object (as Content-Type application/json) to the /courses/importJobs endpoint.

In addition to a url pointing to the location of your media file, the JSON body should indicate the media resource type you expect Engine to download along with any optional mediaFileMetadata information.

{
    "url": "http://localhost:80/Courses/SampleVideo.mp4",
    "contentType": "video/mp4",
    "mediaFileMetadata": {
        "title": "Shoe Tying 101",
        "description": "Video introducing how to tie tennis shoes."
    }
}

Point Engine to the Media File

If your media course content is already hosted on a web server, then you can simply point Engine to the file and have the player load it directly from there when launched.

To do this, POST a JSON object to /courses with the mediaFileReferenceRequest property set to an object containing at least two values:

  • The url property should point to the .mp4, mp3, or .pdf file.
  • The contentType should define the resource type of the file from the URL.
  • Optionally, you may specify an additional mediaFileMeatadata object to describe the media course.
{
    "mediaFileReferenceRequest": {
        "url": "http://localhost:80/Engine2019Courses/new_courses/math_lecture.mp3",
        "contentType": "audio/mp3",
        "mediaFileMetadata": {
            "title": "Linear Algebra Part 2",
            "description": "Professor Mark's day-2 lecture on advanced linear algebra.",
            "contentLanguage": "en-US",
            "moveOn": "Completed"
        }
    }
}

Note: For PDF courses, the server that hosts the file must provide the proper CORS headers to allow Engine's player to load the file. Otherwise there will be an error at launch time from the PDF viewer.

Media Content Settings

There are a number of settings that control how the media content looks and behaves. You can view the complete list here in the MediaContent Settings section.

For example, you may require learners to view 50% of a course to attain completion. Or, you may want to enforce a rule that each learner spend at least 30 seconds on each page of a PDF.

Closed Captioning/Subtitles

Courses based on the video handling above can provide subtitle or closed captioning support via WebVTT files. To use this capability a JSON formatted mapping from language codes to WebVTT file URLs needs to be stored to the ContentLangToUrl course configuration setting.

Example configuration value stored as a string:

[
    {
        "label": "English",
        "srclang":"en",
        "src": "/supportFiles/en.vtt",
        "default": true,
        "kind": "subtitles"
    },
    {
        "label": "French",
        "srclang": "fr",
        "src": "/supportFiles/fr.vtt",
        "default": false,
        "kind": "subtitles"
    },
    ...
]

When the video file has been uploaded directly to Engine or has been acquired via the fetch mechanism it may be desired to have the WebVTT files stored along with the video content. When this is desired it is recommended to use the Course Asset Update API to provide the required asset(s). The src value is the result of using the destination property from the response object returned.

Video.js Enhanced Player

For enhanced video player functionality, including variable playback rates, seek forward and backward buttons, and variable video quality levels, the Video.js player can be enabled. To switch from using the regular HTML5 video player, set the AudioVideoPlayer setting to VideoJS. To switch back, set it to Native.

With AudioVideoPlayer set to VideoJS, several other settings become available to further enhance video playback: AudioVideoPlayerPlaybackRates, AudioVideoPlayerSeekBackward, and AudioVideoPlayerSeekForward. The playback rates setting takes a list of decimal numbers, which will be available to select from a pop-up menu on the video's control bar. The seek settings will each add a button to the video's control bar which will skip the video forward or backward by the given amount in seconds.

Quality Level Switcher

Additionally, with AudioVideoPlayer set to VideoJS, variable quality levels can be provided to the user to manually switch between during viewing. Quality levels are set as a JSON formatted mapping stored to the AudioVideoPlayerQualitySourceList course configuration setting. The sources for the additional quality levels can be uploaded using the Course Asset Update API to provide the required mp4 asset(s). The src property's value should be the value of the destination property from the response object returned from the asset update request.

Example:

[
    {
        "label": "360",
        "type": "video/mp4",
        "src": "/supportFiles/360p.mp4"
    },
    {
        "label": "540",
        "type": "video/mp4",
        "src": "/supportFiles/540p.mp4"
    }
]

The quality selector on the video player's control bar will display the labels provided to the AudioVideoPlayerQualitySourceList setting for the user to switch between along with the height of the original mp4 uploaded for the course.

YouTube Courses

YouTube content can be imported and played directly via Engine's player and acts much like the video media content courses described above. To import a YouTube video use the same methodology as described in "Point Engine to the Media File" above, but with a YouTube URL and with a contentType property value of youtube in the mediaFileReferenceRequest object. For example:

{
    "mediaFileReferenceRequest": {
        "url": "https://www.youtube.com/watch?v=bC5TKUdfnhM",
        "contentType": "youtube",
        "mediaFileMetadata": {
            ...
        }
    }
}

URL Courses

When using the /courses endpoint, you can specify any URL and have Engine create a course that launches it. This is a flexible option if you want to track launches of content that is not available as a learning standard zipped package or a specific media file we support.

Since this could be an external URL to anything, Engine can't track much beyond knowing whether or not the learner launched the course. As soon as the course is launched, Engine automatically marks the registration as Completed.

The JSON body takes a URL property as before, but contentType would simply be url.

{
    "mediaFileReferenceRequest": {
        "url": "http://mysite.com/learn",
        "contentType": "url"
    }
}

results matching ""

    No results matching ""