How To: The LiveCode Create Media Assets API 🖼️

Managing Media from Script: The LiveCode Assets API :framed_picture:

Your app’s media lives in the asset library, and just like the datastore, there’s a complete scripting API behind the visual tools. You can upload files, pull them back down, rename and delete them, read their metadata instantly from a cache, and link them to records. This post covers the asset commands and functions grouped by task, and picks up the same async pattern we used for the datastore.

The Pattern:

The asset handlers share the datastore’s calling convention, so it’s worth a quick recap.

Server-touching commands take optional trailing parameters:

pSynchronous, pCallbackHandler, and pCallbackContext — and your callback receives error, data, context in that order.

The cache functions (anything named …GetCached…) skip all that and return immediately, because they read from data already loaded into memory.

on assetReady pError, pAssetData, pContext

if pError is not empty then

answer "Asset request failed:" && pError

exit assetReady

end if

-- pAssetData holds the asset info or content

end assetReady

Uploading an asset

The core upload handler is:

revMediaAddAsset name, data, icon, anonymous, synchronous, callback, context.

You pass a filename, the raw file contents (not a path), and optionally icon data. If you leave the icon empty one is generated for you automatically. The two parameters worth dwelling on are anonymous and the callback.

The anonymous flag decides whether the asset shows up in the media library. It defaults to non-anonymous, so a plain upload behaves as you’d expect; pass true only if you want a behind-the-scenes asset (these get cleaned up automatically once nothing references them). On completion, the returned data carries the new asset’s ID, available as asset-id (or id).

local tData

put url("binfile:/Users/me/photo.png") into tData -- read the bytes

-- name, data, icon, anonymous(false = visible), synchronous, callback, context

revMediaAddAsset "photo.png", tData, empty, false, false, "assetAdded", empty

on assetAdded pError, pAssetD, pContext

if pError is empty then

put pAssetD["asset-id"] into ... -- the new asset's ID

end if

end assetAdded

One practical guardrail: uploads are size-limited. You can check the ceiling yourself with revMediaMaxAssetFileSizeInBytes()

Or

revMediaMaxAssetFileSizeInMegabytes()

before attempting a large file, and the add handler will also report an oversize file through the error path.

Fetching assets back

There are four fetch handlers, each following the async convention.

revMediaFetchWorkspaceMedia loads the list of all assets in the current workspace and populates the cache — call this once up front so the instant cache getters (below) have something to read.

For a single asset, revMediaFetchAssetInfo assetId, synchronous, callback, context retrieves its metadata (not the file bytes)

revMediaFetchAssetData assetId, synchronous, callback, context retrieves the actual raw content

revMediaFetchIcon pulls the thumbnail.

revMediaFetchWorkspaceMedia false, "mediaReady", empty

on mediaReady pError, pData, pContext

-- the asset cache is now populated; safe to use the getters

end mediaReady

Reading metadata instantly from the cache

Once assets are loaded, you rarely need the async calls again. A set of cache functions return data synchronously.

revMediaGetAllCachedMedia() returns every cached asset keyed by ID

revMediaGetCachedAssetInfo(assetId) returns one asset’s metadata array

revMediaGetCachedAssetData(assetId) / revMediaGetCachedAssetIcon(assetId) returns the raw content and icon if they’ve been fetched.

The most useful of the bunch is:

revMediaGetCachedPropertyOfAsset(assetId, property)

which reads a single property. The supported properties are file-name, file-mime, file-size, and file-type. So showing an asset’s name and size is a one-liner each:

put revMediaGetCachedPropertyOfAsset(tId, "file-name") into tName

put revMediaGetCachedPropertyOfAsset(tId, "file-size") into tBytes

Renaming and deleting

To rename:

revMediaRenameMedia assetId, newName, synchronous, callback, context

updates the asset’s name on the server and refreshes the cache.

To remove one:

revMediaDeleteMedia assetId, synchronous, callback, context

deletes it.

Both fire a callback so you can update your UI once the change lands:

revMediaRenameMedia tId, "final-logo.png", false, "assetRenamed", empty

revMediaDeleteMedia tId, false, "assetDeleted", empty

Tying assets to records

The datastore layer adds a few asset helpers aimed specifically at record fields, which is often what you actually want, an asset attached to a row rather than floating free.

revDatastoreCreateAssetFromFile collection, field prompts the user for a file and links the result to the current record’s field

revDatastoreCreateAssetFromData name, data, collection, field does the same from data you already have.

To pull one back, revDatastoreDownloadAssetFromCollection collection, field downloads the asset stored in the current record’s field

and revDatastoreDeleteAssetFromCollection collection, field clears it.

For standalone metadata work there’s also:

revDatastoreGetAssetById(assetId) to fetch an asset’s info array, and

revDatastoreSetAssetProperty assetId, property, value to update a property such as the file name.

-- create and link in one step

revDatastoreCreateAssetFromData "receipt.pdf", tPdfData, "Expenses", "attachment"

A subtle but important detail: assets created through these collection helpers are uploaded as anonymous and then kept alive by the record link. That’s the opposite trade-off from revMediaAddAsset with a false anonymous flag. So reach for the datastore helpers when the asset belongs to a record, and the media handler when you want a free-standing library asset.

A few handy helpers

Rounding out the API are some small utilities you might otherwise reach for manually: revMediaGetMimeTypeFromFileName(name) and revMediaGetFileTypeFromMime(mime) classify a file (the latter into buckets like Images, Videos, Audio, Documents, Other), and revMediaMediaIsLocal() tells you whether assets are being stored locally versus in the cloud (useful for branching behaviour during development.)

Wrapping up

The mental model is the same as the datastore: fetch once to fill the cache, then lean on the instant getter functions for everything you display; use the async handlers when you upload, rename, delete, or pull down content; and remember the error / data / context callback shape throughout.

When an asset belongs to a record, the datastore helpers handle the linking for you; when it doesn’t, revMediaAddAsset with a visible (non-anonymous) flag puts it straight in the library.