Dario Codipietro

Discovery: Watch v2

As Lead UX Designer at Discovery, I specified Watch v2, the playback journeys and player states for the native apps of every streaming service on its shared platform, written beside the platform's tech specs while I was embedded in its tech team.

Role
Lead UX Designer
Year
2020
Team
platform devs, platform PO, service teams
Shape
One white-label spec, then delivery per service
Watch VOD journey 1 from the spec: an episode page in browse, the inline player loading, playback with on-video controls, the controls faded out, and the end of playback with watch again and watch next episode.

Outcome

Every Discovery streaming service went on to run on v2 of the shared platform, with playback as I documented it in Watch v2. I wrote the white-label spec with the platform’s tech team and its PO, then supported the discovery+, Quest and Eurosport teams through implementation and UI delivery on their services.

Context

Discovery ran discovery+, Eurosport, Quest and its other streaming services on one shared white-label platform. Their content and business models differed. Some had live channels and live events streamed outside a channel as well as VOD, some were ad funded and others sold subscriptions, and parental controls and broadcast guidance rules varied by market.

Playback was being rebuilt for v2 of the platform while its tech specs were still changing. The goal was one set of playback journeys and player states for the iOS and Android apps, on phones and tablets in both orientations, that every service could configure and the platform’s developers could build against.

Writing playback journeys beside the platform’s tech specs

The platform’s playback capabilities were still changing when I started on Watch v2. I worked embedded in the platform’s tech team, with its PO, and documented each journey in Axure beside the tech spec it depended on, revising the journeys as the capabilities changed.

Several features depended on data in the stream: skip intro and the next up cue on markers in the stream metadata, the scrub preview on trick play images, and ad breaks on insertion cues. In the spec each of these journeys applied only where the stream carried the data it needed. The spec published in March 2020 ran to 39 pages: 16 local playback journeys, the player and the full-screen player in five blocks of states, the states of each sub-component, and casting.

01Playback journeys

Letting each service choose how playback opens

The platform had to support services that opened playback in different ways. For each content type, VOD, live and live catch-up, I wrote three journeys: no forced full screen, full screen forced on playback, and full screen forced in landscape. Each runs from the tile in browse through loading, playback start and the controls fading out to the end of playback, where users can close, watch again or load the next episode.

Toggling full screen took six journeys, by device orientation and by whether the service forced full screen on playback and landscape on full screen. On a landscape device with full screen forced, the player showed no toggle. The platform had to support every journey, and each service picked its behaviour through configuration.

Watch VOD, from the spec. The three VOD journeys, from the browse tile to the end of playback: the inline player, full screen forced, and full screen forced in landscape. Browse was still in progress, so its screens are marked WiP.

Open in Axure ↗ Get password →

Supporting live, catch-up and scrubbing

Live content reached the player in two ways, on a channel or as a stream outside one, and either could be live or on now. I gave each its own block of player states, including the states for a viewer who had skipped back. Users who chose watch from start on a live event could skip to live at any point, and if the live stream had ended by then they went to the end of playback.

On VOD the scrub bar showed a preview pane with trick play images from the stream, to help users find a point in the episode. Live streams carried no previews, so scrubbing live showed a timestamp, in a format each product chose: the time behind live, the local time at the playhead, or the time elapsed from the start.

Scrub VOD, from the spec. One journey in the portrait player, the portrait full-screen player and the landscape full-screen player: tap, drag the playhead over the trick play preview, release, buffer and resume.

Open in Axure ↗ Get password →

Handling ads, guidance labels and parental PINs

Ads were inserted dynamically into VOD, live and catch-up. Users needed to know how many ads were in a break and how long until playback resumed, so each ad showed its place in the break and a countdown, with a skip button where the ad allowed one. A user who scrubbed past an ad cue on VOD had to watch the skipped ads before playback resumed, and a second tap on an ad opened its link in the browser. Ads on live catch-up were marked on the page as still needing requirements.

Guidance labels were a legal requirement in some markets and a product choice in others, with visual rules that changed by region. I referenced Denmark’s NICAM ratings and the BBC’s guidance labels, and mapped two journeys meant to cover most cases or to serve as the base for a custom one: full-screen guidance before playback, or a label on the video once the controls fade, held for the legally required time. Content above a profile’s parental control rating asked for the PIN before playback, with a state for a wrong PIN.

Dynamic ads on VOD, from the spec. A skippable ad with its countdown, the skip button, a non-skippable second ad and the last ad of the break, then back to playback. The place in the break, “1 of 3 Ads”, sits top left.

Open in Axure ↗ Get password →

Guidance on playback, from the spec. The label appears once the on-video controls fade and stays for the legally required time. Journey 1, not shown, puts the guidance full screen before the video loads.

Open in Axure ↗ Get password →

Keeping viewers watching at the end of an episode

Some services wanted to offer the next video before the current one ended. For serial content I specified a next up card that autoplays the next episode, with autoplay on or off and a large and a small size, triggered by a cue in the stream metadata or a set time before the end. Where nothing was queued after the current video, a recommended next card offered related VOD. Users could cancel autoplay and still reach the next episode from the end of playback.

Where the stream metadata marked the intro, a skip intro button appeared and faded out after it. I flagged the end of playback in a minimised player as needing exploration and testing.

Next up, from the spec. The card fades in on the cue with a ten-second countdown. Cancelling autoplay keeps a watch next episode button, which stays on the end of playback beside watch again.

Open in Axure ↗ Get password →

02Player

Breaking the player into components and states

The same controls had to work in all three ways into playback, on phones and tablets in both orientations. I specified the player as an organism of components, each with its own page of states: the top bar for closing, casting and minimising, the quick controls for play, pause and 15-second skips, the scrub bar, volume, the metadata box and the next cards. On-video controls showed on load, faded out and toggled on tap. Volume, audio and subtitles, full screen and the metadata sat below the video and stayed visible, with volume behind an icon on small screens.

The player’s states came in five blocks: VOD, a live channel, a live stream, dynamic ads, and no video. The full-screen player used the same five with on-video controls only. Audio and subtitle choices were saved to the profile and followed the user across sessions and devices, and volume was saved to the device. A product could rely on hardware volume alone and drop the on-screen control.

The player, from the spec. The notes on the left list each component and link to its page of states. The next up and related rails below the player were left for Browse v2.

Open in Axure ↗ Get password →

Covering every state where a video cannot play

A tap on a tile could lead to a video the user was not allowed, or not yet able, to watch. I specified eight no video states for the player and the full-screen player, each on large tablets, on tablets and phones in landscape, and on phones: loading, needs an account (L1), needs a subscription (L2), region locked, a generic error, VOD coming soon, live soon, and live ended with a way to catch up. I carried the user levels of Auth v2 into the player through the two unentitled states, each with a call to action, join to watch or get a pass, into sign-up or purchase.

Access states, large tablets. Loading, then the two unentitled states with their calls to action, then region locked.

Open in Axure ↗ Get password →

Schedule and error states, large tablets. A generic error, VOD coming soon, live soon, and live ended with watch again.

Open in Axure ↗ Get password →

03Casting

Casting to the TV with Chromecast and AirPlay

The player had to hand playback to a TV through Chromecast and AirPlay, each with its own platform rules. For Chromecast I wrote two sender journeys, one where casting was off when playback started and one where it was already on and the stream went straight to the receiver. Each sender step named the receiver state it caused, from loading to paused, seeking and idle. The receiver states covered touch receivers too, which toggled controls on tap and hid them during playback and seeking.

The Chromecast journeys followed Google’s Cast UX guidelines and the platform’s native Chromecast APIs. For AirPlay I used Apple’s native components and guidelines, and the top bar showed which cast options were available or active.

Chromecast sender, from the spec. Casting to the living room TV, the cast dialog with its volume and stop casting, the mini player, the expanded player while scrubbing, and the lock screen player.

Open in Axure ↗ Get password →

Watch v2 sat beside Auth v2 and Account v2 in the platform’s v2 documentation, and used the same user levels. Where a journey still needed requirements, such as ads on live catch-up or the end of a minimised player, the spec said so on its page. Browse v2, which the player’s rails pointed to, was still in progress when I published it.

Sources

Get the password

Enter your work email to get the password.

Contact

Get in touch

Product design lead across research, design systems and handover, with coding agents in the loop. Contract, outside IR35, or a permanent lead role.

Available
Now
Location
London, remote or hybrid, UK and EU
Right to work
UK settled status, EU citizen
  • RolesLead Product Designer, Principal Product Designer, Design Engineer
  • Experience10+ years
  • ScopeResearch, design systems, prototyping, handover, QA with agents
  • LanguagesEnglish, Italian, Spanish
  • Email[email protected]
  • LinkedInlinkedin.com/in/dariocodipietro

Professional profile

Copy into your coding agent

Skills

  • Product design, end to end
  • UX and interaction design
  • Visual design and motion
  • Prototyping in Figma and code
  • Design systems at scale
  • User research and testing
  • A/B testing and analytics
  • Strategy and discovery
  • AI product design
  • Design to code, with agents
  • Accessibility, WCAG 2.2 AA
  • Leadership and mentoring

Platforms

iOS, Android, responsive web, smart TV and connected devices

Sectors

  • AI products
  • B2B SaaS
  • Consumer apps
  • Streaming, media and sport
  • Health, wellness and food
  • Legal tech
  • Telecoms and utilities

Tools

  • Figma
  • FigJam
  • Figma Make
  • Claude Design
  • Framer
  • Axure RP
  • Storybook
  • Claude Code
  • Cursor
  • Codex
  • MCP
  • GitHub
  • Linear
  • Jira
  • Confluence
  • Notion
  • Miro
  • Prolific
  • Lyssna
  • Maze
  • PostHog
  • Amplitude

Send a message

Tell me about the role and when it starts, and I will reply by email.