---
name: fullstory-media-entertainment
version: v2
description: Industry-specific guide for implementing Fullstory in media, entertainment, and streaming applications. Covers subscription funnel optimization, content engagement tracking, video player UX, paywall optimization, and ad-supported vs subscription models. Includes detailed examples for streaming services, news sites, gaming platforms, and content creators.
related_skills:
- fullstory-privacy-controls
- fullstory-privacy-strategy
- fullstory-analytics-events
- fullstory-user-properties
- fullstory-element-properties
---
# Fullstory for Media & Entertainment
> ⚠️ **LEGAL DISCLAIMER**: This guidance is for educational purposes only and does not constitute legal, compliance, or regulatory advice. Media applications may be subject to various regulations (GDPR, CCPA, COPPA for children's content, accessibility requirements). Always consult with your legal and compliance teams before implementing any data capture solution. Your organization is responsible for ensuring compliance with all applicable regulations.
## Industry Overview
Media and entertainment have unique characteristics for session analytics:
- **Engagement focus**: Time spent, content consumed, completion rates
- **Subscription models**: Free vs. paid, trial conversions, churn prevention
- **Content discovery**: Recommendations, search, browsing patterns
- **Ad-supported models**: Ad viewability, skip rates, revenue optimization
- **Multi-device**: TV, mobile, web, tablet experiences
- **Personalization**: Recommendation effectiveness, preference learning
### Key Goals for Media Implementations
1. **Optimize subscription conversion** and reduce churn
2. **Understand content engagement** patterns
3. **Improve content discovery** and recommendations
4. **Reduce friction** in video playback experience
5. **Optimize paywall** placement and messaging
6. **Track cross-device** user journeys
---
## What Can Be Captured in Media
| Data Type | Capture? | Privacy Level | Notes |
|-----------|----------|---------------|-------|
| Content viewed (titles) | ✅ Yes | Unmask | Core analytics |
| Watch time / progress | ✅ Yes | Unmask | Engagement metrics |
| Search queries | ✅ Yes | Unmask | Content discovery |
| Browse behavior | ✅ Yes | Unmask | Recommendation analysis |
| Subscription plan | ✅ Yes | Unmask | Segmentation |
| User preferences | ✅ Yes | Unmask | Product data |
| Ratings/reviews | ⚠️ Consider | Mask if user visible | User-generated |
| User names | ⚠️ Mask | Mask | PII |
| Email | ⚠️ Consider | Hash/Mask | For identification |
| Payment details | ❌ Never | Exclude | PCI |
| Children's data | ❌ Never | Exclude | COPPA |
### Special Consideration: COPPA Compliance
If your platform serves children under 13:
- ❌ Do NOT use Fullstory on children's profiles
- ❌ Do NOT capture any data about children's viewing habits
- ✅ Only capture data for verified adult accounts
### Accessibility Feature Tracking
Media platforms must track accessibility feature usage to ensure compliance with WCAG/ADA requirements and improve experiences for all users:
| Accessibility Feature | Track? | Why |
|----------------------|--------|-----|
| **Closed captions/subtitles** | ✅ Yes | Engagement with CC content |
| **Audio descriptions** | ✅ Yes | Usage rates, content coverage |
| **Playback speed** | ✅ Yes | Accessibility and preference |
| **Screen reader compatibility** | ⚠️ Consider | May need special implementation |
| **Keyboard navigation** | ✅ Yes | Identifies non-mouse users |
| **Font size/contrast settings** | ✅ Yes | Accessibility preference adoption |
| **Disability status** | ❌ Never | Sensitive PII |
```javascript
// Track accessibility feature usage
FS('trackEvent', {
name: 'accessibility_feature_enabled',
properties: {
feature: 'closed_captions',
language: 'en',
content_type: 'movie',
content_id: 'mov_12345',
first_time: true, // Is this the first time this user enabled CC?
// Helps identify accessibility feature adoption and content gaps
}
});
// Track accessibility journey patterns
FS('setProperties', {
type: 'user',
properties: {
uses_captions: true,
uses_audio_descriptions: false,
preferred_playback_speed: 1.0,
// Never track WHY they use these features, only THAT they do
}
});
```
> **Important**: Track accessibility feature usage to improve coverage and experience, but NEVER ask or infer why users need these features.
---
## Implementation Architecture
### Privacy Zones for Media
```
┌─────────────────────────────────────────────────────────────────┐
│ MEDIA APPLICATION │
├─────────────────────────────────────────────────────────────────┤
│ FULLY VISIBLE (fs-unmask) │
│ • Content catalog and browse UI │
│ • Video player controls │
│ • Search interface and results │
│ • Content details (titles, descriptions) │
│ • Subscription plans and pricing │
│ • Recommendation carousels │
│ • Navigation and menus │
│ • Error messages │
├─────────────────────────────────────────────────────────────────┤
│ MASKED (fs-mask) │
│ • User display names │
│ • Profile names │
│ • User-generated content (reviews, comments) │
│ • Email addresses │
│ • Custom playlist names │
├─────────────────────────────────────────────────────────────────┤
│ EXCLUDED (fs-exclude) │
│ • Payment card details │
│ • Billing address │
│ • Password fields │
│ • Children's profiles │
│ • Private messages │
│ • Gift card codes │
└─────────────────────────────────────────────────────────────────┘
```
### User Identification Pattern
```javascript
// Media: Identify by account, track viewing behavior
function onLogin(user) {
// Check for children's profile - DO NOT track
if (user.profile.isKids) {
FS('shutdown');
return;
}
FS('setIdentity', {
uid: user.accountId,
displayName: user.profile.name // Profile name, not real name
});
FS('setProperties', {
type: 'user',
properties: {
// Subscription info
subscription_plan: user.subscription.plan, // "free", "basic", "standard", "premium"
subscription_status: user.subscription.status, // "active", "trial", "cancelled", "paused"
is_trial: user.subscription.isTrial,
trial_days_remaining: user.subscription.trialDaysRemaining,
subscription_tenure_months: getMonthsSince(user.subscription.startDate),
// Account info
account_age_days: daysSince(user.createdAt),
profiles_count: user.profilesCount,
is_family_plan: user.isFamilyPlan,
// Engagement metrics
content_watched_30d: user.contentWatched30d,
hours_watched_30d: user.hoursWatched30d,
days_active_30d: user.daysActive30d,
// Preferences
preferred_genres: user.topGenres.slice(0, 3), // Top 3 genres
preferred_content_type: user.preferredType, // "movies", "series", "documentaries"
language: user.preferredLanguage,
// Platform usage
primary_device: user.primaryDevice, // "tv", "mobile", "web"
download_enabled: user.hasDownloads,
// Marketing
email_subscribed: user.emailOptIn
}
});
}
```
---
## Page-Specific Implementations
### Browse / Home Page
```html
Stranger Things
TV-14 · 4 Seasons · Sci-Fi, Horror
When a young boy vanishes...
Continue Watching
Breaking Bad
S2 E5 · 35 min remaining
Because You Watched "Breaking Bad"
Better Call Saul
98% Match
Trending Now
1
```
```javascript
// Browse page tracking
FS('setProperties', {
type: 'page',
properties: {
page_type: 'browse_home',
profile_type: 'adult', // never "kids"
content_rows_visible: 8,
has_continue_watching: continueWatching.length > 0,
hero_content_id: heroContent.id,
hero_content_type: heroContent.type
}
});
// Content row visibility (scroll tracking)
function onRowVisible(row) {
FS('trackEvent', {
name: 'content_row_viewed',
properties: {
row_title: row.title,
row_type: row.type, // "continue_watching", "recommendation", "trending", "genre"
row_position: row.position,
cards_in_row: row.contentCount,
cards_visible: row.visibleCount
}
});
}
// Carousel interaction
function onCarouselScroll(row, direction) {
FS('trackEvent', {
name: 'carousel_scrolled',
properties: {
row_title: row.title,
row_type: row.type,
direction: direction, // "left", "right"
cards_scrolled: cardsScrolled
}
});
}
// Content hover (shows engagement)
function onContentHover(content) {
FS('trackEvent', {
name: 'content_hover',
properties: {
content_id: content.id,
content_title: content.title,
content_type: content.type,
row_type: content.rowType,
position_in_row: content.position,
hover_duration_ms: hoverDuration
}
});
}
```
### Content Detail Page
```html
Breaking Bad
98% Match
2008
TV-MA
5 Seasons
A high school chemistry teacher turned methamphetamine manufacturer...
Starring: Bryan Cranston, Aaron Paul, Anna Gunn
Creator: Vince Gilligan
Dark
Suspenseful
Crime Drama
1. Seven Thirty-Seven
47 min
Walt and Jesse face the deadly consequences...
```
```javascript
// Content detail tracking
FS('setProperties', {
type: 'page',
properties: {
page_type: 'content_detail',
content_id: content.id,
content_title: content.title,
content_type: content.type, // "movie", "series"
genre: content.primaryGenre,
release_year: content.year,
rating: content.rating, // "TV-MA", "PG-13"
seasons: content.seasons,
is_in_my_list: content.inMyList,
user_progress_percent: content.userProgress
}
});
// Content detail interactions
function onAddToList(content) {
FS('trackEvent', {
name: 'content_added_to_list',
properties: {
content_id: content.id,
content_title: content.title,
content_type: content.type,
source: 'detail_page'
}
});
}
function onRating(content, rating) {
FS('trackEvent', {
name: 'content_rated',
properties: {
content_id: content.id,
content_title: content.title,
rating_type: rating // "like", "dislike", "love"
}
});
}
function onEpisodeSelect(episode) {
FS('trackEvent', {
name: 'episode_selected',
properties: {
content_id: episode.seriesId,
season: episode.season,
episode: episode.episode,
selection_method: 'episode_list'
}
});
}
```
### Video Player
```html
23:45 / 52:10
Next Episode in 5 seconds
```
```javascript
// Video player tracking - Rich engagement data
function onPlaybackStart(content) {
FS('trackEvent', {
name: 'playback_started',
properties: {
content_id: content.id,
content_title: content.title,
content_type: content.type,
season: content.season,
episode: content.episode,
start_position_seconds: startPosition,
is_resume: startPosition > 0,
playback_quality: quality,
device_type: deviceType,
source: playbackSource // "browse", "search", "continue_watching", "recommendation"
}
});
}
// Periodic progress tracking (every 25%)
function onPlaybackProgress(content, progress) {
FS('trackEvent', {
name: 'playback_progress',
properties: {
content_id: content.id,
progress_percent: progress, // 25, 50, 75, 100
watch_time_seconds: watchTime,
playback_quality: currentQuality
}
});
}
function onPlaybackComplete(content) {
FS('trackEvent', {
name: 'playback_completed',
properties: {
content_id: content.id,
content_title: content.title,
total_watch_time_seconds: totalWatchTime,
content_duration_seconds: duration,
completion_percent: (totalWatchTime / duration) * 100,
skipped_intro: skippedIntro,
skipped_recap: skippedRecap,
quality_changes: qualityChanges,
buffering_events: bufferingCount,
total_buffering_seconds: totalBufferTime
}
});
}
// Player interactions
function onSkipIntro() {
FS('trackEvent', {
name: 'player_interaction',
properties: {
action: 'skip_intro',
content_id: content.id,
timestamp_seconds: currentTime
}
});
}
function onSeek(fromTime, toTime) {
FS('trackEvent', {
name: 'player_interaction',
properties: {
action: 'seek',
content_id: content.id,
seek_from_seconds: fromTime,
seek_to_seconds: toTime,
seek_direction: toTime > fromTime ? 'forward' : 'backward'
}
});
}
function onQualityChange(oldQuality, newQuality, manual) {
FS('trackEvent', {
name: 'player_interaction',
properties: {
action: 'quality_change',
content_id: content.id,
from_quality: oldQuality,
to_quality: newQuality,
is_manual: manual, // vs adaptive
timestamp_seconds: currentTime
}
});
}
function onSubtitlesToggle(enabled, language) {
FS('trackEvent', {
name: 'player_interaction',
properties: {
action: enabled ? 'subtitles_on' : 'subtitles_off',
content_id: content.id,
subtitle_language: language
}
});
}
// Playback issues
function onBuffering(duration) {
FS('trackEvent', {
name: 'playback_issue',
properties: {
issue_type: 'buffering',
content_id: content.id,
buffering_duration_ms: duration,
timestamp_seconds: currentTime,
current_quality: quality
}
});
}
function onPlaybackError(error) {
FS('trackEvent', {
name: 'playback_issue',
properties: {
issue_type: 'error',
error_category: categorizePlaybackError(error),
content_id: content.id,
timestamp_seconds: currentTime
}
});
}
```
### Search
```html
```
```javascript
// Search tracking
function onSearch(query, results) {
FS('trackEvent', {
name: 'content_search',
properties: {
search_query: query,
search_type: 'text', // or "voice"
result_count: results.total,
title_results: results.titles,
people_results: results.people,
genre_results: results.genres,
has_results: results.total > 0
}
});
}
function onSearchResultClick(result, query) {
FS('trackEvent', {
name: 'search_result_clicked',
properties: {
search_query: query,
content_id: result.id,
content_title: result.title,
result_type: result.type, // "title", "person", "genre"
result_position: result.position
}
});
}
```
### Subscription / Paywall
```html
Choose Your Plan
Watch on any device. Cancel anytime.
Basic
$8.99/month
- ✓ Unlimited movies & TV
- ✓ Watch on 1 device
- ✗ HD not available
- ✗ No downloads
Most Popular
Standard
$13.99/month
- ✓ Unlimited movies & TV
- ✓ Watch on 2 devices
- ✓ HD available
- ✓ Download on 2 devices
Premium
$19.99/month
- ✓ Unlimited movies & TV
- ✓ Watch on 4 devices
- ✓ 4K + HDR available
- ✓ Download on 6 devices
```
```javascript
// Subscription tracking
FS('setProperties', {
type: 'page',
properties: {
page_type: 'subscription',
current_status: user.subscription.status, // "free", "trial", "cancelled"
referrer: subscriptionReferrer // "paywall", "settings", "trial_end"
}
});
function onPlanSelect(plan) {
FS('trackEvent', {
name: 'subscription_plan_selected',
properties: {
plan_name: plan.name,
plan_price: plan.price,
billing_cycle: billingCycle,
is_upgrade: isUpgrade(currentPlan, plan)
}
});
}
function onSubscriptionComplete(subscription) {
FS('trackEvent', {
name: 'subscription_started',
properties: {
plan_name: subscription.plan,
plan_price: subscription.price,
billing_cycle: subscription.billingCycle,
payment_method: subscription.paymentMethod,
is_trial: subscription.isTrial,
conversion_source: conversionSource, // "paywall", "homepage_cta", "trial_end"
// Journey info
sessions_before_conversion: sessionsBeforeConversion,
days_since_signup: daysSinceSignup,
content_viewed_before_conversion: contentViewedCount
}
});
}
// Paywall tracking
function onPaywallShown(context) {
FS('trackEvent', {
name: 'paywall_shown',
properties: {
paywall_type: context.type, // "hard", "soft", "trial_end"
content_blocked: context.content?.title,
trigger: context.trigger // "content_limit", "feature_access", "trial_expired"
}
});
}
function onPaywallDismiss(context) {
FS('trackEvent', {
name: 'paywall_dismissed',
properties: {
paywall_type: context.type,
dismiss_method: context.method // "close_button", "back_navigation", "click_outside"
}
});
}
```
---
## News/Publishing Patterns
For news and publishing sites:
```javascript
// Article tracking
FS('setProperties', {
type: 'page',
properties: {
page_type: 'article',
article_id: article.id,
article_title: article.title,
article_category: article.category,
article_author: article.author,
publish_date: article.publishDate,
word_count: article.wordCount,
has_paywall: article.isPremium,
is_premium_content: article.isPremium
}
});
// Reading progress
function onReadingProgress(percent) {
FS('trackEvent', {
name: 'article_read_progress',
properties: {
article_id: article.id,
progress_percent: percent, // 25, 50, 75, 100
read_time_seconds: readTime
}
});
}
// Metered paywall
function onArticleLimitReached() {
FS('trackEvent', {
name: 'article_limit_reached',
properties: {
articles_read_this_month: articlesRead,
limit: articleLimit
}
});
}
```
---
## Ad-Supported Model Patterns
For ad-supported streaming/content:
```javascript
// Ad tracking (for your analytics, not ad tracking)
function onAdStart(ad) {
FS('trackEvent', {
name: 'ad_started',
properties: {
ad_position: ad.position, // "pre_roll", "mid_roll", "post_roll"
ad_duration_seconds: ad.duration,
content_id: currentContent.id,
content_timestamp: contentTimestamp,
is_skippable: ad.skippable
}
});
}
function onAdSkipped(ad) {
FS('trackEvent', {
name: 'ad_skipped',
properties: {
ad_position: ad.position,
seconds_watched_before_skip: watchedBeforeSkip,
content_id: currentContent.id
}
});
}
function onAdCompleted(ad) {
FS('trackEvent', {
name: 'ad_completed',
properties: {
ad_position: ad.position,
ad_duration_seconds: ad.duration,
content_id: currentContent.id
}
});
}
// Upgrade prompt (for ad-supported to paid)
function onUpgradeToAdFreePrompt() {
FS('trackEvent', {
name: 'upgrade_prompt_shown',
properties: {
prompt_type: 'ad_free',
trigger: 'ad_frequency', // after X ads
content_id: currentContent.id
}
});
}
```
---
## Churn Prevention Signals
```javascript
// Engagement signals for churn prediction
FS('setProperties', {
type: 'user',
properties: {
// Activity metrics
days_since_last_watch: daysSinceLastWatch,
watch_frequency: getWatchFrequency(), // "daily", "weekly", "monthly", "rare"
hours_watched_7d: hoursWatched7d,
hours_watched_30d: hoursWatched30d,
// Content engagement
titles_started_30d: titlesStarted,
titles_completed_30d: titlesCompleted,
completion_rate: titlesCompleted / titlesStarted,
// Feature usage
uses_downloads: hasDownloads,
uses_profiles: profilesCount > 1,
uses_my_list: myListCount > 0,
// Subscription health
payment_failures_90d: paymentFailures,
contacted_support_30d: contactedSupport
}
});
// Cancellation flow tracking
function onCancellationInitiated(reason) {
FS('trackEvent', {
name: 'cancellation_initiated',
properties: {
cancellation_reason: reason, // "price", "not_using", "content", "switching"
subscription_tenure_days: tenureDays,
last_watch_days_ago: daysSinceLastWatch
}
});
}
function onCancellationCompleted() {
FS('trackEvent', {
name: 'cancellation_completed',
properties: {
save_offer_shown: saveOfferShown,
save_offer_accepted: saveOfferAccepted
}
});
}
function onCancellationSaved(offer) {
FS('trackEvent', {
name: 'cancellation_saved',
properties: {
save_offer_type: offer.type, // "discount", "pause", "downgrade"
offer_value: offer.value
}
});
}
```
---
## KEY TAKEAWAYS FOR AGENT
When helping media clients with Fullstory:
1. **Content engagement is core**: Track views, progress, completions, interactions
2. **Subscription conversion is critical**: Track full funnel from browse to paid
3. **Video player interactions are valuable**: Skip, seek, quality, subtitles
4. **COPPA compliance**: Never track children's profiles
5. **Payment details excluded**: Standard PCI compliance
6. **Recommendations tracking**: Understand what drives content discovery
### Questions to Ask Media Clients
1. "Do you have children's profiles that need special handling?"
2. "Are you tracking video playback events comprehensively?"
3. "How are you measuring subscription conversion funnel?"
4. "Do you have ad-supported tiers to track?"
5. "How do you define 'engagement' for churn prediction?"
### Key Metrics to Track
- Browse-to-play conversion
- Content completion rates
- Time to first play (onboarding)
- Subscription conversion rate
- Trial-to-paid conversion
- Churn indicators (declining watch time)
- Recommendation effectiveness
---
## REFERENCE LINKS
- **COPPA Compliance**: https://www.ftc.gov/legal-library/browse/rules/childrens-online-privacy-protection-rule-coppa
- **Fullstory Analytics Events**: ../core/fullstory-analytics-events/SKILL.md
- **User Properties**: ../core/fullstory-user-properties/SKILL.md
- **Privacy Controls**: ../core/fullstory-privacy-controls/SKILL.md
---
*This skill document is specific to media and entertainment implementations. Ensure COPPA compliance if serving children.*