@leafer-in/video 0.0.0-stage → 2.3.1
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 +21 -0
- package/README.md +1 -3
- package/dist/video.cjs +307 -0
- package/dist/video.esm.js +299 -0
- package/dist/video.esm.min.js +2 -0
- package/dist/video.esm.min.js.map +1 -0
- package/dist/video.js +287 -0
- package/dist/video.min.cjs +2 -0
- package/dist/video.min.cjs.map +1 -0
- package/dist/video.min.js +2 -0
- package/dist/video.min.js.map +1 -0
- package/package.json +34 -3
- package/src/PaintVideo.ts +88 -0
- package/src/Video.ts +40 -0
- package/src/VideoDecoder.ts +118 -0
- package/src/data/VideoData.ts +9 -0
- package/src/index.ts +126 -0
- package/src/interface/IVideo.ts +12 -0
- package/types/index.d.ts +82 -0
package/package.json
CHANGED
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafer-in/video",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "2.3.1",
|
|
4
|
+
"description": "@leafer-in/video",
|
|
5
|
+
"author": "Chao (Leafer) Wan",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "dist/video.esm.min.js",
|
|
9
|
+
"exports": {
|
|
10
|
+
"import": "./dist/video.esm.min.js",
|
|
11
|
+
"require": "./dist/video.min.cjs",
|
|
12
|
+
"types": "./types/index.d.ts"
|
|
13
|
+
},
|
|
14
|
+
"types": "types/index.d.ts",
|
|
15
|
+
"unpkg": "dist/video.min.js",
|
|
16
|
+
"jsdelivr": "dist/video.min.js",
|
|
17
|
+
"files": ["src","types","dist"],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/leaferjs/leafer-in.git"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/leaferjs/leafer-in/tree/main/packages/video",
|
|
23
|
+
"bugs": "https://github.com/leaferjs/leafer-in/issues",
|
|
24
|
+
"keywords": [
|
|
25
|
+
"leafer video",
|
|
26
|
+
"leafer-video",
|
|
27
|
+
"leafer-in",
|
|
28
|
+
"video",
|
|
29
|
+
"leafer-ui",
|
|
30
|
+
"leaferjs"
|
|
31
|
+
],
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@leafer-ui/draw": "^2.2.4",
|
|
34
|
+
"@leafer-ui/interface": "^2.2.4",
|
|
35
|
+
"@leafer-in/interface": "^2.2.4"
|
|
36
|
+
}
|
|
6
37
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ILeafPaint, IVideoDecoder, IUI } from '@leafer-ui/interface'
|
|
2
|
+
import { isArray } from '@leafer-ui/draw'
|
|
3
|
+
|
|
4
|
+
export class PaintVideo {
|
|
5
|
+
|
|
6
|
+
public element: IUI
|
|
7
|
+
|
|
8
|
+
public get playerOptions(): ILeafPaint { const { fill } = (this.element || this as any).__; return isArray(fill) && fill.find(item => item.type === 'video') }
|
|
9
|
+
|
|
10
|
+
public get decoder(): IVideoDecoder { const { playerOptions } = this; return playerOptions && playerOptions.image && playerOptions.image.view }
|
|
11
|
+
|
|
12
|
+
public get duration(): number { // 获取当前播放进度 (秒)
|
|
13
|
+
const video = this.decoder
|
|
14
|
+
return video && video.duration
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public get currentTime(): number { // 获取当前播放进度 (秒)
|
|
18
|
+
const video = this.decoder
|
|
19
|
+
return video && video.currentTime
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public set currentTime(time: number) { // 设置播放进度
|
|
23
|
+
const video = this.decoder
|
|
24
|
+
if (video) {
|
|
25
|
+
video.currentTime = time;
|
|
26
|
+
(this.element || this as any as IUI).forceRender()// 需要强制更新一下元素
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public get volume(): number { // 获取当前音量 (0 ~ 1)
|
|
31
|
+
const video = this.decoder
|
|
32
|
+
return video && video.volume
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public set volume(volume: number) { // 设置音量 (0 ~ 1)
|
|
36
|
+
const video = this.decoder
|
|
37
|
+
if (video) video.volume = volume
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public get paused(): boolean {
|
|
41
|
+
const video = this.decoder
|
|
42
|
+
return video && video.paused
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public get ended(): boolean {
|
|
46
|
+
const video = this.decoder
|
|
47
|
+
return video && video.ended
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
constructor(element: IUI) {
|
|
52
|
+
this.element = element
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
public togglePlay(): void {
|
|
57
|
+
const { playerOptions } = this
|
|
58
|
+
if (playerOptions) {
|
|
59
|
+
if (playerOptions.paused !== false) this.play()
|
|
60
|
+
else this.pause()
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public play(): void {
|
|
65
|
+
const { playerOptions } = this
|
|
66
|
+
if (playerOptions && playerOptions.paused !== false) {
|
|
67
|
+
playerOptions.paused = false;
|
|
68
|
+
(this.element || this as any as IUI).forceRender()
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public pause(): void {
|
|
73
|
+
const { playerOptions } = this
|
|
74
|
+
if (playerOptions) {
|
|
75
|
+
playerOptions.paused = true
|
|
76
|
+
this.decoder.pause()
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public stop(): void {
|
|
81
|
+
const { playerOptions } = this
|
|
82
|
+
if (playerOptions) {
|
|
83
|
+
playerOptions.nowIndex = 0
|
|
84
|
+
this.currentTime = 0
|
|
85
|
+
this.pause()
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
package/src/Video.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { IVideo, IVideoInputData, IVideoData, IVideoDecoder, ILeafPaint } from '@leafer-ui/interface'
|
|
2
|
+
import { Image, registerUI, dataProcessor, useModule } from '@leafer-ui/draw'
|
|
3
|
+
|
|
4
|
+
import { VideoData } from './data/VideoData'
|
|
5
|
+
import { PaintVideo } from './PaintVideo'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@useModule(PaintVideo)
|
|
9
|
+
@registerUI()
|
|
10
|
+
export class Video<TInputData = IVideoInputData> extends Image<TInputData> implements IVideo {
|
|
11
|
+
|
|
12
|
+
public get __tag() { return 'Video' }
|
|
13
|
+
|
|
14
|
+
@dataProcessor(VideoData)
|
|
15
|
+
declare public __: IVideoData
|
|
16
|
+
|
|
17
|
+
public autoplay?: boolean
|
|
18
|
+
|
|
19
|
+
public muted?: boolean
|
|
20
|
+
|
|
21
|
+
public loop?: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface Video {
|
|
25
|
+
|
|
26
|
+
readonly playerOptions: ILeafPaint
|
|
27
|
+
readonly decoder: IVideoDecoder
|
|
28
|
+
|
|
29
|
+
duration: number // 总时长
|
|
30
|
+
currentTime: number // 当前播放进度 (秒)
|
|
31
|
+
volume: number // 音量 0 ~1
|
|
32
|
+
|
|
33
|
+
readonly paused: boolean
|
|
34
|
+
readonly ended: boolean // 是否播放结束
|
|
35
|
+
|
|
36
|
+
togglePlay(): void
|
|
37
|
+
play(): void
|
|
38
|
+
pause(): void
|
|
39
|
+
stop(): void
|
|
40
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { MathHelper } from '@leafer-ui/draw'
|
|
2
|
+
import { ICanvasContext2D, IVideoDecoder, IVideoFileType, ILeaf, IVideoPlayOptions } from '@leafer-ui/interface'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
interface IVideoDecoderMap {
|
|
6
|
+
[name: string]: { Decoder: any, force?: boolean }
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class VideoDecoder implements IVideoDecoder {
|
|
10
|
+
|
|
11
|
+
public width: number // 宽度
|
|
12
|
+
public height: number // 高度
|
|
13
|
+
|
|
14
|
+
public duration: number
|
|
15
|
+
|
|
16
|
+
public get currentTime(): number { // 获取当前播放进度 (秒)
|
|
17
|
+
const video = this.decoder
|
|
18
|
+
return video.currentTime
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public set currentTime(time: number) { // 设置播放进度
|
|
22
|
+
const video = this.decoder
|
|
23
|
+
const targetTime = MathHelper.within(time, 0, this.duration)
|
|
24
|
+
video.currentTime = targetTime
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public get volume(): number { // 获取当前音量 (0 ~ 1)
|
|
28
|
+
const video = this.decoder
|
|
29
|
+
return video.volume
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public set volume(volume: number) { // 设置音量 (0 ~ 1)
|
|
33
|
+
const video = this.decoder
|
|
34
|
+
const targetVolume = MathHelper.within(volume, 0, 1)
|
|
35
|
+
video.volume = targetVolume
|
|
36
|
+
if (targetVolume > 0 && video.muted) video.muted = false // 如果音量大于 0,确保解除静音状态
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public get paused(): boolean {
|
|
40
|
+
const video = this.decoder
|
|
41
|
+
return video.paused
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public get ended(): boolean {
|
|
45
|
+
const video = this.decoder
|
|
46
|
+
return video.ended
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public loop: number // 循环次数,为0表示无限循环
|
|
50
|
+
|
|
51
|
+
public decoder: HTMLVideoElement // 解码器
|
|
52
|
+
|
|
53
|
+
// 缓冲画布
|
|
54
|
+
public bufferCanvas?: any
|
|
55
|
+
public bufferContext?: ICanvasContext2D
|
|
56
|
+
|
|
57
|
+
static decoderMap: IVideoDecoderMap = {}
|
|
58
|
+
|
|
59
|
+
static register(type: IVideoFileType, Decoder: any, force?: boolean): void {
|
|
60
|
+
VideoDecoder.decoderMap[type] = { Decoder, force }
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public load(): Promise<void> {
|
|
64
|
+
return undefined
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public play(): void {
|
|
68
|
+
const video = this.decoder
|
|
69
|
+
video.play()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public pause(): void {
|
|
73
|
+
const video = this.decoder
|
|
74
|
+
video.pause()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
public render(canvas: ICanvasContext2D, x: number, y: number, width: number, height: number, leaf: ILeaf, playOptions: IVideoPlayOptions, _imageScaleX: number, _imageScaleY: number): void {
|
|
79
|
+
let { paused } = playOptions
|
|
80
|
+
|
|
81
|
+
const video = this.decoder
|
|
82
|
+
if (video.ended) {
|
|
83
|
+
video.pause()
|
|
84
|
+
playOptions.paused = true
|
|
85
|
+
playOptions.loop = (playOptions.loop as number || 0) + 1
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (paused === false && video.paused) {
|
|
89
|
+
this.play()
|
|
90
|
+
} else if (paused === true && !video.paused) {
|
|
91
|
+
this.pause()
|
|
92
|
+
} else {
|
|
93
|
+
playOptions.paused = video.paused
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 仅在视频处于播放状态,且有实际数据更新时进行绘制
|
|
97
|
+
canvas.drawImage(video, x, y, width, height)
|
|
98
|
+
|
|
99
|
+
if (!video.paused) leaf.forceRender() // 防止停掉
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
public destroyDecoder(): void {
|
|
104
|
+
const video = this.decoder
|
|
105
|
+
if (video) {
|
|
106
|
+
|
|
107
|
+
video.pause()
|
|
108
|
+
video.src = ''
|
|
109
|
+
video.load()
|
|
110
|
+
this.decoder = null
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public close(): void {
|
|
115
|
+
this.destroyDecoder()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { LeaferVideo, Platform, Creator, PaintImage, Resource, Plugin } from '@leafer-ui/draw'
|
|
2
|
+
import { ILeaferVideo, ILeaferVideoConfig, IImageCrossOrigin, ILeaf, ILeafPaint, IVideoFileType } from '@leafer-ui/interface'
|
|
3
|
+
|
|
4
|
+
import { VideoDecoder } from './VideoDecoder'
|
|
5
|
+
|
|
6
|
+
export { Video } from './Video'
|
|
7
|
+
export { VideoData } from './data/VideoData'
|
|
8
|
+
export { VideoDecoder } from './VideoDecoder'
|
|
9
|
+
export { PaintVideo } from './PaintVideo'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
Plugin.add('video')
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
PaintImage.video = function (paint: ILeafPaint): void {
|
|
16
|
+
paint.film = true
|
|
17
|
+
paint.nowIndex = 0
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
Creator.video = function (options?: ILeaferVideoConfig): ILeaferVideo {
|
|
21
|
+
return new LeaferVideo(options)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
Resource.loadVideo = function (key: string, format?: IVideoFileType): Promise<ILeaferVideo> {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const config: ILeaferVideoConfig = { url: key }
|
|
27
|
+
if (format) config.format = format
|
|
28
|
+
const video = Creator.video(config)
|
|
29
|
+
Resource.set(key, video)
|
|
30
|
+
video.load(() => resolve(video), (e: any) => reject(e))
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
LeaferVideo.prototype.render = function (canvas: any, x: number, y: number, width: number, height: number, leaf: ILeaf, paint: any, imageScaleX: number, imageScaleY: number): void {
|
|
35
|
+
this.view.render(canvas, x, y, width, height, leaf, paint, imageScaleX, imageScaleY)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
Platform.origin.loadVideo = async function (url: string, _crossOrigin?: IImageCrossOrigin, _leaferVideo?: ILeaferVideo): Promise<any> {
|
|
40
|
+
//const buffer = await Platform.origin.loadContent(url, 'arrayBuffer')
|
|
41
|
+
|
|
42
|
+
// let ext = getFileExt(url) // 获取文件后缀名
|
|
43
|
+
|
|
44
|
+
// if (!ext) {
|
|
45
|
+
// if (leaferVideo) ext = leaferVideo.config.format
|
|
46
|
+
// if (!ext) ext = 'gif'
|
|
47
|
+
// }
|
|
48
|
+
|
|
49
|
+
// const mimeType = FileHelper.mimeType(ext)
|
|
50
|
+
const video = createVideoElement(url)
|
|
51
|
+
|
|
52
|
+
const decoder = new VideoDecoder()
|
|
53
|
+
|
|
54
|
+
const { width, height, duration } = await waitVideoMetadata(video)
|
|
55
|
+
decoder.decoder = video
|
|
56
|
+
decoder.width = width
|
|
57
|
+
decoder.height = height
|
|
58
|
+
decoder.duration = duration
|
|
59
|
+
|
|
60
|
+
await waitVideoFrameReady(video)
|
|
61
|
+
|
|
62
|
+
return decoder
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 创建并配置一个隐藏的 HTMLVideoElement
|
|
67
|
+
*/
|
|
68
|
+
function createVideoElement(url: string, muted = false, loop = false): HTMLVideoElement {
|
|
69
|
+
const video = document.createElement('video')
|
|
70
|
+
video.src = url
|
|
71
|
+
video.muted = muted
|
|
72
|
+
video.loop = loop
|
|
73
|
+
|
|
74
|
+
// 必须设置 playsInline 保证在移动端浏览器内联播放,而不是弹窗全屏
|
|
75
|
+
video.playsInline = true
|
|
76
|
+
//video.webkitPlaysInline = true
|
|
77
|
+
|
|
78
|
+
// 允许跨域(如果视频托管在 CDN,Canvas 绘制需要此属性避免 Canvas 污染/报错)
|
|
79
|
+
video.crossOrigin = 'anonymous'
|
|
80
|
+
|
|
81
|
+
return video
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 等待视频元数据加载完毕,返回视频的尺寸与时长信息
|
|
86
|
+
*/
|
|
87
|
+
function waitVideoMetadata(video: HTMLVideoElement): Promise<{ width: number; height: number; duration: number }> {
|
|
88
|
+
return new Promise((resolve) => {
|
|
89
|
+
if (video.readyState >= 1) { // HAVE_METADATA 及以上
|
|
90
|
+
resolve({
|
|
91
|
+
width: video.videoWidth,
|
|
92
|
+
height: video.videoHeight,
|
|
93
|
+
duration: video.duration
|
|
94
|
+
})
|
|
95
|
+
} else {
|
|
96
|
+
video.addEventListener('loadedmetadata', () => {
|
|
97
|
+
resolve({
|
|
98
|
+
width: video.videoWidth,
|
|
99
|
+
height: video.videoHeight,
|
|
100
|
+
duration: video.duration
|
|
101
|
+
})
|
|
102
|
+
}, { once: true })
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* 等待视频首帧可绘制到 Canvas
|
|
109
|
+
*/
|
|
110
|
+
export function waitVideoFrameReady(video: HTMLVideoElement): Promise<void> {
|
|
111
|
+
return new Promise((resolve) => {
|
|
112
|
+
if ('requestVideoFrameCallback' in video) {
|
|
113
|
+
video.requestVideoFrameCallback(() => resolve())
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if ((video as any).readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
|
|
118
|
+
resolve()
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
(video as any).addEventListener('loadeddata', () => resolve(), {
|
|
123
|
+
once: true
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IBox, IBoxData, IBoxInputData } from '@leafer-ui/interface' // IVideo, IVideoData, IVideoInputData,
|
|
2
|
+
|
|
3
|
+
// VideoBox
|
|
4
|
+
export interface IVideoBox extends IVideoAttrData, IBox {
|
|
5
|
+
__: IVideoBoxData
|
|
6
|
+
}
|
|
7
|
+
export interface IVideoBoxData extends IVideoAttrData, IBoxData { }
|
|
8
|
+
export interface IVideoBoxInputData extends IVideoAttrData, IBoxInputData { }
|
|
9
|
+
|
|
10
|
+
interface IVideoAttrData {
|
|
11
|
+
url?: string
|
|
12
|
+
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { IVideoInputData, IVideo, IVideoData, ILeafPaint, IVideoDecoder, IMultimediaType, ICanvasContext2D, IVideoFileType, ILeaf, IVideoPlayOptions, IUI } from '@leafer-ui/interface';
|
|
2
|
+
import { Image, ImageData } from '@leafer-ui/draw';
|
|
3
|
+
|
|
4
|
+
declare class Video<TInputData = IVideoInputData> extends Image<TInputData> implements IVideo {
|
|
5
|
+
get __tag(): string;
|
|
6
|
+
__: IVideoData;
|
|
7
|
+
autoplay?: boolean;
|
|
8
|
+
muted?: boolean;
|
|
9
|
+
loop?: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface Video {
|
|
12
|
+
readonly playerOptions: ILeafPaint;
|
|
13
|
+
readonly decoder: IVideoDecoder;
|
|
14
|
+
duration: number;
|
|
15
|
+
currentTime: number;
|
|
16
|
+
volume: number;
|
|
17
|
+
readonly paused: boolean;
|
|
18
|
+
readonly ended: boolean;
|
|
19
|
+
togglePlay(): void;
|
|
20
|
+
play(): void;
|
|
21
|
+
pause(): void;
|
|
22
|
+
stop(): void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare class VideoData extends ImageData {
|
|
26
|
+
get __urlType(): IMultimediaType;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface IVideoDecoderMap {
|
|
30
|
+
[name: string]: {
|
|
31
|
+
Decoder: any;
|
|
32
|
+
force?: boolean;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
declare class VideoDecoder implements IVideoDecoder {
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
duration: number;
|
|
39
|
+
get currentTime(): number;
|
|
40
|
+
set currentTime(time: number);
|
|
41
|
+
get volume(): number;
|
|
42
|
+
set volume(volume: number);
|
|
43
|
+
get paused(): boolean;
|
|
44
|
+
get ended(): boolean;
|
|
45
|
+
loop: number;
|
|
46
|
+
decoder: HTMLVideoElement;
|
|
47
|
+
bufferCanvas?: any;
|
|
48
|
+
bufferContext?: ICanvasContext2D;
|
|
49
|
+
static decoderMap: IVideoDecoderMap;
|
|
50
|
+
static register(type: IVideoFileType, Decoder: any, force?: boolean): void;
|
|
51
|
+
load(): Promise<void>;
|
|
52
|
+
play(): void;
|
|
53
|
+
pause(): void;
|
|
54
|
+
render(canvas: ICanvasContext2D, x: number, y: number, width: number, height: number, leaf: ILeaf, playOptions: IVideoPlayOptions, _imageScaleX: number, _imageScaleY: number): void;
|
|
55
|
+
destroyDecoder(): void;
|
|
56
|
+
close(): void;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
declare class PaintVideo {
|
|
60
|
+
element: IUI;
|
|
61
|
+
get playerOptions(): ILeafPaint;
|
|
62
|
+
get decoder(): IVideoDecoder;
|
|
63
|
+
get duration(): number;
|
|
64
|
+
get currentTime(): number;
|
|
65
|
+
set currentTime(time: number);
|
|
66
|
+
get volume(): number;
|
|
67
|
+
set volume(volume: number);
|
|
68
|
+
get paused(): boolean;
|
|
69
|
+
get ended(): boolean;
|
|
70
|
+
constructor(element: IUI);
|
|
71
|
+
togglePlay(): void;
|
|
72
|
+
play(): void;
|
|
73
|
+
pause(): void;
|
|
74
|
+
stop(): void;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 等待视频首帧可绘制到 Canvas
|
|
79
|
+
*/
|
|
80
|
+
declare function waitVideoFrameReady(video: HTMLVideoElement): Promise<void>;
|
|
81
|
+
|
|
82
|
+
export { PaintVideo, Video, VideoData, VideoDecoder, waitVideoFrameReady };
|