lx-video-player 1.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-player.js","sources":["../node_modules/@vue/web-component-wrapper/dist/vue-wc-wrapper.js","../src/types/index.ts","../src/utils/agent.ts","../src/utils/player.ts","../src/components/VideoPlayer.vue","../src/index.ts"],"sourcesContent":["const camelizeRE = /-(\\w)/g;\nconst camelize = str => {\n return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')\n};\n\nconst hyphenateRE = /\\B([A-Z])/g;\nconst hyphenate = str => {\n return str.replace(hyphenateRE, '-$1').toLowerCase()\n};\n\nfunction getInitialProps (propsList) {\n const res = {};\n propsList.forEach(key => {\n res[key] = undefined;\n });\n return res\n}\n\nfunction injectHook (options, key, hook) {\n options[key] = [].concat(options[key] || []);\n options[key].unshift(hook);\n}\n\nfunction callHooks (vm, hook) {\n if (vm) {\n const hooks = vm.$options[hook] || [];\n hooks.forEach(hook => {\n hook.call(vm);\n });\n }\n}\n\nfunction createCustomEvent (name, args) {\n return new CustomEvent(name, {\n bubbles: false,\n cancelable: false,\n detail: args\n })\n}\n\nconst isBoolean = val => /function Boolean/.test(String(val));\nconst isNumber = val => /function Number/.test(String(val));\n\nfunction convertAttributeValue (value, name, { type } = {}) {\n if (isBoolean(type)) {\n if (value === 'true' || value === 'false') {\n return value === 'true'\n }\n if (value === '' || value === name || value != null) {\n return true\n }\n return value\n } else if (isNumber(type)) {\n const parsed = parseFloat(value, 10);\n return isNaN(parsed) ? value : parsed\n } else {\n return value\n }\n}\n\nfunction toVNodes (h, children) {\n const res = [];\n for (let i = 0, l = children.length; i < l; i++) {\n res.push(toVNode(h, children[i]));\n }\n return res\n}\n\nfunction toVNode (h, node) {\n if (node.nodeType === 3) {\n return node.data.trim() ? node.data : null\n } else if (node.nodeType === 1) {\n const data = {\n attrs: getAttributes(node),\n domProps: {\n innerHTML: node.innerHTML\n }\n };\n if (data.attrs.slot) {\n data.slot = data.attrs.slot;\n delete data.attrs.slot;\n }\n return h(node.tagName, data)\n } else {\n return null\n }\n}\n\nfunction getAttributes (node) {\n const res = {};\n for (let i = 0, l = node.attributes.length; i < l; i++) {\n const attr = node.attributes[i];\n res[attr.nodeName] = attr.nodeValue;\n }\n return res\n}\n\nfunction wrap (Vue, Component) {\n const isAsync = typeof Component === 'function' && !Component.cid;\n let isInitialized = false;\n let hyphenatedPropsList;\n let camelizedPropsList;\n let camelizedPropsMap;\n\n function initialize (Component) {\n if (isInitialized) return\n\n const options = typeof Component === 'function'\n ? Component.options\n : Component;\n\n // extract props info\n const propsList = Array.isArray(options.props)\n ? options.props\n : Object.keys(options.props || {});\n hyphenatedPropsList = propsList.map(hyphenate);\n camelizedPropsList = propsList.map(camelize);\n const originalPropsAsObject = Array.isArray(options.props) ? {} : options.props || {};\n camelizedPropsMap = camelizedPropsList.reduce((map, key, i) => {\n map[key] = originalPropsAsObject[propsList[i]];\n return map\n }, {});\n\n // proxy $emit to native DOM events\n injectHook(options, 'beforeCreate', function () {\n const emit = this.$emit;\n this.$emit = (name, ...args) => {\n this.$root.$options.customElement.dispatchEvent(createCustomEvent(name, args));\n return emit.call(this, name, ...args)\n };\n });\n\n injectHook(options, 'created', function () {\n // sync default props values to wrapper on created\n camelizedPropsList.forEach(key => {\n this.$root.props[key] = this[key];\n });\n });\n\n // proxy props as Element properties\n camelizedPropsList.forEach(key => {\n Object.defineProperty(CustomElement.prototype, key, {\n get () {\n return this._wrapper.props[key]\n },\n set (newVal) {\n this._wrapper.props[key] = newVal;\n },\n enumerable: false,\n configurable: true\n });\n });\n\n isInitialized = true;\n }\n\n function syncAttribute (el, key) {\n const camelized = camelize(key);\n const value = el.hasAttribute(key) ? el.getAttribute(key) : undefined;\n el._wrapper.props[camelized] = convertAttributeValue(\n value,\n key,\n camelizedPropsMap[camelized]\n );\n }\n\n class CustomElement extends HTMLElement {\n constructor () {\n const self = super();\n self.attachShadow({ mode: 'open' });\n\n const wrapper = self._wrapper = new Vue({\n name: 'shadow-root',\n customElement: self,\n shadowRoot: self.shadowRoot,\n data () {\n return {\n props: {},\n slotChildren: []\n }\n },\n render (h) {\n return h(Component, {\n ref: 'inner',\n props: this.props\n }, this.slotChildren)\n }\n });\n\n // Use MutationObserver to react to future attribute & slot content change\n const observer = new MutationObserver(mutations => {\n let hasChildrenChange = false;\n for (let i = 0; i < mutations.length; i++) {\n const m = mutations[i];\n if (isInitialized && m.type === 'attributes' && m.target === self) {\n syncAttribute(self, m.attributeName);\n } else {\n hasChildrenChange = true;\n }\n }\n if (hasChildrenChange) {\n wrapper.slotChildren = Object.freeze(toVNodes(\n wrapper.$createElement,\n self.childNodes\n ));\n }\n });\n observer.observe(self, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true\n });\n }\n\n get vueComponent () {\n return this._wrapper.$refs.inner\n }\n\n connectedCallback () {\n const wrapper = this._wrapper;\n if (!wrapper._isMounted) {\n // initialize attributes\n const syncInitialAttributes = () => {\n wrapper.props = getInitialProps(camelizedPropsList);\n hyphenatedPropsList.forEach(key => {\n syncAttribute(this, key);\n });\n };\n\n if (isInitialized) {\n syncInitialAttributes();\n } else {\n // async & unresolved\n Component().then(resolved => {\n if (resolved.__esModule || resolved[Symbol.toStringTag] === 'Module') {\n resolved = resolved.default;\n }\n initialize(resolved);\n syncInitialAttributes();\n });\n }\n // initialize children\n wrapper.slotChildren = Object.freeze(toVNodes(\n wrapper.$createElement,\n this.childNodes\n ));\n wrapper.$mount();\n this.shadowRoot.appendChild(wrapper.$el);\n } else {\n callHooks(this.vueComponent, 'activated');\n }\n }\n\n disconnectedCallback () {\n callHooks(this.vueComponent, 'deactivated');\n }\n }\n\n if (!isAsync) {\n initialize(Component);\n }\n\n return CustomElement\n}\n\nexport default wrap;\n","export interface SignatureData {\n app_id: string;\n file_id: string;\n vod_cover_url: string;\n status: VideoStatus;\n psign?: string;\n t?: string;\n us?: string;\n sign?: string;\n hls_token?: string;\n exper?: string;\n realtime_url?: string;\n}\n\nexport enum VideoStatus {\n 'converted' = 'converted',\n 'failed' = 'failed',\n 'uploading' = 'uploading',\n 'uploaded' = 'uploaded',\n 'converting' = 'converting',\n}\n\nexport interface VideoInfo {\n status?: VideoStatus;\n}\n\nexport interface Player {\n play: () => void;\n pause: () => void;\n currentTime: (time?: number) => number;\n seek: (time: number) => void;\n dispose: () => void;\n on: (event: string, cb: Function) => void;\n duration: () => number;\n isFullscreen: () => boolean;\n videoWidth: () => number;\n videoHeight: () => number;\n options: () => any;\n el_: HTMLElement;\n}\n\nexport interface PlayerOptions {\n poster: string;\n controlBar: {\n cssFullscreenToggle: boolean;\n pictureInPictureToggle: boolean;\n };\n licenseUrl: string;\n hlsConfig: {\n maxBufferLength: number;\n maxBufferSize: number;\n maxMaxBufferLength: number;\n };\n sources?: Array<{ src: string }>;\n psign?: string;\n appID?: string;\n fileID?: string;\n exper?: string;\n plugins?: any;\n}\n\nexport const HLSCONFIG = {\n maxBufferLength: 10,\n maxBufferSize: 40 * 1024 * 1024,\n maxMaxBufferLength: 30,\n};\n","const ua = navigator.userAgent.toLowerCase();\n\nconst isMicromessenger = ua.indexOf('micromessenger') > 0;\nconst isAndroid = ua.indexOf('android') > 0;\nconst isWechat = isMicromessenger && ua.indexOf('wxwork') === -1;\nconst isWxwork = isMicromessenger && ua.indexOf('wxwork') > 0;\nconst isIOS = /iphone|ipad|ipod|ios/.test(ua);\n\nexport { isAndroid, isWechat, isWxwork, isIOS };\n","import { ref, onUnmounted, nextTick } from 'vue';\nimport { type Player, type VideoInfo, VideoStatus, PlayerOptions } from '../types';\nimport { isIOS, isAndroid, isWxwork } from './agent';\n\ndeclare global {\n interface Window {\n tcplayer: any;\n Hammer: any;\n }\n}\n\nexport function useVideoPlayer() {\n const isLoading = ref(false);\n const videoInfo = ref<VideoInfo>({\n status: VideoStatus.converted,\n });\n\n const usefakeFullscreen = isIOS || (isAndroid && isWxwork);\n\n const tcplayerInstance = ref<Player>();\n let isFullscreen = false;\n let isOrientationLocked = false;\n let panStart = 0;\n let videoPanStartTime = 0;\n let isLandscape = false;\n let isPlaying = false;\n let tcplayerSDK: any = null;\n\n const loadTcplayerPlugin = async (): Promise<any> => {\n if (tcplayerSDK) return tcplayerSDK;\n const { default: tcplayer } = await import('tcplayer.js');\n tcplayerSDK = tcplayer;\n return tcplayerSDK;\n };\n\n const onDoubleTap = (player: Player) => {\n if (!isFullscreen && !isOrientationLocked) return;\n\n if (isPlaying) {\n player?.pause();\n } else {\n player?.play();\n }\n };\n\n const onStart = (ev: any, player: Player) => {\n if (!isFullscreen || isOrientationLocked) return;\n panStart = ev.deltaY;\n videoPanStartTime = player.currentTime();\n };\n\n const onMove = (ev: any, player: Player) => {\n if (!isFullscreen || isOrientationLocked) return;\n\n const delta = isLandscape ? ev.deltaY : ev.deltaX;\n const containerWidth = isLandscape ? window.innerHeight : window.innerWidth;\n const percent = (delta - panStart) / containerWidth;\n const videoDuration = player.duration();\n let currentTime = videoPanStartTime + videoDuration * percent;\n\n if (currentTime < 0) currentTime = 0;\n if (currentTime > videoDuration) currentTime = videoDuration;\n\n player.currentTime(currentTime);\n };\n\n const initGesture = async (player: Player, container: HTMLElement) => {\n try {\n // 动态导入Hammer.js\n const { default: Hammer } = await import('hammerjs');\n\n await nextTick();\n const mc = new Hammer.Manager(container);\n\n mc.add(\n new Hammer.Pan({\n threshold: 10,\n pointers: 0,\n direction: Hammer.DIRECTION_ALL,\n }),\n );\n\n mc.add(new Hammer.Swipe()).recognizeWith(mc.get('pan'));\n mc.add(new Hammer.Tap({ event: 'doubletap', taps: 2 }));\n\n mc.on('doubletap', () => {\n onDoubleTap(player);\n });\n\n mc.on('panstart', (e: any) => {\n onStart(e, player);\n });\n\n mc.on('panmove', (e: any) => {\n onMove(e, player);\n });\n } catch {}\n };\n\n const bindFullscreenHandler = (player: Player) => {\n player.on('fullscreenchange', () => {\n isFullscreen = player.isFullscreen();\n const $el = player.el_;\n const $progressBar = $el.querySelector('.vjs-progress-control') as HTMLElement;\n isLandscape = player.videoWidth() > player.videoHeight();\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n isOrientationLocked = window.orientation === 90 || window.orientation === -90;\n const shift = Math.floor(Math.abs((viewportWidth - viewportHeight) / 2));\n\n if (isLandscape) {\n if (isFullscreen) {\n Object.assign($el.style, {\n top: `${shift}px`,\n left: `-${shift}px`,\n });\n $el.classList.add('landscape');\n if ($progressBar) {\n $progressBar.style.pointerEvents = 'none';\n }\n } else {\n $el.classList.remove('landscape');\n $el.setAttribute('style', '');\n if ($progressBar) {\n $progressBar.style.pointerEvents = '';\n }\n }\n } else {\n if (!isWxwork) return;\n\n if (isFullscreen) {\n Object.assign($el.style, {\n width: '100vw',\n height: '100vh',\n position: 'fixed',\n zIndex: '999',\n top: '0px',\n });\n if ($progressBar) {\n $progressBar.style.pointerEvents = 'none';\n }\n } else {\n $el.removeAttribute('style');\n if ($progressBar) {\n $progressBar.style.pointerEvents = '';\n }\n }\n }\n });\n };\n\n const bindEvents = (selector: string, player: Player) => {\n player.on('play', () => {\n isPlaying = true;\n });\n\n player.on('pause', () => {\n isPlaying = false;\n });\n\n player.on('ended', () => {\n isPlaying = false;\n });\n\n const playerContainer = document?.getElementById(selector);\n if (playerContainer) {\n initGesture(player, playerContainer);\n }\n };\n\n const initPlayer = async (initData: PlayerOptions, selector: string) => {\n const tcplayerSDK = await loadTcplayerPlugin();\n tcplayerInstance.value = tcplayerSDK(selector, { ...initData, fakeFullscreen: usefakeFullscreen });\n if (!tcplayerInstance.value) return;\n bindEvents(selector, tcplayerInstance.value);\n isLoading.value = false;\n\n if (usefakeFullscreen) {\n bindFullscreenHandler(tcplayerInstance.value);\n }\n };\n\n const loadVideo = async (selector: string, options: PlayerOptions) => {\n if (tcplayerInstance.value) {\n tcplayerInstance.value.dispose();\n tcplayerInstance.value = undefined;\n }\n if (!selector || !options) return;\n isLoading.value = true;\n try {\n await initPlayer(options, selector);\n } catch {\n isLoading.value = false;\n }\n };\n\n onUnmounted(() => {\n if (tcplayerInstance.value) {\n tcplayerInstance.value.dispose();\n tcplayerInstance.value = undefined;\n }\n });\n\n return {\n loadVideo,\n tcplayerInstance,\n videoInfo,\n isLoading,\n };\n}\n","<template>\n <!-- 空模板,因为元素将手动添加到 Light DOM,否则会在#shandow-root(open)下,播放器sdk内部通过documnet无法获取到元素 -->\n <div id=\"tc-video-player-container\"></div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';\nimport { useVideoPlayer } from '../utils/player';\nimport type { Player, PlayerOptions } from '../types';\n\ninterface Props {\n selector?: string;\n options: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n selector: 'tcplayer',\n options: '',\n});\n\nconst emit = defineEmits<{\n (e: 'init', player: Player): void;\n (e: 'play' | 'pause' | 'ended' | 'error'): void;\n}>();\nconst { loadVideo, tcplayerInstance } = useVideoPlayer();\nconst videoElement = ref<HTMLVideoElement | null>(null);\n\nconst getHostElement = () => {\n const customElement =\n document.querySelector(`tc-video-player[selector=${props.selector}]`) ||\n document.querySelector('#tc-video-player-container');\n if (customElement && customElement instanceof HTMLElement) {\n return customElement;\n }\n return null;\n};\n\n// 创建并添加 video 元素到 Light DOM\nconst createVideoElement = () => {\n const hostElement = getHostElement();\n if (!hostElement) {\n return null;\n }\n const existingVideo = hostElement.querySelector(`#${props.selector}`);\n\n if (existingVideo) {\n existingVideo.remove();\n }\n const videoEl = document.createElement('video');\n videoEl.id = props.selector;\n videoEl.className = `tcplayer`;\n videoEl.setAttribute('preload', 'auto');\n videoEl.setAttribute('playsinline', '');\n videoEl.setAttribute('webkit-playsinline', '');\n videoEl.style.width = '100%';\n videoEl.style.height = '100%';\n videoEl.style.display = 'block';\n hostElement.parentNode?.appendChild(videoEl);\n return videoEl;\n};\n\nconst handleEmit = (method: string, params?: any) => {\n emit(method, params);\n};\n\n// 初始化播放器\nconst initializePlayer = async () => {\n if (!props.options || props.options === '{}') return;\n try {\n // 确保 video 元素存在\n if (!videoElement.value) {\n videoElement.value = createVideoElement();\n if (!videoElement.value) {\n return;\n }\n }\n await nextTick();\n const options = JSON.parse(props.options || '{}') as PlayerOptions;\n await loadVideo(props.selector, options);\n\n if (tcplayerInstance.value) {\n tcplayerInstance.value.on('play', handleEmit('play'));\n tcplayerInstance.value.on('pause', handleEmit('pause'));\n tcplayerInstance.value.on('ended', handleEmit('ended'));\n tcplayerInstance.value.on('error', handleEmit('error'));\n handleEmit('init', tcplayerInstance.value);\n }\n } catch {\n handleEmit('error');\n }\n};\n\n// 清理 video 元素\nconst cleanupVideoElement = () => {\n if (videoElement.value?.parentNode) {\n videoElement.value.parentNode.removeChild(videoElement.value);\n videoElement.value = null;\n }\n};\n\nonMounted(() => {\n // 使用 setTimeout 确保 DOM 已完全挂载\n setTimeout(() => {\n initializePlayer();\n }, 0);\n});\n\nonUnmounted(() => {\n if (tcplayerInstance.value) {\n tcplayerInstance.value.dispose();\n }\n cleanupVideoElement();\n});\n\nwatch(() => props.options, initializePlayer);\n</script>\n","import Vue from 'vue';\nimport wrap from '@vue/web-component-wrapper';\n\nimport 'tcplayer.js/dist/tcplayer.min.css';\nimport './styles/player.css';\nimport VideoPlayer from './components/VideoPlayer.vue';\n\n// 注册Web Components\nif (typeof window !== 'undefined' && window.customElements) {\n try {\n customElements.define('tc-video-player', VideoPlayerElement);\n const VideoPlayerElement = wrap(Vue, VideoPlayer);\n } catch {}\n}\nexport * from './types/index';\nexport default VideoPlayer;\n"],"names":["camelizeRE","camelize","str","_","c","hyphenateRE","hyphenate","getInitialProps","propsList","res","key","injectHook","options","hook","callHooks","vm","createCustomEvent","name","args","isBoolean","val","isNumber","convertAttributeValue","value","type","parsed","toVNodes","h","children","i","l","toVNode","node","data","getAttributes","attr","wrap","Vue","Component","isAsync","isInitialized","hyphenatedPropsList","camelizedPropsList","camelizedPropsMap","initialize","originalPropsAsObject","map","emit","CustomElement","newVal","syncAttribute","el","camelized","self","wrapper","mutations","hasChildrenChange","m","syncInitialAttributes","resolved","VideoStatus","HLSCONFIG","ua","isMicromessenger","isAndroid","isWxwork","isIOS","useVideoPlayer","isLoading","ref","videoInfo","usefakeFullscreen","tcplayerInstance","isFullscreen","isOrientationLocked","panStart","videoPanStartTime","isLandscape","isPlaying","tcplayerSDK","loadTcplayerPlugin","tcplayer","n","onDoubleTap","player","onStart","ev","onMove","delta","containerWidth","percent","videoDuration","currentTime","initGesture","container","Hammer","nextTick","mc","e","bindFullscreenHandler","$el","$progressBar","viewportWidth","viewportHeight","shift","bindEvents","selector","playerContainer","initPlayer","initData","loadVideo","onUnmounted","videoElement","getHostElement","customElement","props","createVideoElement","hostElement","existingVideo","videoEl","_a","handleEmit","method","params","initializePlayer","cleanupVideoElement","onMounted","watch","VideoPlayerElement","VideoPlayer"],"mappings":"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","x_google_ignoreList":[0]}