MCPcopy
hub / github.com/surmon-china/videojs-player / createPlayer

Function createPlayer

player/player.ts:28–153  ·  view source on GitHub ↗
({ props, element, className, onEvent }: CreatePlayerOptions)

Source from the content-addressed store, hash-verified

26
27export type PlayerResult = ReturnType<typeof createPlayer>
28export const createPlayer = ({ props, element, className, onEvent }: CreatePlayerOptions) => {
29 // Exclude fallback options.
30 const { options: fallbackOptions = {}, ...optProps } = props
31
32 // Exclude undefined value.
33 const propOptions: Omit<Props, 'options'> = {}
34 const optPropKeys = Object.keys(optProps) as Array<keyof typeof optProps>
35 optPropKeys.forEach((key) => {
36 const value = optProps[key]
37 if (value !== undefined) {
38 // @ts-ignore
39 propOptions[key] = value
40 }
41 })
42
43 // Merge fallback options & exclude component options.
44 const { volume, playbackRate, ...initOptions } = {
45 ...propOptions,
46 ...fallbackOptions
47 }
48
49 // Merge some confusing prop names.
50 const videoJsOptions = {
51 ...initOptions,
52 // https://videojs.com/guides/options/#restoreel
53 // Since the dispose > restore element side effect of Video.js occurs after the component has been unmounted,
54 // a DOM retention error will occur if true, so it cannot be set to true.
55 // restoreEl: initOptions.restoreEl ?? false,
56 // Video.js only supports the `playsinline` property.
57 playsinline: initOptions.playsinline ?? initOptions.playsInline
58 }
59
60 // https://videojs.com/guides/embeds/
61 // https://videojs.com/guides/react/
62 // MARK: Player div ingest
63 // There are three ways to initialize a player, the "Player div ingest" type is the most suitable in a component scenario
64 // because it generates the least amount of DOM side effects,
65 // and this way it can fully utilize the existing div outer container and video elements without changing the DOM structure.
66 // The problem is that the Video.js player, when instantiated, reads the className property of the video element as the className of the outer container,
67 // but the component needs to satisfy the user's need to "be able to use the className to specify the style from the moment the component is rendered".
68 // So we need to assume that only the className specified by the user through the component is needed for style control,
69 // while the basic "video-js" - like className is another internal className with a specific side effect and used only for initializing the player.
70 // So we need to distinguish the className into innerClassName, which is controlled internally by the component and remains unchanged,
71 // and userClassName, which will be applied to the container element at times like init and change.
72 // The reason why userClassName cannot be used directly as className for video elements is that it may cause unintended style side effects,
73 // such as misalignment or recursive styles, due to the different DOM hierarchy.
74 // MARK: RawHTML
75 // A better solution may exist to create the player with a freshly created video element while maintaining a mounted identifier,
76 // and when the player is instantiated, return the instantiated DOM entirely through the component,
77 // but this relies on the framework supporting a RawHTML - like API - https://github.com/ reactjs/rfcs/pull/129
78 // Custom controls capabilities can be implemented through the Video.js Component - https://videojs.com/guides/react/
79 const player = videoJs(element, videoJsOptions, function () {
80 // Stringing video.js events to vue emits.
81 events.forEach((eventKey) => {
82 this.on(eventKey, (payload) => {
83 onEvent(eventKey, payload)
84 })
85 })

Callers 2

VideoPlayerFunction · 0.90
setupFunction · 0.90

Calls 2

onEventFunction · 0.85
standardizeClassFunction · 0.85

Tested by

no test coverage detected