MediaRecorder API 为移动端视频处理提供了浏览器端录制的高效方案,通过 getUserMedia 获取音视频流并生成 Blob 文件,降低服务器依赖。结合 Canvas 可实现滤镜与叠加,配合 Web Audio API 能混音处理,利用 canvas.captureStream() 实现带特效的实时录制。虽不直接支持剪辑,但可通过分段录制、时间戳标记或 ffmpeg.wasm 在客户端预处理,提升用户体验并减轻服务端压力。

JS 移动端视频处理,特别是利用 MediaRecorder API,在我看来,它提供了一个相当优雅且原生的方式来解决移动设备上视频录制和部分“剪辑”需求。核心在于它能直接在浏览器端捕获媒体流,生成视频文件,大大降低了对服务器的依赖,让很多实时或离线场景的视频交互成为可能。我们不再需要把所有东西都先上传到服务器再处理,这本身就是一种解放。
JS 移动端视频处理的核心,很多时候就是围绕
MediaRecorder
首先,你需要获取用户的媒体流。这通常通过
navigator.mediaDevices.getUserMedia
async function startRecording() {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: {
facingMode: 'user' // 或 'environment' for后置摄像头
},
audio: true
});
const videoElement = document.getElementById('previewVideo');
if (videoElement) {
videoElement.srcObject = stream;
videoElement.play();
}
const options = { mimeType: 'video/webm; codecs=vp8', bitsPerSecond: 2500000 }; // 2.5 Mbps
let mediaRecorder;
try {
mediaRecorder = new MediaRecorder(stream, options);
} catch (e) {
console.warn('Using default mimeType due to unsupported options:', e);
mediaRecorder = new MediaRecorder(stream); // Fallback
}
const recordedChunks = [];
mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
recordedChunks.push(event.data);
}
};
mediaRecorder.onstop = () => {
const blob = new Blob(recordedChunks, { type: 'video/webm' });
const videoUrl = URL.createObjectURL(blob);
// 这里你可以把 videoUrl 赋值给一个 <video> 标签进行预览,或者上传到服务器
const recordedVideoElement = document.getElementById('recordedVideo');
if (recordedVideoElement) {
recordedVideoElement.src = videoUrl;
recordedVideoElement.controls = true;
recordedVideoElement.play();
}
// 停止所有媒体轨道,释放摄像头和麦克风
stream.getTracks().forEach(track => track.stop());
URL.revokeObjectURL(videoUrl); // 释放内存
};
// 开始录制
mediaRecorder.start();
console.log('Recording started...');
// 假设录制10秒后停止
setTimeout(() => {
mediaRecorder.stop();
console.log('Recording stopped.');
}, 10000);
} catch (err) {
console.error('Error accessing media devices:', err);
alert('无法访问摄像头或麦克风,请检查权限设置。');
}
}
// 示例调用 (需要在用户交互后触发,比如点击按钮)
// document.getElementById('recordButton').addEventListener('click', startRecording);至于“剪辑”,
MediaRecorder
Blob
Blob
<video>
<canvas>
canvas.captureStream()
MediaRecorder
说实话,移动端视频处理一直是个老大难问题。设备性能差异大、电池续航是个坎、浏览器兼容性五花八门,更别提网络环境的复杂性了。你不能指望所有用户都用着最新款手机、连着5G Wi-Fi。传统的做法是把视频传到服务器,服务器处理完再发回来,这中间涉及巨大的带宽消耗和等待时间,用户体验很差。尤其对于短视频社交、在线教育这种场景,实时性要求非常高。
MediaRecorder
Blob
当然,它也不是万能药。复杂的视频编辑,比如多轨剪辑、高精度特效、大规模转码,仍然是服务器或桌面应用的强项。但对于移动端常见的“录制-分享”流程,
MediaRecorder
在移动设备上使用
MediaRecorder
明智选择 mimeType
bitsPerSecond
mimeType
video/webm; codecs=vp8
video/mp4
video/mp4
video/mp4;codecs=h264
MediaRecorder
MediaRecorder.isTypeSupported('video/mp4')bitsPerSecond
function getSupportedMimeType() {
const types = [
'video/webm; codecs=vp9',
'video/webm; codecs=vp8',
'video/mp4; codecs=h264', // 注意:MP4支持在移动端差异大
'video/webm'
];
for (let i = 0; i < types.length; i++) {
if (MediaRecorder.isTypeSupported(types[i])) {
return types[i];
}
}
return 'video/webm'; // Fallback
}
const options = {
mimeType: getSupportedMimeType(),
bitsPerSecond: 3000000 // 3 Mbps
};友好的权限请求和错误处理: 第一次请求摄像头和麦克风权限时,浏览器会弹出提示。确保你的 UI 在此之前就解释清楚为什么需要这些权限,避免用户感到困惑或直接拒绝。如果用户拒绝,或者设备没有摄像头/麦克风,要给出清晰的反馈,而不是让应用崩溃。比如,可以弹出一个友好的提示,引导用户去系统设置中开启权限。
清晰的录制状态反馈: 用户需要知道现在是否在录制、录制了多长时间。一个闪烁的红点、一个倒计时器,或者一个清晰的“正在录制”文本,都能大大提升用户体验。同时,提供暂停/恢复录制的功能,让用户能更好地控制录制过程。
及时释放资源: 录制结束后,务必调用
stream.getTracks().forEach(track => track.stop())
URL.createObjectURL
URL.revokeObjectURL
处理移动端特有的挑战: 比如屏幕旋转。当设备旋转时,视频流的方向可能不会自动调整。你可能需要监听
orientationchange
screen.orientation
transform
仅仅是录制,我觉得有点浪费
MediaRecorder
Canvas 实时滤镜与叠加: 这是我个人觉得最酷的玩法之一。你可以把
getUserMedia
<canvas>
canvas.captureStream()
MediaRecorder
// 假设你有一个 video 元素显示原始视频流,一个 canvas 元素用于处理
const video = document.getElementById('previewVideo');
const canvas = document.getElementById('effectCanvas');
const ctx = canvas.getContext('2d');
let animationFrameId;
function applyEffectAndDraw() {
if (video.paused || video.ended) return;
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
// 示例:应用一个简单的灰度滤镜
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
data[i] = avg; // red
data[i + 1] = avg; // green
data[i + 2] = avg; // blue
}
ctx.putImageData(imageData, 0, 0);
// 示例:在视频上叠加文字
ctx.font = '24px Arial';
ctx.fillStyle = 'white';
ctx.fillText('Hello from Canvas!', 50, 50);
animationFrameId = requestAnimationFrame(applyEffectAndDraw);
}
video.addEventListener('play', () => {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
animationFrameId = requestAnimationFrame(applyEffectAndDraw);
// 现在,你可以用 MediaRecorder 录制 canvas.captureStream()
// const canvasStream = canvas.captureStream();
// const recorder = new MediaRecorder(canvasStream, options);
// ...
});
video.addEventListener('pause', () => {
cancelAnimationFrame(animationFrameId);
});Web Audio API 混音: 录制视频的同时,结合 Web Audio API 来处理音频流。你可以给录制的声音加上混响、均衡器效果,或者在录制时就混入背景音乐,甚至实现实时的语音变声。最后,将处理过的音频流和视频流合并,再用
MediaRecorder
与 WebAssembly (ffmpeg.wasm) 结合: 这是一个更进阶的方案。
MediaRecorder
Blob
ffmpeg.wasm
MediaRecorder
Blob
ffmpeg.wasm
多摄像头/多源录制(实验性): 某些设备和浏览器可能支持同时访问多个摄像头(比如前置和后置),或者同时录制屏幕和摄像头。虽然这实现起来非常复杂,但理论上
MediaRecorder
MediaStreamTrack
总的来说,
MediaRecorder
Blob
Blob
以上就是JS 移动端视频处理 - 使用 MediaRecorder API 实现视频录制与剪辑的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号