簡體   English   中英

Chrome 擴展程序無法播放會議音頻

[英]Chrome extension Can't play meeting audio

我正在使用 Manifest V2 開發一個 google chrome 擴展

擴展的目標是使用戶能夠在瀏覽器中開始在線會議

我使用react開發頁面,然后將這些頁面注入當前打開的網站內的iFrame

我可以從用戶那里捕獲音頻/視頻,我可以成功發送它我從其他加入會議的用戶那里接收音頻和視頻流,我可以播放他們的視頻。

問題出在音頻上,我收到 stream,但無法播放

我試過玩

  • 在有視頻工作的視頻播放器內部
  • 在與視頻相同位置的<audio>標記中
  • 在用戶單擊的第一個 iframe 的<audio>標記中
  • 通過在用戶點擊開始會議按鈕后播放“silence.mp3”文件,然后添加<audio>標簽,甚至使用js(new Audio())
  • 在后台腳本中

在所有這些情況下,我都無法播放流式傳輸的音頻

我什至沒有在控制台中收到錯誤消息

我確實注意到的一件事是,我可以播放自己的音頻(回顯我的麥克風輸入),如果我將其添加到控件可見的<audio>標記中,它就會開始計數。 但是當我將與會者音軌放在<audio>標簽上時,控件停留在 0:00

這是 VideoPlayer.jsx 的代碼

import React, { useEffect, useRef, useState } from 'react';

import msg from '../../lib/msg';
import { Flex } from '@chakra-ui/react';

const VideoPlayer = (props) => {
  const { sessionId } = props;
  const [participants, setParticipants] = useState([]);
  const [currentParticipant, setCurrentParticipant] = useState(null);
  const [videoTrack, setVideoTrack] = useState(null);
  const [audioTrack, setAudioTrack] = useState(null);
  const [isLocal, setIsLocal] = useState(false);

  useEffect(() => {
    if (currentParticipant) {
      if (currentParticipant.videoTrack) {
        setVideoTrack(currentParticipant.videoTrack);
      } else {
        setVideoTrack(null);
      }
      //set the audio track regardless if it's allowed or not, that's a decision for another function
      if (currentParticipant.audioTrack) {
        setAudioTrack(currentParticipant.audioTrack);
      } else {
        setAudioTrack(null);
      }
    }
  }, [currentParticipant]);

  const videoEl = useRef(null);
  const audioEl = useRef(null);

  /**
   * Set the video element's source
   */
  useEffect(() => {
    if (!videoEl.current || !videoTrack) return;

    videoEl.current.srcObject = new MediaStream([videoTrack]);
  }, [videoEl, videoTrack]);

  /**
   * Set the audio element's source
   */
  useEffect(() => {
    if (!audioEl.current || !audioTrack || isLocal) return;
    audioEl.current.srcObject = new MediaStream([audioTrack]);
  }, [audioEl, isLocal, audioTrack]);

  useEffect(() => {
    const reloadParticipants = () => {
      chrome.runtime.getBackgroundPage(function (win) {
        var p = win.getParticipants();
        setParticipants(p);
      });
    };
    const updateTracks = async (message, sender, sendResponse) => {
      
      chrome.runtime.getBackgroundPage(function (win) {
        var participantList = win.getParticipants();
        var index = participantList.findIndex(
          (item) => item.session_id === sessionId
        );
        var participant = participantList[index];
        setCurrentParticipant(participant);
        setIsLocal(participant.local);
      });
    };

    const msgListeners = [
      { action: msg.broadcast.participantListUpdated, fn: reloadParticipants },
      { action: msg.broadcast.tracksUpdated, fn: updateTracks },
    ];
    const initMessageListeners = async () => {
      chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
        msgListeners.forEach(async (item) => {
          if (message.action === item.action) {
            await item.fn(message, sender, sendResponse);
          }
        });
      });
    };

    initMessageListeners();
    reloadParticipants();
  }, [sessionId]);

  return (
    <div className="tile-container">
      <audio autoPlay playsInline ref={audioEl} />
      <video
        autoPlay
        muted
        playsInline
        ref={videoEl}
        style={{
          width: '100%',
          height: '100%',
          position: 'absolute',
          objectFit: 'cover',
        }}
      />
    </div>
  );
};

export default VideoPlayer;

然后我用 webpack 到 package 它成一個頁面

import React from 'react';
import { render } from 'react-dom';

import VideoPlayer from './VideoPlayer';
import './index.css';

render(<VideoPlayer />, window.document.querySelector('#app-container'));

我使用此代碼從內容腳本中注入它

// at top I have the variable
const videoPlayerUrl = chrome.runtime.getURL('/videoPlayer.html');

// I monitor for an event "participant joined" then call the following function
const createParticipantOverlay = (item) => {
    var participantContainer = $(`
    <div id="participant-${item.session_id}" class="bm_videoContainer">
      <iframe
        id="bm_ownerVideoFrame"
        class="bm_videoFrame"
        allow="autoplay *"
        src="${videoPlayerUrl}?session_id=${item.session_id}"
      ></iframe>
      <div id="bm_dragHandler" class="bm_dragHandler"></div>
    </div>`);
    var container = $('#meeting-container');
    container.append(participantContainer);

    var dragHandler = $(`#participant-${item.session_id}`).find(
      '#bm_dragHandler'
    );
    dragHandler.on('mousedown', mouseDown);
    dragHandler.on('mouseup', mouseUp);
    dragHandler.on('mousemove', mouseMove);
  };

注意:我正在使用 daily.co 來管理通話

去年我用 Daily 和 manifest v2 構建了類似的東西(順便說一下,我在 Daily 工作,所以希望我能幫助解決這個問題!)這是我用來參考的參與者Tile React 組件: https:// github.com/daily-demos/daily-notion-chrome-extension/blob/main/src/pages/Content/components/Tile.jsx

查看您的代碼,對我來說沒有什么特別明顯的。. 有沒有我可以查看的公共回購? 您可能需要收聽的不僅僅是participant-joined每日活動。 您是否還有一個用於participant-updated的事件偵聽器?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM