JS代码:
// 顶层变量存储文件对象,供后续合成使用
let videoFile = null;
const {
Input,
Output,
Conversion,
ALL_FORMATS,
BlobSource,
Mp4OutputFormat,
BufferTarget,
CanvasSink
} = Mediabunny;
const range = document.getElementById('clipRange');
// 视频选择与预览
fileVideo.addEventListener('change', async (event) => {
const file = event.target.files[0];
if (file) {
videoFile = file;
const input = new Input({
formats: ALL_FORMATS,
source: new BlobSource(file)
});
const videoTrack = await input.getPrimaryVideoTrack();
if (videoTrack) {
const decodable = await videoTrack.canDecode();
if (decodable) {
const sink = new CanvasSink(videoTrack, {
// 缩略图尺寸
width: 160
});
// 选10张图作为缩略图
const startTimestamp = await videoTrack.getFirstTimestamp();
const endTimestamp = await videoTrack.computeDuration();
// range选择的min max 设置
range.innerHTML = '<input type="range" data-tips="${value}s" is="ui-range" width="100%" multiple step="0.1" min="'+ Math.round(startTimestamp * 10) / 10 +'" max="'+ Math.round(endTimestamp * 10) / 10 +'">';
// 生成10个时间戳
// 10个时间戳,每个时间戳间隔相同
const timestamps = Array.from({ length: 10 }).map(
(t, index) => startTimestamp + index * (endTimestamp - startTimestamp) / 10
);
// Loop over these timestamps
for await (const result of sink.canvasesAtTimestamps(timestamps)) {
const canvas = result.canvas;
const url = canvas.toDataURL('image/jpeg');
const img = document.createElement('img');
img.src = url;
img.alt = `缩略图${result.timestamp}`;
videoThumb.appendChild(img);
}
}
}
}
});
form.addEventListener('submit', async (event) => {
event.preventDefault();
const submit = form.querySelector('button');
submit.textContent = '剪裁中...';
submit.disabled = true;
const input = new Input({
formats: ALL_FORMATS,
source: new BlobSource(videoFile)
});
const output = new Output({
format: new Mp4OutputFormat(), // The format of the file
target: new BufferTarget()
});
const eleRange = range.querySelector('input');
const conversion = await Conversion.init({
input,
output,
trim: {
start: eleRange.from,
end: eleRange.to
},
});
conversion.onProgress = function (progress) {
submit.textContent = `剪裁中...${Math.round(progress * 100)}%`;
};
await conversion.execute();
const buffer = output.target.buffer;
const url = URL.createObjectURL(new Blob([buffer]));
result.innerHTML = `<video src="${url}" controls></video>`;
submit.textContent = '开始剪裁';
submit.disabled = false;
});