@videojs/react 10.0.0-beta.30 → 10.0.0-beta.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/default/i18n/context.js.map +1 -1
- package/dist/default/i18n/create-i18n.js +3 -1
- package/dist/default/i18n/create-i18n.js.map +1 -1
- package/dist/default/i18n/get-provider-root-props.js +4 -2
- package/dist/default/i18n/get-provider-root-props.js.map +1 -1
- package/dist/default/player/container.js +16 -7
- package/dist/default/player/container.js.map +1 -1
- package/dist/default/presets/audio/minimal-skin.css +39 -7
- package/dist/default/presets/audio/skin.css +31 -7
- package/dist/default/presets/live-audio/minimal-skin.css +39 -7
- package/dist/default/presets/live-audio/skin.css +31 -7
- package/dist/default/presets/live-video/minimal-skin.css +39 -7
- package/dist/default/presets/live-video/minimal-skin.js +4 -1
- package/dist/default/presets/live-video/minimal-skin.js.map +1 -1
- package/dist/default/presets/live-video/minimal-skin.tailwind.js +4 -1
- package/dist/default/presets/live-video/minimal-skin.tailwind.js.map +1 -1
- package/dist/default/presets/live-video/skin.css +31 -7
- package/dist/default/presets/live-video/skin.js +4 -1
- package/dist/default/presets/live-video/skin.js.map +1 -1
- package/dist/default/presets/live-video/skin.tailwind.js +4 -1
- package/dist/default/presets/live-video/skin.tailwind.js.map +1 -1
- package/dist/default/presets/video/minimal-skin.css +39 -7
- package/dist/default/presets/video/minimal-skin.js +27 -11
- package/dist/default/presets/video/minimal-skin.js.map +1 -1
- package/dist/default/presets/video/minimal-skin.tailwind.js +28 -12
- package/dist/default/presets/video/minimal-skin.tailwind.js.map +1 -1
- package/dist/default/presets/video/skin.css +31 -7
- package/dist/default/presets/video/skin.js +27 -11
- package/dist/default/presets/video/skin.js.map +1 -1
- package/dist/default/presets/video/skin.tailwind.js +28 -12
- package/dist/default/presets/video/skin.tailwind.js.map +1 -1
- package/dist/default/skins/dist/default/default/tailwind/components/button-group.js +1 -1
- package/dist/default/skins/dist/default/default/tailwind/components/button-group.js.map +1 -1
- package/dist/default/skins/dist/default/default/tailwind/components/controls.js +1 -1
- package/dist/default/skins/dist/default/default/tailwind/components/controls.js.map +1 -1
- package/dist/default/skins/dist/default/default/tailwind/components/menu.js +8 -7
- package/dist/default/skins/dist/default/default/tailwind/components/menu.js.map +1 -1
- package/dist/default/skins/dist/default/default/tailwind/components/time.js +1 -1
- package/dist/default/skins/dist/default/default/tailwind/components/time.js.map +1 -1
- package/dist/default/skins/dist/default/minimal/tailwind/components/button-group.js +1 -1
- package/dist/default/skins/dist/default/minimal/tailwind/components/button-group.js.map +1 -1
- package/dist/default/skins/dist/default/minimal/tailwind/components/controls.js +1 -1
- package/dist/default/skins/dist/default/minimal/tailwind/components/controls.js.map +1 -1
- package/dist/default/skins/dist/default/minimal/tailwind/components/menu.js +8 -7
- package/dist/default/skins/dist/default/minimal/tailwind/components/menu.js.map +1 -1
- package/dist/default/skins/dist/default/minimal/tailwind/components/time.js +2 -2
- package/dist/default/skins/dist/default/minimal/tailwind/components/time.js.map +1 -1
- package/dist/default/ui/hooks/use-slider.js +1 -2
- package/dist/default/ui/hooks/use-slider.js.map +1 -1
- package/dist/dev/i18n/context.d.ts +3 -1
- package/dist/dev/i18n/context.d.ts.map +1 -1
- package/dist/dev/i18n/context.js.map +1 -1
- package/dist/dev/i18n/create-i18n.d.ts.map +1 -1
- package/dist/dev/i18n/create-i18n.js +3 -1
- package/dist/dev/i18n/create-i18n.js.map +1 -1
- package/dist/dev/i18n/get-provider-root-props.js +4 -2
- package/dist/dev/i18n/get-provider-root-props.js.map +1 -1
- package/dist/dev/player/container.d.ts.map +1 -1
- package/dist/dev/player/container.js +16 -7
- package/dist/dev/player/container.js.map +1 -1
- package/dist/dev/presets/audio/minimal-skin.css +39 -7
- package/dist/dev/presets/audio/skin.css +31 -7
- package/dist/dev/presets/live-audio/minimal-skin.css +39 -7
- package/dist/dev/presets/live-audio/skin.css +31 -7
- package/dist/dev/presets/live-video/minimal-skin.css +39 -7
- package/dist/dev/presets/live-video/minimal-skin.js +4 -1
- package/dist/dev/presets/live-video/minimal-skin.js.map +1 -1
- package/dist/dev/presets/live-video/minimal-skin.tailwind.js +4 -1
- package/dist/dev/presets/live-video/minimal-skin.tailwind.js.map +1 -1
- package/dist/dev/presets/live-video/skin.css +31 -7
- package/dist/dev/presets/live-video/skin.js +4 -1
- package/dist/dev/presets/live-video/skin.js.map +1 -1
- package/dist/dev/presets/live-video/skin.tailwind.js +4 -1
- package/dist/dev/presets/live-video/skin.tailwind.js.map +1 -1
- package/dist/dev/presets/video/minimal-skin.css +39 -7
- package/dist/dev/presets/video/minimal-skin.d.ts.map +1 -1
- package/dist/dev/presets/video/minimal-skin.js +27 -11
- package/dist/dev/presets/video/minimal-skin.js.map +1 -1
- package/dist/dev/presets/video/minimal-skin.tailwind.d.ts.map +1 -1
- package/dist/dev/presets/video/minimal-skin.tailwind.js +28 -12
- package/dist/dev/presets/video/minimal-skin.tailwind.js.map +1 -1
- package/dist/dev/presets/video/skin.css +31 -7
- package/dist/dev/presets/video/skin.d.ts.map +1 -1
- package/dist/dev/presets/video/skin.js +27 -11
- package/dist/dev/presets/video/skin.js.map +1 -1
- package/dist/dev/presets/video/skin.tailwind.d.ts.map +1 -1
- package/dist/dev/presets/video/skin.tailwind.js +28 -12
- package/dist/dev/presets/video/skin.tailwind.js.map +1 -1
- package/dist/dev/skins/dist/default/default/tailwind/components/button-group.js +1 -1
- package/dist/dev/skins/dist/default/default/tailwind/components/button-group.js.map +1 -1
- package/dist/dev/skins/dist/default/default/tailwind/components/controls.js +1 -1
- package/dist/dev/skins/dist/default/default/tailwind/components/controls.js.map +1 -1
- package/dist/dev/skins/dist/default/default/tailwind/components/menu.js +8 -7
- package/dist/dev/skins/dist/default/default/tailwind/components/menu.js.map +1 -1
- package/dist/dev/skins/dist/default/default/tailwind/components/time.js +1 -1
- package/dist/dev/skins/dist/default/default/tailwind/components/time.js.map +1 -1
- package/dist/dev/skins/dist/default/minimal/tailwind/components/button-group.js +1 -1
- package/dist/dev/skins/dist/default/minimal/tailwind/components/button-group.js.map +1 -1
- package/dist/dev/skins/dist/default/minimal/tailwind/components/controls.js +1 -1
- package/dist/dev/skins/dist/default/minimal/tailwind/components/controls.js.map +1 -1
- package/dist/dev/skins/dist/default/minimal/tailwind/components/menu.js +8 -7
- package/dist/dev/skins/dist/default/minimal/tailwind/components/menu.js.map +1 -1
- package/dist/dev/skins/dist/default/minimal/tailwind/components/time.js +2 -2
- package/dist/dev/skins/dist/default/minimal/tailwind/components/time.js.map +1 -1
- package/dist/dev/ui/hooks/use-slider.d.ts.map +1 -1
- package/dist/dev/ui/hooks/use-slider.js +1 -2
- package/dist/dev/ui/hooks/use-slider.js.map +1 -1
- package/docs/README.md +1 -1
- package/docs/concepts/media-sources.md +26 -2
- package/docs/concepts/skins.md +48 -16
- package/docs/how-to/customize-skins.md +7933 -50
- package/docs/how-to/i18n-switch-locale.md +27 -0
- package/docs/how-to/installation.md +4 -4
- package/docs/how-to/migrate-from-plyr.md +1 -1
- package/docs/llms.txt +7 -0
- package/docs/reference/cloudflare-video.md +223 -0
- package/docs/reference/dash-video.md +55 -0
- package/docs/reference/feature-metadata.md +3 -1
- package/docs/reference/hls-audio.md +27 -1
- package/docs/reference/hls-video.md +39 -1
- package/docs/reference/hlsjs-video.md +627 -0
- package/docs/reference/native-hls-video.md +41 -0
- package/docs/reference/shaka-video.md +359 -0
- package/docs/reference/spotify-audio.md +188 -0
- package/docs/reference/tiktok-video.md +280 -0
- package/docs/reference/title.md +1 -1
- package/docs/reference/twitch-video.md +211 -0
- package/docs/reference/vimeo-video.md +736 -0
- package/docs/reference/youtube-video.md +339 -0
- package/package.json +8 -8
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
# ShakaVideo
|
|
2
|
+
|
|
3
|
+
Video element powered by Shaka Player for DASH, HLS, and progressive playback with DRM
|
|
4
|
+
|
|
5
|
+
Video element powered by [Shaka Player](https://github.com/shaka-project/shaka-player). One element plays DASH, HLS, and progressive files, and it’s the media component to reach for when you need DRM.
|
|
6
|
+
|
|
7
|
+
## Load a source
|
|
8
|
+
|
|
9
|
+
`src` takes a manifest URL. DASH, HLS, and progressive files all go through the same property, and Shaka picks the parser from the URL.
|
|
10
|
+
|
|
11
|
+
tsx
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
<ShakaVideo src="https://example.com/manifest.mpd" />
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
When the URL carries no extension to go on, name the type with `source.type`. That’s what makes an extensionless manifest playable.
|
|
18
|
+
|
|
19
|
+
tsx
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
<ShakaVideo source={{ src: 'https://example.com/manifest', type: 'application/dash+xml' }} />
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Protected content
|
|
26
|
+
|
|
27
|
+
`source.drm` names your license servers, keyed by [EME key system id](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMediaKeySystemAccess). Name every system you hold a license server for: which one gets negotiated is the browser’s choice.
|
|
28
|
+
|
|
29
|
+
tsx
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
<ShakaVideo
|
|
33
|
+
source={{
|
|
34
|
+
src: 'https://example.com/manifest.mpd',
|
|
35
|
+
drm: {
|
|
36
|
+
'com.widevine.alpha': { licenseUrl: 'https://example.com/widevine' },
|
|
37
|
+
'com.apple.fps': {
|
|
38
|
+
licenseUrl: 'https://example.com/fairplay',
|
|
39
|
+
serverCertificateUrl: 'https://example.com/fairplay.cer',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
}}
|
|
43
|
+
/>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
FairPlay needs a `serverCertificateUrl` unless its CDM is pre-provisioned; Widevine and PlayReady ignore it. `source.drm` takes the same shape as hls.js’s own `drmSystems`, so one object describes DRM for either engine.
|
|
47
|
+
|
|
48
|
+
For the parts of Shaka’s DRM configuration this doesn’t cover, configure Shaka directly. A `drm.servers` under `source.engine.shaka` replaces `source.drm` rather than merging with it.
|
|
49
|
+
|
|
50
|
+
## Behavior
|
|
51
|
+
|
|
52
|
+
* Adaptation stays within renditions no larger than the element rendering them, through Shaka’s `abr.restrictToElementSize`. Override it under `source.engine.shaka`.
|
|
53
|
+
* `preload="none"` defers the load until playback is asked for; `autoplay` or a `play()` counts as asking.
|
|
54
|
+
* `preload="metadata"` loads, then holds Shaka’s buffering goals down to a second until `preload` rises to `auto`.
|
|
55
|
+
* `streamType` is detected from the manifest, so a player skin renders live and on-demand content correctly without being told which it is.
|
|
56
|
+
* Changing `source.engine.shaka` reconfigures the running player in place instead of recreating it.
|
|
57
|
+
|
|
58
|
+
## Examples
|
|
59
|
+
|
|
60
|
+
### Basic Usage
|
|
61
|
+
|
|
62
|
+
App.tsx
|
|
63
|
+
|
|
64
|
+
App.css
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
import { ShakaVideo } from '@videojs/react/media/shaka-video';
|
|
68
|
+
|
|
69
|
+
export default function BasicUsage() {
|
|
70
|
+
return <ShakaVideo className="shaka-video" src="https://dash.akamaized.net/akamai/streamroot/050714/Spring_4Ktest.mpd" autoPlay muted playsInline loop />;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
```
|
|
74
|
+
.shaka-video {
|
|
75
|
+
width: 100%;
|
|
76
|
+
aspect-ratio: 16 / 9;
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## API Reference
|
|
81
|
+
|
|
82
|
+
### Props
|
|
83
|
+
|
|
84
|
+
Accepts the standard React props for a native `<video>`, plus these Video.js-specific props:
|
|
85
|
+
|
|
86
|
+
Prop
|
|
87
|
+
|
|
88
|
+
Type
|
|
89
|
+
|
|
90
|
+
Default
|
|
91
|
+
|
|
92
|
+
Details
|
|
93
|
+
|
|
94
|
+
`preload`
|
|
95
|
+
|
|
96
|
+
`MediaPreloadType`
|
|
97
|
+
|
|
98
|
+
`'metadata'`
|
|
99
|
+
|
|
100
|
+
▸
|
|
101
|
+
|
|
102
|
+
Description
|
|
103
|
+
|
|
104
|
+
How much to fetch before playback is asked for, mirroring the media element's own `preload`. Shaka has no split between "know the source" and "buffer it", so this maps onto when and how `engine.load()` runs:
|
|
105
|
+
|
|
106
|
+
* `'auto'` — load immediately with the configured buffering goals.
|
|
107
|
+
* `'metadata'` — load immediately, holding buffering to about a segment; the configured goals come back on the first play intent.
|
|
108
|
+
* `'none'` / `''` — hold the load entirely until the first play intent.
|
|
109
|
+
|
|
110
|
+
A play intent is a `play` event, a target that is already playing, or `autoplay` — which the spec lets override `preload` for good reason: with nothing fetched there is nothing whose readiness could ever fire it. Widening (`none` → `auto`) takes effect immediately; narrowing after a load began cannot un-fetch and leaves it alone.
|
|
111
|
+
|
|
112
|
+
`source`
|
|
113
|
+
|
|
114
|
+
`ShakaSource | null`
|
|
115
|
+
|
|
116
|
+
`null`
|
|
117
|
+
|
|
118
|
+
▸
|
|
119
|
+
|
|
120
|
+
Description
|
|
121
|
+
|
|
122
|
+
Structured source: what to play (`src`, an optional `type`) plus how to play it (`drm`, `engine.shaka`). Replacing it re-derives `src`.
|
|
123
|
+
|
|
124
|
+
Shaka takes configuration on a live player, so changing `engine.shaka` re-applies it in place instead of recreating the engine.
|
|
125
|
+
|
|
126
|
+
`src`
|
|
127
|
+
|
|
128
|
+
`string`
|
|
129
|
+
|
|
130
|
+
`''`
|
|
131
|
+
|
|
132
|
+
`streamType`
|
|
133
|
+
|
|
134
|
+
`MediaStreamType`
|
|
135
|
+
|
|
136
|
+
`'unknown'`
|
|
137
|
+
|
|
138
|
+
### Engine options
|
|
139
|
+
|
|
140
|
+
#### `source.engine.shaka`
|
|
141
|
+
|
|
142
|
+
Pass Shaka Player’s own configuration here. It’s handed to Shaka untouched, so every option in its [configuration reference](https://shaka-player-demo.appspot.com/docs/api/tutorial-config.html) works, spelled the way Shaka spells it. Replacing the object resets any configuration applied before it. [Media Sources](../concepts/media-sources.md) covers how engine options fit into a structured source.
|
|
143
|
+
|
|
144
|
+
Each entry below is a group of Shaka settings rather than a single value, and Shaka documents what’s inside them. The names and types come from Shaka’s own type definitions.
|
|
145
|
+
|
|
146
|
+
tsx
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
<ShakaVideo
|
|
150
|
+
source={{
|
|
151
|
+
src: 'https://example.com/manifest.mpd',
|
|
152
|
+
engine: { shaka: { streaming: { bufferingGoal: 30 } } },
|
|
153
|
+
}}
|
|
154
|
+
/>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Option
|
|
158
|
+
|
|
159
|
+
Type
|
|
160
|
+
|
|
161
|
+
Details
|
|
162
|
+
|
|
163
|
+
`abr`
|
|
164
|
+
|
|
165
|
+
`object`
|
|
166
|
+
|
|
167
|
+
▸
|
|
168
|
+
|
|
169
|
+
Type
|
|
170
|
+
|
|
171
|
+
`{ advanced?: { droppedFramesBanDuration?: number; droppedFramesInterval?: number; droppedFramesThreshold?: number; fastHalfLife?: number; minBytes?: number; minTotalBytes?: number; slowHalfLife?: number; }; ... 15 more ...; useNetworkInformation?: boolean; }`
|
|
172
|
+
|
|
173
|
+
`abrFactory`
|
|
174
|
+
|
|
175
|
+
`Factory`
|
|
176
|
+
|
|
177
|
+
`accessibility`
|
|
178
|
+
|
|
179
|
+
`object`
|
|
180
|
+
|
|
181
|
+
▸
|
|
182
|
+
|
|
183
|
+
Type
|
|
184
|
+
|
|
185
|
+
`{ handleForcedSubtitlesAutomatically?: boolean; speechToText?: { enabled?: boolean; languagesToTranslate?: string[]; maxTextLength?: number; processLocally?: boolean; }; }`
|
|
186
|
+
|
|
187
|
+
`adaptationSetCriteriaFactory`
|
|
188
|
+
|
|
189
|
+
`Factory`
|
|
190
|
+
|
|
191
|
+
`ads`
|
|
192
|
+
|
|
193
|
+
`object`
|
|
194
|
+
|
|
195
|
+
▸
|
|
196
|
+
|
|
197
|
+
Type
|
|
198
|
+
|
|
199
|
+
`{ allowPreloadOnDomElements?: boolean; allowStartInMiddleOfInterstitial?: boolean; customPlayheadTracker?: boolean; disableDASHInterstitial?: boolean; disableHLSInterstitial?: boolean; ... 6 more ...; supportsMultipleMediaElements?: boolean; }`
|
|
200
|
+
|
|
201
|
+
`cmcd`
|
|
202
|
+
|
|
203
|
+
`object`
|
|
204
|
+
|
|
205
|
+
▸
|
|
206
|
+
|
|
207
|
+
Type
|
|
208
|
+
|
|
209
|
+
`{ contentId?: string; enabled?: boolean; eventTargets?: CmcdTarget[] | null; includeKeys?: string[]; rtpSafetyFactor?: number; sessionId?: string; useHeaders?: boolean; version?: number; }`
|
|
210
|
+
|
|
211
|
+
`cmsd`
|
|
212
|
+
|
|
213
|
+
`object`
|
|
214
|
+
|
|
215
|
+
▸
|
|
216
|
+
|
|
217
|
+
Type
|
|
218
|
+
|
|
219
|
+
`{ applyMaximumSuggestedBitrate?: boolean; enabled?: boolean; estimatedThroughputWeightRatio?: number; }`
|
|
220
|
+
|
|
221
|
+
`drm`
|
|
222
|
+
|
|
223
|
+
`object`
|
|
224
|
+
|
|
225
|
+
▸
|
|
226
|
+
|
|
227
|
+
Type
|
|
228
|
+
|
|
229
|
+
`{ advanced?: { [x: string]: { audioRobustness?: string[] | null; distinctiveIdentifierRequired?: boolean; headers?: { [x: string]: string | undefined; }; individualizationServer?: string; persistentStateRequired?: boolean; serverCertificate?: Uint8Array<...> | null; serverCertificateUri?: string; sessionType?: strin...`
|
|
230
|
+
|
|
231
|
+
`ignoreHardwareResolution`
|
|
232
|
+
|
|
233
|
+
`boolean`
|
|
234
|
+
|
|
235
|
+
`lcevc`
|
|
236
|
+
|
|
237
|
+
`object`
|
|
238
|
+
|
|
239
|
+
▸
|
|
240
|
+
|
|
241
|
+
Type
|
|
242
|
+
|
|
243
|
+
`{ drawLogo?: boolean; dynamicPerformanceScaling?: boolean; enabled?: boolean; logLevel?: number; poster?: boolean; }`
|
|
244
|
+
|
|
245
|
+
`manifest`
|
|
246
|
+
|
|
247
|
+
`object`
|
|
248
|
+
|
|
249
|
+
▸
|
|
250
|
+
|
|
251
|
+
Type
|
|
252
|
+
|
|
253
|
+
`{ availabilityWindowOverride?: number; continueLoadingWhenPaused?: boolean; dash?: { autoCorrectDrift?: boolean; clockSyncUri?: string; enableFastSwitching?: boolean; ignoreEmptyAdaptationSet?: boolean; ... 8 more ...; xlinkFailGracefully?: boolean; }; ... 15 more ...; updatePeriod?: number; }`
|
|
254
|
+
|
|
255
|
+
`mediaSource`
|
|
256
|
+
|
|
257
|
+
`function`
|
|
258
|
+
|
|
259
|
+
▸
|
|
260
|
+
|
|
261
|
+
Type
|
|
262
|
+
|
|
263
|
+
`{ addExtraFeaturesToSourceBuffer?: (a: string) => string; codecSwitchingStrategy?: CodecSwitchingStrategy; correctEc3Enca?: boolean; dispatchAllEmsgBoxes?: boolean; ... 6 more ...; useSourceElements?: boolean; }`
|
|
264
|
+
|
|
265
|
+
`networking`
|
|
266
|
+
|
|
267
|
+
`object`
|
|
268
|
+
|
|
269
|
+
▸
|
|
270
|
+
|
|
271
|
+
Type
|
|
272
|
+
|
|
273
|
+
`{ commonAccessTokenHeaderName?: string; forceHTTP?: boolean; forceHTTPS?: boolean; minBytesForProgressEvents?: number; }`
|
|
274
|
+
|
|
275
|
+
`offline`
|
|
276
|
+
|
|
277
|
+
`function`
|
|
278
|
+
|
|
279
|
+
▸
|
|
280
|
+
|
|
281
|
+
Type
|
|
282
|
+
|
|
283
|
+
`{ downloadSizeCallback?: (a: number) => Promise<boolean>; numberOfParallelDownloads?: number; progressCallback?: (a: StoredContent, b: number) => any; trackSelectionCallback?: (a: TrackList) => Promise<...>; usePersistentLicense?: boolean; }`
|
|
284
|
+
|
|
285
|
+
`playRangeEnd`
|
|
286
|
+
|
|
287
|
+
`number`
|
|
288
|
+
|
|
289
|
+
`playRangeStart`
|
|
290
|
+
|
|
291
|
+
`number`
|
|
292
|
+
|
|
293
|
+
`preferredAudio`
|
|
294
|
+
|
|
295
|
+
`AudioPreference[]`
|
|
296
|
+
|
|
297
|
+
`preferredDecodingAttributes`
|
|
298
|
+
|
|
299
|
+
`string[]`
|
|
300
|
+
|
|
301
|
+
`preferredText`
|
|
302
|
+
|
|
303
|
+
`TextPreference[]`
|
|
304
|
+
|
|
305
|
+
`preferredVideo`
|
|
306
|
+
|
|
307
|
+
`VideoPreference[]`
|
|
308
|
+
|
|
309
|
+
`queue`
|
|
310
|
+
|
|
311
|
+
`object`
|
|
312
|
+
|
|
313
|
+
▸
|
|
314
|
+
|
|
315
|
+
Type
|
|
316
|
+
|
|
317
|
+
`{ preloadNextUrlWindow?: number; preloadPrevItem?: boolean; repeatMode?: RepeatMode; }`
|
|
318
|
+
|
|
319
|
+
`restrictions`
|
|
320
|
+
|
|
321
|
+
`object`
|
|
322
|
+
|
|
323
|
+
▸
|
|
324
|
+
|
|
325
|
+
Type
|
|
326
|
+
|
|
327
|
+
`{ maxBandwidth?: number; maxChannelsCount?: number; maxFrameRate?: number; maxHeight?: number; maxPixels?: number; maxWidth?: number; minBandwidth?: number; minChannelsCount?: number; minFrameRate?: number; minHeight?: number; minPixels?: number; minWidth?: number; }`
|
|
328
|
+
|
|
329
|
+
`streaming`
|
|
330
|
+
|
|
331
|
+
`object`
|
|
332
|
+
|
|
333
|
+
▸
|
|
334
|
+
|
|
335
|
+
Type
|
|
336
|
+
|
|
337
|
+
`{ allowMediaSourceRecoveries?: boolean; avoidEvictionOnQuotaExceededError?: boolean; bufferBehind?: number; bufferingGoal?: number; clampAppendWindowToDuration?: boolean; clearDecodingCache?: boolean; ... 40 more ...; vodDynamicPlaybackRateLowBufferRate?: number; }`
|
|
338
|
+
|
|
339
|
+
`textDisplayer`
|
|
340
|
+
|
|
341
|
+
`object`
|
|
342
|
+
|
|
343
|
+
▸
|
|
344
|
+
|
|
345
|
+
Type
|
|
346
|
+
|
|
347
|
+
`{ fontScaleFactor?: number; positionArea?: PositionArea; subtitleDelay?: number; suspendRenderingWhenHidden?: boolean; }`
|
|
348
|
+
|
|
349
|
+
`textDisplayFactory`
|
|
350
|
+
|
|
351
|
+
`Factory`
|
|
352
|
+
|
|
353
|
+
### Ref
|
|
354
|
+
|
|
355
|
+
Forwards its ref to the rendered `<video>`. The ref is an [HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement) and exposes its complete native property and method API.
|
|
356
|
+
|
|
357
|
+
### Events
|
|
358
|
+
|
|
359
|
+
Handle standard media events with React event props such as `onPlay` and `onTimeUpdate`. For native events without a React prop, attach a listener through the ref with `addEventListener`.
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# SpotifyAudio
|
|
2
|
+
|
|
3
|
+
Audio component that plays Spotify tracks, episodes, playlists, and shows through the Spotify embed
|
|
4
|
+
|
|
5
|
+
Audio component that plays Spotify content through the [Spotify embed](https://developer.spotify.com/documentation/embeds): tracks, episodes, albums, playlists, shows, and artists. Podcast episodes play in full for signed-out listeners; music plays as a preview until the listener logs in to Spotify.
|
|
6
|
+
|
|
7
|
+
## Load a source
|
|
8
|
+
|
|
9
|
+
`src` takes an `open.spotify.com` URL for any embeddable entity, including the localized (`/intl-de/`) and already-embedded (`/embed/`) forms, or a `spotify:<type>:<id>` URI. A `t` parameter sets the start position in seconds.
|
|
10
|
+
|
|
11
|
+
tsx
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
<SpotifyAudio src="https://open.spotify.com/episode/7makk4oTQel546B0PZlDM5" controls />
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Controls
|
|
18
|
+
|
|
19
|
+
Spotify’s own chrome is the only UI the embed offers, so `controls` decides whether the element is visible at all. With `controls`, it shows Spotify’s player. Without it, the element hides itself and plays as an invisible transport: a hidden iframe still loads and plays, so a [player skin](../concepts/skins.md)’s buttons drive playback while the embed takes no room on the page.
|
|
20
|
+
|
|
21
|
+
## Behavior
|
|
22
|
+
|
|
23
|
+
The Spotify embed exposes less than a native `<audio>` element:
|
|
24
|
+
|
|
25
|
+
* No volume and no mute: the embed takes neither command and reports neither value, so a player skin shows no volume controls at all.
|
|
26
|
+
* No playback rate and no text tracks.
|
|
27
|
+
* `loop` replays the entity from the top when it ends; without it, the embed continues into whatever Spotify queues next.
|
|
28
|
+
|
|
29
|
+
## Examples
|
|
30
|
+
|
|
31
|
+
### Basic Usage
|
|
32
|
+
|
|
33
|
+
App.tsx
|
|
34
|
+
|
|
35
|
+
App.css
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
import { SpotifyAudio } from '@videojs/react/media/spotify-audio';
|
|
39
|
+
|
|
40
|
+
export default function BasicUsage() {
|
|
41
|
+
return (
|
|
42
|
+
<div className="spotify-audio">
|
|
43
|
+
<SpotifyAudio src="https://open.spotify.com/episode/7makk4oTQel546B0PZlDM5" controls />
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
```
|
|
49
|
+
.spotify-audio {
|
|
50
|
+
width: 100%;
|
|
51
|
+
height: 152px;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## API Reference
|
|
56
|
+
|
|
57
|
+
### Props
|
|
58
|
+
|
|
59
|
+
Accepts these Video.js-specific props:
|
|
60
|
+
|
|
61
|
+
Prop
|
|
62
|
+
|
|
63
|
+
Type
|
|
64
|
+
|
|
65
|
+
Default
|
|
66
|
+
|
|
67
|
+
Details
|
|
68
|
+
|
|
69
|
+
`autoplay`
|
|
70
|
+
|
|
71
|
+
`boolean`
|
|
72
|
+
|
|
73
|
+
`false`
|
|
74
|
+
|
|
75
|
+
`controls`
|
|
76
|
+
|
|
77
|
+
`boolean`
|
|
78
|
+
|
|
79
|
+
`false`
|
|
80
|
+
|
|
81
|
+
`loop`
|
|
82
|
+
|
|
83
|
+
`boolean`
|
|
84
|
+
|
|
85
|
+
`false`
|
|
86
|
+
|
|
87
|
+
`playsInline`
|
|
88
|
+
|
|
89
|
+
`boolean`
|
|
90
|
+
|
|
91
|
+
`true`
|
|
92
|
+
|
|
93
|
+
`poster`
|
|
94
|
+
|
|
95
|
+
`string`
|
|
96
|
+
|
|
97
|
+
`''`
|
|
98
|
+
|
|
99
|
+
`preload`
|
|
100
|
+
|
|
101
|
+
`MediaPreloadType`
|
|
102
|
+
|
|
103
|
+
`'metadata'`
|
|
104
|
+
|
|
105
|
+
`source`
|
|
106
|
+
|
|
107
|
+
`SpotifySource | null`
|
|
108
|
+
|
|
109
|
+
`null`
|
|
110
|
+
|
|
111
|
+
▸
|
|
112
|
+
|
|
113
|
+
Description
|
|
114
|
+
|
|
115
|
+
Spotify URL or URI in `src`, plus embed options under `engine.spotify`. Replacing it re-derives `src`.
|
|
116
|
+
|
|
117
|
+
`src`
|
|
118
|
+
|
|
119
|
+
`string`
|
|
120
|
+
|
|
121
|
+
`''`
|
|
122
|
+
|
|
123
|
+
### Engine options
|
|
124
|
+
|
|
125
|
+
#### `source.engine.spotify`
|
|
126
|
+
|
|
127
|
+
Pass [Spotify embed options](https://developer.spotify.com/documentation/embeds) under `source.engine.spotify`, spelled exactly as Spotify spells them, plus anything Spotify adds next. [Media Sources](../concepts/media-sources.md) covers how engine options fit into a structured source.
|
|
128
|
+
|
|
129
|
+
tsx
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
<SpotifyAudio
|
|
133
|
+
source={{
|
|
134
|
+
src: 'https://open.spotify.com/episode/7makk4oTQel546B0PZlDM5',
|
|
135
|
+
engine: { spotify: { t: 90, theme: 0 } },
|
|
136
|
+
}}
|
|
137
|
+
/>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Option
|
|
141
|
+
|
|
142
|
+
Type
|
|
143
|
+
|
|
144
|
+
Details
|
|
145
|
+
|
|
146
|
+
`preferVideo`
|
|
147
|
+
|
|
148
|
+
`boolean`
|
|
149
|
+
|
|
150
|
+
▸
|
|
151
|
+
|
|
152
|
+
Description
|
|
153
|
+
|
|
154
|
+
Embed the video variant of an episode when it has one. Not a URL parameter: the video embed lives at its own path.
|
|
155
|
+
|
|
156
|
+
`referrerPolicy`
|
|
157
|
+
|
|
158
|
+
`ReferrerPolicy`
|
|
159
|
+
|
|
160
|
+
▸
|
|
161
|
+
|
|
162
|
+
Description
|
|
163
|
+
|
|
164
|
+
`referrerpolicy` for the embed iframe. Not a Spotify embed parameter.
|
|
165
|
+
|
|
166
|
+
`t`
|
|
167
|
+
|
|
168
|
+
`number`
|
|
169
|
+
|
|
170
|
+
▸
|
|
171
|
+
|
|
172
|
+
Description
|
|
173
|
+
|
|
174
|
+
Start position in seconds.
|
|
175
|
+
|
|
176
|
+
`theme`
|
|
177
|
+
|
|
178
|
+
`0`
|
|
179
|
+
|
|
180
|
+
▸
|
|
181
|
+
|
|
182
|
+
Description
|
|
183
|
+
|
|
184
|
+
`0` renders the embed in its dark theme. Defaults to the light theme. Spotify documents no other value, and the embed goes by whether the parameter is there, so leaving it out is the only way to ask for the default.
|
|
185
|
+
|
|
186
|
+
### Ref
|
|
187
|
+
|
|
188
|
+
Forwards its ref to the rendered `<iframe>`. The ref is an [HTMLIFrameElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement). Control playback with the component props and player APIs rather than the iframe ref.
|