Skip to content

Commit

Permalink
Merge pull request #191 from THEOplayer/feature/adobe-edge
Browse files Browse the repository at this point in the history
Feature/adobe edge
  • Loading branch information
tvanlaerhoven authored Jun 18, 2024
2 parents adf14fe + f2cefdb commit e01f628
Show file tree
Hide file tree
Showing 36 changed files with 7,158 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ the official THEOplayer React Native video player.

| Connector | npm package | Source |
|---------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|
| Adobe analytics, implementing the Media Collections API | [![%40theoplayer/react-native-analytics-adobe](https://img.shields.io/npm/v/%40theoplayer%2Freact-native-analytics-adobe?label=%40theoplayer/react-native-analytics-adobe)](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-adobe) | [`Adobe`](https://github.com/THEOplayer/react-native-connectors/tree/main/adobe) |
| Adobe Heartbeat analytics using the Media Collections API | [![%40theoplayer/react-native-analytics-adobe](https://img.shields.io/npm/v/%40theoplayer%2Freact-native-analytics-adobe?label=%40theoplayer/react-native-analytics-adobe)](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-adobe) | [`Adobe`](https://github.com/THEOplayer/react-native-connectors/tree/main/adobe) |
| Adobe Media Edge analytics | [![%40theoplayer/react-native-analytics-adobe-edge](https://img.shields.io/npm/v/%40theoplayer%2Freact-native-analytics-adobe-edge?label=%40theoplayer/react-native-analytics-adobe-edge)](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-adobe) | [`Adobe Edge`](https://github.com/THEOplayer/react-native-connectors/tree/main/adobe-edge) |
| Agama analytics | [![%40theoplayer/react-native-analytics-agama](https://img.shields.io/npm/v/%40theoplayer%2Freact-native-analytics-agama?label=%40theoplayer/react-native-analytics-agama)](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-agama) | [`Agama`](https://github.com/THEOplayer/react-native-connectors/tree/main/agama) |
| Comscore analytics | [![%40theoplayer/react-native-analytics-comscore](https://img.shields.io/npm/v/%40theoplayer%2Freact-native-analytics-comscore?label=%40theoplayer/react-native-analytics-comscore)](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-comscore) | [`Comscore`](https://github.com/THEOplayer/react-native-connectors/tree/main/comscore) |
| Conviva analytics | [![%40theoplayer/react-native-analytics-conviva](https://img.shields.io/npm/v/%40theoplayer%2Freact-native-analytics-conviva?label=%40theoplayer/react-native-analytics-conviva)](https://www.npmjs.com/package/%40theoplayer%2Freact-native-analytics-conviva) | [`Conviva`](https://github.com/THEOplayer/react-native-connectors/tree/main/conviva) |
Expand Down
10 changes: 10 additions & 0 deletions adobe-edge/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [0.1.0]

Initial release
72 changes: 72 additions & 0 deletions adobe-edge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# THEOplayer React-Native Adobe Edge Connector

An Adobe analytics connector for `@theoplayer/react-native` using the
[Media Edge API](https://developer.adobe.com/client-sdks/edge/media-for-edge-network/).

Media Edge API is the third generation of solution for tracking Media Events.
It features more analytics data, and the delay before the data can be analysed is much shorter: ~15 minutes
compared to ~45 minutes with Media Heartbeats.

To set up terminology, in chronological order, media tracking solutions were:

1. Media Heartbeats solution
2. Media Collection API
3. Media Edge API

## Installation

The `@theoplayer/react-native` package has a peer dependency on `react-native-device-info`, which has to be installed as well:

```sh
npm install \
react-native-device-info \
@theoplayer/react-native-analytics-adobe-edge
```

[//]: # (npm install @theoplayer/react-native-analytics-adobe)

## Usage

### Configuring the connector

Create the connector by providing the `THEOplayer` instance, the Media Collection API's end point,
Visitor Experience Cloud Org ID, Analytics Report Suite ID and the Analytics Tracking Server URL.

```tsx
import { useAdobe } from '@theoplayer/react-native-analytics-adobe';

const baseUrl = "<Media Collection API's end point>";
const dataStreamId = "<dataStreamId or configId>";
const userAgent = "<Custom User-Agent>"; // Optionally provide a custom user-agent header value.
const debugSessionID = "<debugSessionID>"; // Optionally provide a query parameter to be added to outgoing requests.

const App = () => {
const [adobe, initAdobe] = useAdobe(baseUrl, dataStreamId, userAgent, debugSessionID);

const onPlayerReady = (player: THEOplayer) => {
// Initialize Adobe connector
initAdobe(player);
}

return (<THEOplayerView config={playerConfig} onPlayerReady={onPlayerReady}/>);
}
```

The Adobe connector will dispatch player events to Adobe with standard metadata the player has access to,
such as duration or whether it is a live or vod.

### Passing metadata dynamically

The connector allows passing or updating the current asset's metadata at any time:

```typescript
import { AdobeCustomMetadataDetails } from "@theoplayer/react-native-analytics-adobe-edge";

const onUpdateMetadata = () => {
const metadata: AdobeCustomMetadataDetails[] = [
{ "customTag1": "customValue1" },
{ "customTag2": "customValue2" }
]
adobe.current?.updateMetadata(metadata);
};
```
3 changes: 3 additions & 0 deletions adobe-edge/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};
88 changes: 88 additions & 0 deletions adobe-edge/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{
"name": "@theoplayer/react-native-analytics-adobe-edge",
"version": "0.1.0",
"description": "Adobe Edge analytics connector for @theoplayer/react-native",
"main": "lib/commonjs/index",
"module": "lib/module/index",
"types": "lib/typescript/src/index.d.ts",
"react-native": "src/index",
"source": "src/index",
"files": [
"src",
"lib",
"android",
"ios",
"cpp",
"*.podspec",
"*.tgz",
"CHANGELOG.md",
"!lib/typescript/example",
"!ios/build",
"!android/build",
"!android/gradle",
"!android/gradlew",
"!android/gradlew.bat",
"!android/local.properties",
"!**/__tests__",
"!**/__fixtures__",
"!**/__mocks__",
"!**/.*"
],
"scripts": {
"typescript": "tsc --noEmit",
"build": "bob build",
"prepare": "npm run build",
"clean": "rimraf lib android/build example/android/build example/android/app/build example/ios/build",
"generate-types": "openapi-typescript ./src/internal/media-edge/media-edge-0.1.json -o ./src/internal/media-edge/MediaEdge.d.ts"
},
"keywords": [
"react-native",
"THEOplayer",
"ios",
"android",
"adobe"
],
"repository": {
"type": "git",
"url": "[email protected]:THEOplayer/react-native-connectors.git"
},
"author": "THEO Technologies",
"license": "SEE LICENSE AT https://www.theoplayer.com/terms",
"homepage": "https://github.com/THEOplayer/react-native-connectors/tree/main/adobe-edge#readme",
"publishConfig": {
"registry": "https://registry.npmjs.org/"
},
"peerDependencies": {
"react": "*",
"react-native": "*",
"react-native-device-info": "*",
"react-native-theoplayer": "^3.0.0 || ^7.0.0",
"theoplayer": "^5.0.0 || ^6.0.0 || ^7.0.0"
},
"peerDependenciesMeta": {
"theoplayer": {
"optional": true
}
},
"eslintIgnore": [
"node_modules/",
"lib/"
],
"react-native-builder-bob": {
"source": "src",
"output": "lib",
"targets": [
"commonjs",
"module",
[
"typescript",
{
"project": "tsconfig.build.json"
}
]
]
},
"dependencies": {
"openapi-fetch": "^0.9.5"
}
}
61 changes: 61 additions & 0 deletions adobe-edge/src/api/AdobeConnector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { THEOplayer } from 'react-native-theoplayer';
import { AdobeConnectorAdapter } from '../internal/AdobeConnectorAdapter';
import type { AdobeCustomMetadataDetails } from './details/AdobeCustomMetadataDetails';
import type { AdobeErrorDetails } from './details/AdobeErrorDetails';

export class AdobeConnector {
private connectorAdapter: AdobeConnectorAdapter;

constructor(player: THEOplayer, baseUrl: string, dataStreamId: string, userAgent?: string, useDebug?: boolean, debugSessionId?: string) {
this.connectorAdapter = new AdobeConnectorAdapter(player, baseUrl, dataStreamId, userAgent, useDebug, debugSessionId);
}

/**
* Sets customMetadataDetails which will be passed for the session start request.
*/
updateMetadata(customMetadataDetails: AdobeCustomMetadataDetails[]): void {
this.connectorAdapter.updateMetadata(customMetadataDetails);
}

/**
* Dispatch error event to adobe
*/
setError(errorDetails: AdobeErrorDetails): void {
this.connectorAdapter.setError(errorDetails);
}

/**
* Set debug flag.
*
* @param debug whether to write debug info or not.
*/
setDebug(debug: boolean) {
this.connectorAdapter.setDebug(debug);
}

/**
* Set a debugSessionID query parameter that is added to all outgoing requests.
*/
setDebugSessionId(id: string | undefined) {
this.connectorAdapter.setDebugSessionId(id);
}

/**
* Explicitly stop the current session and start a new one.
*
* This can be used to manually mark the start of a new session during a live stream,
* for example when a new program starts.
*
* @param customMetadataDetails media details information.
*/
stopAndStartNewSession(customMetadataDetails: AdobeCustomMetadataDetails[]): void {
void this.connectorAdapter.stopAndStartNewSession(customMetadataDetails);
}

/**
* Stops video and ad analytics and closes all sessions.
*/
destroy(): void {
void this.connectorAdapter.destroy();
}
}
49 changes: 49 additions & 0 deletions adobe-edge/src/api/details/AdobeAdvertisingDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Advertising details information.
*
* https://github.com/adobe/xdm/blob/master/docs/reference/datatypes/advertisingdetails.schema.md
*/
export interface AdobeAdvertisingDetails {
// ID of the ad. Any integer and/or letter combination.
ID?: string;

// Company/Brand whose product is featured in the ad.
advertiser?: string;

// ID of the ad campaign.
campaignID?: string;

// ID of the ad creative.
creativeID?: string;

// URL of the ad creative.
creativeURL?: string;

// Ad is completed.
isCompleted?: boolean;

// Ad is started.
isStarted?: boolean;

// Length of video ad in seconds.
length: number;

// Friendly name of the ad. In reporting, “Ad Name” is the classification and “Ad Name (variable)” is the eVar.
name: string;

// Placement ID of the ad.
placementID?: string;

// The name of the player responsible for rendering the ad.
playerName: string;

// The index of the ad inside the parent ad start, for example, the first ad has index 0 and the second ad has
// index 1.
podPosition: number;

// ID of the ad site.
siteID?: string;

// The total amount of time, in seconds, spent watching the ad (i.e., the number of seconds played).
timePlayed?: number;
}
19 changes: 19 additions & 0 deletions adobe-edge/src/api/details/AdobeAdvertisingPodDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Advertising Pod details information.
*
* https://github.com/adobe/xdm/blob/master/docs/reference/datatypes/advertisingpoddetails.schema.md
*/
export interface AdobeAdvertisingPodDetails {
// The ID of the ad break.
ID?: string;

// The friendly name of the Ad Break.
friendlyName?: string;

// The index of the ad inside the parent ad break start, for example, the first ad has index 0 and the second ad
// has index 1.
index: number;

// The offset of the ad break inside the content, in seconds.
offset: number;
}
30 changes: 30 additions & 0 deletions adobe-edge/src/api/details/AdobeChapterDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Chapter details information.
*
* https://github.com/adobe/xdm/blob/master/docs/reference/datatypes/chapterdetails.schema.md
*/
export interface AdobeChapterDetails {
// The ID of the ad break.
ID?: string;

// The friendly name of the Ad Break.
friendlyName?: string;

// The position (index, integer) of the chapter inside the content.
index: number;

// Chapter is completed.
isCompleted?: boolean;

// Chapter is started.
isStarted?: boolean;

// The length of the chapter, in seconds.
length: number;

// The offset of the chapter inside the content (in seconds) from the start.
offset: number;

// The time spent on the chapter, in seconds.
timePlayed?: number;
}
12 changes: 12 additions & 0 deletions adobe-edge/src/api/details/AdobeCustomMetadataDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Custom metadata details information.
*
* https://github.com/adobe/xdm/blob/master/docs/reference/datatypes/custommetadatadetails.schema.md
*/
export type AdobeCustomMetadataDetails = {
// The name of the custom field.
name?: string;

// The value of the custom field.
value?: string;
};
17 changes: 17 additions & 0 deletions adobe-edge/src/api/details/AdobeErrorDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Error details information.
*
* https://github.com/adobe/xdm/blob/master/docs/reference/datatypes/errordetails.schema.md
*/
export interface AdobeErrorDetails {
// The error ID.
name: string;

// The error source.
source: ErrorSource;
}

export enum ErrorSource {
PLAYER = 'player',
EXTERNAL = 'external',
}
Loading

0 comments on commit e01f628

Please sign in to comment.