An AV session in Piano Analytics is a continuous period of engagement with a single piece of media. It has its own identifier (av_session_id) and its own lifecycle, distinct from the visit (visit_id) that contains it. Understanding the relationship is the key to interpreting AV metrics correctly.
AV Session vs Visit
|
Identifier |
Scope |
When it ends |
|---|---|---|
|
|
The visitor's whole browsing session on your site |
|
|
|
A single piece of media being played |
|
A single visit can contain many AV sessions — a visitor who plays three videos in a row generates three av_session_id values nested inside one visit_id.
The reverse direction is less straightforward: an AV session is not formally tied to the visit. The session terminates on av.stop or on one of the four property changes above — visit_id ending isn't in that list. In practice, the two often end together because three of the four termination conditions (date crossing midnight, a new visitor_id, a new site_id) also end the visit, but a visit expiring on its own — for example, the player pauses long enough that the visit's 30-minute inactivity timer fires — would not on its own terminate the AV session. The next AV event after the visit gap would attach to the existing av_session_id as long as the four key properties still match.
When a new session starts
A new av_session_id is generated when any of the following session-affecting events occurs and the previous session has ended:
-
av.play -
av.start -
av.heartbeat -
av.pause -
av.resume -
av.buffer.start/av.buffer.heartbeat -
av.rebuffer.start/av.rebuffer.heartbeat -
av.seek.start -
av.backward/av.forward
Static events that do NOT create sessions
Some av.* events are static — they carry information for analysis but don't contribute to session calculation: av.ad.click, av.ad.skip, av.error, av.display, av.volume, av.subtitle.on / .off, av.quality, av.speed, av.fullscreen.on / .off, av.share, av.close. If a session contains only static events, it has no AV session built around them.
When the previous session ends
The previous session ends (and the next dynamic event creates a new one) when:
-
An
av.stopor event is explicitly fired, or -
Any of these key properties differ from the previous AV event:
-
Date of the event (crossing midnight)
-
visitor_id -
site_id -
av_content_id
-
This means switching from one piece of content to another — without an explicit stop — automatically closes the previous session and opens a new one. The change in av_content_id is what Piano uses to detect the boundary.
Why session count differs from "play" count
A common point of confusion: a player can fire many av.play events (start, pause, resume, pause, resume…) but produce a single av_session_id for the whole engagement. The relationship is:
-
AV - Plays counts
av.playevent firings (click on play button, start, resume). -
AV - Sessions counts distinct
av_session_idvalues (one per piece of media engaged with). -
AV - Playbacks counts sessions where at least some content was actually consumed (
av_content_time_consumed > 0).
Mobile-specific session behavior
On mobile, backgrounding makes the session-vs-visit interaction worth thinking about:
-
A user who minimizes the app while audio continues playing — the visit can time out (30 minutes of background inactivity) while events keep arriving from the still-playing media. Whether the AV session terminates depends on the four key properties: if the next event crosses midnight, fires from a different visitor or site, or carries a different
av_content_id, the session ends. Otherwise the session can continue across the visit gap. -
A user who switches to a different track or video while backgrounded changes
av_content_id, which does terminate the AV session even if noav.stopwas fired.
If mobile listening times look truncated compared to expected, inspect the event stream to see which of the four termination conditions actually triggered the boundary — don't assume it was the visit ending.
Session continuity across page changes
If your site is a single-page application and the same media keeps playing across route changes, the AV session continues without a new av_session_id as long as av_content_id doesn't change.
If the page genuinely reloads (multi-page application, real navigation), the AV session ends because the SDK reinitializes.
How to debug session boundaries
-
Filter your event stream to a single
av_session_id. -
Inspect the first and last events — the first should be a session-starting event (typically
av.playorav.start); the last should beav.stop, end of content, or the event before a property-change boundary. -
If you see sessions ending unexpectedly, check whether
av_content_idchanged between events, or whether a midnight boundary was crossed. -
If you see sessions never ending (no
av.stoparrived), the player isn't firing the stop event at content end — fix in the player integration.