From d38e0137d4af23949d72a94a542f7725184f33f0 Mon Sep 17 00:00:00 2001 From: jboix Date: Thu, 31 Oct 2024 15:12:06 +0000 Subject: [PATCH] =?UTF-8?q?Deploy=20preview=20for=20PR=20111=20?= =?UTF-8?q?=F0=9F=9B=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pr-preview/pr-111/.nojekyll | 0 pr-preview/pr-111/README.md | 30 ++ pr-preview/pr-111/_coverpage.md | 14 + pr-preview/pr-111/_sidebar.md | 15 + pr-preview/pr-111/img/pillarbox-logo.webp | Bin 0 -> 16942 bytes pr-preview/pr-111/img/srgssr-logo.png | Bin 0 -> 47854 bytes pr-preview/pr-111/index.html | 61 +++ .../pr-111/methodology/DEFINITION_OF_DONE.md | 18 + .../methodology/GITHUB_PROJECTS_SETUP.md | 88 +++++ .../specifications/monitoring/MONITORING.md | 361 ++++++++++++++++++ .../monitoring/schemas/error-schema.json | 70 ++++ .../monitoring/schemas/start-schema.json | 175 +++++++++ .../monitoring/schemas/status-schema.json | 89 +++++ 13 files changed, 921 insertions(+) create mode 100644 pr-preview/pr-111/.nojekyll create mode 100644 pr-preview/pr-111/README.md create mode 100644 pr-preview/pr-111/_coverpage.md create mode 100644 pr-preview/pr-111/_sidebar.md create mode 100644 pr-preview/pr-111/img/pillarbox-logo.webp create mode 100644 pr-preview/pr-111/img/srgssr-logo.png create mode 100644 pr-preview/pr-111/index.html create mode 100644 pr-preview/pr-111/methodology/DEFINITION_OF_DONE.md create mode 100644 pr-preview/pr-111/methodology/GITHUB_PROJECTS_SETUP.md create mode 100644 pr-preview/pr-111/specifications/monitoring/MONITORING.md create mode 100644 pr-preview/pr-111/specifications/monitoring/schemas/error-schema.json create mode 100644 pr-preview/pr-111/specifications/monitoring/schemas/start-schema.json create mode 100644 pr-preview/pr-111/specifications/monitoring/schemas/status-schema.json diff --git a/pr-preview/pr-111/.nojekyll b/pr-preview/pr-111/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/pr-preview/pr-111/README.md b/pr-preview/pr-111/README.md new file mode 100644 index 0000000..3126d96 --- /dev/null +++ b/pr-preview/pr-111/README.md @@ -0,0 +1,30 @@ +# Overview + +Pillarbox is a versatile media playback ecosystem engineered for Android, Apple, and Web platforms. + +Pillarbox is built to be adaptable and generic, ensuring it can be deployed across a variety of media applications. A +key principle of Pillarbox is that it imposes **no user interface** constraints, empowering each product team to craft +their own unique playback experience. + +It integrates seamlessly with platform features and offers robust customization options for metadata handling, +asset management, and analytics. + +This page covers documentation regarding our core methodologies, cross-platform specifications, development workflows, +and best practices. + +## Platform Repositories and Resources + +| Platform | Repository Link | Demo Link | Documentation Link | +|------------|------------------------------------------------------------------|-------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------| +| 🤖 Android | [pillarbox-android](https://github.com/SRGSSR/pillarbox-android) | [Demo Android](https://github.com/SRGSSR/pillarbox-android?tab=readme-ov-file#demo) | [Docs Android](https://android.pillarbox.ch/api) | +| 🍎 Apple | [pillarbox-apple](https://github.com/SRGSSR/pillarbox-apple) | [Demo Apple](https://testflight.apple.com/join/TS6ngLqf) | [Docs Apple](https://swiftpackageindex.com/SRGSSR/pillarbox-apple/3.0.0/documentation/pillarboxplayer) | +| 🌐 Web | [pillarbox-web](https://github.com/SRGSSR/pillarbox-web) | [Demo Web](https://demo.pillarbox.ch) | [Docs Web](https://web.pillarbox.ch/api/) | + +## Web Tools for Pillarbox + +`pillarbox-web` provides a set of web tools for additional functionalities to enhance the developer's experience. + +| Repository Link | Demo Link | Description | +|------------------------------------------------------------------------------------|--------------------------------------|--------------------------------------------------| +| [pillarbox-web-suite](https://github.com/SRGSSR/pillarbox-web-suite) | [Demo](https://plugins.pillarbox.ch) | A collection of plugins, themes, and components. | +| [pillarbox-web-theme-editor](https://github.com/SRGSSR/pillarbox-web-theme-editor) | [Demo](https://editor.pillarbox.ch) | A tool for editing themes for the player. | diff --git a/pr-preview/pr-111/_coverpage.md b/pr-preview/pr-111/_coverpage.md new file mode 100644 index 0000000..1355549 --- /dev/null +++ b/pr-preview/pr-111/_coverpage.md @@ -0,0 +1,14 @@ + + +

+ logo + Pillarbox +

+ +> **The media player that adapts to you.** + +- No UI constraints, fully customizable. +- Seamless platform integration. +- Robust asset management and analytics. + +[Get Started](#overview) diff --git a/pr-preview/pr-111/_sidebar.md b/pr-preview/pr-111/_sidebar.md new file mode 100644 index 0000000..1e314b3 --- /dev/null +++ b/pr-preview/pr-111/_sidebar.md @@ -0,0 +1,15 @@ + + Pillarbox + +* [Overview](/) + +**Specifications** + +* [Monitoring](/specifications/monitoring/MONITORING.md) + +**Methodology** + +* [Definition of Done](/methodology/DEFINITION_OF_DONE.md) +* [GitHub Projects Setup](/methodology/GITHUB_PROJECTS_SETUP.md) + +--- diff --git a/pr-preview/pr-111/img/pillarbox-logo.webp b/pr-preview/pr-111/img/pillarbox-logo.webp new file mode 100644 index 0000000000000000000000000000000000000000..65aa96f36cd6bdaee8ad9b0e586a506043c2b20b GIT binary patch literal 16942 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

STOboT^9L)X&7gQQ%;U8N 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 FbrC5>^qc?y literal 0 HcmV?d00001 diff --git a/pr-preview/pr-111/img/srgssr-logo.png b/pr-preview/pr-111/img/srgssr-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..79d1166917a16dba9cb67e40333daeb3d38d7479 GIT binary patch literal 47854 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
a|G<~+3iW(i_0A5MzU#IUw&gAPwWjP{cs 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 + + + + Pillarbox Documentation + + + + + + + + + + + +

+ + + + + + + + + + + + diff --git a/pr-preview/pr-111/methodology/DEFINITION_OF_DONE.md b/pr-preview/pr-111/methodology/DEFINITION_OF_DONE.md new file mode 100644 index 0000000..e13c543 --- /dev/null +++ b/pr-preview/pr-111/methodology/DEFINITION_OF_DONE.md @@ -0,0 +1,18 @@ +# Definition of Done (DoD) + +This document is a collaborative effort among team members to establish clear criteria for completing tasks. The DoD serves as a guide to ensure the quality and completeness of work within the team. + +To meet our standards, every task should adhere to the following criteria: + +- Code has been reviewed by at least one other team member. +- Functionality works as expected and acceptance criteria are met. +- Coding standards are followed. +- No critical issues are present. +- Performance is not compromised. +- Unit tests pass successfully and the code successfully builds. +- Code meets accessibility standards. +- Code is well-documented. +- README is updated with relevant information. +- API documentation is updated. +- Sensitive information is handled securely. +- Deployment process is documented. diff --git a/pr-preview/pr-111/methodology/GITHUB_PROJECTS_SETUP.md b/pr-preview/pr-111/methodology/GITHUB_PROJECTS_SETUP.md new file mode 100644 index 0000000..80b8852 --- /dev/null +++ b/pr-preview/pr-111/methodology/GITHUB_PROJECTS_SETUP.md @@ -0,0 +1,88 @@ +# GitHub Projects Setup + +This article describes how we manage [our product](https://github.com/orgs/SRGSSR/projects/9) with [GitHub Projects](https://docs.github.com/en/issues/planning-and-tracking-with-projects/learning-about-projects/about-projects). + +## Settings + +We currently use 3 settings: + +- **Status** for the various statuses an issue might have in our workflow. Statuses must be defined in the following order so that board columns are ordered correctly: + - **✏️ Draft**: Tasks which have not been sufficiently refined yet. + - **📋 Backlog**: Tasks which are ready to be planned. + - **🚧 In Progress**: Tasks currently being worked on. + - **🍿 Code Review**: Tasks currently being reviewed. + - **✅ Done**: Completed tasks. +- **Sprint**: Duration of 1 week. +- **Platform**: + - **✨ All** + - **🤖 Android** + - **🍎 Apple** + - **🌍 Web** + +## Workflows + +Workflow management is currently limited on GitHub Projects. Here are the ones we kept and how they are set: + +- **Item added to project**: When an issue or pull request is added set its status to _Draft_. +- **Item reopened**: When an issue or pull request is reopened set its status to _Backlog_. +- **Item closed**: When an issue or pull request is closed set its status to _Done_. +- **Pull request merged**: When a pull request is merged set its status to _Done_. + +## Views + +We have created the following views: + +### Sprint board + +Displays a board of the the current sprint: + +- Layout: Board +- Fields: Title, Assignees, Status, Platform, Linked pull requests +- Column field: Status +- Field sum: Count +- Sort: Manual +- Filter: `-status:"✏️ Draft"` + +### Drafts + +Displays all issues to be refined per platform: + +- Layout: Table +- Fields: Title, Milestone, Platform, Labels +- Group: Platform +- Field sum: Count +- Sort: Manual +- Filter: `status:"✏️ Draft"` + +### Product Backlog + +Displays the product backlog for all platforms: + +- Layout: Table +- Fields: Title, Status, Milestone, Platform, Sprint, Labels +- Group: Status +- Field sum: Count +- Sort: Status-desc +- Filter: `status:"✏️ Draft","📋 Backlog"` + +### Current Milestone + +Displays the current milestone which represents the current focus: + +- Layout: Table +- Fields: Title, Status, Platform, Sprint, Labels, Milestone +- Group: Platform +- Field sum: Count +- Sort: Manual +- Filter: `-status:"✅ Done","✏️ Draft" milestone:` + +### Sprint List + +Displays issues per sprint: + +- Layout: Table +- Fields: Title, Sprint, Milestone, Platform, Status, Linked pull requests, Labels +- Group: Sprint +- Field sum: Count +- Sort: Sprint-desc +- Filter: `-no:sprint` diff --git a/pr-preview/pr-111/specifications/monitoring/MONITORING.md b/pr-preview/pr-111/specifications/monitoring/MONITORING.md new file mode 100644 index 0000000..264e039 --- /dev/null +++ b/pr-preview/pr-111/specifications/monitoring/MONITORING.md @@ -0,0 +1,361 @@ +# Monitoring Specification + +--- + +**Version:** 1.0 | +**Date:** August 19, 2024 + +--- + +## Introduction + +Pillarbox integrates with a monitoring platform that provides real-time and historical dashboards for: + +- Quality of Service (QoS): QoS refers to the performance level of a service, especially in terms of its transmission + quality and service availability. +- Quality of Experience (QoE): QoE is a user-centric measure that evaluates the overall experience of the user with a + service. + +This article describes the flexible event model that allows our players to send data to our monitoring platform. + +## JSON Key / Value Naming Conventions + +The following naming conventions are applied for key / values appearing in JSON payloads: + +- Keys use snake case. +- Values are provided in a form best suited for display, usually capitalized, with possible exceptions when brand + names are involved (e.g. macOS must not be capitalized as MacOS). +- The only values provided in uppercase are event types (e.g. `START`). + +> [!WARNING] +> Values provided by the system (e.g. device names) can be assumed as having a form already best suited for display. +> Their case must not be changed. + +## General Event Format + +Events provide data related to specific points of interests in the lifetime of a playback session. Three kinds of event +types are available: + +- `START` +- `ERROR` +- Status events (`STOP`, `HEARTBEAT`) + +Associated information is provided in JSON payloads all having the same fixed top-level structure containing the +following keys: + +| Key | Description | Format | Examples | +|--------------|---------------------------------------------|-----------------------------------------------------------------|----------------------------------------| +| `data` | Data associated with the event | JSON dictionary | `{ ... }` | +| `event_name` | The name of the event | `START`, `STOP`, `ERROR`, `HEARTBEAT` | `STOP` | +| `session_id` | A unique identifier for the session | [UUID](https://www.itu.int/en/ITU-T/asn1/Pages/UUID/uuids.aspx) | `37b18444-76b6-4159-8539-d48ea5ecbc86` | +| `timestamp` | The timestamp at the time the event is sent | [Unix timestamp](https://unixtime.org) in milliseconds | `1717665997932` | +| `version` | The version of the JSON format | Number | 1 | + +> [!WARNING] +> All keys listed above are mandatory. + +All events associated with the same session **MUST** be assigned the same `session_id`. The `data` format associated +with each event type is described in more detail below. + +## Start Event `data` + +An event with the name `START` **MUST** be sent to signal the start of a playback session. This event conveys important +static context information and is therefore required, no matter playback successfully starts or not: + +- Success: The `START` event **MUST** be sent when the player is ready to play. +- Failure: The `START` event **MUST** be sent immediately before an `ERROR` event describing the reason for the failure. + +The associated event data dictionary supports the following keys: + +| Key | Description | Format | Examples | +|---------------|------------------------------|-----------------|-----------| +| `browser` | Browser information | JSON dictionary | `{ ... }` | +| `device` | Device information | JSON dictionary | `{ ... }` | +| `media` | Media information | JSON dictionary | `{ ... }` | +| `os` | Operating system information | JSON dictionary | `{ ... }` | +| `player` | Player information | JSON dictionary | `{ ... }` | +| `screen` | Screen information | JSON dictionary | `{ ... }` | +| `qoe_timings` | QoE timings | JSON dictionary | `{ ... }` | +| `qos_timings` | QoS timings | JSON dictionary | `{ ... }` | + +> [!WARNING] +> Requirements for each key are not provided explicitly but implementations **SHOULD** fill as much information as +> possible. If some information cannot be reliably determined it **SHOULD** be omitted. + +### JSON Schema + +[start-schema.json](specifications/monitoring/schemas/start-schema.json ':ignore') + +### Browser + +The `browser` JSON data dictionary supports the following keys: + +| Field | Description | Format | Examples | +|-----------|---------------------|--------|---------------------| +| `name` | The browser name | String | `Firefox`, `Safari` | +| `version` | The browser version | String | `129.0` | + +### Device + +The `device` JSON data dictionary supports the following keys: + +| Field | Description | Format | Examples | +|---------|----------------------------------------------|------------------------------------------------------|----------------------------------------| +| `id` | A unique anonymous identifier for the device | String | `105124c0-fa84-4028-908e-618f2402d46f` | +| `model` | The device model | String | `iPhone15.7`, `Samsung Galaxy S24` | +| `type` | The device type | `Car`, `Desktop`, `Headset`, `Phone`, `Tablet`, `TV` | `Phone` | + +### Media + +The `media` JSON data dictionary supports the following keys: + +| Field | Description | Format | Examples | +|----------------|-----------------------------------------------------------|--------|------------------------------------------------------------------------------------------| +| `asset_url` | The URL of the content being played | String | `https://...` | +| `id` | A unique media identifier | String | `urn:rts:video:123456` | +| `metadata_url` | The URL where media metadata was fetched | String | `https://...` | +| `origin` | A description of the context in which the media is played | String | `ch.srgssr.app`, `https://...` | + +Some remarks: + +- Any token appended **by the client** to the URL of the asset being played **SHOULD NOT** appear in `asset_url`. +- The `origin` is flexible but **SHOULD** describe the context of playback, for example an application identifier or the + URL of the web page hosting the media. + +### Operating System + +The `os` JSON data dictionary supports the following keys: + +| Field | Description | Format | Examples | +|-----------|------------------------------|--------|-------------------------------| +| `name` | The operating system name | String | `macOS`, `Windows`, `Android` | +| `version` | The operating system version | String | `14.5` | + +### Player + +The `player` JSON data dictionary supports the following keys: + +| Field | Description | Format | Examples | +|------------|---------------------|---------------------------|--------------------------------------| +| `name` | The player name | String | `Pillarbox`, `Letterbox`, `video.js` | +| `platform` | The player platform | `Android`, `Apple`, `Web` | `Android` | +| `version` | The player version | String | `1.2.3` | + +### Quality of Experience Timings + +The `qoe_timings` JSON data dictionary supports the following keys: + +| Field | Description | Format | Examples | +|------------|---------------------------------------------------|----------------------|----------| +| `asset` | Time the user waited for asset playback to start | Time in milliseconds | `1145` | +| `metadata` | Time the user waited for metadata to be retrieved | Time in milliseconds | `412` | +| `total` | Total time the user waited for playback to start | Time in milliseconds | `1763` | + +> [!WARNING] +> QoE timings measure the perceived user experience. If content preloading in a playlist makes it possible to start +> instantaneously (or almost), these values **SHOULD** be zero or close to zero. + +### Quality of Service Timings + +The `qos_timings` JSON data dictionary supports the following keys: + +| Field | Description | Format | Examples | +|------------|-------------------------------------------------|----------------------|----------| +| `asset` | Time for the player to start playing the asset | Time in milliseconds | `1145` | +| `drm` | Time to load DRM content keys | Time in milliseconds | `245` | +| `metadata` | Time for metadata to be retrieved by the player | Time in milliseconds | `412` | +| `token` | Time to fetch an authorization token | Time in milliseconds | `356` | + +> [!WARNING] +> QoS timings measure actual system performance. They **SHOULD** reflect the time technically required to fetch content, +> whether content preloading could take place or not. + +### Screen + +The `screen` JSON data dictionary supports the following keys: + +| Field | Description | Format | Examples | +|----------|-----------------------------|--------|----------| +| `height` | The screen height in pixels | Number | `2160` | +| `width` | The screen width in pixels | Number | `3840` | + +### Example + +```json +{ + "data": { + "device": { + "id": "8e9242a4-60b6-48f9-8dfb-6ee43e36c7eb", + "model": "iPad13,4", + "type": "Tablet" + }, + "media": { + "asset_url": "https://rts-vod-amd.akamaized.net/ww/14895342/85891228-1e53-371b-997a-094380f533e2/master.m3u8", + "id": "urn:rts:video:14895342", + "metadata_url": "https://il.srgssr.ch/integrationlayer/2.1/mediaComposition/byUrn/urn:rts:video:14895342?onlyChapters=true&vector=appplay", + "origin": "ch.srgssr.Pillarbox-demo" + }, + "os": { + "name": "iPadOS", + "version": "18.0" + }, + "player": { + "name": "Pillarbox", + "platform": "Apple", + "version": "2.0.0-49" + }, + "qoe_timings": { + "asset": 1164, + "metadata": 320, + "total": 1484 + }, + "screen": { + "height": 2388, + "width": 1668 + } + }, + "event_name": "START", + "session_id": "ebdb3da7-bc77-454e-9de0-a1dfa8091e84", + "timestamp": 1723640597805, + "version": 1 +} +``` + +## Error Event `data` + +An event with the name `ERROR` **MUST** be sent when a fatal error makes playback fail without the possibility to recover, either when playback is started or during + playback (e.g. following a network failure). + +> [!WARNING] +> A fatal `ERROR` at startup **MUST** always be preceded by a `START` event. If playback is restarted after a fatal +`ERROR` a new session **MUST** be created, beginning with a new `START` event. + +The associated event data dictionary supports the following keys: + +| Key | Description | Format | Examples | +|----------------------|------------------------------------------------------------------------------------------------------|--------------------------------------------------------|---------------------------------------------------------------------------------------------| +| `duration` | The content duration, as retrieved from the playlist | Time in milliseconds | `16548` | +| `log` | Any additional information that might be helpful | Any | `{ ... }`, `[...]`, `Stack trace symbols: ...` | +| `message` | The message associated with the error (might be localized) | String | `Not found` | +| `name` | The name of the error | String | `ERR-404` | +| `position` | The current player position, relative to the beginning of the playlist. Negative values are admitted | Time in milliseconds | `16548` | +| `position_timestamp` | The current player timestamp, as retrieved from the playlist. Omitted if not available | [Unix timestamp](https://unixtime.org) in milliseconds | `1717665997932` | +| `url` | The URL that was affected by the error | String | `https://...` | +| `vpn` | A value indicating whether a VPN is enabled on the device | Boolean | `true` | + +> [!WARNING] +> Requirements for each key are not provided explicitly but implementations **SHOULD** fill as much information as +> possible. If some information cannot be reliably determined it **SHOULD** be omitted. + +Some remarks: + +- If the error occurs before playback has started (e.g. during metadata retrieval) then `position`, `player_timestamp` + and `duration` **MUST** be omitted. +- The `url` **SHOULD** describe the content that was affected as closely as possible, down to media playlists or segment + URLs, provided this information is available. +- The `log` is informally defined so that any useful information can be added for investigation purposes. + +### JSON Schema + +[error-schema.json](specifications/monitoring/schemas/error-schema.json ':ignore') + +### Example + +```json +{ + "data": { + "message": "Not found", + "name": "PillarboxCoreBusiness.DataError(1)", + "position": 1024, + "url": "https://rts-vod-amd.akamaized.net/ww/14895342/85891228-1e53-371b-997a-094380f533e2/index-f4-v1.m3u8", + "vpn": false + }, + "event_name": "ERROR", + "session_id": "ebdb3da7-bc77-454e-9de0-a1dfa8091e84", + "timestamp": 1723640598877, + "version": 1 +} +``` + +## Status Event `data` + +Other events **MUST** be sent during the playback session: + +| Event name | Description | Time at which the event is sent | +|-------------|-----------------------------------------|-------------------------------------------------------------------------------| +| `STOP` | Playback ended | When playback ends normally or is interrupted | +| `HEARTBEAT` | Informs that the session is still alive | Every 30 seconds (also when paused). First heartbeat sent right after `START` | + +The associated event data dictionary supports the following keys: + +| Key | Description | Format | Examples | +|----------------------|------------------------------------------------------------------------------------------------------|--------------------------------------------------------|---------------------------------------------------------------------------------------------| +| `airplay` | A value indicating whether AirPlay is currently active | Boolean | `true` | +| `bandwidth` | Bandwidth | Number in bits per second | `4000000` | +| `bitrate` | Bitrate of the content being played | Number in bits per second | `1000000` | +| `buffered_duration` | Duration of the content currently available in buffer | Time in milliseconds | `12000` | +| `duration` | The content duration, as retrieved from the playlist | Time in milliseconds | `16548` | +| `frame_drops` | The total number of frame drops experienced during the session | Number | `12` | +| `playback_duration` | The duration of the playback session | Time in milliseconds | `40000` | +| `position` | The current player position, relative to the beginning of the playlist. Negative values are admitted | Time in milliseconds | `16548` | +| `position_timestamp` | The current player timestamp, as retrieved from the playlist. Omitted if not available | [Unix timestamp](https://unixtime.org) in milliseconds | `1717665997932` | +| `stall` | Stall information | JSON dictionary | `{ ... }` | +| `stream_type` | Stream type | `On-demand`, `Live` | `On-demand` | +| `url` | The URL that is being played | String | `https://...` | + +> [!WARNING] +> Requirements for each key are not provided explicitly but implementations **SHOULD** fill as much information as +> possible. If some information cannot be reliably determined it **SHOULD** be omitted. + +Some remarks: + +- The `url` **SHOULD** describe the content currently being played as closely as possible, down to media playlists or + segment URLs, provided this information is available. +- The `playback_duration` **MUST** be measured in wall-clock time, independently of playback speed adjustments. +- The `stream_type` is present in status events only, as those can more closely match potential stream type changes when + a live playlist is closed and turns into an on-demand one. + +### JSON Schema + +[status-schema.json](specifications/monitoring/schemas/status-schema.json ':ignore') + +### Stall + +The `stall` JSON data dictionary supports the following keys: + +| Field | Description | Format | Examples | +|------------|-----------------------------------------------------------|----------------------|----------| +| `count` | The total number of stalls experienced during the session | Number | `4` | +| `duration` | The total duration of stalls | Time in milliseconds | `9000` | + +The stall duration **MUST** be measured in wall-clock time, independently of playback speed adjustments. + +> [!WARNING] +> If a player is able to provide stall information, both `count` and `duration` **MUST** be supplied, even if zero. + +### Example + +```json +{ + "data": { + "airplay": false, + "bandwidth": 23285774, + "bitrate": 6129146, + "buffered_duration": 36000, + "duration": 2386040, + "frame_drops": 2, + "playback_duration": 10663, + "position": 10618, + "stall": { + "count": 0, + "duration": 0 + }, + "stream_type": "On-demand", + "url": "https://rts-vod-amd.akamaized.net/ww/14895342/85891228-1e53-371b-997a-094380f533e2/index-f5-v1.m3u8" + }, + "event_name": "STOP", + "session_id": "ebdb3da7-bc77-454e-9de0-a1dfa8091e84", + "timestamp": 1723640608474, + "version": 1 +} +``` diff --git a/pr-preview/pr-111/specifications/monitoring/schemas/error-schema.json b/pr-preview/pr-111/specifications/monitoring/schemas/error-schema.json new file mode 100644 index 0000000..d9e5bba --- /dev/null +++ b/pr-preview/pr-111/specifications/monitoring/schemas/error-schema.json @@ -0,0 +1,70 @@ +{ + "$id": "https://github.com/SRGSSR/pillarbox-documentation/blob/main/Specifications/error-schema.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "Data associated with the ERROR event, containing details about the error encountered during playback.", + "properties": { + "duration": { + "type": "number", + "description": "The content duration, as retrieved from the playlist, in milliseconds." + }, + "log": { + "description": "Any additional information that might be helpful for debugging or investigation purposes. This can be any data type, including strings, objects, or arrays.", + "oneOf": [ + { "type": "string" }, + { "type": "object" }, + { "type": "array" } + ] + }, + "message": { + "type": "string", + "description": "The message associated with the error, which might be localized." + }, + "name": { + "type": "string", + "description": "The name or code of the error (e.g., ERR-404)." + }, + "position": { + "type": "number", + "description": "The current player position relative to the beginning of the playlist, in milliseconds. Negative values are admitted." + }, + "position_timestamp": { + "type": "integer", + "description": "The current player timestamp, as retrieved from the playlist, in Unix milliseconds. This field may be omitted if not available." + }, + "url": { + "type": "string", + "format": "uri", + "description": "The URL that was affected by the error. This should describe the content that was affected as closely as possible." + }, + "vpn": { + "type": "boolean", + "description": "Indicates whether a VPN is enabled on the device." + } + }, + "required": ["message", "name"] + }, + "event_name": { + "type": "string", + "enum": ["ERROR"], + "description": "The name of the event, which should be 'ERROR' for this schema." + }, + "session_id": { + "type": "string", + "format": "uuid", + "description": "A unique identifier for the session." + }, + "timestamp": { + "type": "integer", + "description": "The timestamp at the time the event is sent, in Unix milliseconds." + }, + "version": { + "type": "integer", + "description": "The version of the JSON format." + } + }, + "required": ["data", "event_name", "session_id", "timestamp", "version"] +} diff --git a/pr-preview/pr-111/specifications/monitoring/schemas/start-schema.json b/pr-preview/pr-111/specifications/monitoring/schemas/start-schema.json new file mode 100644 index 0000000..b790ab4 --- /dev/null +++ b/pr-preview/pr-111/specifications/monitoring/schemas/start-schema.json @@ -0,0 +1,175 @@ +{ + "$id": "https://github.com/SRGSSR/pillarbox-documentation/blob/main/Specifications/start-schema.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "Data associated with the START event, containing details about the device, media, player, and other relevant information.", + "properties": { + "browser": { + "type": "object", + "description": "Information about the browser being used.", + "properties": { + "name": { + "type": "string", + "description": "The browser name (e.g., Firefox, Safari)." + }, + "version": { + "type": "string", + "description": "The version of the browser." + } + } + }, + "device": { + "type": "object", + "description": "Information about the device on which the media is being played.", + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "A unique anonymous identifier for the device." + }, + "model": { + "type": "string", + "description": "The model of the device (e.g., iPhone15.7, Samsung Galaxy S24)." + }, + "type": { + "type": "string", + "description": "The type of the device (e.g., Car, Desktop, Headset, Phone, Tablet, TV)." + } + } + }, + "media": { + "type": "object", + "description": "Information about the media being played.", + "properties": { + "asset_url": { + "type": "string", + "format": "uri", + "description": "The URL of the content being played." + }, + "id": { + "type": "string", + "description": "A unique media identifier." + }, + "metadata_url": { + "type": "string", + "format": "uri", + "description": "The URL where media metadata was fetched." + }, + "origin": { + "type": "string", + "description": "A description of the context in which the media is played (e.g., application identifier or URL of the web page hosting the media)." + } + } + }, + "os": { + "type": "object", + "description": "Information about the operating system of the device.", + "properties": { + "name": { + "type": "string", + "description": "The operating system name (e.g., macOS, Windows, Android)." + }, + "version": { + "type": "string", + "description": "The version of the operating system." + } + } + }, + "player": { + "type": "object", + "description": "Information about the media player.", + "properties": { + "name": { + "type": "string", + "description": "The name of the player (e.g., Pillarbox, Letterbox, video.js)." + }, + "platform": { + "type": "string", + "description": "The platform on which the player is running (e.g., Android, Apple, Web)." + }, + "version": { + "type": "string", + "description": "The version of the player." + } + } + }, + "qoe_timings": { + "type": "object", + "description": "Quality of Experience (QoE) timings measuring the perceived user experience.", + "properties": { + "asset": { + "type": "number", + "description": "Time in milliseconds that the user waited for asset playback to start." + }, + "metadata": { + "type": "number", + "description": "Time in milliseconds that the user waited for metadata to be retrieved." + }, + "total": { + "type": "number", + "description": "Total time in milliseconds that the user waited for playback to start." + } + } + }, + "qos_timings": { + "type": "object", + "description": "Quality of Service (QoS) timings measuring actual system performance.", + "properties": { + "asset": { + "type": "number", + "description": "Time in milliseconds for the player to start playing the asset." + }, + "drm": { + "type": "number", + "description": "Time in milliseconds to load DRM content keys." + }, + "metadata": { + "type": "number", + "description": "Time in milliseconds for metadata to be retrieved by the player." + }, + "token": { + "type": "number", + "description": "Time in milliseconds to fetch an authorization token." + } + } + }, + "screen": { + "type": "object", + "description": "Information about the screen resolution.", + "properties": { + "height": { + "type": "integer", + "description": "The screen height in pixels." + }, + "width": { + "type": "integer", + "description": "The screen width in pixels." + } + } + } + } + }, + "event_name": { + "type": "string", + "enum": ["START"], + "description": "The name of the event, which should be 'START' for this schema." + }, + "session_id": { + "type": "string", + "format": "uuid", + "description": "A unique identifier for the session." + }, + "timestamp": { + "type": "integer", + "description": "The timestamp at the time the event is sent, in Unix milliseconds." + }, + "version": { + "type": "integer", + "description": "The version of the JSON format." + } + }, + "required": ["data", "event_name", "session_id", "timestamp", "version"] +} diff --git a/pr-preview/pr-111/specifications/monitoring/schemas/status-schema.json b/pr-preview/pr-111/specifications/monitoring/schemas/status-schema.json new file mode 100644 index 0000000..ea7b009 --- /dev/null +++ b/pr-preview/pr-111/specifications/monitoring/schemas/status-schema.json @@ -0,0 +1,89 @@ +{ + "$id": "https://github.com/SRGSSR/pillarbox-documentation/blob/main/Specifications/status-schema.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "Data associated with the status event, containing details about the current state of playback, network, and device.", + "properties": { + "airplay": { + "type": "boolean", + "description": "Indicates whether AirPlay is currently active." + }, + "bandwidth": { + "type": "integer", + "description": "The available bandwidth in bits per second." + }, + "bitrate": { + "type": "integer", + "description": "The bitrate of the content being played in bits per second." + }, + "buffered_duration": { + "type": "number", + "description": "The duration of the content currently available in the buffer, in milliseconds." + }, + "duration": { + "type": "number", + "description": "The content duration, as retrieved from the playlist, in milliseconds." + }, + "playback_duration": { + "type": "number", + "description": "The duration of the playback session in milliseconds, measured in wall-clock time." + }, + "position": { + "type": "number", + "description": "The current player position relative to the beginning of the playlist, in milliseconds. Negative values are admitted." + }, + "position_timestamp": { + "type": "integer", + "description": "The current player timestamp as retrieved from the playlist, in Unix milliseconds. This field may be omitted if not available." + }, + "stall": { + "type": "object", + "description": "Information about playback stalls experienced during the session.", + "properties": { + "count": { + "type": "integer", + "description": "The total number of stalls experienced during the session." + }, + "duration": { + "type": "number", + "description": "The total duration of stalls in milliseconds, measured in wall-clock time." + } + }, + "required": ["count", "duration"] + }, + "stream_type": { + "type": "string", + "enum": ["On-demand", "Live"], + "description": "The type of stream being played, either 'On-demand' or 'Live'." + }, + "url": { + "type": "string", + "format": "uri", + "description": "The URL of the content currently being played. This should describe the content as closely as possible, including media playlists or segment URLs if available." + } + } + }, + "event_name": { + "type": "string", + "enum": ["STOP", "HEARTBEAT"], + "description": "The name of the event, which can be either 'STOP' or 'HEARTBEAT'." + }, + "session_id": { + "type": "string", + "format": "uuid", + "description": "A unique identifier for the session." + }, + "timestamp": { + "type": "integer", + "description": "The timestamp at the time the event is sent, in Unix milliseconds." + }, + "version": { + "type": "integer", + "description": "The version of the JSON format." + } + }, + "required": ["data", "event_name", "session_id", "timestamp", "version"] +}