前端H5实现视频上传,并截取第一帧作为封面。解决微信内ios系统无法上传视频的问题,解决ios截取视频作为封面的问题。
回忆哆啦没有A梦 2024-09-18 17:33:01 阅读 91
前端H5实现视频上传,并截取封面
前端实现视频上传,并截取第一帧作为封面。
写的过程中出现的问题:
在微信内ios系统无法上传视频,无法触发<code>addEventListener的loadedmetadata
解决完1问题后,ios截取视频第一帧作为封面有问题,获取的宽度高度为0。
解决完上述两个问题后,最后完整版代码:
getCoverAndUploadVideo
入参是视频资源videoFile
,通过oss上传或者后台上传接口。
最终抛出的是视频的url,封面的url。
关于前端实现oss上传可以访问这个文章👉:vue3使用阿里oss上传资源文件
function getCoverAndUploadVideo (videoFile) {
if (!videoFile) {
return Promise.reject('Please upload a video file.');
}
return new Promise((rs, rj) => {
const video = document.createElement('video');
const url = URL.createObjectURL(videoFile);
video.src = url;
function addVideoLoadListener() {
video.addEventListener('loadedmetadata', function() {
setTimeout(() => {
try {
// 设置video的尺寸,确保能够获取整个视频帧
video.width = video.videoWidth;
video.height = video.videoHeight;
// 在视频准备好后,将currentTime设置为0尝试获取第一帧
video.currentTime = 0;
video.addEventListener('seeked', function() {
// 使用canvas绘制当前帧
const canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
// 从canvas导出图片,例如导出为base64的图片
const mimeType = 'image/png';
const imageData = canvas.toDataURL(mimeType);
const blob = base64ToBlob(imageData.split(',')[1], mimeType)
const coverFileName = videoFile.name.split('.')[0] + '_cover.png';
const coverFile = new File([blob], coverFileName, { type: mimeType });
const resources = await Promise.all([
// 通过oss上传
// window.globalOSSClient.put(videoFile.name,videoFile),
// window.globalOSSClient.put(coverFileName, coverFile),
// or
// 后端给的接口,上传后,返回的url
// ...
]).catch(rj);
rs({
videoUrl: resources[0].url,
coverUrl: resources[1].url,
});
// 释放视频URL对象
URL.revokeObjectURL(url);
}, { once: true });
} catch (err) {
rj(err);
}
}, 100)
});
}
// 解决微信浏览器下,ios上传视频,出现的问题
if ((window as any).WeixinJSBridge && /(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
window.WeixinJSBridge.invoke('getNetworkType', { }, () => {
video.muted = true;
video.playsInline = true;
video['webkit-playsinline'] = true;
addVideoLoadListener()
video.play().then(() => video.pause());
});
} else {
addVideoLoadListener();
}
});
}
function base64ToBlob(base64, mimeType) {
const byteString = atob(base64);
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++ ) {
ia[i] = byteString.charCodeAt(i);
}
const blob = new Blob([ab], { type: mimeType });
return blob;
}
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。