การบันทึกเสียงและการจับภาพหน้าจอ

คู่มือนี้อธิบายวิธีต่างๆ ในการบันทึกเสียงและวิดีโอจากแท็บ หน้าต่าง หรือหน้าจอโดยใช้ API เช่น chrome.tabCapture หรือ getDisplayMedia()

การบันทึกหน้าจอ

สำหรับการบันทึกหน้าจอ ให้เรียกใช้ getDisplayMedia() ซึ่งจะเรียกกล่องโต้ตอบดังที่แสดงด้านล่าง ซึ่งทำให้ผู้ใช้สามารถเลือกแท็บ หน้าต่าง หรือหน้าจอที่ต้องการแชร์ และช่วยบอกได้อย่างชัดเจนว่ากำลังมีการบันทึก

กล่องโต้ตอบการแชร์หน้าจอสำหรับ example.com
กล่องโต้ตอบการแชร์หน้าจอสำหรับ example.com

ตัวอย่างต่อไปนี้จะขอสิทธิ์เข้าถึงเพื่อบันทึกทั้งเสียงและวิดีโอ

const stream = await navigator.mediaDevices.getDisplayMedia({ audio: true, video: true });

หากมีการเรียกใช้ภายในสคริปต์เนื้อหา การบันทึกจะสิ้นสุดลงโดยอัตโนมัติเมื่อผู้ใช้ไปที่หน้าใหม่ หากต้องการบันทึกในเบื้องหลังและไปยังส่วนต่างๆ ให้ใช้เอกสารนอกหน้าจอพร้อมเหตุผล DISPLAY_MEDIA

การจับภาพแท็บตามท่าทางสัมผัสของผู้ใช้

การเรียกใช้ getDisplayMedia() จะทำให้เบราว์เซอร์แสดงกล่องโต้ตอบที่ถามผู้ใช้ว่าต้องการแชร์อะไร อย่างไรก็ตาม ในบางกรณีผู้ใช้เพิ่งคลิกปุ่มการทำงานเพื่อเรียกใช้ส่วนขยายของแท็บใดแท็บหนึ่ง และคุณต้องการเริ่มจับภาพแท็บทันทีโดยไม่มีข้อความแจ้งนี้

บันทึกเสียงและวิดีโอขณะล็อกหน้าจอหรือขณะใช้แอปอื่น

ตั้งแต่ Chrome 116 เป็นต้นไป คุณจะเรียกใช้ chrome.tabCapture API ใน Service Worker เพื่อรับรหัสสตรีมได้หลังจากท่าทางสัมผัสของผู้ใช้ ระบบจะส่งต่อไปไปยังเอกสารนอกหน้าจอเพื่อเริ่มบันทึก

ใน Service Worker ให้ทำดังนี้

chrome.action.onClicked.addListener(async (tab) => {
  const existingContexts = await chrome.runtime.getContexts({});

  const offscreenDocument = existingContexts.find(
    (c) => c.contextType === 'OFFSCREEN_DOCUMENT'
  );

  // If an offscreen document is not already open, create one.
  if (!offscreenDocument) {
    // Create an offscreen document.
    await chrome.offscreen.createDocument({
      url: 'offscreen.html',
      reasons: ['USER_MEDIA'],
      justification: 'Recording from chrome.tabCapture API',
    });
  }

  // Get a MediaStream for the active tab.
  const streamId = await chrome.tabCapture.getMediaStreamId({
    targetTabId: tab.id
  });

  // Send the stream ID to the offscreen document to start recording.
  chrome.runtime.sendMessage({
    type: 'start-recording',
    target: 'offscreen',
    data: streamId
  });
});

จากนั้นให้ทำดังนี้ในเอกสารนอกหน้าจอ

chrome.runtime.onMessage.addListener(async (message) => {
  if (message.target !== 'offscreen') return;
  
  if (message.type === 'start-recording') {
    const media = await navigator.mediaDevices.getUserMedia({
      audio: {
        mandatory: {
          chromeMediaSource: "tab",
          chromeMediaSourceId: message.data,
        },
      },
      video: {
        mandatory: {
          chromeMediaSource: "tab",
          chromeMediaSourceId: message.data,
        },
      },
    });

    // Continue to play the captured audio to the user.
    const output = new AudioContext();
    const source = output.createMediaStreamSource(media);
    source.connect(output.destination);

    // TODO: Do something to recording the MediaStream.
  }
});

ดูตัวอย่างแบบเต็มได้จากตัวอย่าง Tab Capture - โปรแกรมอัดเสียง

บันทึกเสียงและวิดีโอในแท็บใหม่

ก่อนที่จะมี Chrome 116 คุณจะใช้ chrome.tabCapture API ใน Service Worker หรือใช้รหัสสตรีมที่สร้างโดย API นั้นในเอกสารนอกหน้าจอไม่ได้ ทั้ง 2 ข้อนี้เป็นข้อกำหนดสำหรับวิธีข้างต้น

แต่คุณสามารถเปิดหน้าส่วนขยายในแท็บหรือหน้าต่างใหม่ และรับสตรีมโดยตรงแทนได้ ตั้งค่าพร็อพเพอร์ตี้ targetTabId เพื่อจับภาพแท็บที่ถูกต้อง

เริ่มต้นด้วยการเปิดหน้าส่วนขยาย (อาจอยู่ในป๊อปอัปหรือ Service Worker) ดังนี้

chrome.windows.create({ url: chrome.runtime.getURL("recorder.html") });

จากนั้นให้ทำดังนี้ในหน้าส่วนขยาย

chrome.tabCapture.getMediaStreamId({ targetTabId: tabId }, async (id) => {
  const media = await navigator.mediaDevices.getUserMedia({
    audio: {
      mandatory: {
        chromeMediaSource: "tab",
        chromeMediaSourceId: id,
      },
    },
    video: {
      mandatory: {
        chromeMediaSource: "tab",
        chromeMediaSourceId: id,
      },
    },
  });

  // Continue to play the captured audio to the user.
  const output = new AudioContext();
  const source = output.createMediaStreamSource(media);
  source.connect(output.destination);
});

หรืออาจลองใช้วิธีการบันทึกหน้าจอซึ่งช่วยให้คุณบันทึกในเบื้องหลังโดยใช้เอกสารนอกหน้าจอ แต่แสดงกล่องโต้ตอบให้ผู้ใช้เลือกแท็บ หน้าต่าง หรือหน้าจอที่จะใช้บันทึกได้

บันทึกเสียงในป๊อปอัป

หากต้องการบันทึกเสียงเพียงอย่างเดียว คุณสตรีมในป๊อปอัปส่วนขยายได้โดยตรงโดยใช้ chrome.tabCapture.capture เมื่อปิดป๊อปอัป การบันทึกจะหยุดลง

chrome.tabCapture.capture({ audio: true }, (stream) => {
  // Continue to play the captured audio to the user.
  const output = new AudioContext();
  const source = output.createMediaStreamSource(stream);
  source.connect(output.destination);

  // TODO: Do something with the stream (e.g record it)
});

หากต้องการให้การบันทึกคงอยู่ในการนำทางต่างๆ ให้พิจารณาใช้วิธีที่อธิบายไว้ในส่วนก่อนหน้า

ข้อควรพิจารณาอื่นๆ

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีบันทึกสตรีมได้ที่ MediaRecorder API