Conviva Rust Sensor Integration

Explains how to install and integrate the Conviva sensor in Rust players to collect video streaming experience data.

Updated 2026-08-03 rust, stream, sensor, sensor developer center, sensor integration

Conviva VSI Sensor Integration

Follow these instructions to complete the Conviva Stream Sensor integration on Rust players.

Step 1: Install Conviva Library

  • Install the Conviva library and import required modules.

  • Initialize the main Conviva object.

  • Implement platform interface and device metadata.

Developer Steps

  • Install the Conviva library and import required modules.

  • Initialize the library by calling get_conviva_client() by providing customer_key, platform_interface, and settings parameters (Optional).

Step 2: Configure Metadata

  • Most metadata is autocollected.

  • Configure additional custom metadata tags (if applicable).

Developers Steps

  • Use the pre-defined metadata key/value pairs.

  • Optionally, set custom metadata.

Step 3: Report Events and Metadata

  • Use Conviva methods to report video stream events and metadata. Conviva computes stream data and metrics.

Developer Steps

  • Use create_session(content_info) method to report playback attempt request along with metadata (content, workflow, audience, and other relevant metadata).

Start monitoring the ads by calling create_ad_session(ad_info, video_session) for each ad in the ad break. Report the end of the playback by calling the cleanup() method.

  • To report video and ad related events, use CISPlayerIf as a callback container object.

Step 4: Handle User Actions

Use Conviva methods to handle user actions, such as backgrounding and foregrounding.

Use Conviva methods to report custom events.

Use Conviva methods to control data collection and delete collected data.

Developer Steps

  • Set the player state to paused for background events.

  • Continue to report player state changes or metrics for foreground events.

  • Report video related events and application-level events.

  • Manage Data Collection and User Preferences.

Step 5: Clean Up Session

  • Use Conviva release methods to clean up objects on player application exit.

Developer Steps

  • To release the library and all tied up memory or resources, call cleanup() API.

Prerequisites

  • Obtain your account's CUSTOMER_KEYs.**Conviva provides a test account and a production account for Test and Production environments, respectively. You can find your CUSTOMER_KEY here: Pulse - Account Info. Ask your Conviva representative for assistance if you have problems accessing it.

  • Pass the gatewayUrl parameter to init() method of Conviva SDK. The gatewayUrl is specific for your account and shall ONLY be used for tests, never for production deployment.

    Sample gatewayUrl for Testing:

    https://<*customer_key*>.ts-testonly.conviva.com

    IMPORTANT: If there's any doubt on how to set the gateway URL, consult your Conviva representative - this is a critical parameter. For production, Conviva library uses the automatically-assigned gatewayUrl.

    Use Touchstone 2.0 in Pulse to perform self-validation and debugging of video sensor integration

  • For Conviva JavaScript Sensor Integration, you can use any custom gateway URL with a proxy service setup. This is applicable for JavaScript version 4.7.13 onwards.

  • Plan your metadata

    Conviva supports Pre-defined, Device, and Custom metadata. Work with your project team to determine the need to collect any custom metadata. It's also recommended to work with your Conviva representative to create your metadata plan prior to integration.

  • Integration Summary

    1. Install Conviva Library
    • Install the library and add dependencies.

    • Implement the platform interface.

    • Implement device metadata as part of the platform interface.

    • Initialize the library by calling get_conviva_client() using your CUSTOMER_KEY.

    1. Configure Metadata
    • Implement the metadata by following the instructions to use the pre-defined keys, as well as custom metadata, if applicable.
    • Report ad break start / end.
    • Implement ad metadata, events and metric reporting (if applicable).
    1. Report Events and Metadata
    • Start monitoring session by calling create_session(content_info) method to report playback attempt request along with metadata (content, workflow, audience, and other relevant metadata).
    • For the ads, start monitoring by calling create_ad_session(ad_info, &mut video_session); for each ad in the ad break.
    • Use the cleanup(&self) method to report the of end playback.
    • Create an instance of CISPlayerIf object to report video and ad related events (if your player has ads).
    • [Optional] Implement start_monitoring() to report metrics.
    1. Handle User Actions
    • Handle user actions such as backgrounding, user dialogue, pin popup according to the specification.

    • Report Network Metrics.

    1. Clean Up
    • Call cleanup(&self){} to cleanup Conviva library, and release memory or resources.

    Test and Validate

    1. After integration, perform a sanity check following the test cases in the Stream Sensor Sanity Test Plans spreadsheet. For the full validation test, use the test cases in the Stream Sensor Full Test Plans spreadsheet.

    2. Use Touchstone in Pulse to perform self-validation and debugging of video sensor integration.

    Be sure to replace your TEST CUSTOMER_KEY with the PRODUCTION key to go live with your application, and generate the session traffic to the following Touchstone 2 gateway URL:https://.ts-testonly.conviva.com
    1. Done! Analyse your data in Pulse and improve your viewer experience.

    Sample Application

    The sample application illustrating Conviva integration example can be found along with the library, in the same .zip file. Please refer to the next step below for details.

    1. Install Conviva Library

    Add Conviva Library and Implement Platform Interface

    Add Conviva Library and Import Modules

    Download the Rust SDK library from the RUST SDK downloads page.

    Install the Conviva library and import these modules:

    use convivasdk::common::types::*;
    use convivasdk::platform_if::*;
    use convivasdk::player_if::CISPlayerIf;
    use convivasdk::client::*;
    /// Add below module only if Experiance Insights is required
    use convivasdk::video_session::CISVideoSession;
    /// Add below module only if Ad Insights is required
    use convivasdk::ad_session::CISAdSession;
    

    Initialize the Conviva Rust Client object

    Initialize the Conviva Rust Client by calling get_conviva_client() by providing customer_key, platform_interface, and settings parameters.

    pub fn get_conviva_client(
        customer_key: String,
        platform_if: &'static CISPlatformIf,
        settings: Option<CISSettings>
    ) -> Result<CISClient, CISError> {}
    
    • customer_key: String to identify specific customer account. Different keys shall be used for development / debug versus production environment. Find your keys on the account info page in Pulse;

    • platform_interface: Your implementation of CISPlatformIf for your device.

    • settings: [Optional] Custom settings of type CISSettings for the library. The allowed parameters are:

  • gateway_url: Option: once enabled, the data will appear in Pulse for performing self-validation of video sensor integration. For more information, see Self-validation using Touchstone. - enable_player_state_inference: By default, this field is *false*. When *false*, report the player state changes by calling the set_state() API. When updated to *True*, Conviva sensor infers the player state based on *Play Head TIme*, *Buffer Length*, *Frame Rate* and *Minimum Buffer Length*. You need not report the player state changes explicitly.
    fn configure_settings() -> CISSettings {
        /// Instantiate settings interface
        let mut settings = CISSettings::new();
        // Configure settings
        settings.gateway_url = Some(GW_URL.to_string());
        return settings;
    }
    

    IMPORTANT: There's no need to explicitly set gateway_url and enable_player_state_inference for your production release. The Conviva sensor has the correct default value.

  • Expected Errors Due to Dual Stack IPv4/v6 Network Support

    When the Conviva sensor is initialized with production settings, the SDK sends a single request to the endpoints below:
    • [customer_key].ipv4.cws.conviva.com for IPv4 only

    • [customer_key].ipv6.cws.conviva.com for IPv6 only

    Sending both requests enables correlation of IPv4 and IPv6 addresses in dual-stack networks. If only IPv4 or IPv6 addressing is used (single-stack networking), it is expected that one request will fail. All the following requests will be sent to the endpoint below, which supports both IPv4 and IPv6:

    • [customer_key].cws.conviva.com

    Implement Platform Interface

    The CISPlatformIf structure allows the client to implement the platform dependent functions for the Conviva library, such as Http_Post, timer, and storage. For example, to send the HTTP Posts, implement the send_http_post_request() method as shown in this example:

    async fn send_http_post_request(
        &self,
        url: &str,
        content_type: &str,
        data: &str,
        timeout: u32
    ) -> Result<CISHttpResponse,()> {
        let mut f = File::options().append(true).open("./hbRust.json").expect("Unable to open");
        let client = reqwest::Client::new();
        let response: Result<CISHttpResponse, CISError> = client
            .post(url)
            .header("Accept", "application/json")
            .header("Content-Type", "application/json")
            .header("User-Agent", "rust-agent/1.0")
            .body(data.to_string())
            .send().await
            .unwrap()
            .text().await
            .and_then(
                |res| -> Result<CISHttpResponse, _> {
                    println!("Response {}", res);
                    Ok(CISHttpResponse { response: res, http_response_code: 200 })
                }
            )
            .or_else(
                |err| -> Result<_, CISError> {
                    Err(CISError { status_code: CISErrorCode::Failed, message: "".to_string() })
                }
            );
        response
    }
    

    A complete example that runs on a Linux machine is included in the SDK inside test or sample-app folder.

    Implement Device Metadata

    While initializing Rust SDK through get_conviva_client(), the application provides all the platform metadata in CISPlatformMetaData structure while passing the CISPlatformIf instance. Here’s an example that demonstrates the get_platform_metadata() call back implementation:

    fn platform_meta_data() -> CISPlatformMetaData {
        let platform_metadata = CISPlatformMetaData {
    		device_brand: "Playstation".to_string(),
    		device_manufacturer: "Sony".to_string(),
    		device_model: "PS4 Pro".to_string(),
    		device_type: CISDeviceType::Desktop,
    		device_version: "A136".to_string(),
    		framework_name: "mediax".to_string(),
    		framework_version: "WASM:2.5.6;PLUGIN:4.2.13".to_string(),
    		operating_system_name: "Sony_System_Software".to_string(),
    		operating_system_version: "2.0.0+.09-00.00.00.0.1".to_string(),
    		screen_height: Some(1080),
    		screen_width: Some(1920),
    		screen_scale_factor: Some(2.0),
    		schema: "sdk.rust.1".to_string(),
    		category: "LNX".to_string(),
        };
        return platform_metadata;
    }
    
    static PLATFORM_INSTANCE: OnceCell<CISPlatformIf> = OnceCell::new();
    fn get_platform_if() -> CISPlatformIf {
        let storage_if = app_platform_if::AppStorageIf::new();
        // Instantiate http interface
        let http_if = app_platform_if::AppHttpIf::new();
        //let platform_metadata: CISPlatformMetaData = platform_meta_data();
        let platform_metadata: CISPlatformMetaData = CISPlatformMetaData::new();
        let utils = UtilsIf {};
        let async_task_if = app_platform_if::AppAsyncTaskIf::new();
    
        // Configure platform interface
        CISPlatformIf::new(platform_metadata, http_if, storage_if, utils,async_task_if)
    }
    
    
    // Instantiate settings interface
    let mut settings = configure_settings();
    let _ = PLATFORM_INSTANCE.set(get_platform_if());
    let mut conviva_data = ConvivaData::new();
    // Create conviva client by passing customer key,platform interface and settings
    let conviva_client_result = get_conviva_client(
        CUSTOMER_KEY.to_string(),
        PLATFORM_INSTANCE.get().unwrap(),
        Some(settings)
    );
    
    Call app_tick() method To make the metrics data available for Conviva, call CISClient's app_tick() method for the following scenarios: - Immediately after creating the Conviva client object - After creating any video or ad session - At regular intervals (recommended every 200ms)

    2. Configure Metadata

    Metadata enables analysis of your data using different dimensions, for example, content, audience, device, workflow, player, and operating system.

    Conviva categorizes metadata tags into three buckets: Pre-defined, Device, and Custom.

    Implement Video Metadata

    Implement pre-defined and custom tags for video by setting the properties of the CISContentInfo object.

    An example to illustrate pre-defined and custom metadata implementation for video:

    fn create_metadata() -> CISContentInfo {
        /// Configure metadata
        let mut content_info = CISContentInfo::new();
        content_info.asset_name = Some("Guardians of the Galaxy".to_string());
        content_info.default_bitrate = Some(5555);
        content_info.default_average_bitrate = Some(3333);
        content_info.viewer_id = Some("9ea10d4c-f458-4b90-b5f7-4e01f06bfed5".to_string());
        content_info.player_name = Some("DemoPlayerName++".to_string());
        content_info.stream_url = Some("http://Stream_Url.m3u8".to_string());
        content_info.is_live = Some(false);
        content_info.duration = Some(100);
        content_info.default_resource = Some("DEFAULT_RC_new".to_string());
        let mut tags: HashMap<String, CISGenericValueType> = HashMap::new();
        tags.insert("tag1".to_string(), CISGenericValueType::CisStringValue("test".to_string()));
        content_info.tags = Some(tags);
        return content_info;
    }
    

    Implement Ad Metadata

    Implement pre-defined and custom tags for ad content by setting the properties of the CISContentInfo object.

    Refer to the below example illustrating pre-defined and custom metadata for ads:

    //Create ad_info
    fn create_ad_server_side_metadata()-> CISContentInfo {
    	let  mut  ad_info = CISContentInfo::new();
    	ad_info.asset_name = Some("Server_Side_Asset_Name".to_string());
    	ad_info.duration = Some(30);
    	ad_info.default_resource = Some("adDEFAULT_RC_new".to_string());
    	ad_info.stream_url = Some(("adurl.conviva.com").to_string());
    	let  mut  tags:  HashMap<String, CISGenericValueType> = HashMap::new();
    	tags.insert("tag1ad".to_string(),CISGenericValueType::CisStringValue("test".to_string()));
    	ad_info.tags  =  Some(tags);
    	return  ad_info;
    }
    

    Pre-defined Metadata for Video and Ads

    Conviva defines the constants or fixed string keys for commonly used metadata. These metadata keys provide critical information about video and ad content, versioning, workflow.

    The below tags shall be added to both video and ad CISContentInfo objects:

    Constants for Pre-defined Metadata for Video and Ads

    Key / Constant Type Video Ads
    CISContentInfo.asset_name Option Report as unique name for each stream/video asset. Values are up to your choice, but a human-readable text prefixed with the unique video ID works best in most Conviva sensors.This provides for clarity in reports and makes most popular content easily identifiable.Pattern: [videoID] Video Title

    The following are typical patterns for VOD (movies and episodic content) and Live streams: Movie Pattern: [{contentId}] {Movie Title} Sample Value: [12345] The ABC Movie Episode Pattern: [{contentId}] {Show Title} - S:{Season Number}:E{Episode Number} - {Episode Title} Sample Value: [67890] The XYZ Show - S3:E1 - The Pilot Episode Live Stream Pattern: [{channelNumber}] {Chanel Name} Sample Value: [10] PQRS Bay Area

    Report as "ad title" or "[ad_id] ad_title".
    CISContentInfo.is_live Option Denotes whether the content is video on-demand or a live stream. Affects the computation and availability of the Conviva metrics. For Ads, the value shall be the same as for the video stream.
    CISContentInfo.player_name Option A string value used to distinguish video players (applications). Simple values that are unique across all of your integrated platforms work best here. If the same player used across multiple platforms, e.g Tizen, LG TV, WEB, give separate names for each application / platofrm: e.g "JS Tizen", "JS LGTV", "JS WEB". Do not include the build or version number in this property. The intention is to have a simple way of differentiating data from different players / platforms. Automatically copied from the video session.
    CISContentInfo.viewer_id Option Required for Viewers Module. A unique identifier to distinguish individual viewers or devices through Conviva's Viewers Module. The value shall be unique abstract user's identifier. If user is anonymous, do not set any value for this tag. Automatically copied from the video session.
    CISContentInfo.stream_url Option

    The manifest URL of the video stream. The Conviva backend config server attempts to map a portion of StreamURL into a CDN name. For example: In the URL https://www.akamai.net/avengers.m3u8, akamai.net maps to the AKAMAI label. Conviva VSI users can then retrieve metrics based on the mapped CDN name (AKAMAI, in this case).

    The URL values reported in the streamURL are case insensitive. The streamURLs with either uppercase or lowercase are acceptable.
    The manifest URL of the ad stream.
    CISContentInfo .default_resource Option

    Video server resource the stream is played from. Set this field when the video server resource cannot be inferred from the STREAM_URL.

    For example, if the streamURL is https://cbd12348.cdn.cms.somewebsitehostname.com/abc.txt, it is not possible to infer the AKAMAI name from the streamURL, and in such a case, it is necessary to report the default_resource as AKAMAI.

    The DEFAULT_Resource value is case sensitive. If the resource name is initially reported as AKAMAI (uppercase) and subsequently modified in the app to akamai (lowercase), it is necessary to inform Conviva about the change because both need to be mapped in the Conviva backend configuration server to ensure that both point to the same CDN name (AKAMAI).
    Ad server resource the stream is played from. Set this field when the video server resource cannot be inferred from the STREAM_URL.
    CISContentInfo.duration Option Duration of the video content, in seconds. Duration of the single ad clip, in seconds. For example, in a block of 3 ads each 30 seconds long, report 30 sec for each corresponding ad.
    "c3.app.version" Option

    Application build version. Ads and video have same values.

    Application build version.

    IMPORTANT: To assign content category labels, such as Audio, Trailer, Tile Play, or Short Video, use the c3.cm.categoryType pre-defined content metadata constant.

    Constants for Pre-defined Metadata for Video Only

    Set these metadata tags using video_content_info.tags object for video session:

    Sample Code:

    let mut tags: HashMap<String, CISGenericValueType> = HashMap::new();
    tags.insert(
       "c3.cm.channel".to_string(),
       CISGenericValueType::CisStringValue("ABC".to_string()),
    );
    video_content_info.tags = Some(tags);
    

    Key Type Description
    "c3.cm.contentType"

    String

    Advanced content delivery methods along with Live and VOD.

    Acceptable values: "Live", "Live-Linear", "DVR", "Catchup", "VOD".

    "c3.cm.channel" String The channel on which the content is consumed.

    Example: "ABC".

    "c3.cm.brand" String The name of the brand to which the content belongs.

    Examples: "ABC X", "ABC Y".

    "c3.cm.affiliate" String Affiliate or MVPD name for TV Everywhere authenticated services.

    Examples: "Xfinity", "Comcast".

    "c3.cm.categoryType" String

    Content business categories of interest.

    Use this constant to assign content category labels, such as Audio, Trailer, Tile Play, or Short Video.

    Examples: "Episodic", "Movies", "News", "Sports", "Events", "Informercials", "Shorts", "Promos", "Audio", "Tile Play", "Short Videos", "Trailer".

    "c3.cm.name" String Name of CMS Provider.

    Examples: "CMS", "ROVI", "TMS".

    "c3.cm.id" String Unique asset identifier to query CMS system to gather additional asset metadata information for a specific asset.

    Example: "003b094d-fc5c-3d5a-8ed0-301bf848291e".

    "c3.cm.seriesName" String The name of Series. Set the value only if the metadata cannot be gathered from CMS System. Null if not applicable.

    Examples: "Friends", "Null".

    "c3.cm.seasonNumber" String The Season number. Set the value only if the details cannot be inferred from Asset Provider Server. Null if not applicable.

    Examples: "1", "Null".

    "c3.cm.showTitle" String The name of the Episode or Show Title. Set the value only if the details cannot be inferred from Asset Provider Server. Null if not applicable.

    Examples: "The One with All the Cheesecakes", "Null".

    "c3.cm.episodeNumber" String The Episode number. Set the value only if the details cannot be inferred from Asset Provider Server. Null if not applicable.

    Examples: "3", "Null".

    "c3.cm.genre" String The Primary content genre. Set the value only if the details cannot be inferred from Asset Provider Server. Null if not applicable.

    Examples: "Drama", "Null".

    "c3.cm.genreList" String The list of the applicable content genre. Set the values in a comma separated list only if the details cannot be inferred from Asset Provider Server. Null if not applicable.

    Examples: "Drama, Crime, Political, Violence", "Null"

    "c3.cm.utmTrackingUrl" String Provide the UTM parameters in the URL to track the effectiveness of the online marketing campaign across traffic sources and publishing media. Conviva uses CONTAINS logic to parse the individual UTM parameters from the URL provided, so either the full URL or just the UTM parameters is acceptable.

    Example values: http://www.example.com/?utm_source=newsletter1&utm_medium=email&utm_campaign=summer-sale&utm_content=toplink or utm_source=newsletter1&utm_medium=email&utm_campaign=summer-sale&utm_content=toplink

    This tag is only applicable for web and mobile devices.

    Constants for Pre-defined Metadata for Ads Only

    Implement the pre-defined metadata mentioned in the following table:

    Set the metadata tags using ad_content_info.tags object for ad session:

    Sample Code:

    let mut tags: HashMap<String, CISGenericValueType> = HashMap::new();
    tags.insert(
       "c3.ad.technology".to_string(),
       CISGenericValueType::CisStringValue("Client Side".to_string()),
    );
    ad_content_info.tags = Some(tags);
    
    Key Type Description
    "c3.ad.technology" string Set the technology of the ad belongs to. Only allows the CISAdTechnology.CLIENT_SIDE/SERVER_SIDE values. Allowed values: "Server Side" and "Client Side".
    "c3.ad.id" string The Ad ID extracted from the Ad Server that actually has the ad creative. For wrapper ads, this is the last Ad ID at the end of the wrapper chain. Example: "411687224".
    "c3.ad.system" string The name of the Ad System (i.e. the Ad Server). This Ad System represents the Ad Server that actually has the ad creative. For wrapper ads, this is the last Ad System at the end of the wrapper chain. Set to "NA" if not available. Examples: "Freewheel", "Innovid", "Extreme IO", "NA".
    "c3.ad.position" string The position of the ad. Only allows CISAdPosition.PREROLL/MIDROLL/POSTROLL values which are string constants of "Pre-roll", "Mid-roll", and "Post-roll" respectively.
    "c3.ad.isSlate" string A boolean value that indicates whether this ad is a Slate or not. Set to "true" for Slate and "false" for a regular ad. By default, set to "false".
    "c3.ad.mediaFileApiFramework" string The name of the creative media framework. Generally used for VPAID ads. Set to "NA" for non-VPAID ads. Examples: "VPAID", "NA".
    "c3.ad.adStitcher" string "The name of the Ad Stitcher. If not using an Ad Stitcher, set to "NA". Examples: "Uplynk", "Google DAI", "Google Anvato", "YoSpace", "NA".
    "c3.ad.firstAdSystem" string Only valid for wrapper VAST responses. This tag must capture the "first" Ad System in the wrapper chain when a Linear creative is available or there is an error at the end of the wrapper chain. Set to "NA" if not available. If there is no wrapper VAST response then the Ad System and First Ad System should be the same. Examples: "GDFP", "NA".
    "c3.ad.firstAdId" string Only valid for wrapper VAST responses. This tag must capture the "first" Ad Id in the wrapper chain when a Linear creative is available or there is an error at the end of the wrapper chain. Set to "NA" if not available. If there is no wrapper VAST response then the Ad Id and First Ad Id should be the same. Examples: "709684096", "NA".
    "c3.ad.firstCreativeId" string Only valid for wrapper VAST responses. This tag must capture the "first" Creative Id in the wrapper chain when a Linear creative is available or there is an error at the end of the wrapper chain. Set to "NA" if not available. If there is no wrapper VAST response then the Ad Creative Id and First Ad Creative Id should be the same. Examples: "57861167296", "NA".
    "c3.ad.creativeId" string The creative id of the ad. This creative id is from the Ad Server that actually has the ad creative. For wrapper ads, this is the last creative id at the end of the wrapper chain. Set to "NA" if not available. Examples: "57861167296", "NA".

    Device Metadata

    The Implement Device Metadata section prescribes how to implement platform metadata as a part of Platform Interface implementation. Device metadata is also used for inferring the device tags dimensions.

    Custom Metadata

    Refer to App Manager -> Metadata page for your account to find the custom tags to be implemented.

    Set custom tags in a similar way for either video or ads, by using appropriate video_content_info or ad_content_info object and its corresponding methods.

    Conviva recommends to label the custom tags as "MyCustomTag1" or "my_custom_tag", and not use the c3.cm format, for instance, c3.cm.MyCustomTag1. Conviva reserved the c3.cm naming convention for the pre-defined or required metadata.

    Update/Amend Metadata

    To update or amend metadata for video:

    pub fn update_content_info(&mut  self, content_info:  CISContentInfo) ->  Result<(), CISError> {}
    
    • content_info is the object containing the updated or amended metadata, for ads or video.

    IMPORTANT: Please note that different Conviva products, such as Conviva VSI and Conviva Viewer Insights may have different logic with respect to handling updated values. Conviva recommends to update the metadata only when it is available and do not set any default values before the metadata is available.

    Ad Events and Metadata

    Report Ad Break

    This step is required to accurately report Video Startup Time (VST) that excludes the time taken by the ad break. Notify Conviva sensor of the ad break events:

    Report ad break start
    pub fn report_ad_break_started(
        &mut self,
        ad_player_type: CISAdPlayerType,
        ad_technology: CISAdTechnology,
        pod_info: Option<CISPodInfo>
    ) -> Result<(), CISError>;
    
    • ad_player_type: informs Conviva sensor which player is used to play the ads - the same as main video content or separate instance.

    • ad_technology: specifies type of the ad (server side / client side);

    • pod_info: Ad pod info like pod position, pod index, and pod duration.

    Sample code to illustrate the reporting of client-side and server-side ads: Client-side Ads

    video_session.report_ad_break_started(
        CISAdPlayerType::Content,
        CISAdTechnology::ClientSide,
        Some(pod_info_preroll)
    );
    

    Server-side Ads

    video_session.report_ad_break_started(
        CISAdPlayerType::Content,
        CISAdTechnology::ServerSide,
        None
    );
    
    Report ad break end
    video_session.report_ad_break_ended();
    

    The following steps are required when the video content contains pre-roll and mid-roll ads.

    Handling Ad Breaks

    A common way to handle pre-roll ads is to preload the main content, pause it while the pre-roll ad plays, and then resume the main content after the pre-roll completes. Essentially, the ad plays while the main content is loaded. However, you don't want the play time for the ad to be counted as part of the Video Startup Time metric, nor do you want to be constantly polling the player while the ad runs. The solution is to notify the Conviva layer of the pre-roll's existence and its start and end events . The attach() call is deferred, and the report_ad_break_started() API is called with required parameter. When the Pre-roll ad ends, call the report_ad_break_ended() API and attach CISPlayerIf, as shown in this example:

    let pod_info_preroll = CISPodInfo {
        pod_index: Some(1),
        pod_position: Some(CISAdPosition::MidRoll),
        pod_duration: Some(30),
    };
    let _ = video_session.detach();
    let _ = video_session.report_ad_break_started(
        CISAdPlayerType::Content,
        CISAdTechnology::ClientSide,
        Some(pod_info_preroll),
    ); 
    
    let _ = video_session.report_ad_break_ended();
    interval.tick().await;
    conviva_client.app_tick().await;
    let _ = video_session.attach(Arc::downgrade(&player_if));
    

    3. Report Events and Metadata

    Manage Video Session

    To create video session

    Use the following method to create Conviva monitoring session upon user playback request, along with metadata (content, workflow, audience, and other relevant metadata):

    pub fn create_session(
        &mut self,
        content_info: CISContentInfo
    ) -> Result<CISVideoSession, CISError>;
    
    • content_info: Metadata associated with the content to be monitored.

    • Returns a reference to CISVideoSession on success.

    Sample code to illustrate video session creation:

    // Configure metadata
    let  content_info  =  create_metadata();
    // Create video session
    let  video_session_result  =  conviva_client.create_session(content_info);
    

    IMPORTANT: It's critical to make this API call correctly to monitor video experience - monitoring session created from this moment, and key metrics are captured based on this event. For example, if this call done late (say, when video starts rather than user clicks 'play'), the Video Startup Time will be under-reported, Video Start Failures will be missed, etc.

    Please note that each video should be monitored separately - call this method for each new video played.

    IMPORTANT: If some of the content metadata tags aren't available at start, they can be set later or amended by calling update_content_info() API. To accurately attribute metadata to the video asset, it's required to set the content metadata before the player reports "play" for the first time,

    Refer to the below table to know when to invoke the corresponding API calls:

    Invoke ccl_session_create() On: Invoke ccl_session_destroy() On:
    User clicks play button User stops the video; User starts another video; Video ends;
    Video starts in autoplay mode
    A new video starts in playlist
    Video item ends in playlist

    To close video session

    Report the end of playback:

    cleanup();
    
    After integrating the video player, review advanced use cases such as fatal errors, live program and playlist changes that can be applicable for specific goals.

    Manage Ad Session

    To create ad session

    Use the following method to create Ad session:

    let ad_session_result = conviva_client.create_ad_session(ad_info, &mut  video_session);
    
    • ad_info: metadata associated with the ad to be monitored

    • video_session: instance of video session

    • Returns a reference to CISAdSession on success

    IMPORTANT: It's critical to make this API call correctly to monitor ad experience - monitoring session created from this moment, and key metrics are captured based on this event. For example, if this call done late (say, when ad starts rather than ad is requested), the Ad Startup Time will be under-reported, Ad Start Failures will be missed, etc.

    To close ad session

    Report end or skip of an ad:

    cleanup();
    

    Initialize Metric Reporting Interfaces

    Initialize CISPlayerIf

    The Conviva sensor uses CISPlayerIf instance to collect video playback data from your media player.

    As soon as the CISPlayerIf instance is attached to a session and the Conviva sensor starts monitoring it, the on_start_monitoring() callback is called by Conviva sensor.

    Sample code to illustrate the instantiation of the CISPlayerIf object:

    pub trait CISPlayerIf: 'static + Send {
        fn on_start_monitoring(&mut self);
        fn on_stop_monitoring(&mut self);
        fn get_playhead_time(&mut self) -> Option<u32>;
        fn get_buffer_length(&mut self) -> Option<u32>;
        fn get_rendered_framerate(&mut self) -> Option<f32>;
        fn get_min_buffer_length(&mut self) -> Option<u32>;
        fn get_player_type(&mut self) -> Option<String>;
        fn get_player_version(&mut self) -> Option<String>;
    }
    

    Implement the "get_*" callbacks above to report video or ad player metrics. Conviva sensor polls these methods periodically to receive the latest values.

    Attach CISPlayerIf to the session

    Once the CISPlayerIf instance is created, attach it to the current session to report the events and metrics into that session. pub fn attach(&mut self, player_if: impl CISPlayerIf) -> Result<(), CISError>

    • player_if: Interface to the video player

    • Returns: CISStatus

    // Attach Player

    // Attach Player
    let player_if = CISPlayerIfImpl::new();
    let attach_status = video_session.attach(player_if);
    
    match attach_status {
        Ok(_) => {}
        Err(error) => {
            error!("Failed to attach {:?}", error);
        }
    }
    

    Implement on_start_monitoring() callback

    The on_start_monitoring() callback is called by the Conviva sensor to notify the application that a player has been successfully attached to the session and the monitoring has started.

    fn on_start_monitoring(&mut self) {
        debug!("on_start_monitoring");
    }
    

    To detach the player instance from the session, call the on_stop_monitoring() callback API.

    Report Metrics and Events

    To report playback events

    To report metric events refer to the following table, which prescribes the required events and the corresponding APIs for either content session or ad sessions:

    Event Method Implementation Note
    Player State Change pub fn set_state(&mut self, new_state: CISPlayerState) -> Result<(), CISError>;

    Report any player state changes such as Playing, Buffering, Paused. The new_state parameter is an enum of CISPlayerState type.

    Peak Bitrate pub fn set_bitrate(&mut self, bitrate_kbps: i32) -> Result<(), CISError>;

    Report new peak bitrate value (in kbps) on change event (video + audio, or video only if audio isn't available).

    For the Average Peak Bitrate definition, refer to Average Peak Bitrate in the Metric Dictionary.

    CDN Resource Change pub fn set_cdn_resource(&mut self, resource: &str) -> Result<(), CISError>; Report any change in the CDN resource
    Duration Change pub fn set_duration(&mut self, duration: i32) -> Result<(), CISError>; Report a change in the duration of the content in seconds
    Encoded Framerate pub fn set_encoded_framerate(&mut self, framerate: i32) -> Result<(), CISError>; Report encoded frame rate of the video content in frames per second.
    Seek Start / End pub(crate) fn set_seek(&mut self, action: CISPlayerSeekAction, seektoposition: i32) Report start of seeking or scrubbing by user. The argument action defines whether it's seek start or seek end (CISPlayerSeekAction:Start / CISPlayerSeekAction:End). If seek position is known, report as the method argument seektoposition. If seek position is unknown, pass -1.
    Set CDN IP pub fn set_cdn_server_ip(&mut self, cdn_server_ip: &str) -> Result<(), CISError> Report change in the CDN Edge Server IP used to serve video stream.
    Average Bitrate Change pub fn set_average_bitrate(&mut self, avg_bitrate_kbps: i32) -> Result<(), CISError>

    Report new average bitrate value (in kbps) (video + audio, or video only if audio isn't available).

    For the Avg. Average Bitrate definition, refer to Avg. Average Bitrate in the Metric Dictionary.

    Dropped Frames Count pub fn set_dropped_frame_count(&mut self, dropped_frame_count: i32) -> Result<(), CISError>; Report the number of dropped video frames at regular intervals.
    Dropped Frames Total pub fn set_dropped_frame_total(&mut self, dropped_frame_total: i32) -> Result<(), CISError> Report the cumulative dropped frames count.

    To report playback failures

    To report fatal errors or warnings, call the set_error() method on CISPlayerEvents instance:

    pub  fn  set_error(&mut  self,error_message:  &str,fatal:  bool,) ->  Result<(), CISError>
    
    • error_message: string message specifying the error. Report the reason of the failure; avoid including metadata.

    • fatal: set to true if the error is fatal. Set to false for warning.

    To implement callback metrics

    The following metrics are reported as a return value by corresponding callbacks of the CISPlayerIf object. The application or player implements these methods to report metrics , such as Play Head Time, Buffer Length, and Rendered Framerate.

    Metric Method Implementation Note
    Play Head Time fn get_playhead_time(&mut self) -> Option Retrieves the current position of the play head (in milliseconds). The current position within the video content measures how far the video has been played from the start of the content.
    Buffer Length fn get_buffer_length(&mut self) -> Option Retrieves the number of milliseconds worth of data present in the video buffer. Return -1 if not available.
    Minimum Buffer Length fn get_min_buffer_length(&mut self) -> Option Retrieves the minimum buffer length threshold (in milliseconds) for the video to keep playing. Return -1 if not available.
    Rendered Framerate fn get_rendered_framerate(&mut self) -> Option Retrieves the current rendered frame rate, in frames per second. A moving average over the last couple seconds is recommended. Rendered frame rate of 0 indicates no video frames have been rendered during the last sampling window. Return -1.0 if not available.

    4. Handle User Actions

    Report Network Metrics

    Connection Type

    It requires the application to detect the connection type and send through set_network_connection_type API:

    // The network connection type that the video player is using.
    let  _  =  conviva_client.set_network_connection_type("WiFi");
    

    The table below shows the representation string values for the setConnectionType() API:

    Internet Connection Type Representation String
    Wireless WiFi
    Wired Ethernet
    Cellular 2G 2G
    Cellular 3G 3G
    Cellular 4G 4G
    Cellular 5G 5G
    Other OTHER

    If you can fetch wireless connection sub-type, such as "802.11 a", "802.11b", "802.11n", "802.11g", then pass the sub-type instead of "WiFi". If you can measure 4G data connection sub-type like "LTE", then pass the sub-type instead of "4G".

    The Network Connection Type can be updated after session creation, but only before the first video frame is rendered.

    Signal Strength

    Set the current WiFi signal strength of your device using the following method:

    let  _  =  conviva_client.set_network_connection_type("WiFi");
    

    The value of the signal strength is a f32 in decibel-milliwatts (dBm) that your device detects.

    Set the current WiFi link encryption of your device using the following method:

    let  _  =  conviva_client.set_network_wifi_link_encryption("WPA2");
    

    The values for the link encryption can be any string that your device detects, such as WPA2, WPA, EAP, WEP, and NONE.

    Report Custom Events

    Player Insight is an advanced feature which allows you to track custom events that are not related to video rendering, but rather specific to your player's functionality. These events and their attributes are then tabulated in the Player Insight dashboard at Conviva VSI (Pulse). Contact your Conviva representative to enable Player Insights in Pulse.

    You may send a custom Player Insight event that can be associated with a video playback using the following method:

    pub fn send_event(
        &mut self,
        name: &str,
        data: HashMap<String, CISGenericValueType>
    ) -> Result<(), CISError>;
    

    Sample Code:

    match video_session_result {
        Ok(mut video_session) => {
            let mut data: HashMap<String, CISGenericValueType> = HashMap::new();
            data.insert(
                "old_quality".to_string(),
                CISGenericValueType::CisStringValue("SD".to_string())
            );
            data.insert(
                "new_quality".to_string(),
                CISGenericValueType::CisStringValue("HD".to_string())
            );
            let result = video_session.send_event("video_quality_change", data);
        }
        Err(error) => {}
    }
    

    Report app-level events by the send_event() method on CISClient object:

    let  mut  data1:  HashMap<String, String> =  HashMap::new();
    data1.insert("location".to_string(), "Toolbar".to_string());
    data1.insert("assetName".to_string(), "Sample Video".to_string());
    data1.insert("shareService".to_string(), "Facebook".to_string());
    // Set the custom metadata
    let  result  =  conviva_client.send_event("share_click", Some(data1));
    

    5. Cleanup

    Releases the library and all tied up memory / resources

    pub  fn  cleanup(&self) {}
    

    Advanced Use Cases

    You can use specific APIs in the Conviva sensor for various advanced use cases, such as:

    • Live or live linear streaming program changes

    • Video changes in the playlist

    • Playback does not recover from error and is reported once only

    • Multiple errors due to retry when playback does not recover

    • Playback recovers from a fatal error by switching to a different asset URL or CDN

    • A warning occurs when there's no impact on the playback

    • Handling user actions, such as user dialogues

    To learn more about these advanced use cases, see here.

    Self Validation

    Upon completion of your integration, and before submission to Conviva QA team, developers should complete a comprehensive self-validation test pass of each Device Application.

    Perform self-validation of video sensor integration using Touchstone in Pulse.

    Conviva provides sample test cases with detailed steps and expected results.

    Developers should be checking for both metric and metadata accuracy. Based on our experience, comprehensive self-validation can reduce your QE cycles, saving your costly project time.