Tapemetric

Live events / Shows

Live shows — concerts, awards, talk shows

Segment-aware analytics for any live event that isn't a sports match. Audience engagement is first-class — votes, polls, reactions, chat, donations, super-chat.

How shows differ from sports

Sports have phases and a score. Shows have segments and engagement. The dashboard renders these differently:

  • A wicket or goal becomes a marker on the timeline. A segment change becomes a segment_start marker plus a new bar on the segment-retention chart.
  • Score progression matters in sports. It doesn’t in shows — what matters is which segments held the audience and which lost them.
  • Audience reactions are passive in sports. In shows they’re active — viewers vote, react, donate, super-chat. We capture those as first-class engagement events, not just generic markers.

Concept: the active show context

Calling startLiveShow(ctx) on the SDK installs a show context that the SDK stamps onto every event you emit until you call stopLiveShow(). This works just like the live-match context but with show-flavored fields — and it auto-stamps the current live_segment and live_segment_index so retention queries can correlate every event with which segment was on screen.

typescript
type LiveShowContext = {
  eventId: string;        // = the match_id you registered + content_id you send
  segment?: string;       // free-form segment name e.g. 'Best Actor'
  segmentIndex?: number;  // zero-based ordering, useful for sorting
  getLatencyMs?: () => number | undefined; // sampled per event
};

Concert example

Concerts are mostly performance-driven. Use segments to mark each artist or set, and reactions to gauge audience response in real-time. Donations are common for ticketed virtual concerts.

typescript
import Tapemetric from '@tapemetric/analytics';

const tm = Tapemetric.init({ apiKey: 'tm_live_yourkey' });

// Viewer joins
tm.startLiveShow({
  eventId: 'arijit_singh_live_2026',
  segment: 'pre_show',
  segmentIndex: 0,
  getLatencyMs: () => Math.round((hls.liveSyncPosition - video.currentTime) * 1000),
});

tm.trackPlayStart({
  contentId: 'arijit_singh_live_2026',
  contentType: 'live',
});

// Set 1 begins — fires segment_start marker, updates auto-stamp
tm.setSegment('Set 1 — Tum Hi Ho medley', 1);

// Audience reactions
tm.trackReaction('heart');
tm.trackReaction('fire');

// A super-chat tip during the encore
tm.setSegment('Encore — Channa Mereya', 5);
tm.trackDonation(500, { display_name: 'Riya', message_length: 24 });

tm.stopLiveShow();

Awards show example

typescript
tm.startLiveShow({
  eventId: 'filmfare_2026',
  segment: 'red_carpet',
  segmentIndex: 0,
});

tm.trackPlayStart({ contentId: 'filmfare_2026', contentType: 'live' });

// Hosts come on
tm.setSegment('Opening monologue', 1);

// People's choice voting opens
tm.trackShowMarker('vote_open', 'Best film — public vote');
tm.trackPoll('best_film_2026', 'Animal');
tm.trackPoll('best_film_2026', 'Jawan');
tm.trackShowMarker('vote_close', 'Best film — public vote');

// Best Actor segment
tm.setSegment('Best Actor', 4);
tm.trackShowMarker('winner_announced', 'Best Actor — Shah Rukh Khan');
tm.trackReaction('clap');

// In Memoriam
tm.setSegment('In Memoriam', 8);

tm.stopLiveShow();

Talk show with live polls

typescript
tm.startLiveShow({
  eventId: 'koffee_with_karan_s8e12',
  segment: 'opening',
  segmentIndex: 0,
});

// Move to Rapid Fire round
tm.setSegment('Rapid Fire', 3);

// Chat metadata only — never the message body
tm.trackChatMessage({ length: 42, has_emoji: true });

// Audience poll embedded in player
tm.trackPoll('best_guest_appearance', 'Deepika Padukone');

// Vote for next week's guest
tm.trackVote('Ranveer Singh', { context: 'next_week_guest' });

tm.stopLiveShow();

iOS

swift
import TapemetricAnalytics

Tapemetric.shared.startLiveShow(
    eventId: "filmfare_2026",
    segment: "red_carpet",
    segmentIndex: 0,
    getLatencyMs: { [weak self] in
        guard let p = self?.player else { return nil }
        return Int(p.liveLatencySeconds * 1000)
    }
)

Tapemetric.shared.setSegment("Best Actor", index: 4)

Tapemetric.shared.trackShowMarker(
    kind: "winner_announced",
    label: "Best Actor — Shah Rukh Khan"
)

Tapemetric.shared.trackReaction(kind: "clap")
Tapemetric.shared.trackDonation(amountInr: 500.0)

Tapemetric.shared.stopLiveShow()

Android

kotlin
import com.tapemetric.analytics.Tapemetric

Tapemetric.startLiveShow(
    eventId = "koffee_with_karan_s8e12",
    segment = "opening",
    segmentIndex = 0
)

Tapemetric.setSegment("Rapid Fire", index = 3)

Tapemetric.trackPoll("best_guest_appearance", "Deepika Padukone")
Tapemetric.trackReaction("fire")
Tapemetric.trackChatMessage(mapOf("length" to 42, "has_emoji" to true))

Tapemetric.stopLiveShow()

Engagement event reference

MethodEvent typeUse it for
trackVote(option)voteSingle-pick votes — best song, fan favourite, next-week guest
trackPoll(pollId, choice)poll_responseMulti-question polls during a show
trackReaction(kind)reactionEmoji reactions during performances
trackChatMessage(props)chat_messageChat metadata only (length, has_emoji) — not the body
trackDonation(amount)donationTips / super-chat with INR amount
trackShowMarker(kind, label)live_markerCustom moments — winner announced, encore, host change
Privacy note. Don’t send the chat message body to trackChatMessage. Send length and emoji presence as properties; the message text has no analytics value and creates a privacy problem.

Segment retention algorithm

The retention chart is computed by collecting all distinct anonymous_id values per segment, then taking the set intersection with the previous segment to compute "held_from_previous". Hold rate is intersection size / previous segment size. This is more meaningful than a sliding-window concurrency view because it captures viewer-level continuity — a viewer who left at the In Memoriam segment and came back for Best Picture counts as having dropped, not held.

Segments endpoint

bash
GET /v1/live/matches/{id}/segments
Authorization: Bearer eyJ...

200 OK
{
  "match_id": "filmfare_2026",
  "title": "Filmfare Awards 2026",
  "kind": "awards",
  "segments": [
    { "index": 0, "label": "red_carpet",
      "viewers": 250000, "held_from_previous": null, "hold_rate": null },
    { "index": 1, "label": "Opening monologue",
      "viewers": 410000, "held_from_previous": 230000, "hold_rate": 0.92 },
    { "index": 4, "label": "Best Actor",
      "viewers": 580000, "held_from_previous": 380000, "hold_rate": 0.95 },
    { "index": 8, "label": "In Memoriam",
      "viewers": 380000, "held_from_previous": 320000, "hold_rate": 0.65 }
  ]
}

Engagement endpoint

bash
GET /v1/live/matches/{id}/engagement
Authorization: Bearer eyJ...

200 OK
{
  "match_id": "filmfare_2026",
  "title": "Filmfare Awards 2026",
  "kind": "awards",
  "engagement": {
    "vote":          { "count": 47210,  "unique_users": 32104 },
    "poll_response": { "count": 18933,  "unique_users": 14889 },
    "reaction":      { "count": 142550, "unique_users": 38120 },
    "chat_message":  { "count": 23005,  "unique_users": 9180  },
    "donation":      { "count": 412,    "unique_users": 387   }
  }
}

Operational best practices

  • Plan segments before broadcast. A rough rundown with 10–20 segments works well. Too few and the retention curve is uninformative; too many and the dashboard gets noisy.
  • Use stable segment names. 'Best Actor' not 'Best Actor (40 min in)'. The dashboard groups by exact label.
  • Throttle reactions. If your UI lets viewers tap a heart 10 times per second, throttle to one per second on the client. Otherwise a hundred-thousand viewer concert generates a million events per second of reactions.
  • Pair vote_open / vote_close markers with the actual voting window so you can compute participation rate (votes / unique viewers during the window).
  • For watch parties, set kind: 'watch_party' and use segments for the underlying content’s natural breaks (episode 1, episode 2). The host’s commentary sits in 'host_change' markers.

When to use match vs show kind

If the event has teams and a score, use kind: 'match'. If it has segments and audience interaction, use kind: 'show' (or one of the more specific kinds). For hybrid events — say a cricket exhibition with celebrity halftime performances — pick whichever metric matters more for your business and use markers/segments to capture the rest. The dashboard renders one or the other; it doesn’t switch mid-event.