--- 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

When a young boy vanishes...

Continue Watching

Because You Watched "Breaking Bad"

Trending Now

Action & Adventure

``` ```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

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

Top Searches

Results for "bryan cranston"

Titles

Breaking Bad

Breaking Bad

Malcolm in the Middle

Malcolm in the Middle

People

Bryan Cranston

Bryan Cranston

Actor, Producer

``` ```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

Premium

$19.99/month

  • ✓ Unlimited movies & TV
  • ✓ Watch on 4 devices
  • ✓ 4K + HDR available
  • ✓ Download on 6 devices

Payment Details

By clicking below, you agree to our Terms of Service and Privacy Policy.

Your subscription will auto-renew monthly until cancelled.

``` ```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.*