51
51
52
52
<UButtonGroup >
53
53
<UButton @click =" confirm(close)" >确定</UButton >
54
- <UButton color =" white" @click =" reset(close )" >清空</UButton >
54
+ <UButton color =" white" @click =" reset()" >清空</UButton >
55
55
</UButtonGroup >
56
56
</div >
57
57
</template >
58
58
</UPopover >
59
59
</template >
60
60
61
61
<script setup lang="ts">
62
- import type {Video , VideoType } from " ~/types" ;
63
- import {toast } from " vue-sonner" ;
64
- import {useUpload } from " ~/utils" ;
62
+ import type { Video , VideoType } from " ~/types" ;
63
+ import { toast } from " vue-sonner" ;
64
+ import { useUpload } from " ~/utils" ;
65
65
66
66
const props = withDefaults (defineProps <Video >(), {
67
67
type: " youtube" ,
68
68
value: " "
69
69
})
70
70
const emit = defineEmits ([' confirm' ])
71
- const videoType = ref < VideoType >( props . type )
71
+
72
72
const youtubeUrl = ref (' ' )
73
73
const bilibiliUrl = ref (' ' )
74
74
const onlineUrl = ref (' ' )
75
- const youtubeUrlRegs = [/ v=([^ &#] + )/ , / youtu\. be\/ (. * )\? / ]
76
75
const progress = ref (0 )
77
76
const filename = ref (' ' )
78
77
const total = ref (0 )
79
78
const current = ref (0 )
79
+
80
80
const items = [{
81
81
slot: ' uploadVideo' ,
82
82
label: ' 本地'
@@ -85,8 +85,36 @@ const items = [{
85
85
label: ' 在线'
86
86
}]
87
87
88
+ const youtubeUrlTemplateList = [
89
+ {
90
+ reg: / src=['"] (?:https? :)? (?:\/ )* ([^ '"] + )['"] / ,
91
+ template: ' https://@{placeholder}' ,
92
+ },
93
+ {
94
+ reg: / v=([^ &#] + )/ ,
95
+ template: ' https://www.youtube.com/embed/@{placeholder}' ,
96
+ },
97
+ {
98
+ reg: / youtu\. be\/ ([^ \/\? ] + )/ ,
99
+ template: ' https://www.youtube.com/embed/@{placeholder}' ,
100
+ },
101
+ ]
102
+ const bilibiliUrlTemplateList = [
103
+ {
104
+ reg: / src=['"] (?:https? :)? (?:\/ )* ([^ '"] + )['"] / ,
105
+ template: ' https://@{placeholder}' ,
106
+ },
107
+ {
108
+ reg: / av(\d + )/ i ,
109
+ template: ' https://player.bilibili.com/player.html?aid=@{placeholder}' ,
110
+ },
111
+ {
112
+ reg: / (bv[\w ] + )/ i ,
113
+ template: ' https://player.bilibili.com/player.html?bvid=@{placeholder}' ,
114
+ },
115
+ ]
116
+
88
117
watch (props , () => {
89
- videoType .value = props .type
90
118
if (props .type === ' youtube' ) {
91
119
youtubeUrl .value = props .value
92
120
} else if (props .type === ' bilibili' ) {
@@ -98,7 +126,7 @@ watch(props, () => {
98
126
99
127
const handleUploadVideo = async (files : FileList ) => {
100
128
for (let i = 0 ; i < files .length ; i ++ ) {
101
- if (files [i ].type .indexOf (" video" ) < 0 ){
129
+ if (files [i ].type .indexOf (" video" ) < 0 ) {
102
130
toast .error (" 只能上传视频文件" );
103
131
return
104
132
}
@@ -114,69 +142,95 @@ const handleUploadVideo = async (files: FileList) => {
114
142
onlineUrl .value = result [0 ]
115
143
}
116
144
}
145
+
146
+ const emitUrl = (type : VideoType , value : string ) => {
147
+ if (type !== ' youtube' ) {
148
+ youtubeUrl .value = ' '
149
+ }
150
+
151
+ if (type !== ' bilibili' ) {
152
+ bilibiliUrl .value = ' '
153
+ }
154
+
155
+ if (type !== ' online' ) {
156
+ onlineUrl .value = ' '
157
+ }
158
+
159
+ emit (' confirm' , {
160
+ type ,
161
+ value ,
162
+ })
163
+ }
164
+
117
165
const confirm = (close : Function ) => {
118
- const match = bilibiliUrl .value .match (/ src=['"] ([^ '"] + )['"] / )
166
+ if (bilibiliUrl .value .trim () && youtubeUrl .value .trim ()) {
167
+ toast .warning (" 请勿同时填写两个地址" )
168
+ return
169
+ }
170
+
119
171
if (bilibiliUrl .value .trim ()) {
120
- videoType .value = ' bilibili'
121
- if (match && match .length > 1 ) {
122
- emit (' confirm' , {
123
- type: videoType .value ,
124
- value: bilibiliUrl .value
125
- })
172
+ if (bilibiliUrl .value .startsWith (' https://player.bilibili.com/player.html' )) {
173
+ emitUrl (' bilibili' , bilibiliUrl .value )
126
174
close ()
127
- } else {
128
- toast .warning (" 无效的B站视频地址" )
129
175
return
130
176
}
177
+
178
+ for (const bilibiliUrlTemplate of bilibiliUrlTemplateList ) {
179
+ const { reg, template } = bilibiliUrlTemplate
180
+ const [_, matchedValue] = bilibiliUrl .value .match (reg ) || []
181
+ if (matchedValue ) {
182
+ const url = template .replace (' @{placeholder}' , matchedValue )
183
+ emitUrl (' bilibili' , url )
184
+ close ()
185
+ return
186
+ }
187
+ }
188
+
189
+ toast .warning (" 无效的B站视频地址" )
131
190
return
132
191
}
133
192
134
193
if (youtubeUrl .value .trim ()) {
135
- videoType .value = ' youtube'
136
- let success = false
137
- for (let i = 0 ; i < youtubeUrlRegs .length ; i ++ ) {
138
- const match = youtubeUrl .value .match (youtubeUrlRegs [i ])
139
- if (match && match .length > 1 ) {
140
- success = true
141
- break
142
- }
143
- }
144
- if (success ) {
145
- emit (' confirm' , {
146
- type: videoType .value ,
147
- value: youtubeUrl .value
148
- })
194
+ if (youtubeUrl .value .startsWith (' https://www.youtube.com/embed' )) {
195
+ emitUrl (' youtube' , youtubeUrl .value )
149
196
close ()
150
- } else {
151
- toast .warning (" 无效的Youtube视频地址" )
197
+ return
152
198
}
199
+
200
+ for (const youtubeUrlTemplate of youtubeUrlTemplateList ) {
201
+ const { reg, template } = youtubeUrlTemplate
202
+ const [_, matchedValue] = youtubeUrl .value .match (reg ) || []
203
+ if (matchedValue ) {
204
+ const url = template .replace (' @{placeholder}' , matchedValue )
205
+ emitUrl (' youtube' , url )
206
+ close ()
207
+ return
208
+ }
209
+ }
210
+
211
+ toast .warning (" 无效的Youtube视频地址" )
153
212
return
154
213
}
214
+
155
215
if (onlineUrl .value .trim ()) {
156
- videoType .value = ' online'
157
- emit (' confirm' , {
158
- type: videoType .value ,
159
- value: onlineUrl .value .trim ()
160
- })
216
+ emitUrl (' online' , onlineUrl .value .trim ())
161
217
close ()
162
218
return
163
219
}
164
220
}
165
221
166
- const reset = (close : Function ) => {
167
- videoType .value = ' youtube'
222
+ const reset = () => {
168
223
youtubeUrl .value = ' '
169
224
bilibiliUrl .value = ' '
170
225
onlineUrl .value = ' '
226
+
171
227
emit (' confirm' , {
172
- type: videoType . value ,
228
+ type: ' youtube ' ,
173
229
value: " "
174
230
})
175
231
}
176
232
177
233
178
234
</script >
179
235
180
- <style scoped>
181
-
182
- </style >
236
+ <style scoped></style >
0 commit comments