Skip to content

Play Session Monitoring

Play sessions are records of subscribers watching channels. Catena automatically registers each stream opening and saves detailed session information for monitoring, analytics, and debugging.

What is a Play Session

A play session is a period of time when a subscriber watches a specific channel. Each session contains information about who, what, when, and from where they watched.

Session lifecycle:

Stream opening → Active viewing → Stream closing
   (openedAt)     (active: true)    (closedAt)

What is recorded:

  • Who is watching: subscriberId, token
  • What is being watched: channelId, channelName, programId
  • When: openedAt, closedAt, updatedAt (timestamps)
  • From where: IP address, userAgent (player/device)
  • How much: bytes (data transferred), session duration
  • Status: active (session open or closed)

Applications:

  • Real-time monitoring — who is watching channels now
  • Problem debugging — why subscriber can't watch channel
  • Viewing analytics — popular channels, viewing time
  • Billing — traffic consumption calculation
  • Security — anomaly detection (one token from different IPs)
  • Statistics — reports for content owners

Play Session Structure

Main Fields

Identifiers:

  • sessionId — unique session ID
  • Format: base64-encoded Snowflake ID
  • Example: sessKl9SW3AAAE.
  • Generated when opening stream

  • subscriberId — ID of subscriber watching channel

  • Link to user account
  • Example: sKl9SW3AAAE.

  • channelId — ID of channel being watched

  • Example: chKl9SW3AAAE.

  • channelName — technical channel name

  • More convenient for debugging than ID
  • Example: sport1, news-hd

  • programId — program ID (if watching from archive)

  • Null for live viewing
  • Example: prKl9SW3AAAE.

  • portalId — portal ID

  • Data isolation between portals
  • Example: pKl9SW3AAAE.

Timestamps:

  • openedAt — Unix timestamp of session opening
  • When subscriber started watching
  • Example: 1714233600 (April 28, 2024, 10:00:00 UTC)

  • closedAt — Unix timestamp of session closing

  • When stream was stopped
  • Null for active sessions
  • Example: 1714237200

  • updatedAt — Unix timestamp of last update

  • Updated periodically during viewing
  • Used to determine "dead" connections

Network information:

  • ip — subscriber's IP address
  • Example: 192.168.1.100, 2001:db8::1
  • Used for geolocation and anomaly detection

  • userAgent — player User-Agent string

  • Identifies device and application
  • Examples:
    • VLC/3.0.16
    • Mozilla/5.0 (Linux; Android 11) AppleWebKit/537.36
    • Catena/1.0 (Android 11; Samsung SM-G991B)

Statistics:

  • active — session activity flag
  • true — session open, viewing in progress
  • false — session closed, viewing finished

  • bytes — data transferred in bytes

  • Updated during viewing
  • Example: 5242880000 (5 GB)
  • Used for traffic billing

  • token — subscriber's playback token

  • Used by streaming server for authorization
  • Example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Device:

  • deviceId — device identifier
  • If app sends device ID
  • Example: device_android_samsung_s21
  • Helps track number of devices per subscriber

Getting Session List

Basic Request

Get list of all sessions:

curl -X GET https://your-catena-domain.com/tv-management/api/v1/play-sessions \
  -H "X-Auth-Token: your-api-key"

Response:

{
  "sessions": [
    {
      "sessionId": "sessKl9SW3AAAE.",
      "subscriberId": "sKl9SW3AAAE.",
      "channelId": "chKl9SW3AAAE.",
      "channelName": "sport1",
      "programId": null,
      "portalId": "pKl9SW3AAAE.",
      "openedAt": 1714233600,
      "closedAt": null,
      "updatedAt": 1714237200,
      "active": true,
      "bytes": 1073741824,
      "ip": "192.168.1.100",
      "userAgent": "Catena/1.0 (Android 11)",
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "deviceId": "device_123"
    },
    {
      "sessionId": "sessKl9SW3AAAB.",
      "subscriberId": "sKl9SW3AAAB.",
      "channelId": "chKl9SW3AAAB.",
      "channelName": "news-hd",
      "programId": null,
      "portalId": "pKl9SW3AAAE.",
      "openedAt": 1714230000,
      "closedAt": 1714233600,
      "updatedAt": 1714233600,
      "active": false,
      "bytes": 524288000,
      "ip": "10.0.0.50",
      "userAgent": "VLC/3.0.16",
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "deviceId": null
    }
  ],
  "next": "cursor-for-next-page"
}

Pagination

For large data volumes, cursor-based pagination is used:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?cursor=cursor-for-next-page" \
  -H "X-Auth-Token: your-api-key"

Recommendations:

  • Process data page by page
  • Use filters to reduce volume
  • For periodic monitoring, query only active sessions

Session Filtering

By Subscriber

Get all sessions for specific subscriber:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?subscriberId=sKl9SW3AAAE." \
  -H "X-Auth-Token: your-api-key"

Applications:

  • View specific user history
  • Debug subscriber issues
  • Analyze viewing patterns

Multiple subscribers:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?subscriberId=sKl9SW3AAAE.&subscriberId=sKl9SW3AAAB." \
  -H "X-Auth-Token: your-api-key"

By Channel

Get all sessions for specific channel:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?channelId=chKl9SW3AAAE." \
  -H "X-Auth-Token: your-api-key"

Applications:

  • Determine channel popularity
  • Analyze channel load peaks
  • Debug specific channel issues

Multiple channels:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?channelId=chKl9SW3AAAE.&channelId=chKl9SW3AAAB." \
  -H "X-Auth-Token: your-api-key"

By Activity Status

Only active sessions (who is watching now):

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?active=true" \
  -H "X-Auth-Token: your-api-key"

Only completed sessions (history):

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?active=false" \
  -H "X-Auth-Token: your-api-key"

Applications:

  • active=true — real-time monitoring
  • active=false — history analysis, report building

By Time

Sessions opened after specific time:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?opened_at_gte=1714233600" \
  -H "X-Auth-Token: your-api-key"

Sessions opened before specific time:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?opened_at_lt=1714320000" \
  -H "X-Auth-Token: your-api-key"

Sessions in time interval:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?opened_at_gte=1714233600&opened_at_lt=1714320000" \
  -H "X-Auth-Token: your-api-key"

Applications:

  • Analyze views for specific period
  • Build time-based graphs
  • Identify peak hours

Converting dates to Unix timestamp:

# Current date/time
date +%s
# Result: 1714233600

# Specific date (GNU date)
date -d "2024-04-28 10:00:00" +%s

# macOS
date -j -f "%Y-%m-%d %H:%M:%S" "2024-04-28 10:00:00" +%s

Combined Filters

Active sessions for specific subscriber:

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?subscriberId=sKl9SW3AAAE.&active=true" \
  -H "X-Auth-Token: your-api-key"

Channel sessions for last 24 hours:

# Current time minus 24 hours
TIMESTAMP_24H_AGO=$(date -d '24 hours ago' +%s)

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?channelId=chKl9SW3AAAE.&opened_at_gte=$TIMESTAMP_24H_AGO" \
  -H "X-Auth-Token: your-api-key"

Typical Use Cases

Scenario 1: Real-time Monitoring

Task: Display dashboard with current viewers

Solution:

#!/bin/bash
# realtime-dashboard.sh

API_URL="https://catena.example.com/tv-management/api/v1"
API_KEY="your-api-key"

while true; do
  # Get active sessions
  RESPONSE=$(curl -s -X GET "$API_URL/play-sessions?active=true" \
    -H "X-Auth-Token: $API_KEY")

  # Total viewers
  TOTAL_VIEWERS=$(echo $RESPONSE | jq '.sessions | length')

  # Top-5 popular channels
  TOP_CHANNELS=$(echo $RESPONSE | jq -r '.sessions | group_by(.channelName) | 
    map({channel: .[0].channelName, viewers: length}) | 
    sort_by(.viewers) | reverse | .[0:5]')

  clear
  echo "=== Current Viewers ==="
  echo "Total: $TOTAL_VIEWERS"
  echo ""
  echo "Top channels:"
  echo "$TOP_CHANNELS" | jq -r '.[] | "\(.channel): \(.viewers) viewers"'

  sleep 10
done

Python version with Prometheus metrics:

import requests
import time
from prometheus_client import Gauge, start_http_server

# Metrics
active_sessions = Gauge('catena_active_sessions', 'Number of active sessions')
channel_viewers = Gauge('catena_channel_viewers', 'Viewers per channel', ['channel'])

API_URL = "https://catena.example.com/tv-management/api/v1"
API_KEY = "your-api-key"

def update_metrics():
    response = requests.get(
        f"{API_URL}/play-sessions?active=true",
        headers={"X-Auth-Token": API_KEY}
    )

    sessions = response.json()['sessions']

    # Update total count
    active_sessions.set(len(sessions))

    # Count by channels
    channels = {}
    for session in sessions:
        channel = session['channelName']
        channels[channel] = channels.get(channel, 0) + 1

    # Update channel metrics
    for channel, count in channels.items():
        channel_viewers.labels(channel=channel).set(count)

if __name__ == '__main__':
    # Start HTTP server for Prometheus
    start_http_server(8000)

    while True:
        update_metrics()
        time.sleep(30)

Scenario 2: Subscriber Issue Debugging

Task: Subscriber complains they can't watch channel

Debugging steps:

  1. Check subscriber's active sessions:
curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?subscriberId=sKl9SW3AAAE.&active=true" \
  -H "X-Auth-Token: your-api-key"

Analysis: - If no sessions — authorization or network issue - If session exists — check updatedAt (recently updated?) - Check IP and userAgent — match subscriber's device?

  1. Check recent session history:
# Last 1 hour
TIMESTAMP_1H_AGO=$(date -d '1 hour ago' +%s)

curl -X GET "https://your-catena-domain.com/tv-management/api/v1/play-sessions?subscriberId=sKl9SW3AAAE.&opened_at_gte=$TIMESTAMP_1H_AGO" \
  -H "X-Auth-Token: your-api-key"

What to look for: - Frequent reconnections (many short sessions) - Low data transfer (streaming issues) - Different IP addresses (subscriber switching networks)

  1. Check if subscriber can watch specific channel:
# Check subscriptions
curl -X GET "https://your-catena-domain.com/tv-management/api/v1/subscribers/sKl9SW3AAAE." \
  -H "X-Auth-Token: your-api-key" \
  | jq '.packages'

# Check which packages have this channel
curl -X GET "https://your-catena-domain.com/tv-management/api/v1/channels/chKl9SW3AAAE." \
  -H "X-Auth-Token: your-api-key" \
  | jq '.packages'

Best Practices

Periodic Data Collection

Recommendations:

  • Active sessions: poll every 30-60 seconds for monitoring
  • History: collect once daily for analysis
  • Archiving: move old data (>30 days) to cold storage

Example cron jobs:

# Every minute — monitor active sessions
*/1 * * * * /usr/local/bin/monitor-active-sessions.sh

# Every hour — collect statistics
0 * * * * /usr/local/bin/collect-hourly-stats.sh

# Daily at 01:00 — generate reports
0 1 * * * /usr/local/bin/generate-daily-report.sh

Query Optimization

Use filters to reduce data volume:

# BAD — get all sessions
curl -X GET "$API_URL/play-sessions"

# GOOD — only active
curl -X GET "$API_URL/play-sessions?active=true"

# BETTER — active from last hour
TIMESTAMP_1H=$(date -d '1 hour ago' +%s)
curl -X GET "$API_URL/play-sessions?active=true&opened_at_gte=$TIMESTAMP_1H"

Troubleshooting

Sessions Not Created

Problem: Subscribers watching but sessions don't appear in API

Possible causes:

  1. Streaming server not integrated with Management API
  2. Incorrect webhook configuration on streaming server
  3. Network issues between servers

Solution:

  1. Check streaming server (Flussonic) configuration
  2. Ensure webhook configured for Management API
  3. Check streaming server logs for errors

Sessions Not Closing

Problem: Sessions remain active after viewing stopped

Causes:

  • Subscriber closed app without proper stream stop
  • Network connection lost
  • Streaming server didn't send closing webhook

Solution:

  • Sessions have timeout (usually 5-10 minutes of inactivity)
  • Check updatedAt field — if not updated recently, session is "dead"
  • Configure automatic cleanup of "stuck" sessions

See Also