礼貌是儿童和青年都应该特别小心地养成习惯的第一件大事——约翰·洛克

先放代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<script>
/**
*
* @param src string 视频url
* @param currentTime double 视频截取位置,单位秒
* @return 截取图片的 base64
*/
function getImgFromVideoUrl(src, currentTime) {
if (!src) return
if (!currentTime || currentTime < 0) {
// 如果传入截取位置小于0, 给个默认值
currentTime = 0.001
}
return new Promise(resolve => {
const body = document.querySelector("body")
// 获取/创建video节点
const video = document.querySelector("#imgExtractorVideo") || document.createElement("video")
if (!video.id) {
// id,隐藏样式
Object.assign(video, {
id: 'imgExtractorVideo',
style: "display: none"
})
// 允许跨域
video.setAttribute('crossorigin', 'anonymous')
// 添加到页面上,下次就不用创建,直接用
body.append(video)
}
// 此处给video赋值,canplay需要重新赋值,否则load后不会重复调用
Object.assign(video, { src, currentTime, oncanplay })
// 获取/创建canvas节点
const canvas = document.querySelector("#imgExtractorCanvas") || document.createElement("canvas")
if (!canvas.id) {
// id,隐藏样式
Object.assign(canvas, {
id: 'imgExtractorCanvas',
style: "display: none"
})
// 添加到页面上,下次就不用创建,直接用
body.append(canvas)
}
// 获取canvas context
const context = canvas.getContext("2d")
// canvas渲染视频节点,转换为base64
async function oncanplay() {
// 为canvas设置宽高为视频的宽高
Object.assign(canvas, { height: video.videoHeight, width: video.videoWidth })
// 渲染视频
context.drawImage(video, 0, 0)
// 获取视频时长
const duration = isNaN(video.duration) ? 0 : video.duration
if (currentTime > duration) {
// 如果当前传入截取位置大于视频时长,取视频时长 -0.1 然后重新截取
currentTime = duration - 0.1;
resolve(await getImgFromVideoUrl(src, currentTime))
} else {
// 这里的 toDataURL 第二个参数为图片质量,可接受范围 0~1 ,超出后为默认值 0.92
resolve(canvas.toDataURL("image/png", 1.0))
}
}
})
}



window.onload = async () => {
// 视频长度 15s 左右

// 调用
let imgBase64 = await getImgFromVideoUrl("/imgs/oss/picGo/rabbit.mp4")

// 使用
console.log({ imgBase64 })
let img = document.createElement("img")
img.src = imgBase64
document.querySelector("body").append(img)

// 调用
imgBase64 = await getImgFromVideoUrl("/imgs/oss/picGo/rabbit.mp4", 3)
// 重复使用
console.log({ imgBase64 })
img = document.createElement("img")
img.src = imgBase64
document.querySelector("body").append(img)

// 调用
imgBase64 = await getImgFromVideoUrl("/imgs/oss/picGo/rabbit.mp4", 4)
// 重复使用
console.log({ imgBase64 })
img = document.createElement("img")
img.src = imgBase64
document.querySelector("body").append(img)

// 调用
imgBase64 = await getImgFromVideoUrl("/imgs/oss/picGo/rabbit.mp4", 20)
// 重复使用
console.log({ imgBase64 })
img = document.createElement("img")
img.src = imgBase64
document.querySelector("body").append(img)

// Promise回调地狱
getImgFromVideoUrl("/imgs/oss/picGo/rabbit.mp4", 3)
.then(base64 => {
// 使用
console.log({ base64 })
let img = document.createElement("img")
img.src = base64
document.querySelector("body").append(img)

// Promise回调地狱
getImgFromVideoUrl("/imgs/oss/picGo/rabbit.mp4", 4)
.then(base64 => {
// 使用
console.log({ base64 })
let img = document.createElement("img")
img.src = base64
document.querySelector("body").append(img)

// Promise回调地狱
getImgFromVideoUrl("/imgs/oss/picGo/rabbit.mp4", 5)
.then(base64 => {
// 使用
console.log({ base64 })
let img = document.createElement("img")
img.src = base64
document.querySelector("body").append(img)
})
})
})

}



</script>

效果:

image-20220903231413684

接下来是博客和MDN

Promise博客:https://VampireAchao.github.io/2021/12/04/Promise/

oss视频截封面博客:https://VampireAchao.github.io/2022/01/10/oss视频截封面/

MDN

如果我们Base64需要下载,可以参考:blob和base64互转