Recently listened to the group of small partners to share the screen recording of the relevant content -MediaRecorder, and then successfully access to an internal project.
Today share with you how to useMediaRecorder
, a few lines of code to achieve the screen recording function, and the actual scene may encounter problems.
Let me experience
Introduce the MediaRecorder
MediaRecorder is the MediaStream Recording API for easy Recording of media interface, he needs to call the MediaRecorder() constructor to instantiate.
This interface also exposes many methods and configuration items. If you are interested, you can click here to view them
This section mainly introduces some common methods according to the process.
1. Permission application
// Obtain the user screen recording permission
const stream = await navigator.mediaDevices.getDisplayMedia({
video: true
})
Copy the code
2. Confirm the recorded video type
// Verify the screen recording file types supported by the current environment
const mime = MediaRecorder.isTypeSupported('video/webm; codecs=vp9')?'video/webm; codecs=vp9' : 'video/webm'
Copy the code
Instantiate MediaRecorder
// The mimeType of step 2 and step 1stream are required
const mediaRecorder = new MediaRecorder(stream, {
mimeType: mime
})
Copy the code
3. Event monitoring
dataavailable
This event is emitted after recording is stopped (prior to onStop) and can be used to retrieve recorded media resources (a available Blob object is provided in the data property of the event)
stop
Used to handle the stop event. This event is triggered when a media recording ends, a MediaStream ends, and dataavailable is triggered.
// Used to store recorded BLOB data
const chunks = []
mediaRecorder.addEventListener('dataavailable'.function (e) {
chunks.push(e.data)
})
mediaRecorder.addEventListener('stop'.() = > {
const blob = new Blob(chunks, {
type: chunks[0].type
})
// Get the available URL
const url = URL.createObjectURL(blob)
// Get the temporary recording file path and perform your operation
// ...
}
Copy the code
4. Trigger the recording behavior
mediaRecorder.start()
Copy the code
The scene of actual combat
This application scenario is in an internal quality management platform. During the steps of asking questions, problems are described through screen recording. During the process, some common problems are encountered, so I would like to share with you.
The conventional steps of pasting images in rich text are to paste and upload, and then get a URL to display them. However, for videos, uploading immediately after recording is really a little bad user experience, and there is a waste of resources.
So we upload and replace them as we save them.
As mentioned, in the onStop callback, we can take a BLOB stream and generate a temporary path that we can preview.
When we save, we need to do two things:
1. Upload the rich text content with the video tag SRC pointing to a temporary file to our own server and get a real URL.
Rich text description replaces the corresponding temporary path with the real URL.
Code implementation
export function backTraceNode(el) {
if(! el? .children? .length) {return [el]
}
return [el, ...Array.from(el.children).map(backTraceNode)].flat()
}
// 1. Extract the temporary path of bolB file from the HTML string
const getVideoListByHtml = (html) = > {
const dom = document.createElement('div')
dom.innerHTML = html
return backTraceNode(dom)
.filter((item) = > item.nodeName === 'VIDEO')
.map((v) = > v.src)
}
// 2. Generate the corresponding File according to the temporary path
const getFileFromBlobUrl = async (blobUrlList) => {
const pList = list.map((url) = > {
return fetch(url)
})
const data = await Promise.all(pList)
const blobList = data.map((v) = > v.blob())
const res = await Promise.all(blobList)
return res.map(blob= >{
return new File([blob], 'video.webm', { type: 'video/webm'})})}// upload the file and replace the corresponding URL
const replaceVideoUrl = (html, hashUrlMapList) = > {
const dom = document.createElement('div')
dom.innerHTML = html
const videoList = backTraceNode(dom).filter((item) = > item.nodeName === 'VIDEO')
videoList.forEach((el) = > {
el.src = 'https:' + findUrlByHash(el.src, hashUrlMapList)
})
return dom.innerHTML
}
Copy the code
Matters needing attention
compatibility
Unfriendly, so far only inChrome
Can meet the application scenarios. Other browsers either do not support the API or do not support recording screen file types. However, you can obtain the support level of the current browser in advance. If you are not satisfied, you can design the interaction level. For example, if you do not support this feature, hide it or give a message.
const isSupportRecorder = () = > {
const types = ['video/webm; codecs=vp9'.'video/webm']
const isTypeSupport = types.some((v) = > MediaRecorder.isTypeSupported(v))
const isApiSupport = Boolean(navigator.mediaDevices)
return isApiSupport && isTypeSupport
}
Copy the code
- For security reasons, apply for permissions at the browser level (
navigator.mediaDevices
), supported onlyhttps
orlocalhost
- When replacing rich text content, if multiple temporary files exist, replace them with hash based on the corresponding names. Otherwise, videos may be out of order.
reference
- Developer.mozilla.org/zh-CN/docs/…
- www.wangeditor.com/doc