本篇我們將實作音視訊的錄製並下載,內容包含:
錄製影片
回放影片
下載影片
複製上一篇程式碼
cp -r take-a-photo video-recording
index.html 中 將 video play
及 button
替換為以下
<div><video autoplay playsinline id="player"></video></div>
<div><button id="shoot">拍照</button></div>
替換為
<div>
<video autoplay playsinline id="player"></video>
<video autoplay id="replayer"></video>
</div>
<div>
<button id="shoot">拍照</button>
<button id="record">錄影</button>
<button id="replay" disabled>回放</button>
<button id="download" disabled>下載</button>
</div>
錄影
、 回放
、 下載
main.js 實作
在原本的方法中增加 window.stream = stream
// 將視訊顯示在 video 標籤上
function gotStream(stream) {
videoElement.srcObject = stream
+ window.stream = stream // 增加這段,錄影需要取得stream
return navigator.mediaDevices.enumerateDevices()
}
在後面加上錄影的程式碼:
//record
let buffer
let mediaRecorder
const recvideo = document.querySelector('video#replayer');
const btnRecord = document.querySelector('button#record');
const btnPlay = document.querySelector('button#replay');
const btnDownload = document.querySelector('button#download');
function handleDataAvailable(e) {
if (e && e.data && e.data.size > 0) {
buffer.push(e.data)
}
}
function startRecord() {
buffer = []
var options = {
mimeType: 'video/webm;codecs=vp8',
}
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
console.error(`${options.mimeType} is not supported!`)
return
}
try {
mediaRecorder = new MediaRecorder(window.stream, options)
} catch (e) {
console.error('Failed to create MediaRecorder:', e)
return
}
mediaRecorder.ondataavailable = handleDataAvailable
mediaRecorder.start(10)
}
function stopRecord() {
mediaRecorder.stop()
}
btnRecord.onclick = () => {
if (btnRecord.textContent === '錄影') {
startRecord()
btnRecord.textContent = '停止'
btnPlay.disabled = true
btnDownload.disabled = true
} else {
stopRecord()
btnRecord.textContent = '錄影'
btnPlay.disabled = false
btnDownload.disabled = false
}
}
btnPlay.onclick = () => {
var blob = new Blob(buffer, { type: 'video/webm' })
recvideo.src = window.URL.createObjectURL(blob)
recvideo.srcObject = null
recvideo.controls = true
recvideo.play()
}
btnDownload.onclick = () => {
var blob = new Blob(buffer, { type: 'video/webm' })
var url = window.URL.createObjectURL(blob)
var a = document.createElement('a')
a.href = url
a.style.display = 'none'
a.download = 'video.webm'
a.click()
}
可以在瀏覽器的 console 中輸入以下
function getSupportedMimeTypes() {
const VIDEO_TYPES = ['webm', 'ogg', 'mp4', 'x-matroska']
const VIDEO_CODECS = [
'vp9', 'vp9.0', 'vp8', 'vp8.0', 'avc1', 'av1',
'h265', 'h.265', 'h264', 'h.264', 'opus'
]
const supportedTypes = []
VIDEO_TYPES.forEach((videoType) => {
const type = `video/${videoType}`
VIDEO_CODECS.forEach((codec) => {
const variations = [
`${type};codecs=${codec}`,
`${type};codecs:${codec}`,
`${type};codecs=${codec.toUpperCase()}`,
`${type};codecs:${codec.toUpperCase()}`,
`${type}`,
]
variations.forEach((variation) => {
if (MediaRecorder.isTypeSupported(variation))
supportedTypes.push(variation)
})
})
})
return supportedTypes
}
const supportedMimeTypes = getSupportedMimeTypes()
console.log('Best supported mime types by priority : ', supportedMimeTypes[0])
console.log(
'All supported mime types ordered by priority : ',
supportedMimeTypes,
)