diff --git a/pr-preview/pr-110/.nojekyll b/pr-preview/pr-110/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/pr-preview/pr-110/README.md b/pr-preview/pr-110/README.md new file mode 100644 index 0000000..aba677a --- /dev/null +++ b/pr-preview/pr-110/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://github.com/SRGSSR/pillarbox-android?tab=readme-ov-file#integrate-pillarbox) | +| 🍎 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://srgssr.github.io/pillarbox-web-demo/) | [Docs Web](https://srgssr.github.io/pillarbox-web/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://srgssr.github.io/pillarbox-web-suite/) | A collection of plugins, themes, and components. | +| [pillarbox-web-theme-editor](https://github.com/SRGSSR/pillarbox-web-theme-editor) | [Demo](https://srgssr.github.io/pillarbox-web-theme-editor/) | A tool for editing themes for the player. | diff --git a/pr-preview/pr-110/_coverpage.md b/pr-preview/pr-110/_coverpage.md new file mode 100644 index 0000000..1355549 --- /dev/null +++ b/pr-preview/pr-110/_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-110/_sidebar.md b/pr-preview/pr-110/_sidebar.md new file mode 100644 index 0000000..1e314b3 --- /dev/null +++ b/pr-preview/pr-110/_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-110/img/pillarbox-logo.webp b/pr-preview/pr-110/img/pillarbox-logo.webp new file mode 100644 index 0000000..65aa96f Binary files /dev/null and b/pr-preview/pr-110/img/pillarbox-logo.webp differ diff --git a/pr-preview/pr-110/img/srgssr-logo.png b/pr-preview/pr-110/img/srgssr-logo.png new file mode 100644 index 0000000..79d1166 Binary files /dev/null and b/pr-preview/pr-110/img/srgssr-logo.png differ diff --git a/pr-preview/pr-110/index.html b/pr-preview/pr-110/index.html new file mode 100644 index 0000000..434af90 --- /dev/null +++ b/pr-preview/pr-110/index.html @@ -0,0 +1,61 @@ + + + + + Pillarbox Documentation + + + + + + + + + + + +
+ + + + + + + + + + + + diff --git a/pr-preview/pr-110/methodology/DEFINITION_OF_DONE.md b/pr-preview/pr-110/methodology/DEFINITION_OF_DONE.md new file mode 100644 index 0000000..e13c543 --- /dev/null +++ b/pr-preview/pr-110/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-110/methodology/GITHUB_PROJECTS_SETUP.md b/pr-preview/pr-110/methodology/GITHUB_PROJECTS_SETUP.md new file mode 100644 index 0000000..80b8852 --- /dev/null +++ b/pr-preview/pr-110/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-110/specifications/monitoring/MONITORING.md b/pr-preview/pr-110/specifications/monitoring/MONITORING.md new file mode 100644 index 0000000..f4c7e1a --- /dev/null +++ b/pr-preview/pr-110/specifications/monitoring/MONITORING.md @@ -0,0 +1,365 @@ +# 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 an error, either fatal or not, has been encountered: + +- 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). +- A non-fatal error (warning) informs about potential issues that occur behind the scenes and might affect the playback + experience negatively. + +> [!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": "Segment exceeds specified bandwidth for variant", + "name": "CoreMediaErrorDomain(-12318)", + "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-110/specifications/monitoring/schemas/error-schema.json b/pr-preview/pr-110/specifications/monitoring/schemas/error-schema.json new file mode 100644 index 0000000..d9e5bba --- /dev/null +++ b/pr-preview/pr-110/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-110/specifications/monitoring/schemas/start-schema.json b/pr-preview/pr-110/specifications/monitoring/schemas/start-schema.json new file mode 100644 index 0000000..b790ab4 --- /dev/null +++ b/pr-preview/pr-110/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-110/specifications/monitoring/schemas/status-schema.json b/pr-preview/pr-110/specifications/monitoring/schemas/status-schema.json new file mode 100644 index 0000000..ea7b009 --- /dev/null +++ b/pr-preview/pr-110/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"] +}