@cassette/player
@cassette/player
provides a responsive, zero-config-needed React media player component, implemented with @cassette/core
. Its control components can also be consumed directly.
Installation
npm install @cassette/player
Player components included:
MediaPlayer
- A media player component which plays a provided playlist of media
MediaPlayerControls
- The UI component of MediaPlayer
, which requires an ancestor PlayerContextProvider
(and optional ancestor FullscreenContextProvider
) in order to work
Control components included:
BackSkipButton
- a button which, when clicked, either skips to the previous track in the playlist or to the beginning of the current playing track, depending upon the currently elapsed time
ForwardSkipButton
- a button which, when clicked, skips to the next track in the playlist
FullscreenButton
- a button which, when clicked, tells the surrounding FullscreenContextProvider
(if present) to toggle fullscreen mode
MediaProgress
- an interactive media progress bar which can be adjusted by dragging, along with a text overlay of the current track metadata and the elapsed time
MediaProgressDisplay
- a non-interactive version of MediaProgress
MuteButton
- a button which, when clicked, toggles whether the media's audio is muted
PlayPauseButton
- a button which, when clicked, toggles whether the media is paused
RepeatButton
- a button which, when clicked, cycles to the next repeatStrategy
(none
, playlist
or track
)
ShuffleButton
- a button which, when clicked, toggles whether the playlist is being played in specified order or in shuffle order
Spacer
- provides a buffer between control components
VolumeControl
- a MuteButton
which, when hovered (with a mouse) or initially tapped (on touch screens), displays a bar for adjusting media volume
Find full documentation here!
[v2.0.0-beta.4] - 2019-09-26
v2 is a huge update! And yes, there are breaking changes. If you're just trying to upgrade from v1, you can check the Changed and Removed sections.
These notes are on changes since the previous stable release (v1.5.0). For changes that have occurred between alpha/beta releases, check the release notes.
All updates are mentioned on a broad level, but it wouldn't make sense to explain all new and changed APIs in minute detail here, so be sure to read the docs.
Changed
- The project has been renamed from react-responsive-audio-player to Cassette (#284, #291), and is now distributed in several packages (#292), so upgrading to version 2 will mean installing a new package or packages from npm. A simple upgrade will typically require only the
@cassette/player
package.
- Previously the package had a default export (
AudioPlayer
). AudioPlayer
has been renamed to MediaPlayer
and is a named export from @cassette/player
. So anything that previously looked like import AudioPlayer from 'react-responsive-audio-player'
will become import { MediaPlayer } from '@cassette/player'
.
MediaPlayer
is the combination of two components: MediaPlayerControls
from the @cassette/player
package and PlayerContextProvider
(#214) from the @cassette/core
package. MediaPlayer
doesn't accept any unique props of its own, but rather all the props accepted by MediaPlayerControls
and PlayerContextProvider
. Discussion of prop changes or additions since v1 in this changelog section pertain to one of those two components.
- The
audioElementRef
prop to PlayerContextProvider
/MediaPlayer
has been renamed mediaElementRef
(#284)
- A few minor style tweaks and improvements have been made for the player UI (#69, #94), but things look overall the same when you upgrade. However HTML and CSS have been totally refactored and classes renamed for v2 so any CSS extensions you wrote for v1 will need to be recreated using the new stylesheets for v2. (#42, #81)
- New/improved timestamp formatting in the default UI implementation from
@cassette/player
(#397)
- Timestamp display always rounds down (#429).
- When an end user begins seeking with a progress bar or similar, the default behavior (which can be configured) is now to update the
currentTime
immediately instead of waiting until the user releases the mouse. (#204)
- Initiating a forward skip during playback of the last track in a playlist, when the
cycle
prop is false
, no longer works - the action will be ignored and playback will continue. (#68)
- Track duration is now reset to 0 when a new track is selected, then changes once metadata loads. To avoid this funny intermediate state, you should set the
duration
property on your tracks! (#372)
- We no longer pause media when the
stalled
event fires (#166)
- If a user tries to manually set the media
src
to something that isn't in the playlist, it will now be reset automatically to the previous state (#178)
- Although things will still function without it, the
isUnboundedStream
property should be set on track objects that are indeed unbounded streams (e.g. radio) since one of our fixes means retrying media fetches that yield Infinity
duration. Setting isUnboundedStream
to true
skips the refetch. (#373)
- Now requires a peer dependency of React v16.3 or higher (#138)
Removed
- The
onMediaEvent
prop is removed, since most of its use cases can be solved better now by using the PlayerContextProvider
(#226)
mediaElementRef
(previously called audioElementRef
(#284)) still exists as an escape hatch
- The
cycle
prop was removed. Use defaultRepeatStrategy
instead, and any subsequent updates should be set via playerContext
(since we would expect this setting to be changed as a result of an end user action) (#79)
- Features deprecated in v1.x.x have now been totally removed:
- The
style
prop to AudioPlayer
(now MediaPlayer
) is no longer accepted. Use styles on a container element, or CSS, instead.
- Mutating and re-using playlist arrays no longer works as expected. Playlists should be shallow copied if they need to be modified. See this docs entry for more information. (#268)
- The
displayText
property on a playlist track is removed in favor of the artist
and title
properties (also used by Media Session API) (#148).
- If this isn't enough, you can pass the
getDisplayText
prop to MediaPlayer
/MediaPlayerControls
.
- The
hideBackSkip
, hideForwardSkip
and disableSeek
props from AudioPlayer
in v1.x.x are not available on MediaPlayer
/MediaPlayerControls
. Use the controls
prop instead, which is more flexible.
Added
- Video (#206, #316) and fullscreen (#221) support!
- New
showVideo
prop for MediaPlayer
/MediaPlayerControls
can be set true to activate a video display (#221)
- Can pass custom video display implementation to
MediaPlayer
/MediaPlayerControls
(#253)
- Video display will show track album artwork for audio (#241)
- React Context-based API exposes media state and callbacks and allows totally custom player UI implementation (#138, #208)
- Besides what comes in the
@cassette/core
package, there is a @cassette/hooks
package for those who prefer to work with React hooks (#361)
PlayerContextGroup
can wrap multiple PlayerContextProvider
/MediaPlayer
instances to share configuration and prevent simultaneous audio playback (#219)
- Several new control types for
@cassette/player
: volume (#72), mute (#257), repeat (#79), shuffle (#87), read-only progress (#60), fullscreen (#221)
- Helper primitives for building custom UI (
ProgressBar
, ProgressBarDisplay
, MaybeMarquee
(#245), VideoDisplay
) available from @cassette/components
package (#292)
- Keyboard navigation support for UI controls (#124, #396)
- New
controls
prop functionality for MediaPlayerControls
/MediaPlayer
- previously in v1 controls
supported a few control types as keywords, but in v2 several more built-in control keywords are supported, and custom controls can be implemented by passing in a function as a member of the controls
array (#42)
- New props for
PlayerContextProvider
, which can also be passed to MediaPlayer
:
initialStateSnapshot
and onStateSnapshot
can be used to persist media player state and restore at load time later (#226)
loadFirstTrackOnPlaylistComplete
can be set false
to prevent a playlist from resetting on the first track when the playlist finishes (#42)
defaultVolume
, defaultMuted
, defaultPlaybackRate
, startingTrackIndex
(#61)
defaultRepeatStrategy
(#79)
maintainPlaybackRate
- can be set true
in order to override the default browser behavior which resets the playback rate on every new track (#129)
seekMode
- for specifying whether to pause, seek immediately, or continue playback and seek after release, when seeking with a progress bar (#204)
onActiveTrackUpdate
callback prop (#76, #406)
onTrackPlaybackFailure
callback prop (#356)
onTimeUpdate
callback prop (#369)
- Support for specifying multiple source audio files (e.g. ogg, mp3) for the same track (#178)
duration
property supported on playlist track objects so the player can display nicely before media has finished loading (#372)
@cassette/player
exports components for individual player controls now (#42, #231, #341)
- SCSS and CSS stylesheets for individual control components are now shipped for
@cassette/player
, in case you want to include only a subset of CSS you know you'll use. (#42) (#73, #231)
- A
trackIndex
can now be passed to a play/pause button in order to tie that button to a particular track in the playlist (#338)
- A
durationOverride
can be set on a media progress bar if you're running a live stream or similar and have stream duration info that isn't available to the media element (#379)
- The media
title
attribute is now set, and configurable, for system notifcation support on iOS (#344)
- You can set a
startingTime
property on a track object if you need to restore currentTime
from some previously recorded state (advanced use case) (#369)
- You can now bring your own
HTMLMediaElement
implementation (#349)
- You can now force the player to reload if something goes wrong with the network. (#426)
Fixed
- Prevent fullscreen player from opening automatically on iOS (#307)
- Fix issue with
undefined
crossOrigin
prop in Microsoft Edge (#368)
- Proper time/progress display for unbounded streams e.g. radio (#377)
- Address weird infinity duration bug on iOS (#373)
- This fix means you should set the
isUnboundedStream
property on a playlist track if it is indeed an unbounded stream