Player
The Player component provides an easy way to display video or audio.
The Player
component provides an easy way to display video or audio.
It automatically handles different source types from a Livepeer provider, such as WebRTC, MP4, and HLS. These are seamlessly integrated so that playback has low latency under all network conditions.
Usage
The following example assumes a stream or asset was created via useCreateAsset
or useCreateStream
, and the playbackId
was passed to the viewer.
Here we also introduce a custom PosterImage
React component, which is
described in more detail below in poster
configuration.
Compatibility
Browser | Version |
---|---|
Chrome | 102+ |
Chrome for Android | 105+ |
iOS Safari | 12.2+ |
Edge | 103+ |
Safari | 13.1+ |
Firefox | 103+ |
Opera | 89+ |
Samsung Internet | 17+ |
UC Browser | 13.4+ |
Firefox Android | 104+ |
Opera Mini | all |
We aim to support ~93% of browsers tracked on caniuse. We use browserslist to track compatibility and core-js for polyfills.
Configuration
playbackId or src
A playbackId
for an
asset
or
Stream,
or src
, a media source URL. One of these is required.
playbackId
The playbackId
passed to the Player
can be either a short playback ID which
is created on asset/stream creation, or, for an asset, an IPFS CID. If the
provided IPFS CID or IPFS/Arweave URL has not been uploaded yet, it can be
auto-uploaded and played back - see autoUrlUpload
for more
details.
src
Using an arbitrary src
that is not from a provider will not be transcoded
(unless autoUrlUpload
is used), and will take up
significant network bandwidth. It’s highly recommended to upload media to a
provider, and serve content to viewers with a playbackId
.
The Player also supports an arbitrary src
URL which can correspond to any
common video or audio which most browsers support. See
caniuse video format for more
details on browser support.
Metrics reporting will not work with an arbitrary src
(e.g. not a Studio
playback URL).
If the src
is an IPFS/Arweave URL, it can be auto-uploaded and played back -
see autoUrlUpload
for more details.
jwt or accessKey
This section defines ways to play back a video which has a playback policy applied to it. Your application can prevent playback unless the user meets application-specific requirements (this can be done either with JWTs or webhooks, and solves use-cases like restricting viewership to users who own an NFT, have created an account on your platform, are part of a multisig, etc).
jwt
The JSON Web Token (JWT) used to access media gated by a jwt
playback policy.
Alternatively, accessKey
can be used for a webhook
playback policy. See the
Access Control example for more
details.
accessKey
The access key used to access media behind a webhook
playback policy.
Alternatively, onAccessKeyRequest
can be used to return this access key in a
callback. See the
Access Control example for more
details.
onAccessKeyRequest
A callback which returns the access key used to gate access to media. Similar to
accessKey
above, this is used to gate content based on a webhook
playback
policy. This is used instead of the accessKey
prop, and can be asynchronous
and accepts any Promise or simple callback which returns a string. See the
Access Control example for more
details.
priority
When true, the media will be considered high priority and preload. Lazy loading
is automatically disabled for media using priority
. You should use the
priority property on any media detected as the
Largest Contentful Paint (LCP) element. It may be
appropriate to have multiple, as different content may be the LCP element for
different viewport sizes.
Should only be used when the media is visible above the fold. Defaults to false.
lowLatency
When enabled, the Player will play back live streams with low-latency
WebRTC. Defaults to true
. If this does not succeed in playing back (commonly
due to a slow network or connectivity issues), the Player will automatically
fall back to HLS playback. Also, if the stream contains B-frames (bidirectional
frames, which are common for users streaming with OBS or other streaming apps),
the Player will automatically switch to HLS, so that out-of-order frames are not
displayed.
OBS users should be instructed to use the Livepeer stream profile, or to manually turn off B-frames in their stream. See our Stream from OBS docs for more information.
This only applies to video elements which are playing back livestreams - assets will play back with MP4 or HLS.
You may also specify "force"
, which forces WebRTC and disables fallback to
HLS. This is not a recommended default unless your application requires low
latency (and should not play if low latency is not available), due to the
possible connectivity issues which WebRTC can face, which HLS is not subject to.
We are planning on adding similar functionality to the React Native Player
-
please reach out on Discord if you are interested.
clipLength
The clip length enables the “live clipping” feature - the value is in seconds, and controls the length of the clip that is created when the clip button is clicked by a viewer. This can be one of 90, 60, 45, 30, 15, or 10 seconds.
This allows for dynamic viewing experiences, along with the onClipStarted
,
onClipCreated
, and onClipError
callbacks for clips.
You can use the onClipStarted
, onClipCreated
, and onClipError
callbacks
to control UI outside of the Player, to show toasts or other loading
indicators, as well as track the status of the Asset which is created and
processed. See useAsset
for how to poll the status of the asset.
playRecording
When allowed, the Player will include recording URLs in playback. This is the HLS URL that allows users to watch the entire recording of a stream, without requiring the user to play from the latest playhead (as is usually required in stream playback). This can be used to create historical clipping experiences for streams - users can watch a version of the stream that constantly appended with the latest segments.
Keep in mind that latency for the latest segments will be higher when this option is enabled, and is not recommended for low latency applications.
title
The title
for the content. This is highly recommended, since it is used for
accessibility labels in the Player. If you do
not want to show the title visually, see showTitle
.
showTitle
Enables/disables the title component.
aspectRatio
Sets the aspect ratio for the content. Highly recommended for a great viewing
experience (for more information, see
Cumulative Layout Shift). Defaults to 16to9
.
loop
Sets whether the content will loop when finished. Defaults to false
.
poster
Sets the poster image. This can be either a string for an image URL, or a React component.
The poster
can be a simple image URL, and it will be rendered with a regular
img
HTML tag.
If the poster is a React component, it will be rendered with similar CSS
attributes to the img
above. In the below example, we show the use of
Next.js Image to
render an optimized image, which will automatically handle slow network
conditions/different device sizes.
showLoadingSpinner
Shows/hides the loading spinner for the media content. Defaults to true
.
hlsConfig
Sets the underlying HLS.js config used for playback. See the HLS.js docs for more details on the possible values.
webrtcConfig
Sets the underlying WebRTC config used for
WHEP SDP negotiation.
The possible config options are constant
and sdpTimeout
.
A constant=true
boolean indicates that audio will not be distorted if the
playhead falls behind the livestream. This is usually used for music
applications, where audio quality and consistency is more important than
latency.
The sdpTimeout
config sets the amount of time in milliseconds that the Player
will wait for a response from SDP negotiation before falling back to HLS.
controls
Configures the timeout for autohiding controls, default volume, and (only on web) if keyboard hotkeys for controlling video are enabled.
autoPlay and muted
Sets the video to autoplay when the content comes into focus on the webpage. If
autoPlay
is specified, muted
will be forced to be true
. This is
enforced in many modern browsers.
objectFit
Sets the video’s
object fit
property. Defaults to contain
. cover
is usually used when there is a
guarantee that the aspectRatio
matches the content displayed in the Player.
showPipButton
Shows the Picture-in-Picture button to the left of the fullscreen button.
Defaults to false
. See children for an example on how to use the
underlying <PictureInPictureButton />
.
We support both the w3c standard (which most modern browsers support), as well as the older Safari/iOS spec. See the browsers which support Picture-in-Picture on caniuse.
viewerId
Allows a wallet identifier to be passed to the backend which allows for querying views by an identifier. This should be an wallet’s public address.
We are planning on adding further features to the viewer ID, such as “verified views” with a provable signature claim attached to these view counts. Reach out to us on Discord if you’re interested!
autoUrlUpload
Enables automatic upload and playback from decentralized storage providers.
Currently supports IPFS CIDs and IPFS/Arweave URLs. Defaults to true
.
For IPFS HTTP gateway URLs, the player currently only supports “path style” URLs and does not support “subdomain style” URLs. The player will support both styles of URLs in a future update.
If fallback
is specified, while the URL upload is being processed in the
background, the video will start non-transcoded playback immediately (defaulting
to w3s.link
for IPFS and arweave.net
for Arweave). Once this finishes, the
Player will switch to playing from the transcoded version from the Livepeer
provider. To show/hide the indicator of current upload progress, see
showUploadingIndicator
.
It is highly recommended for the best playback experience to upload from an
Arweave/IPFS URL using useCreateAsset
(with the format ipfs://<CID>
or
ar://<HASH>
) before presenting the content to the user - the first view with
automatic URL upload can take a few minutes, then it will be permanently cached
and play back quickly.
An IPFS v0 or v1 CID or
IPFS/Arweave URL (including directories) can be passed as the src
or
playbackID
to the Player, and it will automatically detect if it is a
dStorage identifier and attempt to play from a cached version. If the API does
not have a cached version with the corresponding ID, the Player will upload
the content using IPFS/Arweave, and then start playing the transcoded content
back. This may take a few minutes. If fallback
is specified, it will attempt
to play back instantly from the provided gateway or default gateway.
For best performance, use a custom gateway URL, and ideally, use the same gateway and pinning service, to avoid timeout errors.
showUploadingIndicator
Shows/hides the uploading indication for autoUrlUpload
. Defaults to true
-
only used with autoUrlUpload
.
theme
Sets the Player-specific theme overrides. It is recommended to use
LivepeerConfig
for any global app
styles, and the theme
prop to override those styles on a per-Player basis.
children
Overrides the custom controls for the Player. See the
Player
default controls
for more details on how the ControlsContainer
component is used.
This can be used alongside renderChildrenOutsideContainer
to render the
children outside of the aspect ratio container. This is used for custom
controls, so children of the Player can use useMediaController
without any
parent elements.
streamOfflineErrorComponent
Sets the error component that is shown when playback fails due to the stream
being offline. When this component is shown, the Player will retry playback in
the background. This will override the
OfflineStreamError
component.
accessControlErrorComponent
Sets the error component that is shown when playback fails due to an access
control error. This will override the
PrivateStreamError
component.
playbackFailedErrorComponent
Sets the error component that is shown when playback fails for a generic reason
(usually this is an intermittent network issue). When this component is shown,
the Player will be retrying playback in the background, with linear backoff.
This will override the
GenericError
component.
mediaElementRef
Sets the React
callback ref
passed to the underlying media element. Useful when integrating with third party
tools, or when access to the underlying video element is needed (usually it
isn’t!). Simple refs are not supported - only callback refs (which will be
called when the underlying media element is set/updated on initial render).
onPlaybackStatusUpdate
Callback called when the Player store status updates. This must be used with
playbackStatusSelector
to limit state updates. This allows developers to use
the underlying state of the Player component in their UI.
Hooks
usePlayerList
usePlayerList
is currently only available for React Native, since there are
List primitives which provide a standard API to hook into. We are working on a
React version.
The usePlayerList
hook makes it easy to preload and display videos in a
FlatList
-compatible list, by using
viewabilityConfigCallbackPairs
to trigger preloading on upcoming videos, and automatically playing/pausing
media when it is shown/hidden from the list.
See our Expo sample app for a real-world example.
Usage
Return Value
The return value extends the data
array which is passed into the hook, to add
Player-specific props to it. The viewabilityConfigCallbackPairs
prop is also
returned, which must be passed into the FlatList
-compatible list to maintain
the correct preloading/playing states for the Player(s).
Configuration
data
The data used in the list - required. This is extended to add Player-specific
props, which are passed into the Player using item.playerProps
.
itemPreload
The number of items to preload ahead of the currently-viewable Player. For
instance, if itemPreload
is set to 8 and there are 30 items in the Player
list, when the user is currently viewing the 5th item, the 6th-14th Players will
actively preload in the background. Defaults to 3.
itemVisibleMinimumViewTime
The minimum amount of time in milliseconds that an item must be viewable before
it is considered “shown”. This will also be the delay between when the item
becomes visible and when the autoPlay logic is triggered. Defaults to 100 ms,
use null
to unset. See
FlatList’s viewabilityConfig
for more details.
itemVisiblePercentThreshold
The percent of the item that must be visible for the item to count as
“viewable”, from 0-100. Defaults to 60%, use null
to unset. See
FlatList’s viewabilityConfig
for more details.
itemVisibleViewAreaCoveragePercentThreshold
The percent of the viewport that must be covered for a partially occluded item
to count as “viewable”, 0-100. No default value. See
FlatList’s viewabilityConfig
for more details.
itemVisibleWaitForInteraction
Indicates that the item is not considered viewable until the user scrolls or
recordInteraction
is called after render. Defaults to false. See
FlatList’s viewabilityConfig
for more details.
SSR
The following section only applies to web-based use-cases - React Native has no concept of SSR.
Next.js
The Player also comes with a
Tanstack Query prefetch query,
prefetchPlayer
, which makes it easy to prefetch the data used internally for
the Player during server-side rendering.
First, you add a
getStaticProps
function to the page which you want to prefetch data on. The props should match
the Player props to ensure that the correct data is prefetched.
We need to update the _app.tsx
to pass the dehydratedState
in pageProps
to
the LivepeerConfig. We also move the livepeerClient
into a useMemo hook so
that a new client is created on each request.
That’s it! You now have data prefetching on the server, which is passed to the browser and used to hydrate the initial query client.
Other Frameworks
The process is very similar for other frameworks, with the exception that there
is a clearClient
boolean which should be used to ensure that the client cache
is not reused across users.
Technical Details
The Player is opinionated about the ways it handles playback of media, specifically regarding HLS reconnect and playback URL choices.
HLS Reconnect
The Player will perform a linear backoff strategy when it encounters any network/response errors. The reconnect will initially wait one second, and add one second every retry. This ensures that if there are any intermittent network/API errors, they are resolved as quickly as possible. Most open source players do not do this automatically, which results in a poor playback experience for the user.
MP4 Playback URLs
When videos are uploaded which are shorter than two minutes, the Studio provider will automatically generate MP4 renditions alongside the usual HLS playback URL. This allows for rapid playback/caching at the CDN layer to enable your application to load video instantly.
The MP4 renditions will be prioritized over HLS and are chosen with the
following algorithm: the device screen width is multiplied by a static
multiplier (currently set to x2.5
). This value is then compared to the
rendition widths, and the renditions are prioritized based on the distance
between these values. This results in a choice of a rendition which is close to
the screen size without visual quality issues. For instance, a device with a
1280 pixel width would compute 1280px * 2.5 = 3200px
, and then sort the MP4
renditions by which are closest to this value.
Was this page helpful?