// media and streaming

The big match starts in ten minutes. We test the spike before it happens.

Streaming breaks on the device you did not try, the renewal that runs after a cancellation, and the minute everyone signs in. We test those on real devices and real traffic shapes.

Start a two-week pilot
ISO 27001:2022clients include Le Figaro4.9 Clutch, 65+ reviews$25-45/hour
I test subscription flows the way a subscriber meets them: a real phone, a real operator SIM, mobile data. Price, the SMS text word for word, billing and the STOP message, all against the brief. That is how a logged-out visitor downloading paid wallpapers got caught before launch.
Fabian Laszlo, QA engineer on carrier billing for digital content
// what keeps you up at night, and what you get
"The stream fails during the live event, in front of everyone."
Players and apps checked for accessibility, which the European Accessibility Act now covers.Auditi
"Subscription or phone-bill charges go wrong and refunds pile up."
Subscription, renewal and carrier-billing flows tested end to end.BugBoard
"Playback works on one TV and breaks on the next one."
Sign-up and playback tested across phones, browsers and TVs.Flows
// four places streaming products break
01 · hls ladder

A TV starts on a rendition it cannot decode

The master playlist lists a low-bitrate HEVC variant first. Many players start on the first listed variant, and some older TV browsers do not skip a CODECS value they cannot decode. The picture stays black, audio may play, and no error event reaches your analytics.

HLS, RFC 8216 CODECS attribute; check Tizen, webOS, Fire TV
#EXT-X-STREAM-INF: (abbreviated) BANDWIDTH=900000,CODECS="hvc1.1.6.L90" v/360p_hevc.m3u8 BANDWIDTH=2800000,CODECS="avc1.4d401f" v/720p_h264.m3u8
BLACK SCREENstarts on a rendition it cannot decode
how we test itParse the master playlist per device profile, assert the first variant is decodable there, then play it on the real device and watch the clock.
for (const dev of lab.devices(['tizen', 'webos', 'firetv'])) {
  const m = parseMaster(await get(MASTER))
  expect(dev.canDecode(m.variants[0].codecs)).toBe(true)
  await dev.play(MASTER)
  await dev.waitPlaying(8_000)
  expect(await dev.position()).toBeGreaterThan(5)
}
02 · carrier billing

Cancelled in the app, charged by the operator

The user cancels at 23:58. The cancel call to the operator times out, but the app records the cancellation and confirms it. The operator never saw it, so the renewal runs at 00:05 and charges the phone bill. The app and the operator now disagree about whether a subscription exists.

found when the support queue fills with refund requests
userappoperatorcancel subscription, 23:58DELETE /subscriptions/s81timeout, nothing appliedlocal state = cancelledcancelled, access until 30threnewal 00:05, charged 4.99
FAILcancelled in the app, still billed by the operator
how we test itPut a fake operator between the app and the sandbox that drops the cancel, then run the renewal. A cancellation is pending until the operator confirms it.
operator.dropNext('DELETE /subscriptions')
await user.cancel(sub)
expect(await app.subStatus(sub)).toBe('cancel_pending')
await operator.runRenewalJob()
expect(operator.charges(sub)).toHaveLength(0)  // retries until acked
expect(await reconcile(app, operator)).toEqual([])
03 · live spike

Everyone's entitlement check expires at kickoff

Four hundred thousand viewers sign in within a minute before the match, and every access token carries the same 5 minute lifetime. Five minutes later they all renew together, and the entitlement service gets several times its capacity. Paying viewers see an error exactly when the stream matters most.

fail-open or fail-closed on a timeout must be a decision, not an accident
viewers at kickoff400000token lifetime300 srenewals/s if spread over 300 s1333renewals/s if clustered in 60 s6667entitlement capacity/s2000overload3.3x
lifetime 150-450 s, randomserve last known entitlementqueue sign-up, not playback
FAIL6667/s against 2000/s, 503 for payers
PASSjittered renewals, p99 under 800 ms
how we test itLoad test the real shape: a ramp to kickoff, then the renewal wave five minutes later. Assert on the entitlement service, not just the CDN.
ramp({ users: 400_000, over: '60s' })        // sign-in before kickoff
holdFor('5m'); expectRenewalWave()           // tokens expire together
expect(p99('entitlement')).toBeLessThan(800)
expect(rate('http_5xx')).toBeLessThan(0.001)
expect(playbackStarted / signedIn).toBeGreaterThan(0.99)
04 · captions

Captions run 30 seconds early after the ad break

WebVTT cues are timed against the content clock. When an ad is stitched into the stream the media timeline moves, but the subtitle segments keep their old timestamps, or lack the X-TIMESTAMP-MAP header HLS players use to align them. Every cue after the break appears 30 seconds before the line is spoken, the first ones over the ad.

EAA and EN 301 549 cover captions; a late caption is not a caption
00:10cue 41
00:55ad break
01:05cue 42
01:40cue 43
30s EARLYad offset never applied
how we test itPlay a stream with a known ad break and test clip, read each cue's displayed time against the audio, and fail on drift above your tolerance.
const run = await player.play(STREAM_WITH_AD_BREAK)
for (const cue of run.displayedCues()) {
  const drift = cue.shownAt - run.speechStart(cue.id)
  expect(Math.abs(drift)).toBeLessThan(0.5)   // seconds
}
expect(run.subtitleTrack.hasTimestampMap).toBe(true)

Illustrative examples built from defect patterns we test for. Not client data.

// on every pull request

Your code is written in hours. Our pipeline keeps up.

Pull requestfrom your coding agent
Flowsjourneys and fault injection
Security Toolkit15 scanners + 20 own checks
QA engineerconfirms every finding
BugBoardrelease report, Jira sync
// the regulation, in testing terms
regimewhere it actually breakswhat we run
EAA, EN 301 549Player controls, captions and focus order on TV and mobile appskeyboard and remote-control walks, caption sync checks, contrast
GDPR, ePrivacyAnalytics and ad tags firing before consent is givennetwork capture before and after the consent choice
PSD2 article 3(l)Operator billing exemption: limits per payment and per monthboundary tests at the limits, cap resets, refund paths
Content licencesHD and 4K often tied to DRM security level, with fallback to lower qualitylicence checks per device class, expiry and device-limit tests
// proof

Where we work in media and streaming

Le Figaroteams at Pluto TV300+ issues reported
  • A company that sells digital content through mobile operator billing: a dedicated tester since July 2026, with more than 300 issues reported.
  • Le Figaro, one of France's oldest newspapers: functional testing.
  • Sports video and AI camera products, tested since 2025.

The operator-billing client is not named.

BUG-0518 · playback / smart tv · examplehigh

Black screen on older TVs when the first video starts

  1. Open the app on a TV model from the oldest supported list
  2. Start any title
  3. Audio plays, the picture stays black, no error is logged

Fix: List an H.264 rendition first, or filter variants by device codec support.

RFC 8216REQ-PLAY-03TC-0942 addedJira STR-377

Two weeks on your apps and players. Free if you're not happy.

Start a pilot