Custom endpoint reports carry the recordedAt ISO-8601 timestamp again (alongside time), so endpoints that validated on the pre-4.0 field accept 4.x reports instead of rejecting them with 4xx and leaving them in the offline retry queue
playCheckSkipOnError per-element attribute — with "true", a playCheckUrl gate transport error (server unreachable/timeout) or unlisted 5xx status skips the pass instead of the default fail-open; listed statuses and other unlisted statuses behave as before. Only meaningful next to playCheckUrl; default false keeps today's behavior
events attribute on <meta log> — comma-separated list of report events to send to the custom endpoint (or save to the offline log). When set, only the listed events are reported; when absent or empty, the default set is used (media-download, media-playback, playlist-download, playlist-playback). Unknown names are ignored. Applies to the custom endpoint only
New opt-in report events, sent only when listed in events: media-copied (content reused for another URL without a new download), media-moved (content found under a new URL, nothing downloaded), media-restored (content restored from device storage instead of re-downloaded), media-deleted (stored content removed by playlist cleanup or storage eviction), media-skipped (element skipped for one pass by its playCheckUrl gate). Payload has the same shape as media-download
logger applet config key — selects where the player's diagnostic output goes: console (default) or remote. remote batches every log line and POSTs them as JSON to the loggerUrl applet config key every 5 seconds, so logs can be collected from devices without access to a developer console. Both honour debugEnabled, so logging is switched on and off from device config without a redeploy. Switching between loggers needs no rebuild. The remote logger keeps one request in flight at a time with a 10 s timeout, so a slow log server costs the device dropped log batches, never piled-up connections
playCheckUrl playability gate sends GET instead of HEAD (some gate backends do not answer HEAD); still only the response status code is evaluated
Log levels now mean something: failures the player recovers from (download errors, playback errors, sync setup or coordination failures, storage and migration errors, trigger initialisation failures) are logged at error, and degraded-but-handled conditions (local fallback after an HTTP error, skipped content, insufficient storage, sync timeouts, invalid SMIL kept out by fallbackToPreviousPlaylist, unsupported elements) at warn. Everything else stays debug. All levels are still gated only by debugEnabled, so nothing disappears from the console or the remote log stream; in the browser console the promoted lines now show as warnings and errors
Media was never downloaded on Tizen 2.4 since 4.0.0 when another file of the same type (e.g. the intro image) was already stored — the element was skipped or showed that other file's content, and an image playlist stayed on its intro image. Devices already affected need their applet storage wiped once after the update
Player did not start on Chrome 38 devices (webOS 3.x and older) since 4.0.0 — the screen stayed blank with TypeError: undefined is not a function in the log
Updated media was not downloaded when its Last-Modified date (or Location URL) matched a file that had been removed from the device earlier, or matched the SMIL file itself; the element was then skipped on every pass, even across player restarts. Such content is now downloaded; genuinely moved content (file still on device) is still copied instead of re-downloaded
A higher-priority wallclock campaign could be interrupted by lower-priority content: a lower element could slip in between two repeatCount passes of the campaign (when the player started inside an already-open window, e.g. after a SMIL update, applet restart or reboot) and then alternate with the campaign for the rest of the window, and a lower video that was just starting when the campaign began could cover the campaign and play to its end. Lower and defer/never sibling content now waits for the whole active window of the playing campaign
A priority campaign with a future wallclock begin that arrived via a SMIL update (not at player start) never played when it was a <par> directly under a priorityClass or the only wallclock element in its class
An element with a conditional expr (e.g. a dayparted campaign) lost its condition after a single skipContentOnHttpStatus skip and played unconditionally from then on
Regions could freeze on a stale frame when an element was skipped and recovered, or after a report was sent for it, because the player briefly treated it as a different element; deeply nested playlists could also be confused with each other in priority handling
log="false" now really disables custom-endpoint reporting — previously reports were still sent whenever type="manual" and an endpoint were configured
The first playlist-playback report after start was dropped when logging was configured only via <meta log>
media-download / playlist-download reports sent before first playback contained a null tag (and a shifted URL field) when useInReportUrl was not set; the element's src is now used, matching playback reports
checkAheadCount meta attribute — pre-checks a content slot a configurable number of positions ahead so updated media is downloaded before it is due to play
playCheckUrl per-element playability gate — a dedicated URL HEAD-checked right before each play; when the status is listed in the new <meta skipPlaybackOnHttpStatus> (required, independent of skipContentOnHttpStatus), the element is skipped for that pass only and recovers automatically. Pure play/skip control with zero effect on downloads or update checks; fails open (plays from cache) on network errors and unlisted statuses
cross-trigger cancellation — a trigger can now stop content started by a different trigger (begin="trigger1" end="trigger2"), for widget, mouse, and keyboard triggers
reports uploaded from offline storage are now flagged with isOfflineReport
checkBeforePlay meta attribute to check each media file for updates right before playback instead of periodic polling
reportUrl applet configuration option for custom reporting endpoint
HTTP status codes in custom endpoint and standard event download reports
batch download optimization with content deduplication for location header strategy
storage preservation system for content movement detection — avoids re-downloading when content moves to a new URL
BREAKING: the custom report (reportUrl) payload format changed: proof-of-play entries now include the HTTP status and the played url, and use a numeric epoch time field in place of the previous recordedAt ISO timestamp; a playlist-playback record is now sent each time the SMIL playlist (re)starts; the SyncWait event-report type was removed. Consumers reading recordedAt must migrate to time
reduced startup time by checking media files for updates in parallel instead of one at a time
download reports are now sent only for real network downloads, not for internal copy or restore operations
content whose URL returns a status listed in skipContentOnHttpStatus is no longer downloaded or error-reported
hardened skipContentOnHttpStatus / skipPlaybackOnHttpStatus / updateContentOnHttpStatus meta parsing: malformed values (wrong separator, non-numeric entries, boolean-coerced "true") no longer crash SMIL parsing or silently produce never-matching status lists — invalid entries are dropped and a fully malformed list behaves as absent
fixed synchronized devices freezing on a black screen when a sync-group peer was temporarily on a different SMIL version (e.g. during a staged content-update rollout) — the device now keeps playing its own content and re-syncs automatically once the peers are back on the same version
fixed nested <par repeatCount="indefinite"> regions playing once and then freezing on their last frame when a sibling branch runs its own indefinite loop
fixed gallery and repeatCount-based playlists freezing on their last element after a content update (parent-identity drift and lost play-count tracking)
fixed expr-disabled media leaving a phantom "playing" region that could deadlock other regions
fixed wallclock begin times more than ~24 days in the future activating immediately and jumping the playlist ahead instead of waiting for their scheduled window
fixed video playback not recovering when an internal stop() call fails — playback is now retried
fixed an updated video continuing to play the old file, and the internal video-player pool filling up until playback hung permanently, when a looping video was replaced during a content update
fixed playback stopping permanently when a video failed to open and never reported that it had ended — an upper bound is now applied when no duration information is available
fixed a synchronized region freezing on a stale frame for many minutes when the sync master became unreachable — after repeated failed coordination attempts the region continues playing on its own and rejoins the group automatically once coordination messages arrive again
fixed synchronized devices freezing on a stale frame after a scheduled higher-priority campaign window closed — every paused lower-priority playlist is now released, not just the most recent one
fixed regions playing the wrong content after a player restart when two playlist slots had swapped their media between restarts
fixed in-use media being evicted from storage and re-downloaded when Location-header URLs carried changing query parameters
fixed a burst of update-check requests per playback cycle when checkAheadCount was used on a playlist containing unavailable content
fixed proof-of-play reports showing the wrong URL when the same media file is used in several playlist slots, and reports using the SMIL query URL instead of the final Location-header URL
fixed already-downloaded content being deleted when its URL started returning a status listed in skipContentOnHttpStatus — the local copy is now preserved and played
fixed empty SMIL playlists triggering the backup-image fallback; an intentionally empty playlist is now treated as a valid state
fixed the default background image not clearing on the first playback cycle
fixed priority higher="pause" being ignored and always behaving as stop
fixed a lower-priority element incorrectly stopping or pausing the higher-priority content that was playing
fixed lower="never" allowing lower-priority content to appear alongside higher-priority content, against the SMIL spec
fixed priority and dynamic-content races and pause/resume edge cases that could freeze playback or briefly show the wrong region — including two peer regions stalling paused without either playing, and a region's normal content not resuming after a trigger-activated dynamic insert finished
fixed competing wallclock-scheduled priority campaigns in sibling <par> groups all starting at once and ignoring each other's defer/pause/stop rules; each campaign now respects its own begin/end window, and deferred lower-priority content resumes once all campaigns have expired
fixed playMode="one" and playMode="random_one" playing all children instead of one when the children are nested <seq>/<par> groups
fixed the SMIL playlist file deleting itself during a content update and falling back to the backup image
fixed the backup image not displaying (blank screen) when the SMIL file is invalid or missing
fixed a checkBeforePlay element staying permanently disabled after a single transient 404 — it now recovers on the next cycle
fixed updateMechanism="location" filenames and content-update lookahead (extension taken from the Location header, the correct upcoming slot is pre-checked, and skipped slots are re-checked)
fixed a request storm when content stayed unavailable — retries are now paced
fixed false media re-preparation and a temporary-file race during content refresh cycles
fixed devices filling up storage: a 100 MB minimum free-space floor is now enforced on every download and copy, free space is tracked accurately, and downloads are skipped (instead of retried in a loop) when storage is full
fixed Tizen AVPlayer playback by not appending the __smil_version query to file:// URIs
fixed a DOM event-listener leak that accumulated across playlist reloads
fixed stale region caching and free-region selection for nested trigger regions
fixed re-firing a widget trigger while its content was already playing spawning duplicate playback loops and leaking video event listeners — repeated widget-trigger events are now idempotent
fixed a ticker animation timeout leak on re-entry and incorrect ticker spacing on first layout
fixed wallclock scheduling crashing on malformed weekday values, and hardened filename decoding and JSON parsing against malformed input
fixed offline-stored reports not being retried on the next upload pass, SMIL meta logging types being lost when a custom reportUrl is set, and reportMode not propagating to iframe-rendered media
fixed the promise-chain mutex breaking on a rejected batch commit
fixed playlist element errors cascading across regions — errors are now isolated per element
fixed playback errors during updates by copying instead of moving files during storage preservation
fixed offline report index tracking on startup to avoid overwriting existing reports
fixed duplicate downloads for URLs differing only in query parameters
fixed duplicate HEAD requests when update detection had already been performed
fixed the forceDownload flag being ignored when skipUpdateCheck is true
BREAKING: the new ACK-based sync protocol is not compatible with the previous timing-based protocol — all devices in a sync group must be upgraded together; a mixed-version sync group will not synchronize
added multiple sync group for synchronization before sync content plays and after sync content finishes for smoother sync transitions
added billboard transitions support for images
added option to specify default transition in smil file header ( default transition is used for all images in playlist unless different transition is specified)
added onClick/onTouch triggers with duration specified in seconds
added support for image to image crossFade transition
added optional serialPortDevice in sos.config to dynamically define device address for serial communication
added support for fixed video duration
added support for widgets with query parameters
added support for auth headers for media download
added ICS format implementation for conditional expression
added support for smil files with no active content
added support for backup image if smil-player fails on smil file download or smil xml parse functionality supports image stored directly in smil repo or on remote server.