@videojs/soundcloud-audio 0.0.0-stage → 10.3.0
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/LICENSE +20 -0
- package/README.md +24 -2
- package/dist/default/adapter.js +733 -0
- package/dist/default/index.js +3 -0
- package/dist/default/source.js +53 -0
- package/dist/default/widget-api.js +33 -0
- package/dist/dev/adapter.d.ts +82 -0
- package/dist/dev/adapter.js +735 -0
- package/dist/dev/adapter.js.map +1 -0
- package/dist/dev/index.d.ts +4 -0
- package/dist/dev/index.js +3 -0
- package/dist/dev/props.d.ts +13 -0
- package/dist/dev/source.d.ts +82 -0
- package/dist/dev/source.js +55 -0
- package/dist/dev/source.js.map +1 -0
- package/dist/dev/widget-api.js +35 -0
- package/dist/dev/widget-api.js.map +1 -0
- package/package.json +48 -3
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { buildSoundCloudIframeSrc, buildSoundCloudWidgetUrl, parseSoundCloudSource, wantsSoundCloudAutoplay } from "./source.js";
|
|
2
|
+
import { SoundCloudAdapter } from "./adapter.js";
|
|
3
|
+
export { SoundCloudAdapter, buildSoundCloudIframeSrc, buildSoundCloudWidgetUrl, parseSoundCloudSource, wantsSoundCloudAutoplay };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { WIDGET_ORIGIN } from "./widget-api.js";
|
|
2
|
+
import { parseSoundCloudSource, parseSoundCloudSource as parseSoundCloudSource$1 } from "@videojs/media";
|
|
3
|
+
//#region src/source.ts
|
|
4
|
+
/**
|
|
5
|
+
* Build the widget iframe URL for a source. Empty when `src` is not a SoundCloud URL.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
function buildSoundCloudIframeSrc(src, props = {}) {
|
|
10
|
+
const parsed = parseSoundCloudSource(src);
|
|
11
|
+
if (!parsed) return "";
|
|
12
|
+
return buildSoundCloudWidgetUrl(parsed.url, parsed, props);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Build the widget iframe URL for a resource URL the widget plays, carrying the parameters of the source it came from.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
function buildSoundCloudWidgetUrl(resourceUrl, parsed, props = {}) {
|
|
20
|
+
const { referrerPolicy: _referrerPolicy, ...engine } = props.source?.engine?.soundcloud ?? {};
|
|
21
|
+
const params = {
|
|
22
|
+
...DEFAULT_PARAMS,
|
|
23
|
+
...parsed.params,
|
|
24
|
+
...engine
|
|
25
|
+
};
|
|
26
|
+
const query = new URLSearchParams({ url: resourceUrl });
|
|
27
|
+
for (const [key, value] of Object.entries(params)) {
|
|
28
|
+
if (key === "url" || key === "auto_play" || value === null || value === void 0) continue;
|
|
29
|
+
query.set(key, String(value));
|
|
30
|
+
}
|
|
31
|
+
return `${WIDGET_ORIGIN}/player/?${query}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Whether the source asks to autoplay through the widget's own `auto_play` parameter.
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
function wantsSoundCloudAutoplay(parsed, source) {
|
|
39
|
+
const value = source?.engine?.soundcloud?.auto_play ?? parsed?.params.auto_play;
|
|
40
|
+
return value === true || value === "true";
|
|
41
|
+
}
|
|
42
|
+
const DEFAULT_PARAMS = {
|
|
43
|
+
visual: false,
|
|
44
|
+
hide_related: true,
|
|
45
|
+
show_comments: false,
|
|
46
|
+
show_reposts: false,
|
|
47
|
+
show_teaser: false,
|
|
48
|
+
buying: false,
|
|
49
|
+
sharing: false,
|
|
50
|
+
download: false
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
export { buildSoundCloudIframeSrc, buildSoundCloudWidgetUrl, parseSoundCloudSource$1 as parseSoundCloudSource, wantsSoundCloudAutoplay };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isNumber, isObject, isString } from "@videojs/utils/predicate";
|
|
2
|
+
//#region src/widget-api.ts
|
|
3
|
+
/** Where the widget is served from: commands are posted to it, and only its messages are read. */
|
|
4
|
+
const WIDGET_ORIGIN = "https://w.soundcloud.com";
|
|
5
|
+
/** Read a `message` event's data as a widget message; anything else another frame posts comes back null. */
|
|
6
|
+
function parseSoundCloudMessage(data) {
|
|
7
|
+
if (!isString(data) || !data.includes("\"method\"")) return null;
|
|
8
|
+
let message;
|
|
9
|
+
try {
|
|
10
|
+
message = JSON.parse(data);
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
return isObject(message) && isString(message.method) ? message : null;
|
|
15
|
+
}
|
|
16
|
+
function createSoundCloudCommand(method, value) {
|
|
17
|
+
return JSON.stringify(value === void 0 ? { method } : {
|
|
18
|
+
method,
|
|
19
|
+
value
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function isSoundCloudProgress(value) {
|
|
23
|
+
if (!isObject(value)) return false;
|
|
24
|
+
const { currentPosition } = value;
|
|
25
|
+
return isNumber(currentPosition);
|
|
26
|
+
}
|
|
27
|
+
/** The share of the sound the widget has loaded, under either spelling. */
|
|
28
|
+
function loadedShareOf(progress) {
|
|
29
|
+
const share = progress.loadedProgress ?? progress.loadProgress;
|
|
30
|
+
return isNumber(share) ? share : void 0;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { WIDGET_ORIGIN, createSoundCloudCommand, isSoundCloudProgress, loadedShareOf, parseSoundCloudMessage };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { SoundCloudSource } from "./source.js";
|
|
2
|
+
import { SoundCloudAdapterProps } from "./props.js";
|
|
3
|
+
import { MediaContentData, MediaError, Video } from "@videojs/media";
|
|
4
|
+
//#region src/adapter.d.ts
|
|
5
|
+
declare const SoundCloudAdapter_base: import("@videojs/utils/types").MixinReturn<{
|
|
6
|
+
new (): EventTarget;
|
|
7
|
+
prototype: EventTarget;
|
|
8
|
+
}, import("@videojs/media/dom").MediaPlayedRangesAPI>;
|
|
9
|
+
/**
|
|
10
|
+
* Plays SoundCloud tracks and sets through the SoundCloud Widget. A set plays as one source: moving to another track
|
|
11
|
+
* reports a new `duration` and restarts `currentTime`, and `ended` fires once the last track ends. The widget stays
|
|
12
|
+
* visible and takes input, since it is what credits the uploader and SoundCloud; what it does is reported like anything
|
|
13
|
+
* the host asked for.
|
|
14
|
+
*
|
|
15
|
+
* @fires sourcechange - Fired when `source` changes, either directly or by resolving a new `src`. Read `source` for the
|
|
16
|
+
* new value.
|
|
17
|
+
* @fires contentdatachange - Fired when the widget reports the title and artwork of a track, and when they are cleared.
|
|
18
|
+
* Read `contentData` for them.
|
|
19
|
+
*/
|
|
20
|
+
export declare class SoundCloudAdapter extends SoundCloudAdapter_base implements Partial<Video> {
|
|
21
|
+
#private;
|
|
22
|
+
static readonly defaultProps: SoundCloudAdapterProps;
|
|
23
|
+
static PLAYER_SOFTWARE_NAME: string;
|
|
24
|
+
/** The widget's window, which commands are posted to. Null until rendered. */
|
|
25
|
+
get engine(): Window | null;
|
|
26
|
+
get target(): HTMLIFrameElement | null;
|
|
27
|
+
/** Bind the iframe hosting the widget. The widget follows once a `src` resolves, which may be after attach. */
|
|
28
|
+
attach(target: HTMLIFrameElement | null): void;
|
|
29
|
+
detach(): void;
|
|
30
|
+
destroy(): void;
|
|
31
|
+
get src(): string;
|
|
32
|
+
/** SoundCloud URL. Setting it re-derives `source`, carrying its engine options over. */
|
|
33
|
+
set src(value: string);
|
|
34
|
+
get currentSrc(): string;
|
|
35
|
+
get readyState(): number;
|
|
36
|
+
/** Point the widget at the current source; rewriting the iframe URL is the only load the widget takes parameters on. */
|
|
37
|
+
load(): Promise<void>;
|
|
38
|
+
get paused(): boolean;
|
|
39
|
+
get ended(): boolean;
|
|
40
|
+
get seeking(): boolean;
|
|
41
|
+
play(): Promise<void>;
|
|
42
|
+
pause(): void;
|
|
43
|
+
get currentTime(): number;
|
|
44
|
+
set currentTime(value: number);
|
|
45
|
+
get duration(): number;
|
|
46
|
+
get volume(): number;
|
|
47
|
+
set volume(value: number);
|
|
48
|
+
get muted(): boolean;
|
|
49
|
+
set muted(value: boolean);
|
|
50
|
+
/** Starts playback once the widget is ready, after the volume and start position apply. Browsers may refuse it. */
|
|
51
|
+
get autoplay(): boolean;
|
|
52
|
+
set autoplay(value: boolean);
|
|
53
|
+
get defaultMuted(): boolean;
|
|
54
|
+
set defaultMuted(value: boolean);
|
|
55
|
+
/** Replays the track, or a set from its first track, when the last one ends. */
|
|
56
|
+
get loop(): boolean;
|
|
57
|
+
set loop(value: boolean);
|
|
58
|
+
get controls(): boolean;
|
|
59
|
+
set controls(value: boolean);
|
|
60
|
+
get playsInline(): boolean;
|
|
61
|
+
set playsInline(value: boolean);
|
|
62
|
+
get preload(): import("@videojs/media").MediaPreloadType;
|
|
63
|
+
set preload(value: import("@videojs/media").MediaPreloadType);
|
|
64
|
+
get poster(): string;
|
|
65
|
+
set poster(value: string);
|
|
66
|
+
/** SoundCloud URL in `src`, widget parameters under `engine.soundcloud`. Replacing it re-derives `src`. */
|
|
67
|
+
get source(): SoundCloudSource | null;
|
|
68
|
+
set source(value: SoundCloudSource | null);
|
|
69
|
+
/** The stretch the widget reports loaded, from where playback last started or landed. */
|
|
70
|
+
get buffered(): import("@videojs/media").TimeRangeLike;
|
|
71
|
+
get seekable(): import("@videojs/media").TimeRangeLike;
|
|
72
|
+
get error(): MediaError | null;
|
|
73
|
+
/**
|
|
74
|
+
* The `title` and `poster` of the track playing, which change with each track of a set. Empty until the widget
|
|
75
|
+
* reports them, and again across a source change. `contentdatachange` announces both.
|
|
76
|
+
*/
|
|
77
|
+
get contentData(): MediaContentData;
|
|
78
|
+
/** Always empty: SoundCloud has no captions or other text tracks. */
|
|
79
|
+
get textTracks(): import("@videojs/media").TextTrackListLike;
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
//# sourceMappingURL=adapter.d.ts.map
|