CarsonSlovoka/chrome

console video REC

Closed this issue · 5 comments

待辦清單

TBD

v0.1

#9 (comment)

  • 新增一個控制面板,可以調整width, height, fps, ... 不用全部都使用命令列來完成
  • 可以查看到settings和maxFrameRate等等 (有一個debug的選項)

#9 (comment)

  • 解決錄製影像很模糊的問題
  • 錄製可以包含聲音
  • 修正video -h的指令會和-help指令搞混的問題

v0.0.0以前就解決的問題

#9 (comment)

  • 有可以隱藏錄製的視窗的選項 (當我們錄製console本身的時候才不會有無限的鏡中鏡) (visibility)
  • 可以調整寬、高、FPS

#9 (comment)

  • 不要使用URI改用blob
  • 可以下載檔案

  • 可以抓取螢幕、視窗、網頁分頁來錄製 (3ab9fe7)

3ab9fe7

applyConstraints 可以達到動態調整,但似乎沒辦法真的改變

/*
// const allTracks = mediaStream.getTracks()
const [track] = mediaStream.getVideoTracks()
track.applyConstraints({
width: {min: 1000, ideal: 1920, max: 1920},
height: {min: 800, ideal: 1080},
}
)
*/

視窗的主要屬性主要還是取決於

navigator.mediaDevices.getUserMedia({ // https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
audio: false,
video: { // https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#syntax
// width: { min: 640, ideal: 1920, max: 1920 }, // Cannot use both optional/mandatory and specific or advanced constraints.
mandatory: { // https://github.com/hokein/electron-sample-apps/issues/62
chromeMediaSource: "desktop",
chromeMediaSourceId: id,
maxWidth: 192,
maxHeight: 108,
maxFrameRate: fps,
}
}


透過mediaRecorder.requestData會觸發ondataavaiable的屬性,透過這邊可以寫入chunk的資料

stop() {
return new Promise(resolve => {
this.mediaRecorder.ondataavailable = (event) => {
this.chunks.push(event.data)
}
this.mediaRecorder.onstop = async (event) => {
const blob = new Blob(this.chunks, {
type: this.mediaRecorder.mimeType
})
const reader = new FileReader()
reader.readAsDataURL(blob)
const dataURI = await new Promise(resolve => {
reader.onloadend = (event) => {
resolve(event.target.result)
}
})
resolve(dataURI)
}
this.mediaRecorder.requestData() // trigger ``ondataavailable`` // https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/requestData
this.mediaRecorder.stop()
})
}

在onstop中,最後要獲得的是dataURI,但因為這個是綁在event之中,所以利用Promise的方式,它會一直等待直到resolve回傳

5a0c098

  • 改用blob,舊有的方式,使用URI其實沒有這個必要,因為不會有permission的問題

    const reader = new FileReader()
    reader.readAsDataURL(blob)
    const dataURI = await new Promise(resolve => {
    reader.onloadend = (event) => {
    resolve(event.target.result)
    }
    })
    resolve(dataURI)
    */
    resolve(URL.createObjectURL(blob)) // blobURL

  • 下載檔案,把blob的資源給它即可

    <a href="${blobURL}" download="result.webm"><button class="btn btn-primary">result.webm</button></a>
    <button data-name="release" class="ms-3 btn btn-primary">${chrome.i18n.getMessage("ReleaseResource")}</button>

b976e6f

  • 錄製影片的寬度和高度不建議調整

    video.onloadedmetadata = (e) => {
    video.width = this.#constraints.width ?? video.clientWidth
    video.height = this.#constraints.height ?? video.clientHeight
    video.play()

    視窗的大小是一開始錄製的時候就決定(中間調整視窗大小解析度也是會跑掉),

    如果這邊硬改,解析度會跑掉。

  • display and visibility

    if (!this.#constraints.display) {
    video.style.visibility = "hidden"
    }

    display 如果是 none會真的去除掉這個控鍵、也不會佔位(但是您也無法再供給canvas東西)

    而visibility只是看不到,但東西還在。

d141491

  • 解決錄製影像很模糊的問題
    這個問題主要是因為調整大小和一開始錄製的選項不符所導致
    而我們後來抓取stream的方法改用

    const videoStream = video.captureStream()
    const mediaRecorder = new MediaRecorder(videoStream, {
    // mimeType : "video/webm",
    })

    也就是不在透過canvas來獲取stream,直接抓video本身,如此我們改變video的大小和他提供的stream是兩回事,不會動到stream的內容,因此可以做到使用較小的圖,來觀測大的結果

  • 錄製可以包含聲音

    • 之前使用的是getUserMedia所以他的audio是必須具備麥克風才可以把聲音錄起來
    • getDisplayMedia可以直接抓取電腦喇叭所撥出來的聲音
  • 修正video -h的指令會和-help指令搞混的問題

    if (argObj === undefined || argObj.help) {
    showVideoHelp()
    return
    }

    移除-h的選項免得和height搞混


其他參考資料: https://github.com/CarsonSlovoka/go-src/issues/46

20384d5

UI面板

  • 新增一個控制面板,可以調整width, height, fps, ... 不用全部都使用命令列來完成
    透過指令

    video -rec -controller

  • 可以查看到settings和maxFrameRate等等 (有一個debug的選項)

    新增一個debug的選項

debug: argObj.debug ?? false,
}
const parentNode = document.getElementById(`msg-area`)
if (argObj.controller) {
Rec.RTCMediaRecorder.DisplayController(parentNode, argObj.debug ?? false)